diff --git a/README.md b/README.md index b29d9b05e7..c653b9afd8 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ Run an `autopilot` with: ```sh cargo run --bin autopilot -- \ - --skip-event-sync \ + --skip-event-sync true \ --node-url ``` diff --git a/crates/contracts/artifacts/TestnetUniswapV2Router02.json b/crates/contracts/artifacts/TestnetUniswapV2Router02.json new file mode 120000 index 0000000000..e485e1a596 --- /dev/null +++ b/crates/contracts/artifacts/TestnetUniswapV2Router02.json @@ -0,0 +1 @@ +IUniswapLikeRouter.json \ No newline at end of file diff --git a/crates/contracts/build.rs b/crates/contracts/build.rs index 9697c5db1e..ca38a84e9d 100644 --- a/crates/contracts/build.rs +++ b/crates/contracts/build.rs @@ -13,6 +13,7 @@ mod paths; const MAINNET: &str = "1"; const GOERLI: &str = "5"; const GNOSIS: &str = "100"; +const SEPOLIA: &str = "11155111"; fn main() { // NOTE: This is a workaround for `rerun-if-changed` directives for @@ -51,6 +52,15 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(25414331)), }, ) + .add_network( + SEPOLIA, + Network { + // + address: addr("0x0b7795E18767259CC253a2dF471db34c72B49516"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(4718739)), + }, + ) }); generate_contract_with_config("CoWSwapOnchainOrders", |builder| { builder.contract_mod_override("cowswap_onchain_orders") @@ -93,11 +103,20 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(24821598)), }, ) + .add_network( + SEPOLIA, + Network { + address: addr("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(3418831)), + }, + ) }); generate_contract_with_config("BalancerV2WeightedPoolFactory", |builder| { builder .contract_mod_override("balancer_v2_weighted_pool_factory") .add_network( + // MAINNET, Network { address: addr("0x8E9aa87E45e92bad84D5F8DD1bff34Fb92637dE9"), @@ -106,6 +125,7 @@ fn main() { }, ) .add_network( + // GOERLI, Network { address: addr("0x8E9aa87E45e92bad84D5F8DD1bff34Fb92637dE9"), @@ -113,11 +133,14 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(4648101)), }, ) + // Not available on Sepolia (only version ≥ 4) + // }); generate_contract_with_config("BalancerV2WeightedPoolFactoryV3", |builder| { builder .contract_mod_override("balancer_v2_weighted_pool_factory_v3") .add_network( + // MAINNET, Network { address: addr("0x5Dd94Da3644DDD055fcf6B3E1aa310Bb7801EB8b"), @@ -126,6 +149,7 @@ fn main() { }, ) .add_network( + // GOERLI, Network { address: addr("0x26575A44755E0aaa969FDda1E4291Df22C5624Ea"), @@ -141,6 +165,8 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(26226256)), }, ) + // Not available on Sepolia (only version ≥ 4) + // }); generate_contract_with_config("BalancerV2WeightedPoolFactoryV4", |builder| { builder @@ -169,11 +195,21 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(27055829)), }, ) + .add_network( + // + SEPOLIA, + Network { + address: addr("0x7920BFa1b2041911b354747CA7A6cDD2dfC50Cfd"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(3424893)), + }, + ) }); generate_contract_with_config("BalancerV2WeightedPool2TokensFactory", |builder| { builder .contract_mod_override("balancer_v2_weighted_pool_2_tokens_factory") .add_network( + // MAINNET, Network { address: addr("0xa5bf2ddf098bb0ef6d120c98217dd6b141c74ee0"), @@ -182,6 +218,7 @@ fn main() { }, ) .add_network( + // GOERLI, Network { address: addr("0xa5bf2ddf098bb0ef6d120c98217dd6b141c74ee0"), @@ -189,11 +226,14 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(4716924)), }, ) + // Not available on Sepolia + // }); generate_contract_with_config("BalancerV2StablePoolFactoryV2", |builder| { builder .contract_mod_override("balancer_v2_stable_pool_factory_v2") .add_network( + // MAINNET, Network { address: addr("0x8df6efec5547e31b0eb7d1291b511ff8a2bf987c"), @@ -202,6 +242,7 @@ fn main() { }, ) .add_network( + // GOERLI, Network { address: addr("0xD360B8afb3d7463bE823bE1Ec3c33aA173EbE86e"), @@ -217,11 +258,14 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(25415344)), }, ) + // Not available on Sepolia + // }); generate_contract_with_config("BalancerV2LiquidityBootstrappingPoolFactory", |builder| { builder .contract_mod_override("balancer_v2_liquidity_bootstrapping_pool_factory") .add_network( + // MAINNET, Network { address: addr("0x751A0bC0e3f75b38e01Cf25bFCE7fF36DE1C87DE"), @@ -229,7 +273,16 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(12871780)), }, ) - // Not deployed on Görli + .add_network( + GOERLI, + Network { + address: addr("0xb48Cc42C45d262534e46d5965a9Ac496F1B7a830"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(6993037)), + }, + ) + // Not available on Sepolia + // }); generate_contract_with_config( "BalancerV2NoProtocolFeeLiquidityBootstrappingPoolFactory", @@ -239,6 +292,7 @@ fn main() { "balancer_v2_no_protocol_fee_liquidity_bootstrapping_pool_factory", ) .add_network( + // MAINNET, Network { address: addr("0x0F3e0c4218b7b0108a3643cFe9D3ec0d4F57c54e"), @@ -246,7 +300,33 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(13730248)), }, ) - // Not deployed on Görli + .add_network( + // + GOERLI, + Network { + address: addr("0xB0C726778C3AE4B3454D85557A48e8fa502bDD6A"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(6993471)), + }, + ) + .add_network( + // + GNOSIS, + Network { + address: addr("0x85a80afee867aDf27B50BdB7b76DA70f1E853062"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(25415236)), + }, + ) + .add_network( + // + SEPOLIA, + Network { + address: addr("0x45fFd460cC6642B8D8Fb12373DFd77Ceb0f4932B"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(3419649)), + }, + ) }, ); generate_contract_with_config("BalancerV2ComposableStablePoolFactory", |builder| { @@ -268,6 +348,9 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(7542764)), }, ) + // Not available on Sepolia and Gnosis Chain + // + // }); generate_contract_with_config("BalancerV2ComposableStablePoolFactoryV3", |builder| { builder @@ -296,6 +379,8 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(26365805)), }, ) + // Not available on Sepolia (only version ≥ 4) + // }); generate_contract_with_config("BalancerV2ComposableStablePoolFactoryV4", |builder| { builder @@ -324,6 +409,15 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(27056416)), }, ) + .add_network( + // + SEPOLIA, + Network { + address: addr("0xA3fd20E29358c056B727657E83DFd139abBC9924"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(3425277)), + }, + ) }); generate_contract_with_config("BalancerV2ComposableStablePoolFactoryV5", |builder| { builder @@ -352,6 +446,15 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(28900564)), }, ) + .add_network( + // + SEPOLIA, + Network { + address: addr("0xa523f47A933D5020b23629dDf689695AA94612Dc"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(3872211)), + }, + ) }); generate_contract("BalancerV2WeightedPool"); generate_contract_with_config("BalancerV2StablePool", |builder| { @@ -395,6 +498,14 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(16465099)), }, ) + .add_network( + SEPOLIA, + Network { + address: addr("0x2c4c28DDBdAc9C5E7055b4C863b72eA0149D8aFE"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(4717469)), + }, + ) }); generate_contract_with_config("GPv2Settlement", |builder| { builder @@ -423,6 +534,14 @@ fn main() { deployment_information: Some(DeploymentInformation::BlockNumber(16465100)), }, ) + .add_network( + SEPOLIA, + Network { + address: addr("0x9008D19f58AAbD9eD0D60971565AA8510560ab41"), + // + deployment_information: Some(DeploymentInformation::BlockNumber(4717488)), + }, + ) }); generate_contract("GnosisSafe"); generate_contract_with_config("GnosisSafeCompatibilityFallbackHandler", |builder| { @@ -434,10 +553,12 @@ fn main() { builder.add_network_str(GNOSIS, "0x1C232F01118CB8B424793ae03F870aa7D0ac7f77") }); generate_contract_with_config("HooksTrampoline", |builder| { + // builder .add_network_str(MAINNET, "0x01DcB88678aedD0C4cC9552B20F4718550250574") .add_network_str(GOERLI, "0x01DcB88678aedD0C4cC9552B20F4718550250574") .add_network_str(GNOSIS, "0x01DcB88678aedD0C4cC9552B20F4718550250574") + .add_network_str(SEPOLIA, "0x01DcB88678aedD0C4cC9552B20F4718550250574") }); generate_contract("IUniswapLikeRouter"); generate_contract("IUniswapLikePair"); @@ -447,49 +568,65 @@ fn main() { builder.add_network_str(MAINNET, "0xEfF92A263d31888d860bD50809A8D171709b7b1c") }); generate_contract_with_config("SushiSwapRouter", |builder| { + // builder .add_network_str(MAINNET, "0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F") .add_network_str(GOERLI, "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506") .add_network_str(GNOSIS, "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506") }); generate_contract_with_config("SwaprRouter", |builder| { + // builder .add_network_str(MAINNET, "0xb9960d9bca016e9748be75dd52f02188b9d0829f") .add_network_str(GNOSIS, "0xE43e60736b1cb4a75ad25240E2f9a62Bff65c0C0") }); generate_contract("ISwaprPair"); generate_contract_with_config("UniswapV2Factory", |builder| { + // builder .add_network_str(MAINNET, "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f") .add_network_str(GOERLI, "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f") - .add_network_str(GNOSIS, "0xA818b4F111Ccac7AA31D0BCc0806d64F2E0737D7") + // Not available on Sepolia or Gnosis Chain }); generate_contract_with_config("UniswapV2Router02", |builder| { + // builder .add_network_str(MAINNET, "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D") .add_network_str(GOERLI, "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D") - .add_network_str(GNOSIS, "0x1b02da8cb0d097eb8d57a175b88c7d8b47997506") + // Not available on Sepolia or Gnosis Chain }); generate_contract_with_config("UniswapV3SwapRouter", |builder| { + // builder .add_network_str(MAINNET, "0xE592427A0AEce92De3Edee1F18E0157C05861564") .add_network_str(GOERLI, "0xE592427A0AEce92De3Edee1F18E0157C05861564") + .add_network_str(SEPOLIA, "0xE592427A0AEce92De3Edee1F18E0157C05861564") + // Not available on Gnosis Chain }); generate_contract("UniswapV3Pool"); generate_contract_with_config("WETH9", |builder| { + // Note: the WETH address must be consistent with the one used by the ETH-flow + // contract builder .add_network_str(MAINNET, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") .add_network_str(GOERLI, "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6") .add_network_str(GNOSIS, "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d") + .add_network_str(SEPOLIA, "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14") }); generate_contract_with_config("IUniswapV3Factory", |builder| { + // builder .add_network_str(MAINNET, "0x1F98431c8aD98523631AE4a59f267346ea31F984") .add_network_str(GOERLI, "0x1F98431c8aD98523631AE4a59f267346ea31F984") + .add_network_str(SEPOLIA, "0x1F98431c8aD98523631AE4a59f267346ea31F984") + // Not available on Gnosis Chain }); generate_contract_with_config("IZeroEx", |builder| { + // + // builder .add_network_str(MAINNET, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") + .add_network_str(SEPOLIA, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") .add_method_alias( "_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[],bool,\ address))", @@ -517,9 +654,13 @@ fn main() { .add_network_str(MAINNET, "0xDEf1CA1fb7FBcDC777520aa7f396b4E015F497aB") .add_network_str(GOERLI, "0x91056D4A53E1faa1A84306D4deAEc71085394bC8") .add_network_str(GNOSIS, "0x177127622c4A00F3d409B75571e12cB3c8973d3c") + .add_network_str(SEPOLIA, "0x0625aFB445C3B6B7B929342a04A22599fd5dBB59") }); - generate_contract_with_config("SolverTrampoline", |builder| { - builder.add_network_str("5", "0xd29ae121Ad58479c9Eb8C4F235c618fcF42eCba0") + + // Unofficial Uniswap v2 liquidity on the Sepolia testnet. + generate_contract_with_config("TestnetUniswapV2Router02", |builder| { + // + builder.add_network_str(SEPOLIA, "0x86dcd3293C53Cf8EFd7303B57beb2a3F671dDE98") }); // Support contracts used for trade and token simulations. diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index e4a7caec0e..ef1735605f 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -58,9 +58,9 @@ include_contracts! { IUniswapV3Factory; IZeroEx; PancakeRouter; - SolverTrampoline; SushiSwapRouter; SwaprRouter; + TestnetUniswapV2Router02; UniswapV2Factory; UniswapV2Router02; UniswapV3Pool; @@ -93,6 +93,7 @@ mod tests { const MAINNET: u64 = 1; const GOERLI: u64 = 5; const GNOSIS: u64 = 100; + const SEPOLIA: u64 = 11155111; use { super::*, @@ -155,27 +156,31 @@ mod tests { }}; } - for network in &[MAINNET, GOERLI, GNOSIS] { + for network in &[MAINNET, GOERLI, GNOSIS, SEPOLIA] { assert_has_deployment_address!(GPv2Settlement for *network); - assert_has_deployment_address!(SushiSwapRouter for *network); assert_has_deployment_address!(WETH9 for *network); assert_has_deployment_address!(CowProtocolToken for *network); assert_has_deployment_address!(HooksTrampoline for *network); + assert_has_deployment_address!(BalancerV2Vault for *network); + assert_has_deployment_address!(BalancerV2NoProtocolFeeLiquidityBootstrappingPoolFactory for *network); + } + for network in &[MAINNET, GOERLI, GNOSIS] { + assert_has_deployment_address!(SushiSwapRouter for *network); + } + for network in &[MAINNET, GOERLI, SEPOLIA] { + assert_has_deployment_address!(UniswapV3SwapRouter for *network); + assert_has_deployment_address!(IUniswapV3Factory for *network); } for network in &[MAINNET, GOERLI] { - assert_has_deployment_address!(BalancerV2Vault for *network); assert_has_deployment_address!(BalancerV2WeightedPoolFactory for *network); assert_has_deployment_address!(BalancerV2WeightedPool2TokensFactory for *network); assert_has_deployment_address!(UniswapV2Factory for *network); assert_has_deployment_address!(UniswapV2Router02 for *network); - assert_has_deployment_address!(UniswapV3SwapRouter for *network); - assert_has_deployment_address!(IUniswapV3Factory for *network); } // only mainnet assert_has_deployment_address!(BalancerV2StablePoolFactoryV2 for MAINNET); assert_has_deployment_address!(BalancerV2LiquidityBootstrappingPoolFactory for MAINNET); - assert_has_deployment_address!(BalancerV2NoProtocolFeeLiquidityBootstrappingPoolFactory for MAINNET); assert_has_deployment_address!(PancakeRouter for MAINNET); assert_has_deployment_address!(IZeroEx for MAINNET); @@ -183,6 +188,9 @@ mod tests { assert_has_deployment_address!(BaoswapRouter for GNOSIS); assert_has_deployment_address!(HoneyswapRouter for GNOSIS); assert_has_deployment_address!(SwaprRouter for GNOSIS); + + // only sepolia + assert_has_deployment_address!(TestnetUniswapV2Router02 for SEPOLIA); } #[test] @@ -198,11 +206,11 @@ mod tests { }}; } - for network in &[MAINNET, GOERLI, GNOSIS] { + for network in &[MAINNET, GOERLI, GNOSIS, SEPOLIA] { assert_has_deployment_information!(GPv2Settlement for *network); + assert_has_deployment_information!(BalancerV2Vault for *network); } for network in &[MAINNET, GOERLI] { - assert_has_deployment_information!(BalancerV2Vault for *network); assert_has_deployment_information!(BalancerV2WeightedPoolFactory for *network); assert_has_deployment_information!(BalancerV2WeightedPool2TokensFactory for *network); } diff --git a/crates/driver/src/infra/config/file/load.rs b/crates/driver/src/infra/config/file/load.rs index 48a5823dbe..e480cc7b16 100644 --- a/crates/driver/src/infra/config/file/load.rs +++ b/crates/driver/src/infra/config/file/load.rs @@ -124,6 +124,9 @@ pub async fn load(network: &blockchain::Network, path: &Path) -> infra::Config { file::UniswapV2Preset::PancakeSwap => { liquidity::config::UniswapV2::pancake_swap(&network.id) } + file::UniswapV2Preset::TestnetUniswapV2 => { + liquidity::config::UniswapV2::testnet_uniswapv2(&network.id) + } } .expect("no Uniswap V2 preset for current network"), file::UniswapV2Config::Manual { diff --git a/crates/driver/src/infra/config/file/mod.rs b/crates/driver/src/infra/config/file/mod.rs index d39b817d5d..ffc498ef69 100644 --- a/crates/driver/src/infra/config/file/mod.rs +++ b/crates/driver/src/infra/config/file/mod.rs @@ -327,6 +327,7 @@ enum UniswapV2Preset { Honeyswap, Baoswap, PancakeSwap, + TestnetUniswapV2, } #[derive(Clone, Debug, Deserialize)] diff --git a/crates/driver/src/infra/liquidity/config.rs b/crates/driver/src/infra/liquidity/config.rs index a149c00148..22e3448da8 100644 --- a/crates/driver/src/infra/liquidity/config.rs +++ b/crates/driver/src/infra/liquidity/config.rs @@ -93,6 +93,20 @@ impl UniswapV2 { missing_pool_cache_time: Duration::from_secs(60 * 60), }) } + + /// Returns the liquidity configuration for liquidity sources only used on + /// test networks. + pub fn testnet_uniswapv2(network: ð::NetworkId) -> Option { + Some(Self { + router: deployment_address( + contracts::TestnetUniswapV2Router02::raw_contract(), + network, + )?, + pool_code: hex!("0efd7612822d579e24a8851501d8c2ad854264a1050e3dfcee8afcca08f80a86") + .into(), + missing_pool_cache_time: Duration::from_secs(60 * 60), + }) + } } /// Swapr (Uniswap V2 clone with a twist) liquidity fetching options. diff --git a/crates/model/src/lib.rs b/crates/model/src/lib.rs index 9b14227fe4..3f027ad7ac 100644 --- a/crates/model/src/lib.rs +++ b/crates/model/src/lib.rs @@ -165,16 +165,17 @@ mod tests { } #[test] - fn domain_separator_goerli() { + fn domain_separator_sepolia() { let contract_address: H160 = hex!("9008D19f58AAbD9eD0D60971565AA8510560ab41").into(); // new deployment - let chain_id: u64 = 5; - let domain_separator_goerli = DomainSeparator::new(chain_id, contract_address); - // domain separator is taken from goerli deployment at address + let chain_id: u64 = 11155111; + let domain_separator_sepolia = DomainSeparator::new(chain_id, contract_address); + // domain separator is taken from Sepolia deployment at address // 0x9008D19f58AAbD9eD0D60971565AA8510560ab41 + // https://sepolia.etherscan.io/address/0x9008d19f58aabd9ed0d60971565aa8510560ab41#readContract#F2 let expected_domain_separator = DomainSeparator(hex!( - "fb378b35457022ecc5709ae5dafad9393c1387ae6d8ce24913a0c969074c07fb" + "daee378bd0eb30ddf479272accf91761e697bc00e067a268f95f1d2732ed230b" )); - assert_eq!(domain_separator_goerli, expected_domain_separator); + assert_eq!(domain_separator_sepolia, expected_domain_separator); } #[test] diff --git a/crates/shared/src/bad_token/token_owner_finder/blockscout.rs b/crates/shared/src/bad_token/token_owner_finder/blockscout.rs index ea362fc1cb..b03dfc6d82 100644 --- a/crates/shared/src/bad_token/token_owner_finder/blockscout.rs +++ b/crates/shared/src/bad_token/token_owner_finder/blockscout.rs @@ -21,6 +21,7 @@ impl BlockscoutTokenOwnerFinder { 1 => "https://eth.blockscout.com/api", 5 => "https://eth-goerli.blockscout.com/api", 100 => "https://blockscout.com/xdai/mainnet/api", + 11155111 => "https://eth-sepolia.blockscout.com/api", _ => bail!("Unsupported Network"), }; diff --git a/crates/shared/src/network.rs b/crates/shared/src/network.rs index 7b4e650b61..cbf8b42771 100644 --- a/crates/shared/src/network.rs +++ b/crates/shared/src/network.rs @@ -21,6 +21,7 @@ pub fn block_interval(network_id: &str, chain_id: u64) -> Option { ("1", 1) => 12, ("5", 5) => 12, ("100", 100) => 5, + ("11155111", 11155111) => 12, _ => return None, })) } diff --git a/crates/shared/src/price_estimation/native.rs b/crates/shared/src/price_estimation/native.rs index 2c5e2c912e..e8d18043ac 100644 --- a/crates/shared/src/price_estimation/native.rs +++ b/crates/shared/src/price_estimation/native.rs @@ -14,8 +14,8 @@ pub type NativePriceEstimateResult = Result; pub fn default_amount_to_estimate_native_prices_with(chain_id: u64) -> Option { match chain_id { - // Mainnet, Göŕli - 1 | 5 => Some(10u128.pow(18).into()), + // Mainnet, Göŕli, Sepolia + 1 | 5 | 11155111 => Some(10u128.pow(18).into()), // Gnosis chain 100 => Some(10u128.pow(21).into()), _ => None, diff --git a/crates/shared/src/sources.rs b/crates/shared/src/sources.rs index eff8a705e4..5bdd7cb0b8 100644 --- a/crates/shared/src/sources.rs +++ b/crates/shared/src/sources.rs @@ -26,6 +26,7 @@ pub enum BaselineSource { Swapr, ZeroEx, UniswapV3, + TestnetUniswapV2, } pub fn defaults_for_chain(chain_id: u64) -> Result> { @@ -38,11 +39,6 @@ pub fn defaults_for_chain(chain_id: u64) -> Result> { BaselineSource::ZeroEx, BaselineSource::UniswapV3, ], - 4 => vec![ - BaselineSource::UniswapV2, - BaselineSource::SushiSwap, - BaselineSource::BalancerV2, - ], 5 => vec![ BaselineSource::UniswapV2, BaselineSource::SushiSwap, @@ -54,6 +50,7 @@ pub fn defaults_for_chain(chain_id: u64) -> Result> { BaselineSource::Baoswap, BaselineSource::Swapr, ], + 11155111 => vec![BaselineSource::TestnetUniswapV2], _ => bail!("unsupported chain {:#x}", chain_id), }) } diff --git a/crates/shared/src/sources/balancer_v2/pool_fetching.rs b/crates/shared/src/sources/balancer_v2/pool_fetching.rs index af0340d3b4..fc3c43d4cb 100644 --- a/crates/shared/src/sources/balancer_v2/pool_fetching.rs +++ b/crates/shared/src/sources/balancer_v2/pool_fetching.rs @@ -206,6 +206,12 @@ impl BalancerFactoryKind { Self::ComposableStableV4, Self::ComposableStableV5, ], + 11155111 => vec![ + Self::WeightedV4, + Self::ComposableStableV4, + Self::ComposableStableV5, + Self::NoProtocolFeeLiquidityBootstrapping, + ], _ => Default::default(), } } diff --git a/crates/shared/src/sources/uniswap_v2.rs b/crates/shared/src/sources/uniswap_v2.rs index 5e5136eb14..42b335e869 100644 --- a/crates/shared/src/sources/uniswap_v2.rs +++ b/crates/shared/src/sources/uniswap_v2.rs @@ -20,6 +20,14 @@ use { std::{fmt::Display, str::FromStr, sync::Arc}, }; +// How to compute for unknown contracts +// Find a pair creation transaction and open it with Tenderly on the debugger +// page. Example: +// https://dashboard.tenderly.co/tx/sepolia/0x4d31daa9e74b96a5c9a780cf8839b115ac25127b17226ecb1ad6e7f244fd1c8f/debugger?trace=0.1 +// Find the CREATE2 step and take the "input" value in the debugger box; this +// is the init code. Trim 0x and hash the resulting hex-encoded bytestring, for +// example with `xxd -ps -r < ./initcode.txt | openssl dgst -keccak-256` (with +// Openssl version ≥3.2) or https://emn178.github.io/online-tools/keccak_256.html pub const UNISWAP_INIT: [u8; 32] = hex!("96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f"); pub const HONEYSWAP_INIT: [u8; 32] = @@ -30,6 +38,8 @@ pub const BAOSWAP_INIT: [u8; 32] = hex!("0bae3ead48c325ce433426d2e8e6b07dac10835baec21e163760682ea3d3520d"); pub const SWAPR_INIT: [u8; 32] = hex!("d306a548755b9295ee49cc729e13ca4a45e00199bbd890fa146da43a50571776"); +pub const TESTNET_UNISWAP_INIT: [u8; 32] = + hex!("0efd7612822d579e24a8851501d8c2ad854264a1050e3dfcee8afcca08f80a86"); #[derive(Debug, Clone, Copy)] pub struct UniV2BaselineSourceParameters { @@ -80,6 +90,11 @@ impl UniV2BaselineSourceParameters { SWAPR_INIT, PoolReadingStyle::Swapr, )), + BS::TestnetUniswapV2 => Some(( + contracts::TestnetUniswapV2Router02::raw_contract(), + TESTNET_UNISWAP_INIT, + PoolReadingStyle::Default, + )), }?; Some(Self { router: contract.networks.get(net_version)?.address, @@ -232,6 +247,27 @@ mod tests { .await; } + #[tokio::test] + #[ignore] + async fn baseline_sepolia() { + let http = crate::ethrpc::create_env_test_transport(); + let web3 = Web3::new(http); + let version = web3.net().version().await.unwrap(); + assert_eq!(version, "11155111", "test must be run with mainnet node"); + let test = |source, token0, token1, expected| { + test_baseline_source(&web3, "11155111", source, token0, token1, expected) + }; + + // https://sepolia.etherscan.io/tx/0x4d31daa9e74b96a5c9a780cf8839b115ac25127b17226ecb1ad6e7f244fd1c8f + test( + BaselineSource::TestnetUniswapV2, + addr!("fff9976782d46cc05630d1f6ebab18b2324d6b14"), + addr!("7c43482436624585c27cc9f804e53463d5a37aba"), + addr!("84A1CE0e56500D51a6a6e2559567007E26dc8a7C"), + ) + .await; + } + #[tokio::test] #[ignore] async fn baseline_xdai() { diff --git a/crates/solver/src/settlement_submission/submitter.rs b/crates/solver/src/settlement_submission/submitter.rs index 39843699ea..afae17374c 100644 --- a/crates/solver/src/settlement_submission/submitter.rs +++ b/crates/solver/src/settlement_submission/submitter.rs @@ -63,7 +63,7 @@ pub struct SubmitterParams { pub deadline: Option, /// Re-simulate and resend transaction on every retry_interval seconds pub retry_interval: Duration, - /// Network id (mainnet, rinkeby, goerli, gnosis chain) + /// Network id (mainnet, goerli, sepolia, gnosis chain) pub network_id: String, /// Additional bytes to append to the call data. This is required by the /// `driver`. diff --git a/crates/solvers/src/domain/eth/chain.rs b/crates/solvers/src/domain/eth/chain.rs index 08aa75c08e..fea63ba837 100644 --- a/crates/solvers/src/domain/eth/chain.rs +++ b/crates/solvers/src/domain/eth/chain.rs @@ -6,6 +6,7 @@ pub enum ChainId { Mainnet = 1, Goerli = 5, Gnosis = 100, + Sepolia = 11155111, } impl ChainId { @@ -21,6 +22,7 @@ impl ChainId { 1 => Ok(Self::Mainnet), 5 => Ok(Self::Goerli), 100 => Ok(Self::Gnosis), + 11155111 => Ok(Self::Sepolia), _ => Err(UnsupportedChain), } } @@ -31,6 +33,7 @@ impl ChainId { ChainId::Mainnet => "1", ChainId::Goerli => "5", ChainId::Gnosis => "100", + ChainId::Sepolia => "11155111", } }