Skip to content

Commit

Permalink
Merge pull request #36 from darkforestry/feat/izumi
Browse files Browse the repository at this point in the history
Feat/izumi
  • Loading branch information
0xKitsune authored May 16, 2023
2 parents c8f493e + dca9b6c commit 2f23f58
Show file tree
Hide file tree
Showing 17 changed files with 8,872 additions and 30 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ cargo doc --open
| Curve Pools |||
| Balancer Pools |||
| Bancor Pools |||
| Izumi Pools | ||
| Izumi Pools | ||
| ERC4626 Vaults |||


Expand Down
154 changes: 154 additions & 0 deletions contracts/izumi/GetiZiPoolDataBatchRequest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IiZiSwapPool {
function liquidity(bytes32 key)
external
view
returns (
uint128 liquidity,
uint256 lastFeeScaleX_128,
uint256 lastFeeScaleY_128,
uint256 tokenOwedX,
uint256 tokenOwedY
);

function tokenX() external view returns (address);
function tokenY() external view returns (address);

function sqrtRate_96() external view returns(uint160);
function fee() external view returns (uint24);
function pointDelta() external view returns (int24);
function state()
external view
returns(
uint160 sqrtPrice_96,
int24 currentPoint,
uint16 observationCurrentIndex,
uint16 observationQueueLen,
uint16 observationNextQueueLen,
bool locked,
uint128 liquidity,
uint128 liquidityX
);
}
/**
@dev This contract is not meant to be deployed. Instead, use a static call with the
deployment bytecode as payload.
*/
contract GetiZiPoolDataBatchRequest {
struct PoolData {
address tokenA;
uint8 tokenADecimals;
address tokenB;
uint8 tokenBDecimals;
uint128 liquidity;
uint160 sqrtPrice;
uint128 liquidityA;
uint128 liquidityB;
int24 currentPoint;
int24 pointDelta;
uint24 fee;
}

constructor(address[] memory pools) {
PoolData[] memory allPoolData = new PoolData[](pools.length);

for (uint256 i = 0; i < pools.length; ++i) {
address poolAddress = pools[i];

if (codeSizeIsZero(poolAddress)) continue;

PoolData memory poolData;

poolData.tokenA = IiZiSwapPool(poolAddress).tokenX();
poolData.tokenB = IiZiSwapPool(poolAddress).tokenY();

//Check that tokenA and tokenB do not have codesize of 0
if (codeSizeIsZero(poolData.tokenA)) continue;
if (codeSizeIsZero(poolData.tokenB)) continue;

//Get tokenA decimals
(
bool tokenADecimalsSuccess,
bytes memory tokenADecimalsData
) = poolData.tokenA.call(abi.encodeWithSignature("decimals()"));

if (tokenADecimalsSuccess) {
uint256 tokenADecimals;

if (tokenADecimalsData.length == 32) {
(tokenADecimals) = abi.decode(
tokenADecimalsData,
(uint256)
);

if (tokenADecimals == 0 || tokenADecimals > 255) {
continue;
} else {
poolData.tokenADecimals = uint8(tokenADecimals);
}
} else {
continue;
}
} else {
continue;
}

(
bool tokenBDecimalsSuccess,
bytes memory tokenBDecimalsData
) = poolData.tokenB.call(abi.encodeWithSignature("decimals()"));

if (tokenBDecimalsSuccess) {
uint256 tokenBDecimals;
if (tokenBDecimalsData.length == 32) {
(tokenBDecimals) = abi.decode(
tokenBDecimalsData,
(uint256)
);

if (tokenBDecimals == 0 || tokenBDecimals > 255) {
continue;
} else {
poolData.tokenBDecimals = uint8(tokenBDecimals);
}
} else {
continue;
}
} else {
continue;
}

(uint160 sqrtPriceX96, int24 currentPoint, , , , , uint128 liquidity, uint128 liquidityX) = IiZiSwapPool(
poolAddress
).state();


poolData.fee = IiZiSwapPool(poolAddress).fee();
poolData.pointDelta = IiZiSwapPool(poolAddress).pointDelta();
poolData.sqrtPrice = sqrtPriceX96;
poolData.currentPoint = currentPoint;
poolData.liquidity = liquidity;
poolData.liquidityA = liquidityX;
poolData.liquidityB = liquidity - liquidityX;
allPoolData[i] = poolData;
}

bytes memory _abiEncodedData = abi.encode(allPoolData);
assembly {
// Return from the start of the data (discarding the original data address)
// up to the end of the memory used
let dataStart := add(_abiEncodedData, 0x20)
return(dataStart, sub(msize(), dataStart))
}
}

function codeSizeIsZero(address target) internal view returns (bool) {
if (target.code.length == 0) {
return true;
} else {
return false;
}
}
}
101 changes: 101 additions & 0 deletions contracts/izumi/SynciZiPoolDataBatchRequest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IiZiSwapPool {
function liquidity(
bytes32 key
)
external
view
returns (
uint128 liquidity,
uint256 lastFeeScaleX_128,
uint256 lastFeeScaleY_128,
uint256 tokenOwedX,
uint256 tokenOwedY
);

function tokenX() external view returns (address);

function tokenY() external view returns (address);

function sqrtRate_96() external view returns (uint160);

function fee() external view returns (uint24);

function pointDelta() external view returns (int24);

function state()
external
view
returns (
uint160 sqrtPrice_96,
int24 currentPoint,
uint16 observationCurrentIndex,
uint16 observationQueueLen,
uint16 observationNextQueueLen,
bool locked,
uint128 liquidity,
uint128 liquidityX
);
}

/**
@dev This contract is not meant to be deployed. Instead, use a static call with the
deployment bytecode as payload.
*/
contract SynciZiPoolDataBatchRequest {
struct PoolData {
uint128 liquidity;
uint160 sqrtPrice;
uint128 liquidityA;
uint128 liquidityB;
int24 currentPoint;
}

constructor(address[] memory pools) {
PoolData[] memory allPoolData = new PoolData[](pools.length);

for (uint256 i = 0; i < pools.length; ++i) {
address poolAddress = pools[i];

if (codeSizeIsZero(poolAddress)) continue;

PoolData memory poolData;

(
uint160 sqrtPriceX96,
int24 currentPoint,
,
,
,
,
uint128 liquidity,
uint128 liquidityX
) = IiZiSwapPool(poolAddress).state();

poolData.sqrtPrice = sqrtPriceX96;
poolData.currentPoint = currentPoint;
poolData.liquidity = liquidity;
poolData.liquidityA = liquidityX;
poolData.liquidityB = liquidity - liquidityX;
allPoolData[i] = poolData;
}

bytes memory _abiEncodedData = abi.encode(allPoolData);
assembly {
// Return from the start of the data (discarding the original data address)
// up to the end of the memory used
let dataStart := add(_abiEncodedData, 0x20)
return(dataStart, sub(msize(), dataStart))
}
}

function codeSizeIsZero(address target) internal view returns (bool) {
if (target.code.length == 0) {
return true;
} else {
return false;
}
}
}
2 changes: 1 addition & 1 deletion examples/discover-erc-4626-vaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
let provider = Arc::new(Provider::<Http>::try_from(rpc_endpoint).unwrap());

//discover vaults
let _vaults = discovery::erc_4626::discover_erc_4626_vaults(provider).await?;
let _vaults = discovery::erc_4626::discover_erc_4626_vaults(provider, 30000).await?;

Ok(())
}
8 changes: 5 additions & 3 deletions examples/discover-factories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ use damms::discovery::factory::{discover_factories, DiscoverableFactory};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let factories_filename = "gnosis_factories.json";
let number_of_amms_threshold = 50;
let factories_filename = "fantom_factories.json";
let number_of_amms_threshold = 10;

//Add rpc endpoint here:
let rpc_endpoint = "https://rpc.gnosis.gateway.fm";
let rpc_endpoint =
std::env::var("ARBITRUM_MAINNET_ENDPOINT").expect("Could not get ETHEREUM_RPC_ENDPOINT");

let provider = Arc::new(Provider::<Http>::try_from(rpc_endpoint).unwrap());

let factories = discover_factories(
vec![
DiscoverableFactory::UniswapV2Factory,
DiscoverableFactory::UniswapV3Factory,
DiscoverableFactory::IziSwapFactory,
],
number_of_amms_threshold,
provider,
Expand Down
41 changes: 21 additions & 20 deletions examples/sync-amms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,43 @@ use ethers::{
};

use damms::{
amm::{
factory::Factory, uniswap_v2::factory::UniswapV2Factory,
uniswap_v3::factory::UniswapV3Factory,
},
amm::{factory::Factory, izumi::factory::IziSwapFactory},
sync,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
//Add rpc endpoint here:
let rpc_endpoint =
std::env::var("ETHEREUM_RPC_ENDPOINT").expect("Could not get ETHEREUM_RPC_ENDPOINT");
std::env::var("ARBITRUM_MAINNET_ENDPOINT").expect("Could not get ETHEREUM_RPC_ENDPOINT");
let provider = Arc::new(Provider::<Http>::try_from(rpc_endpoint).unwrap());

let factories = vec![
//UniswapV2
Factory::UniswapV2Factory(UniswapV2Factory::new(
H160::from_str("0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f").unwrap(),
2638438,
300,
)),
//Add Sushiswap
Factory::UniswapV2Factory(UniswapV2Factory::new(
H160::from_str("0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac").unwrap(),
10794229,
300,
)),
// Factory::UniswapV2Factory(UniswapV2Factory::new(
// H160::from_str("0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f").unwrap(),
// 2638438,
// 300,
// )),
// //Add Sushiswap
// Factory::UniswapV2Factory(UniswapV2Factory::new(
// H160::from_str("0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac").unwrap(),
// 10794229,
// 300,
// )),
//Add UniswapV3
Factory::UniswapV3Factory(UniswapV3Factory::new(
H160::from_str("0x1F98431c8aD98523631AE4a59f267346ea31F984").unwrap(),
12369621,
// Factory::UniswapV3Factory(UniswapV3Factory::new(
// H160::from_str("0x1F98431c8aD98523631AE4a59f267346ea31F984").unwrap(),
// 185,
// )),
Factory::IziSwapFactory(IziSwapFactory::new(
H160::from_str("0x45e5f26451cdb01b0fa1f8582e0aad9a6f27c218").unwrap(),
26815159,
)),
];

//Sync pairs
sync::sync_amms(factories, provider, None).await?;
sync::sync_amms(factories, provider, None, 30000).await?;

Ok(())
}
Loading

0 comments on commit 2f23f58

Please sign in to comment.