From eb62cd6c73ef904612f124fa19cccb34fd53f7d4 Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 9 Sep 2025 13:19:33 +0300 Subject: [PATCH 1/5] BalancerV2BasePool alloy bindings --- crates/contracts/src/alloy.rs | 26 + crates/contracts/src/lib.rs | 1 - .../src/boundary/liquidity/balancer/v2/mod.rs | 14 +- .../boundary/liquidity/balancer/v2/stable.rs | 2 + .../liquidity/balancer/v2/weighted.rs | 2 + crates/ethrpc/src/alloy/conversions.rs | 8 + .../sources/balancer_v2/pool_fetching/mod.rs | 8 +- .../src/sources/balancer_v2/pools/common.rs | 511 ++++++++++++------ crates/solver/src/interactions/balancer_v2.rs | 59 +- crates/solver/src/liquidity/balancer_v2.rs | 23 +- 10 files changed, 456 insertions(+), 198 deletions(-) diff --git a/crates/contracts/src/alloy.rs b/crates/contracts/src/alloy.rs index 582c1a588d..babb06f688 100644 --- a/crates/contracts/src/alloy.rs +++ b/crates/contracts/src/alloy.rs @@ -47,6 +47,32 @@ crate::bindings!(GnosisSafeCompatibilityFallbackHandler); crate::bindings!(GnosisSafeProxy); crate::bindings!(GnosisSafeProxyFactory); +crate::bindings!(BalancerV2BasePool); +crate::bindings!( + BalancerV2Vault, + crate::deployments! { + // + MAINNET => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 12272146), + // + GNOSIS => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 24821598), + // + SEPOLIA => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 3418831), + // + ARBITRUM_ONE => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 222832), + // + BASE => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 1196036), + // + AVALANCHE => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 26386141), + // + BNB => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 22691002), + // + OPTIMISM => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 7003431), + // + POLYGON => (address!("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), 15832990), + // Not available on Lens + } +); + pub use alloy::providers::DynProvider as Provider; /// Extension trait to attach some useful functions to the contract instance. diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index 31cf0eba14..6be650a256 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -51,7 +51,6 @@ macro_rules! include_contracts { include_contracts! { AaveFlashLoanSolverWrapper; BalancerV2Authorizer; - BalancerV2BasePool; BalancerV2BasePoolFactory; BalancerV2ComposableStablePool; BalancerV2ComposableStablePoolFactory; diff --git a/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs b/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs index 0dcff6f79b..403cfe50f2 100644 --- a/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs +++ b/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs @@ -12,12 +12,15 @@ use { BalancerV2ComposableStablePoolFactory, BalancerV2LiquidityBootstrappingPoolFactory, BalancerV2StablePoolFactoryV2, - BalancerV2Vault, BalancerV2WeightedPoolFactory, BalancerV2WeightedPoolFactoryV3, GPv2Settlement, + alloy::BalancerV2Vault, + }, + ethrpc::{ + alloy::conversions::IntoAlloy, + block_stream::{BlockRetrieving, CurrentBlockWatcher}, }, - ethrpc::block_stream::{BlockRetrieving, CurrentBlockWatcher}, shared::{ http_solver::model::TokenAmount, sources::balancer_v2::{ @@ -56,7 +59,7 @@ fn to_interaction( // also baked into the Balancer V2 logic in the `shared` crate, so to // change this assumption, we would need to change it there as well. GPv2Settlement::at(&web3, receiver.0), - BalancerV2Vault::at(&web3, pool.vault.into()), + BalancerV2Vault::Instance::new(pool.vault.0.into_alloy(), ethrpc::mock::web3().alloy), Allowances::empty(receiver.0), ); @@ -107,7 +110,10 @@ async fn init_liquidity( ) -> Result> { let web3 = eth.web3().clone(); let contracts = BalancerContracts { - vault: BalancerV2Vault::at(&web3, config.vault.into()), + vault: BalancerV2Vault::Instance::new( + config.vault.0.into_alloy(), + ethrpc::mock::web3().alloy, + ), factories: [ config .weighted diff --git a/crates/driver/src/boundary/liquidity/balancer/v2/stable.rs b/crates/driver/src/boundary/liquidity/balancer/v2/stable.rs index e211b9fe88..1ce175a390 100644 --- a/crates/driver/src/boundary/liquidity/balancer/v2/stable.rs +++ b/crates/driver/src/boundary/liquidity/balancer/v2/stable.rs @@ -6,6 +6,7 @@ use { liquidity::{self, balancer}, }, }, + ethrpc::alloy::conversions::IntoLegacy, solver::liquidity::{StablePoolOrder, balancer_v2}, }; @@ -52,6 +53,7 @@ fn vault(pool: &StablePoolOrder) -> eth::ContractAddress { .expect("downcast balancer settlement handler") .vault() .address() + .into_legacy() .into() } diff --git a/crates/driver/src/boundary/liquidity/balancer/v2/weighted.rs b/crates/driver/src/boundary/liquidity/balancer/v2/weighted.rs index 520ad4cfc0..5d86fe77db 100644 --- a/crates/driver/src/boundary/liquidity/balancer/v2/weighted.rs +++ b/crates/driver/src/boundary/liquidity/balancer/v2/weighted.rs @@ -6,6 +6,7 @@ use { liquidity::{self, balancer}, }, }, + ethrpc::alloy::conversions::IntoLegacy, shared::sources::balancer_v2::pool_fetching::WeightedPoolVersion, solver::liquidity::{WeightedProductOrder, balancer_v2}, }; @@ -56,6 +57,7 @@ fn vault(pool: &WeightedProductOrder) -> eth::ContractAddress { .expect("downcast balancer settlement handler") .vault() .address() + .into_legacy() .into() } diff --git a/crates/ethrpc/src/alloy/conversions.rs b/crates/ethrpc/src/alloy/conversions.rs index 5ac5850342..2d9393cfab 100644 --- a/crates/ethrpc/src/alloy/conversions.rs +++ b/crates/ethrpc/src/alloy/conversions.rs @@ -83,6 +83,14 @@ impl IntoAlloy for web3::types::BlockId { } } +impl IntoAlloy for ethcontract::tokens::Bytes> { + type To = alloy::primitives::Bytes; + + fn into_alloy(self) -> Self::To { + alloy::primitives::Bytes::copy_from_slice(self.0.as_slice()) + } +} + pub enum Account { Address(alloy::primitives::Address), Signer(Box + Send + Sync + 'static>), diff --git a/crates/shared/src/sources/balancer_v2/pool_fetching/mod.rs b/crates/shared/src/sources/balancer_v2/pool_fetching/mod.rs index c9e00a0744..b77aae6f91 100644 --- a/crates/shared/src/sources/balancer_v2/pool_fetching/mod.rs +++ b/crates/shared/src/sources/balancer_v2/pool_fetching/mod.rs @@ -41,11 +41,11 @@ use { BalancerV2LiquidityBootstrappingPoolFactory, BalancerV2NoProtocolFeeLiquidityBootstrappingPoolFactory, BalancerV2StablePoolFactoryV2, - BalancerV2Vault, BalancerV2WeightedPool2TokensFactory, BalancerV2WeightedPoolFactory, BalancerV2WeightedPoolFactoryV3, BalancerV2WeightedPoolFactoryV4, + alloy::{BalancerV2Vault, InstanceExt}, }, ethcontract::{BlockId, H160, H256, Instance, dyns::DynInstance}, ethrpc::block_stream::{BlockRetrieving, CurrentBlockWatcher}, @@ -225,14 +225,14 @@ impl BalancerFactoryKind { /// All balancer related contracts that we expect to exist. pub struct BalancerContracts { - pub vault: BalancerV2Vault, + pub vault: BalancerV2Vault::Instance, pub factories: Vec<(BalancerFactoryKind, DynInstance)>, } impl BalancerContracts { pub async fn try_new(web3: &Web3, factory_kinds: Vec) -> Result { let web3 = ethrpc::instrumented::instrument_with_label(web3, "balancerV2".into()); - let vault = BalancerV2Vault::deployed(&web3) + let vault = BalancerV2Vault::Instance::deployed(&web3.alloy) .await .context("Cannot retrieve balancer vault")?; @@ -463,7 +463,7 @@ async fn create_aggregate_pool_fetcher( /// Helper method for creating a boxed `InternalPoolFetching` instance for the /// specified factory and parameters. fn create_internal_pool_fetcher( - vault: BalancerV2Vault, + vault: BalancerV2Vault::Instance, factory: Factory, block_retriever: Arc, token_infos: Arc, diff --git a/crates/shared/src/sources/balancer_v2/pools/common.rs b/crates/shared/src/sources/balancer_v2/pools/common.rs index e331752a3e..91927519c8 100644 --- a/crates/shared/src/sources/balancer_v2/pools/common.rs +++ b/crates/shared/src/sources/balancer_v2/pools/common.rs @@ -10,9 +10,10 @@ use { token_info::TokenInfoFetching, }, anyhow::{Context, Result, anyhow, ensure}, - contracts::{BalancerV2BasePool, BalancerV2Vault}, - ethcontract::{BlockId, Bytes, H160, H256, U256}, - futures::{FutureExt as _, TryFutureExt, future::BoxFuture}, + contracts::alloy::{BalancerV2BasePool, BalancerV2Vault}, + ethcontract::{BlockId, H160, H256, U256}, + ethrpc::alloy::conversions::{IntoAlloy, IntoLegacy}, + futures::{FutureExt as _, future::BoxFuture}, std::{collections::BTreeMap, future::Future, sync::Arc}, tokio::sync::oneshot, }; @@ -40,14 +41,14 @@ where /// Generic pool info fetcher for fetching pool info and state that is generic /// on a pool factory type and its inner pool type. pub struct PoolInfoFetcher { - vault: BalancerV2Vault, + vault: BalancerV2Vault::Instance, factory: Factory, token_infos: Arc, } impl PoolInfoFetcher { pub fn new( - vault: BalancerV2Vault, + vault: BalancerV2Vault::Instance, factory: Factory, token_infos: Arc, ) -> Self { @@ -59,9 +60,9 @@ impl PoolInfoFetcher { } /// Returns a Balancer base pool contract instance at the specified address. - fn base_pool_at(&self, pool_address: H160) -> BalancerV2BasePool { - let web3 = self.vault.raw_instance().web3(); - BalancerV2BasePool::at(&web3, pool_address) + fn base_pool_at(&self, pool_address: H160) -> BalancerV2BasePool::Instance { + let provider = self.vault.provider().clone(); + BalancerV2BasePool::Instance::new(pool_address.into_alloy(), provider) } /// Retrieves the scaling exponents for the specified tokens. @@ -87,13 +88,16 @@ impl PoolInfoFetcher { ) -> Result { let pool = self.base_pool_at(pool_address); - let pool_id = H256(pool.methods().get_pool_id().call().await?.0); - let (tokens, _, _) = self + let pool_id = pool.getPoolId().call().await?.into_alloy(); + let tokens = self .vault - .methods() - .get_pool_tokens(Bytes(pool_id.0)) + .getPoolTokens(pool_id.0.into()) .call() - .await?; + .await? + .tokens + .into_iter() + .map(|token| token.into_legacy()) + .collect::>(); let scaling_factors = self.scaling_factors(&tokens).await?; Ok(PoolInfo { @@ -110,18 +114,34 @@ impl PoolInfoFetcher { pool: &PoolInfo, block: BlockId, ) -> BoxFuture<'static, Result> { - let pool_contract = self.base_pool_at(pool.address); - let fetch_paused = pool_contract - .get_paused_state() - .block(block) - .call() - .map_ok(|result| result.0); - let fetch_swap_fee = pool_contract.get_swap_fee_percentage().block(block).call(); - let fetch_balances = self - .vault - .get_pool_tokens(Bytes(pool.id.0)) - .block(block) - .call(); + let pool_address = pool.address; + let pool_id = pool.id; + let vault = self.vault.clone(); + let pool_contract_paused = self.base_pool_at(pool_address); + let pool_contract_fee = self.base_pool_at(pool_address); + + let fetch_paused = async move { + pool_contract_paused + .getPausedState() + .block(block.into_alloy()) + .call() + .await + .map(|result| result.paused) + }; + let fetch_swap_fee = async move { + pool_contract_fee + .getSwapFeePercentage() + .block(block.into_alloy()) + .call() + .await + }; + let fetch_balances = async move { + vault + .getPoolTokens(pool_id.0.into()) + .block(block.into_alloy()) + .call() + .await + }; // Because of a `mockall` limitation, we **need** the future returned // here to be `'static`. This requires us to clone and move `pool` into @@ -129,18 +149,23 @@ impl PoolInfoFetcher { // `pool`, i.e. `'_`. let pool = pool.clone(); async move { - let (paused, swap_fee, balances) = + let (paused, swap_fee, pool_tokens) = futures::try_join!(fetch_paused, fetch_swap_fee, fetch_balances)?; - let swap_fee = Bfp::from_wei(swap_fee); + let swap_fee = Bfp::from_wei(swap_fee.into_legacy()); - let (token_addresses, balances, _) = balances; - ensure!(pool.tokens == token_addresses, "pool token mismatch"); + let balances = pool_tokens.balances; + let tokens = pool_tokens + .tokens + .into_iter() + .map(|t| t.into_legacy()) + .collect::>(); + ensure!(pool.tokens == tokens, "pool token mismatch"); let tokens = itertools::izip!(&pool.tokens, balances, &pool.scaling_factors) .map(|(&address, balance, &scaling_factor)| { ( address, TokenState { - balance, + balance: balance.into_legacy(), scaling_factor, }, ) @@ -338,37 +363,57 @@ mod tests { super::*, crate::{ sources::balancer_v2::{ + PoolKind, graph_api::{PoolType, Token}, - pools::{MockFactoryIndexing, PoolKind, weighted}, + pools::{MockFactoryIndexing, weighted}, }, token_info::{MockTokenInfoFetching, TokenInfo}, }, + alloy::{ + dyn_abi::{DynSolValue, FunctionExt}, + providers::{Provider, ProviderBuilder}, + transports::mock::Asserter, + }, anyhow::bail, - contracts::{BalancerV2WeightedPool, dummy_contract}, ethcontract::U256, - ethcontract_mock::Mock, - futures::future, maplit::{btreemap, hashmap}, mockall::predicate, + std::future, + web3::types::BlockNumber, }; #[tokio::test] async fn fetch_common_pool_info() { - let pool_id = H256([0x90; 32]); + let pool_id = alloy::primitives::FixedBytes([0x90; 32]); let tokens = [H160([1; 20]), H160([2; 20]), H160([3; 20])]; - let mock = Mock::new(42); - let web3 = mock.web3(); - - let pool = mock.deploy(BalancerV2BasePool::raw_contract().interface.abi.clone()); - pool.expect_call(BalancerV2BasePool::signatures().get_pool_id()) - .returns(Bytes(pool_id.0)); - - let vault = mock.deploy(BalancerV2Vault::raw_contract().interface.abi.clone()); - vault - .expect_call(BalancerV2Vault::signatures().get_pool_tokens()) - .predicate((predicate::eq(Bytes(pool_id.0)),)) - .returns((tokens.to_vec(), vec![], U256::zero())); + let asserter = Asserter::new(); + let provider = ProviderBuilder::new() + .connect_mocked_client(asserter.clone()) + .erased(); + + let pool = BalancerV2BasePool::Instance::new(H160::random().into_alloy(), provider.clone()); + let vault = BalancerV2Vault::Instance::new(H160::random().into_alloy(), provider.clone()); + asserter.push_success(&pool_id); + + let get_pool_tokens_response = { + let tokens_response = DynSolValue::Array( + tokens + .iter() + .copied() + .map(|t| DynSolValue::Address(t.into_alloy())) + .collect(), + ); + let balances_response = DynSolValue::Array(vec![]); + let last_block_reponse = DynSolValue::Uint(U256::zero().into_alloy(), 256); + BalancerV2Vault::abi_functions_by_name("getPoolTokens") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[tokens_response, balances_response, last_block_reponse]) + .unwrap() + }; + asserter.push_success(&get_pool_tokens_response); let mut token_infos = MockTokenInfoFetching::new(); token_infos @@ -383,20 +428,20 @@ mod tests { }); let pool_info_fetcher = PoolInfoFetcher { - vault: BalancerV2Vault::at(&web3, vault.address()), + vault, factory: MockFactoryIndexing::new(), token_infos: Arc::new(token_infos), }; let pool_info = pool_info_fetcher - .fetch_common_pool_info(pool.address(), 1337) + .fetch_common_pool_info(pool.address().into_legacy(), 1337) .await .unwrap(); assert_eq!( pool_info, PoolInfo { - id: pool_id, - address: pool.address(), + id: pool_id.into_alloy(), + address: pool.address().into_legacy(), tokens: tokens.to_vec(), scaling_factors: vec![Bfp::exp10(0), Bfp::exp10(0), Bfp::exp10(12)], block_created: 1337, @@ -411,44 +456,81 @@ mod tests { let balances = [bfp!("1000.0"), bfp!("10.0"), bfp!("15.0")]; let scaling_factors = [Bfp::exp10(0), Bfp::exp10(0), Bfp::exp10(12)]; - let mock = Mock::new(42); - let web3 = mock.web3(); - - let pool = mock.deploy(BalancerV2BasePool::raw_contract().interface.abi.clone()); - pool.expect_call(BalancerV2BasePool::signatures().get_paused_state()) - .returns((false, 0.into(), 0.into())); - pool.expect_call(BalancerV2BasePool::signatures().get_swap_fee_percentage()) - .returns(bfp!("0.003").as_uint256()); - - let vault = mock.deploy(BalancerV2Vault::raw_contract().interface.abi.clone()); - vault - .expect_call(BalancerV2Vault::signatures().get_pool_tokens()) - .predicate((predicate::eq(Bytes(pool_id.0)),)) - .returns(( - tokens.to_vec(), - balances.into_iter().map(Bfp::as_uint256).collect(), - 0.into(), - )); + let asserter = Asserter::new(); + let provider = ProviderBuilder::new() + .connect_mocked_client(asserter.clone()) + .erased(); + + let pool = BalancerV2BasePool::Instance::new(H160::random().into_alloy(), provider.clone()); + let vault = BalancerV2Vault::Instance::new(H160::random().into_alloy(), provider.clone()); + + let get_paused_state_response = BalancerV2BasePool::abi_functions_by_name("getPausedState") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[ + DynSolValue::Bool(false), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + ]) + .unwrap(); + asserter.push_success(&get_paused_state_response); + let get_swap_fee_percentage_response = + BalancerV2BasePool::abi_functions_by_name("getSwapFeePercentage") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[DynSolValue::Uint( + bfp!("0.003").as_uint256().into_alloy(), + 256, + )]) + .unwrap(); + asserter.push_success(&get_swap_fee_percentage_response); + + let get_pool_tokens_response = { + let tokens_response = DynSolValue::Array( + tokens + .iter() + .copied() + .map(|t| DynSolValue::Address(t.into_alloy())) + .collect(), + ); + let balances_response = DynSolValue::Array( + balances + .iter() + .map(|b| DynSolValue::Uint(b.as_uint256().into_alloy(), 256)) + .collect(), + ); + let last_block_reponse = DynSolValue::Uint(U256::zero().into_alloy(), 256); + BalancerV2Vault::abi_functions_by_name("getPoolTokens") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[tokens_response, balances_response, last_block_reponse]) + .unwrap() + }; + asserter.push_success(&get_pool_tokens_response); let token_infos = MockTokenInfoFetching::new(); let pool_info_fetcher = PoolInfoFetcher { - vault: BalancerV2Vault::at(&web3, vault.address()), + vault, factory: MockFactoryIndexing::new(), token_infos: Arc::new(token_infos), }; let pool_info = PoolInfo { id: pool_id, - address: pool.address(), + address: pool.address().into_legacy(), tokens: tokens.to_vec(), scaling_factors: scaling_factors.to_vec(), block_created: 1337, }; let pool_state = { - let block = web3.eth().block_number().await.unwrap(); - - let pool_state = pool_info_fetcher.fetch_common_pool_state(&pool_info, block.into()); + let pool_state = pool_info_fetcher.fetch_common_pool_state( + &pool_info, + BlockId::Number(BlockNumber::Number(1.into())), + ); pool_state.await.unwrap() }; @@ -480,44 +562,74 @@ mod tests { async fn fetch_state_errors_on_token_mismatch() { let tokens = [H160([1; 20]), H160([2; 20]), H160([3; 20])]; - let mock = Mock::new(42); - let web3 = mock.web3(); - - let pool = mock.deploy(BalancerV2BasePool::raw_contract().interface.abi.clone()); - pool.expect_call(BalancerV2BasePool::signatures().get_paused_state()) - .returns((false, 0.into(), 0.into())); - pool.expect_call(BalancerV2BasePool::signatures().get_swap_fee_percentage()) - .returns(0.into()); - - let vault = mock.deploy(BalancerV2Vault::raw_contract().interface.abi.clone()); - vault - .expect_call(BalancerV2Vault::signatures().get_pool_tokens()) - .predicate((predicate::eq(Bytes(Default::default())),)) - .returns(( - vec![H160([1; 20]), H160([4; 20])], - vec![0.into(), 0.into()], - 0.into(), - )); + let asserter = Asserter::new(); + let provider = ProviderBuilder::new() + .connect_mocked_client(asserter.clone()) + .erased(); + + let pool = BalancerV2BasePool::Instance::new(H160::random().into_alloy(), provider.clone()); + let vault = BalancerV2Vault::Instance::new(H160::random().into_alloy(), provider.clone()); + + let get_paused_state_response = BalancerV2BasePool::abi_functions_by_name("getPausedState") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[ + DynSolValue::Bool(false), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + ]) + .unwrap(); + asserter.push_success(&get_paused_state_response); + + let get_swap_fee_percentage_response = + BalancerV2BasePool::abi_functions_by_name("getSwapFeePercentage") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[DynSolValue::Uint(U256::zero().into_alloy(), 256)]) + .unwrap(); + asserter.push_success(&get_swap_fee_percentage_response); + + let get_pool_tokens_response = { + let tokens_response = DynSolValue::Array(vec![ + DynSolValue::Address(H160([1; 20]).into_alloy()), + DynSolValue::Address(H160([4; 20]).into_alloy()), // Mismatched token + ]); + let balances_response = DynSolValue::Array(vec![ + DynSolValue::Uint(U256::zero().into_alloy(), 256), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + ]); + let last_block_reponse = DynSolValue::Uint(U256::zero().into_alloy(), 256); + BalancerV2Vault::abi_functions_by_name("getPoolTokens") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[tokens_response, balances_response, last_block_reponse]) + .unwrap() + }; + asserter.push_success(&get_pool_tokens_response); let token_infos = MockTokenInfoFetching::new(); let pool_info_fetcher = PoolInfoFetcher { - vault: BalancerV2Vault::at(&web3, vault.address()), + vault, factory: MockFactoryIndexing::new(), token_infos: Arc::new(token_infos), }; let pool_info = PoolInfo { id: Default::default(), - address: pool.address(), + address: pool.address().into_legacy(), tokens: tokens.to_vec(), scaling_factors: vec![Bfp::exp10(0), Bfp::exp10(0), Bfp::exp10(0)], block_created: 1337, }; let pool_state = { - let block = web3.eth().block_number().await.unwrap(); - - let pool_state = pool_info_fetcher.fetch_common_pool_state(&pool_info, block.into()); + let pool_state = pool_info_fetcher.fetch_common_pool_state( + &pool_info, + BlockId::Number(BlockNumber::Number(1.into())), + ); pool_state.await }; @@ -529,19 +641,38 @@ mod tests { async fn fetch_specialized_pool_state() { let swap_fee = bfp!("0.003"); - let mock = Mock::new(42); - let web3 = mock.web3(); - - let pool = mock.deploy(BalancerV2WeightedPool::raw_contract().interface.abi.clone()); - pool.expect_call(BalancerV2WeightedPool::signatures().get_paused_state()) - .returns((false, 0.into(), 0.into())); - pool.expect_call(BalancerV2WeightedPool::signatures().get_swap_fee_percentage()) - .returns(swap_fee.as_uint256()); + let asserter = Asserter::new(); + let provider = ProviderBuilder::new() + .connect_mocked_client(asserter.clone()) + .erased(); + + let pool = BalancerV2BasePool::Instance::new(H160::random().into_alloy(), provider.clone()); + let vault = BalancerV2Vault::Instance::new(H160::random().into_alloy(), provider.clone()); + + let get_paused_state_response = BalancerV2BasePool::abi_functions_by_name("getPausedState") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[ + DynSolValue::Bool(false), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + ]) + .unwrap(); + asserter.push_success(&get_paused_state_response); + let get_swap_fee_percentage_response = + BalancerV2BasePool::abi_functions_by_name("getSwapFeePercentage") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[DynSolValue::Uint(swap_fee.as_uint256().into_alloy(), 256)]) + .unwrap(); + asserter.push_success(&get_swap_fee_percentage_response); let pool_info = weighted::PoolInfo { common: PoolInfo { id: H256([0x90; 32]), - address: pool.address(), + address: pool.address().into_legacy(), tokens: vec![H160([1; 20]), H160([2; 20]), H160([3; 20])], scaling_factors: vec![Bfp::exp10(0), Bfp::exp10(0), Bfp::exp10(12)], block_created: 1337, @@ -576,29 +707,41 @@ mod tests { version: Default::default(), }; - let vault = mock.deploy(BalancerV2Vault::raw_contract().interface.abi.clone()); - vault - .expect_call(BalancerV2Vault::signatures().get_pool_tokens()) - .predicate((predicate::eq(Bytes(pool_info.common.id.0)),)) - .returns(( - pool_info.common.tokens.clone(), + let get_pool_tokens_response = { + let tokens_response = DynSolValue::Array( + pool_info + .common + .tokens + .iter() + .copied() + .map(|t| DynSolValue::Address(t.into_alloy())) + .collect(), + ); + let balances_response = DynSolValue::Array( pool_state .tokens .values() - .map(|token| token.common.balance) + .map(|token| DynSolValue::Uint(token.common.balance.into_alloy(), 256)) .collect(), - 0.into(), - )); - - let block = web3.eth().block_number().await.unwrap(); + ); + let last_block_reponse = DynSolValue::Uint(U256::zero().into_alloy(), 256); + BalancerV2Vault::abi_functions_by_name("getPoolTokens") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[tokens_response, balances_response, last_block_reponse]) + .unwrap() + }; + asserter.push_success(&get_pool_tokens_response); let mut factory = MockFactoryIndexing::new(); + let block_id = BlockId::Number(BlockNumber::Number(1.into())); factory .expect_fetch_pool_state() .with( predicate::eq(pool_info.clone()), predicate::always(), - predicate::eq(BlockId::from(block)), + predicate::eq(block_id), ) .returning({ let pool_state = pool_state.clone(); @@ -606,13 +749,13 @@ mod tests { }); let pool_info_fetcher = PoolInfoFetcher { - vault: BalancerV2Vault::at(&web3, vault.address()), + vault, factory, token_infos: Arc::new(MockTokenInfoFetching::new()), }; let pool_status = pool_info_fetcher - .fetch_pool(&pool_info, block.into()) + .fetch_pool(&pool_info, block_id) .await .unwrap(); @@ -627,19 +770,47 @@ mod tests { #[tokio::test] async fn fetch_specialized_pool_state_for_paused_pool() { - let mock = Mock::new(42); - let web3 = mock.web3(); - - let pool = mock.deploy(BalancerV2WeightedPool::raw_contract().interface.abi.clone()); - pool.expect_call(BalancerV2WeightedPool::signatures().get_paused_state()) - .returns((true, 0.into(), 0.into())); - pool.expect_call(BalancerV2WeightedPool::signatures().get_swap_fee_percentage()) - .returns(Default::default()); + let asserter = Asserter::new(); + let provider = ProviderBuilder::new() + .connect_mocked_client(asserter.clone()) + .erased(); + + let pool = BalancerV2BasePool::Instance::new(H160::random().into_alloy(), provider.clone()); + let vault = BalancerV2Vault::Instance::new(H160::random().into_alloy(), provider.clone()); + + let get_paused_state_response = BalancerV2BasePool::abi_functions_by_name("getPausedState") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[ + DynSolValue::Bool(true), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + ]) + .unwrap(); + asserter.push_success(&get_paused_state_response); - let vault = mock.deploy(BalancerV2Vault::raw_contract().interface.abi.clone()); - vault - .expect_call(BalancerV2Vault::signatures().get_pool_tokens()) - .returns(Default::default()); + let get_swap_fee_percentage_response = + BalancerV2BasePool::abi_functions_by_name("getSwapFeePercentage") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[DynSolValue::Uint(U256::zero().into_alloy(), 256)]) + .unwrap(); + asserter.push_success(&get_swap_fee_percentage_response); + + let get_pool_tokens_response = { + let tokens_response = DynSolValue::Array(vec![]); + let balances_response = DynSolValue::Array(vec![]); + let last_block_reponse = DynSolValue::Uint(U256::zero().into_alloy(), 256); + BalancerV2Vault::abi_functions_by_name("getPoolTokens") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[tokens_response, balances_response, last_block_reponse]) + .unwrap() + }; + asserter.push_success(&get_pool_tokens_response); let mut factory = MockFactoryIndexing::new(); factory @@ -659,14 +830,14 @@ mod tests { }); let pool_info_fetcher = PoolInfoFetcher { - vault: BalancerV2Vault::at(&web3, vault.address()), + vault, factory, token_infos: Arc::new(MockTokenInfoFetching::new()), }; let pool_info = weighted::PoolInfo { common: PoolInfo { id: Default::default(), - address: pool.address(), + address: pool.address().into_legacy(), tokens: Default::default(), scaling_factors: Default::default(), block_created: Default::default(), @@ -675,9 +846,8 @@ mod tests { }; let pool_status = { - let block = web3.eth().block_number().await.unwrap(); pool_info_fetcher - .fetch_pool(&pool_info, block.into()) + .fetch_pool(&pool_info, BlockId::Number(BlockNumber::Number(1.into()))) .await .unwrap() }; @@ -687,19 +857,47 @@ mod tests { #[tokio::test] async fn fetch_specialized_pool_state_for_disabled_pool() { - let mock = Mock::new(42); - let web3 = mock.web3(); - - let pool = mock.deploy(BalancerV2WeightedPool::raw_contract().interface.abi.clone()); - pool.expect_call(BalancerV2WeightedPool::signatures().get_paused_state()) - .returns((false, 0.into(), 0.into())); - pool.expect_call(BalancerV2WeightedPool::signatures().get_swap_fee_percentage()) - .returns(Default::default()); + let asserter = Asserter::new(); + let provider = ProviderBuilder::new() + .connect_mocked_client(asserter.clone()) + .erased(); + + let pool = BalancerV2BasePool::Instance::new(H160::random().into_alloy(), provider.clone()); + let vault = BalancerV2Vault::Instance::new(H160::random().into_alloy(), provider.clone()); + + let get_paused_state_response = BalancerV2BasePool::abi_functions_by_name("getPausedState") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[ + DynSolValue::Bool(false), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + DynSolValue::Uint(U256::zero().into_alloy(), 256), + ]) + .unwrap(); + asserter.push_success(&get_paused_state_response); - let vault = mock.deploy(BalancerV2Vault::raw_contract().interface.abi.clone()); - vault - .expect_call(BalancerV2Vault::signatures().get_pool_tokens()) - .returns(Default::default()); + let get_swap_fee_percentage_response = + BalancerV2BasePool::abi_functions_by_name("getSwapFeePercentage") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[DynSolValue::Uint(U256::zero().into_alloy(), 256)]) + .unwrap(); + asserter.push_success(&get_swap_fee_percentage_response); + + let get_pool_tokens_response = { + let tokens_response = DynSolValue::Array(vec![]); + let balances_response = DynSolValue::Array(vec![]); + let last_block_reponse = DynSolValue::Uint(U256::zero().into_alloy(), 256); + BalancerV2Vault::abi_functions_by_name("getPoolTokens") + .unwrap() + .first() + .unwrap() + .abi_encode_output(&[tokens_response, balances_response, last_block_reponse]) + .unwrap() + }; + asserter.push_success(&get_pool_tokens_response); let mut factory = MockFactoryIndexing::new(); factory @@ -712,14 +910,14 @@ mod tests { .returning(|_, _, _| future::ready(Ok(None)).boxed()); let pool_info_fetcher = PoolInfoFetcher { - vault: BalancerV2Vault::at(&web3, vault.address()), + vault, factory, token_infos: Arc::new(MockTokenInfoFetching::new()), }; let pool_info = weighted::PoolInfo { common: PoolInfo { id: Default::default(), - address: pool.address(), + address: pool.address().into_legacy(), tokens: Default::default(), scaling_factors: Default::default(), block_created: Default::default(), @@ -728,9 +926,8 @@ mod tests { }; let pool_status = { - let block = web3.eth().block_number().await.unwrap(); pool_info_fetcher - .fetch_pool(&pool_info, block.into()) + .fetch_pool(&pool_info, BlockId::Number(BlockNumber::Number(1.into()))) .await .unwrap() }; @@ -746,7 +943,10 @@ mod tests { .returning(|_| hashmap! {}); let pool_info_fetcher = PoolInfoFetcher { - vault: dummy_contract!(BalancerV2Vault, H160([0xba; 20])), + vault: BalancerV2Vault::Instance::new( + H160([0xba; 20]).into_alloy(), + ethrpc::mock::web3().alloy, + ), factory: MockFactoryIndexing::new(), token_infos: Arc::new(token_infos), }; @@ -769,7 +969,10 @@ mod tests { }); let pool_info_fetcher = PoolInfoFetcher { - vault: dummy_contract!(BalancerV2Vault, H160([0xba; 20])), + vault: BalancerV2Vault::Instance::new( + H160([0xba; 20]).into_alloy(), + ethrpc::mock::web3().alloy, + ), factory: MockFactoryIndexing::new(), token_infos: Arc::new(token_infos), }; diff --git a/crates/solver/src/interactions/balancer_v2.rs b/crates/solver/src/interactions/balancer_v2.rs index 6239843568..a8b3c603f3 100644 --- a/crates/solver/src/interactions/balancer_v2.rs +++ b/crates/solver/src/interactions/balancer_v2.rs @@ -1,6 +1,7 @@ use { - contracts::{BalancerV2Vault, GPv2Settlement}, + contracts::{GPv2Settlement, alloy::BalancerV2Vault}, ethcontract::{Bytes, H256}, + ethrpc::alloy::conversions::{IntoAlloy, IntoLegacy}, primitive_types::U256, shared::{ http_solver::model::TokenAmount, @@ -12,7 +13,7 @@ use { #[derive(Clone, Debug)] pub struct BalancerSwapGivenOutInteraction { pub settlement: GPv2Settlement, - pub vault: BalancerV2Vault, + pub vault: BalancerV2Vault::Instance, pub pool_id: H256, pub asset_in_max: TokenAmount, pub asset_out: TokenAmount, @@ -26,26 +27,36 @@ pub static NEVER: LazyLock = LazyLock::new(|| U256::from(1) << 255); impl BalancerSwapGivenOutInteraction { pub fn encode_swap(&self) -> EncodedInteraction { - let method = self.vault.swap( - ( - Bytes(self.pool_id.0), - 1, // GivenOut, - self.asset_in_max.token, - self.asset_out.token, - self.asset_out.amount, - self.user_data.clone(), - ), - ( - self.settlement.address(), // sender - false, // fromInternalBalance - self.settlement.address(), // recipient - false, // toInternalBalance - ), - self.asset_in_max.amount, - *NEVER, - ); - let calldata = method.tx.data.expect("no calldata").0; - (self.vault.address(), 0.into(), Bytes(calldata)) + let single_swap = BalancerV2Vault::IVault::SingleSwap { + poolId: self.pool_id.into_alloy(), + kind: 1, // GivenOut + assetIn: self.asset_in_max.token.into_alloy(), + assetOut: self.asset_out.token.into_alloy(), + amount: self.asset_out.amount.into_alloy(), + userData: self.user_data.clone().into_alloy(), + }; + let funds = BalancerV2Vault::IVault::FundManagement { + sender: self.settlement.address().into_alloy(), + fromInternalBalance: false, + recipient: self.settlement.address().into_alloy(), + toInternalBalance: false, + }; + let method = self + .vault + .swap( + single_swap, + funds, + self.asset_in_max.amount.into_alloy(), + (*NEVER).into_alloy(), + ) + .calldata() + .clone(); + + ( + self.vault.address().into_legacy(), + 0.into(), + Bytes(method.to_vec()), + ) } } @@ -61,7 +72,7 @@ mod tests { #[test] fn encode_unwrap_weth() { - let vault = dummy_contract!(BalancerV2Vault, [0x01; 20]); + let vault = BalancerV2Vault::Instance::new([0x01; 20].into(), ethrpc::mock::web3().alloy); let interaction = BalancerSwapGivenOutInteraction { settlement: dummy_contract!(GPv2Settlement, [0x02; 20]), vault: vault.clone(), @@ -95,7 +106,7 @@ mod tests { assert_eq!( interaction.encode(), ( - vault.address(), + vault.address().into_legacy(), 0.into(), Bytes( hex::decode( diff --git a/crates/solver/src/liquidity/balancer_v2.rs b/crates/solver/src/liquidity/balancer_v2.rs index 1d635ec8e4..441cbcf43d 100644 --- a/crates/solver/src/liquidity/balancer_v2.rs +++ b/crates/solver/src/liquidity/balancer_v2.rs @@ -17,8 +17,9 @@ use { settlement::SettlementEncoder, }, anyhow::Result, - contracts::{BalancerV2Vault, GPv2Settlement}, + contracts::{GPv2Settlement, alloy::BalancerV2Vault}, ethcontract::H256, + ethrpc::alloy::conversions::IntoLegacy, model::TokenPair, shared::{ ethrpc::Web3, @@ -33,7 +34,7 @@ use { /// A liquidity provider for Balancer V2 weighted pools. pub struct BalancerV2Liquidity { settlement: GPv2Settlement, - vault: BalancerV2Vault, + vault: BalancerV2Vault::Instance, pool_fetcher: Arc, allowance_manager: Box, } @@ -43,7 +44,7 @@ impl BalancerV2Liquidity { web3: Web3, pool_fetcher: Arc, settlement: GPv2Settlement, - vault: BalancerV2Vault, + vault: BalancerV2Vault::Instance, ) -> Self { let allowance_manager = AllowanceManager::new(web3, settlement.address()); Self { @@ -65,7 +66,7 @@ impl BalancerV2Liquidity { let allowances = self .allowance_manager - .get_allowances(tokens, self.vault.address()) + .get_allowances(tokens, self.vault.address().into_legacy()) .await?; let inner = Arc::new(Inner { @@ -134,7 +135,7 @@ pub struct SettlementHandler { struct Inner { settlement: GPv2Settlement, - vault: BalancerV2Vault, + vault: BalancerV2Vault::Instance, allowances: Allowances, } @@ -142,7 +143,7 @@ impl SettlementHandler { pub fn new( pool_id: H256, settlement: GPv2Settlement, - vault: BalancerV2Vault, + vault: BalancerV2Vault::Instance, allowances: Allowances, ) -> Self { SettlementHandler { @@ -155,7 +156,7 @@ impl SettlementHandler { } } - pub fn vault(&self) -> &BalancerV2Vault { + pub fn vault(&self) -> &BalancerV2Vault::Instance { &self.inner.vault } @@ -258,10 +259,10 @@ mod tests { }, }; - fn dummy_contracts() -> (GPv2Settlement, BalancerV2Vault) { + fn dummy_contracts() -> (GPv2Settlement, BalancerV2Vault::Instance) { ( dummy_contract!(GPv2Settlement, H160([0xc0; 20])), - dummy_contract!(BalancerV2Vault, H160([0xc1; 20])), + BalancerV2Vault::Instance::new([0xc1; 20].into(), ethrpc::mock::web3().alloy), ) } @@ -454,7 +455,7 @@ mod tests { settlement: settlement.clone(), vault: vault.clone(), allowances: Allowances::new( - vault.address(), + vault.address().into_legacy(), hashmap! { H160([0x70; 20]) => 0.into(), H160([0x71; 20]) => 100.into(), @@ -496,7 +497,7 @@ mod tests { [ Approval { token: H160([0x70; 20]), - spender: vault.address(), + spender: vault.address().into_legacy(), } .encode(), BalancerSwapGivenOutInteraction { From e2679fe5b03ed890cd7ef24f8aeab137c7931bf0 Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 9 Sep 2025 13:39:32 +0300 Subject: [PATCH 2/5] Typo --- crates/driver/src/boundary/liquidity/balancer/v2/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs b/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs index 403cfe50f2..7de4e30541 100644 --- a/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs +++ b/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs @@ -110,10 +110,7 @@ async fn init_liquidity( ) -> Result> { let web3 = eth.web3().clone(); let contracts = BalancerContracts { - vault: BalancerV2Vault::Instance::new( - config.vault.0.into_alloy(), - ethrpc::mock::web3().alloy, - ), + vault: BalancerV2Vault::Instance::new(config.vault.0.into_alloy(), web3.alloy.clone()), factories: [ config .weighted From 54cd3b55cddf061c655e773103b99dce2632b658 Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 9 Sep 2025 13:46:11 +0300 Subject: [PATCH 3/5] Drop redundant bindings --- crates/contracts/build.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/contracts/build.rs b/crates/contracts/build.rs index 4ad0abc2c4..62fe8cecca 100644 --- a/crates/contracts/build.rs +++ b/crates/contracts/build.rs @@ -152,9 +152,6 @@ fn main() { generate_contract_with_config("BalancerV2Authorizer", |builder| { builder.contract_mod_override("balancer_v2_authorizer") }); - generate_contract_with_config("BalancerV2BasePool", |builder| { - builder.contract_mod_override("balancer_v2_base_pool") - }); generate_contract_with_config("BalancerV2BasePoolFactory", |builder| { builder.contract_mod_override("balancer_v2_base_pool_factory") }); From 1d57247d59e47613a4daa748cc173c47ac54ce90 Mon Sep 17 00:00:00 2001 From: ilya Date: Thu, 11 Sep 2025 12:41:57 +0300 Subject: [PATCH 4/5] Naming --- crates/ethrpc/src/alloy/conversions.rs | 4 ++-- crates/shared/src/sources/balancer_v2/pools/common.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/ethrpc/src/alloy/conversions.rs b/crates/ethrpc/src/alloy/conversions.rs index 2d9393cfab..eb63e05125 100644 --- a/crates/ethrpc/src/alloy/conversions.rs +++ b/crates/ethrpc/src/alloy/conversions.rs @@ -168,10 +168,10 @@ impl IntoLegacy for alloy::primitives::Address { } } -impl IntoAlloy for alloy::primitives::aliases::B256 { +impl IntoLegacy for alloy::primitives::aliases::B256 { type To = primitive_types::H256; - fn into_alloy(self) -> Self::To { + fn into_legacy(self) -> Self::To { primitive_types::H256(self.into()) } } diff --git a/crates/shared/src/sources/balancer_v2/pools/common.rs b/crates/shared/src/sources/balancer_v2/pools/common.rs index 91927519c8..19925c710d 100644 --- a/crates/shared/src/sources/balancer_v2/pools/common.rs +++ b/crates/shared/src/sources/balancer_v2/pools/common.rs @@ -88,7 +88,7 @@ impl PoolInfoFetcher { ) -> Result { let pool = self.base_pool_at(pool_address); - let pool_id = pool.getPoolId().call().await?.into_alloy(); + let pool_id = pool.getPoolId().call().await?.into_legacy(); let tokens = self .vault .getPoolTokens(pool_id.0.into()) @@ -135,7 +135,7 @@ impl PoolInfoFetcher { .call() .await }; - let fetch_balances = async move { + let pool_tokens = async move { vault .getPoolTokens(pool_id.0.into()) .block(block.into_alloy()) @@ -150,7 +150,7 @@ impl PoolInfoFetcher { let pool = pool.clone(); async move { let (paused, swap_fee, pool_tokens) = - futures::try_join!(fetch_paused, fetch_swap_fee, fetch_balances)?; + futures::try_join!(fetch_paused, fetch_swap_fee, pool_tokens)?; let swap_fee = Bfp::from_wei(swap_fee.into_legacy()); let balances = pool_tokens.balances; @@ -440,7 +440,7 @@ mod tests { assert_eq!( pool_info, PoolInfo { - id: pool_id.into_alloy(), + id: pool_id.into_legacy(), address: pool.address().into_legacy(), tokens: tokens.to_vec(), scaling_factors: vec![Bfp::exp10(0), Bfp::exp10(0), Bfp::exp10(12)], From 18d1be4866434f08e22647f4d5c550fbc3d8ad4e Mon Sep 17 00:00:00 2001 From: ilya Date: Thu, 11 Sep 2025 12:57:48 +0300 Subject: [PATCH 5/5] Fixes --- Cargo.lock | 1 + crates/e2e/tests/e2e/liquidity.rs | 2 +- crates/shared/src/sources/balancer_v2/pools/common.rs | 7 ++++--- crates/solver/Cargo.toml | 1 + crates/solver/src/interactions/balancer_v2.rs | 4 ++-- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02d65ce03c..3a726d6261 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6008,6 +6008,7 @@ dependencies = [ name = "solver" version = "0.1.0" dependencies = [ + "alloy", "anyhow", "arc-swap", "async-trait", diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 2c1468a576..2761a94d46 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -400,5 +400,5 @@ async fn fill_or_kill_zeroex_limit_order( .watch() .await?; - Ok(tx_hash.into_alloy()) + Ok(tx_hash.into_legacy()) } diff --git a/crates/shared/src/sources/balancer_v2/pools/common.rs b/crates/shared/src/sources/balancer_v2/pools/common.rs index 19925c710d..d5ea1b4739 100644 --- a/crates/shared/src/sources/balancer_v2/pools/common.rs +++ b/crates/shared/src/sources/balancer_v2/pools/common.rs @@ -114,6 +114,7 @@ impl PoolInfoFetcher { pool: &PoolInfo, block: BlockId, ) -> BoxFuture<'static, Result> { + let block = block.into_alloy(); let pool_address = pool.address; let pool_id = pool.id; let vault = self.vault.clone(); @@ -123,7 +124,7 @@ impl PoolInfoFetcher { let fetch_paused = async move { pool_contract_paused .getPausedState() - .block(block.into_alloy()) + .block(block) .call() .await .map(|result| result.paused) @@ -131,14 +132,14 @@ impl PoolInfoFetcher { let fetch_swap_fee = async move { pool_contract_fee .getSwapFeePercentage() - .block(block.into_alloy()) + .block(block) .call() .await }; let pool_tokens = async move { vault .getPoolTokens(pool_id.0.into()) - .block(block.into_alloy()) + .block(block) .call() .await }; diff --git a/crates/solver/Cargo.toml b/crates/solver/Cargo.toml index deeec8329c..fd036272a8 100644 --- a/crates/solver/Cargo.toml +++ b/crates/solver/Cargo.toml @@ -11,6 +11,7 @@ path = "src/lib.rs" doctest = false [dependencies] +alloy = { workspace = true } anyhow = { workspace = true } arc-swap = { workspace = true } async-trait = { workspace = true } diff --git a/crates/solver/src/interactions/balancer_v2.rs b/crates/solver/src/interactions/balancer_v2.rs index a8b3c603f3..a91d4f8810 100644 --- a/crates/solver/src/interactions/balancer_v2.rs +++ b/crates/solver/src/interactions/balancer_v2.rs @@ -1,8 +1,8 @@ use { + alloy::primitives::U256, contracts::{GPv2Settlement, alloy::BalancerV2Vault}, ethcontract::{Bytes, H256}, ethrpc::alloy::conversions::{IntoAlloy, IntoLegacy}, - primitive_types::U256, shared::{ http_solver::model::TokenAmount, interaction::{EncodedInteraction, Interaction}, @@ -47,7 +47,7 @@ impl BalancerSwapGivenOutInteraction { single_swap, funds, self.asset_in_max.amount.into_alloy(), - (*NEVER).into_alloy(), + *NEVER, ) .calldata() .clone();