From d7372b408bb64927f3c8d421b5998897bec40db5 Mon Sep 17 00:00:00 2001 From: MartinquaXD Date: Wed, 27 Aug 2025 14:25:37 +0000 Subject: [PATCH 01/34] Introduce Web3 wrapper type --- Cargo.lock | 56 +++++++++++++++++- crates/autopilot/Cargo.toml | 1 + .../ethflow_events/event_retriever.rs | 2 +- .../onchain_order_events/event_retriever.rs | 2 +- .../src/database/onchain_order_events/mod.rs | 4 +- crates/autopilot/src/infra/blockchain/mod.rs | 15 +++-- crates/autopilot/src/run.rs | 16 ++---- crates/cow-amm/src/factory.rs | 2 +- .../src/boundary/liquidity/balancer/v2/mod.rs | 2 +- crates/driver/src/boundary/liquidity/mod.rs | 3 +- .../src/boundary/liquidity/uniswap/v2.rs | 5 +- .../src/boundary/liquidity/uniswap/v3.rs | 2 +- .../driver/src/boundary/liquidity/zeroex.rs | 2 +- crates/driver/src/boundary/mod.rs | 10 +--- .../driver/src/infra/blockchain/contracts.rs | 5 +- crates/driver/src/infra/blockchain/gas.rs | 6 +- crates/driver/src/infra/blockchain/mod.rs | 13 ++--- crates/driver/src/infra/mempool/mod.rs | 8 +-- crates/driver/src/tests/setup/blockchain.rs | 21 ++++--- crates/e2e/src/setup/mod.rs | 5 +- .../e2e/src/setup/onchain_components/mod.rs | 2 +- crates/ethrpc/Cargo.toml | 2 +- crates/ethrpc/src/alloy/mod.rs | 20 +++++++ crates/ethrpc/src/block_stream/mod.rs | 16 ++++-- crates/ethrpc/src/extensions.rs | 11 +--- crates/ethrpc/src/instrumented.rs | 13 +++-- crates/ethrpc/src/lib.rs | 57 +++++++++++++++---- crates/ethrpc/src/mock.rs | 13 ++++- crates/ethrpc/src/multicall.rs | 10 +--- crates/refunder/src/refund_service.rs | 2 +- .../shared/src/account_balances/simulation.rs | 8 +-- crates/shared/src/bad_token/trace_call.rs | 11 ++-- crates/shared/src/code_simulation.rs | 7 ++- crates/shared/src/ethrpc.rs | 8 +-- crates/shared/src/event_handling.rs | 18 ++---- crates/shared/src/gas_price_estimation/mod.rs | 2 +- .../balance_overrides/detector.rs | 6 +- crates/shared/src/sources/swapr.rs | 5 +- crates/shared/src/sources/uniswap_v2/mod.rs | 9 +-- .../src/sources/uniswap_v3/event_fetching.rs | 2 +- crates/solver/src/interactions/allowances.rs | 2 +- 41 files changed, 236 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 605e5b0b87..9b58cc7e73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,6 +325,7 @@ dependencies = [ "alloy-signer", "alloy-sol-types", "alloy-transport", + "alloy-transport-http", "async-stream", "async-trait", "auto_impl", @@ -336,11 +337,13 @@ dependencies = [ "lru 0.13.0", "parking_lot", "pin-project", + "reqwest 0.12.12", "serde", "serde_json", "thiserror 2.0.12", "tokio", "tracing", + "url", "wasmtimer", ] @@ -374,9 +377,11 @@ dependencies = [ "alloy-json-rpc", "alloy-primitives", "alloy-transport", + "alloy-transport-http", "async-stream", "futures", "pin-project", + "reqwest 0.12.12", "serde", "serde_json", "tokio", @@ -384,6 +389,7 @@ dependencies = [ "tower 0.5.2", "tracing", "tracing-futures", + "url", "wasmtimer", ] @@ -537,7 +543,12 @@ name = "alloy-transport-http" version = "1.0.17" source = "git+https://github.com/alloy-rs/alloy?rev=c15a4a3c04ce15bfa3796cc449f8407200b7599f#c15a4a3c04ce15bfa3796cc449f8407200b7599f" dependencies = [ + "alloy-json-rpc", "alloy-transport", + "reqwest 0.12.12", + "serde_json", + "tower 0.5.2", + "tracing", "url", ] @@ -899,6 +910,7 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" name = "autopilot" version = "0.1.0" dependencies = [ + "alloy", "anyhow", "app-data", "async-trait", @@ -3687,6 +3699,22 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.6.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.14" @@ -5377,7 +5405,7 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "hyper 0.14.29", - "hyper-tls", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -5386,7 +5414,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -5418,19 +5446,23 @@ dependencies = [ "http-body 1.0.0", "http-body-util", "hyper 1.6.0", + "hyper-tls 0.6.0", "hyper-util", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile 2.2.0", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", "tokio", + "tokio-native-tls", "tower 0.5.2", "tower-service", "url", @@ -5667,7 +5699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] @@ -5681,6 +5713,24 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + [[package]] name = "rustls-webpki" version = "0.101.7" diff --git a/crates/autopilot/Cargo.toml b/crates/autopilot/Cargo.toml index 8d58677189..bbbd52a57e 100644 --- a/crates/autopilot/Cargo.toml +++ b/crates/autopilot/Cargo.toml @@ -15,6 +15,7 @@ name = "autopilot" path = "src/main.rs" [dependencies] +alloy = { workspace = true } app-data = { workspace = true } bytes-hex = { workspace = true } anyhow = { workspace = true } diff --git a/crates/autopilot/src/database/ethflow_events/event_retriever.rs b/crates/autopilot/src/database/ethflow_events/event_retriever.rs index dad46ba831..88f7cb5b43 100644 --- a/crates/autopilot/src/database/ethflow_events/event_retriever.rs +++ b/crates/autopilot/src/database/ethflow_events/event_retriever.rs @@ -30,7 +30,7 @@ impl EventRetrieving for EthFlowRefundRetriever { type Event = contracts::cowswap_eth_flow::Event; fn get_events(&self) -> AllEventsBuilder { - let mut events = AllEventsBuilder::new(self.web3.clone(), H160::default(), None); + let mut events = AllEventsBuilder::new(self.web3.legacy.clone(), H160::default(), None); // We want to observe multiple addresses for events. events.filter = events.filter.address(self.addresses.clone()); // Filter out events that we don't want to listen for in the contract. `Self` is diff --git a/crates/autopilot/src/database/onchain_order_events/event_retriever.rs b/crates/autopilot/src/database/onchain_order_events/event_retriever.rs index 5808f5f8f4..cec9145e28 100644 --- a/crates/autopilot/src/database/onchain_order_events/event_retriever.rs +++ b/crates/autopilot/src/database/onchain_order_events/event_retriever.rs @@ -40,7 +40,7 @@ impl EventRetrieving for CoWSwapOnchainOrdersContract { type Event = cowswap_onchain_orders::Event; fn get_events(&self) -> AllEventsBuilder { - let mut events = AllEventsBuilder::new(self.web3.clone(), H160::default(), None); + let mut events = AllEventsBuilder::new(self.web3.legacy.clone(), H160::default(), None); // We want to observe multiple addresses for events. events.filter = events.filter.address(self.addresses.clone()); // Filter out events that don't belong to the ABI of `OnchainOrdersContract`. diff --git a/crates/autopilot/src/database/onchain_order_events/mod.rs b/crates/autopilot/src/database/onchain_order_events/mod.rs index e2fa6f3522..1eb9c04bd8 100644 --- a/crates/autopilot/src/database/onchain_order_events/mod.rs +++ b/crates/autopilot/src/database/onchain_order_events/mod.rs @@ -793,6 +793,7 @@ mod test { contracts::cowswap_onchain_orders::event_data::OrderPlacement as ContractOrderPlacement, database::{byte_array::ByteArray, onchain_broadcasted_orders::OnchainOrderPlacement}, ethcontract::{Bytes, EventMetadata, H160, U256}, + ethrpc::Web3, model::{ DomainSeparator, order::{BuyTokenDestination, OrderData, OrderKind, SellTokenSource}, @@ -806,7 +807,6 @@ mod test { sell_token_source_into, signing_scheme_into, }, - ethrpc::create_env_test_transport, fee::FeeParameters, order_quoting::{MockOrderQuoting, Quote, QuoteData}, }, @@ -1234,7 +1234,7 @@ mod test { custom_onchain_order_parser .expect_customized_event_data_for_event_index() .returning(|_, _, _, _| 1u8); - let web3 = Web3::new(create_env_test_transport()); + let web3 = Web3::new_from_env(); let onchain_order_parser = OnchainOrderParser { db: Postgres { pool: PgPool::connect_lazy("postgresql://").unwrap(), diff --git a/crates/autopilot/src/infra/blockchain/mod.rs b/crates/autopilot/src/infra/blockchain/mod.rs index 575c735b48..97e596a26e 100644 --- a/crates/autopilot/src/infra/blockchain/mod.rs +++ b/crates/autopilot/src/infra/blockchain/mod.rs @@ -2,8 +2,7 @@ use { self::contracts::Contracts, crate::{boundary, domain::eth}, chain::Chain, - ethcontract::dyns::DynWeb3, - ethrpc::{block_stream::CurrentBlockWatcher, extensions::DebugNamespace}, + ethrpc::{Web3, block_stream::CurrentBlockWatcher, extensions::DebugNamespace}, primitive_types::U256, std::time::Duration, thiserror::Error, @@ -14,7 +13,7 @@ pub mod contracts; /// An Ethereum RPC connection. pub struct Rpc { - web3: DynWeb3, + web3: Web3, chain: Chain, url: Url, } @@ -43,7 +42,7 @@ impl Rpc { } /// Returns a reference to the underlying web3 client. - pub fn web3(&self) -> &DynWeb3 { + pub fn web3(&self) -> &Web3 { &self.web3 } @@ -56,8 +55,8 @@ impl Rpc { /// The Ethereum blockchain. #[derive(Clone)] pub struct Ethereum { - web3: DynWeb3, - unbuffered_web3: DynWeb3, + web3: Web3, + unbuffered_web3: Web3, chain: Chain, current_block: CurrentBlockWatcher, contracts: Contracts, @@ -71,8 +70,8 @@ impl Ethereum { /// Since this type is essential for the program this method will panic on /// any initialization error. pub async fn new( - web3: DynWeb3, - unbuffered_web3: DynWeb3, + web3: Web3, + unbuffered_web3: Web3, chain: &Chain, url: Url, addresses: contracts::Addresses, diff --git a/crates/autopilot/src/run.rs b/crates/autopilot/src/run.rs index cf756cc2fd..67206abbc0 100644 --- a/crates/autopilot/src/run.rs +++ b/crates/autopilot/src/run.rs @@ -26,15 +26,9 @@ use { chain::Chain, clap::Parser, contracts::{BalancerV2Vault, IUniswapV3Factory}, - ethcontract::{ - BlockNumber, - H160, - common::DeploymentInformation, - dyns::DynWeb3, - errors::DeployError, - }, - ethrpc::block_stream::block_number_to_block_number_hash, - futures::stream::StreamExt, + ethcontract::{BlockNumber, H160, common::DeploymentInformation, errors::DeployError}, + ethrpc::{Web3, block_stream::block_number_to_block_number_hash}, + futures::StreamExt, model::DomainSeparator, observe::metrics::LivenessChecking, shared::{ @@ -116,8 +110,8 @@ async fn unbuffered_ethrpc(url: &Url) -> infra::blockchain::Rpc { #[instrument(skip_all)] async fn ethereum( - web3: DynWeb3, - unbuffered_web3: DynWeb3, + web3: Web3, + unbuffered_web3: Web3, chain: &Chain, url: Url, contracts: infra::blockchain::contracts::Addresses, diff --git a/crates/cow-amm/src/factory.rs b/crates/cow-amm/src/factory.rs index a6bc60d12f..b1022ecf5e 100644 --- a/crates/cow-amm/src/factory.rs +++ b/crates/cow-amm/src/factory.rs @@ -18,7 +18,7 @@ impl EventRetrieving for Factory { type Event = CowAmmEvent; fn get_events(&self) -> AllEventsBuilder { - let mut events = AllEventsBuilder::new(self.web3.clone(), self.address, None); + let mut events = AllEventsBuilder::new(self.web3.legacy.clone(), self.address, None); events.filter = events.filter.topic0(Some(AMM_DEPLOYED_TOPIC).into()); events } diff --git a/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs b/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs index bc4fb8f2bd..0dcff6f79b 100644 --- a/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs +++ b/crates/driver/src/boundary/liquidity/balancer/v2/mod.rs @@ -105,7 +105,7 @@ async fn init_liquidity( block_retriever: Arc, config: &infra::liquidity::config::BalancerV2, ) -> Result> { - let web3 = boundary::web3(eth); + let web3 = eth.web3().clone(); let contracts = BalancerContracts { vault: BalancerV2Vault::at(&web3, config.vault.into()), factories: [ diff --git a/crates/driver/src/boundary/liquidity/mod.rs b/crates/driver/src/boundary/liquidity/mod.rs index bb7b6b4576..5cff9649bb 100644 --- a/crates/driver/src/boundary/liquidity/mod.rs +++ b/crates/driver/src/boundary/liquidity/mod.rs @@ -1,6 +1,5 @@ use { crate::{ - boundary, domain::{eth, liquidity}, infra::{self, blockchain::Ethereum}, }, @@ -65,7 +64,7 @@ impl Fetcher { }; let block_stream = eth.current_block(); - let block_retriever = blocks.retriever(boundary::web3(eth)); + let block_retriever = blocks.retriever(eth.web3().clone()); let uni_v2: Vec<_> = future::try_join_all( config diff --git a/crates/driver/src/boundary/liquidity/uniswap/v2.rs b/crates/driver/src/boundary/liquidity/uniswap/v2.rs index dbc4b35547..e6e1caab99 100644 --- a/crates/driver/src/boundary/liquidity/uniswap/v2.rs +++ b/crates/driver/src/boundary/liquidity/uniswap/v2.rs @@ -134,7 +134,6 @@ where { let router = eth.contract_at::(config.router); let settlement = eth.contracts().settlement().clone(); - let web3 = router.raw_instance().web3().clone(); let pool_fetcher = { let factory = router.factory().call().await?; let pair_provider = PairProvider { @@ -143,8 +142,8 @@ where }; let pool_fetcher = PoolFetcher::new( - reader(web3.clone(), pair_provider), - web3.clone(), + reader(eth.web3().clone(), pair_provider), + eth.web3().clone(), config.missing_pool_cache_time, ); diff --git a/crates/driver/src/boundary/liquidity/uniswap/v3.rs b/crates/driver/src/boundary/liquidity/uniswap/v3.rs index c97577f250..21a412c248 100644 --- a/crates/driver/src/boundary/liquidity/uniswap/v3.rs +++ b/crates/driver/src/boundary/liquidity/uniswap/v3.rs @@ -128,7 +128,7 @@ async fn init_liquidity( block_retriever: Arc, config: &infra::liquidity::config::UniswapV3, ) -> anyhow::Result> { - let web3 = boundary::web3(eth); + let web3 = eth.web3().clone(); let router = UniswapV3SwapRouterV2::at(&web3, config.router.0); let pool_fetcher = Arc::new( diff --git a/crates/driver/src/boundary/liquidity/zeroex.rs b/crates/driver/src/boundary/liquidity/zeroex.rs index 080aa79103..3500fb1f3a 100644 --- a/crates/driver/src/boundary/liquidity/zeroex.rs +++ b/crates/driver/src/boundary/liquidity/zeroex.rs @@ -84,7 +84,7 @@ pub async fn collector( ) -> anyhow::Result> { let eth = eth.with_metric_label("zeroex".into()); let settlement = eth.contracts().settlement().clone(); - let web3 = settlement.raw_instance().web3().clone(); + let web3 = eth.web3().clone(); let contract = contracts::IZeroEx::deployed(&web3).await?; let http_client_factory = &HttpClientFactory::new(&shared::http_client::Arguments { http_timeout: config.http_timeout, diff --git a/crates/driver/src/boundary/mod.rs b/crates/driver/src/boundary/mod.rs index 8d16122106..0e220a985d 100644 --- a/crates/driver/src/boundary/mod.rs +++ b/crates/driver/src/boundary/mod.rs @@ -27,7 +27,7 @@ pub mod liquidity; // The [`anyhow::Error`] type is re-exported because the legacy code mostly // returns that error. This will change as the legacy code gets refactored away. -use {crate::infra::blockchain::Ethereum, url::Url}; +use url::Url; pub use { anyhow::{Error, Result}, contracts, @@ -35,14 +35,6 @@ pub use { shared::ethrpc::Web3, }; -/// Returns a Web3 instance with a trait object transport needed by various -/// boundary components. -fn web3(eth: &Ethereum) -> Web3 { - // Ugly way to get access to one of these... However, this way we don't - // leak this into our domain logic. - eth.contracts().settlement().raw_instance().web3() -} - /// Builds a web3 client that buffers requests and sends them in a /// batch call. pub fn buffered_web3_client( diff --git a/crates/driver/src/infra/blockchain/contracts.rs b/crates/driver/src/infra/blockchain/contracts.rs index d96c41aa59..f3a767aeae 100644 --- a/crates/driver/src/infra/blockchain/contracts.rs +++ b/crates/driver/src/infra/blockchain/contracts.rs @@ -6,8 +6,7 @@ use { }, chain::Chain, contracts::FlashLoanRouter, - ethcontract::dyns::DynWeb3, - ethrpc::block_stream::CurrentBlockWatcher, + ethrpc::{Web3, block_stream::CurrentBlockWatcher}, std::collections::HashMap, thiserror::Error, }; @@ -57,7 +56,7 @@ pub struct Addresses { impl Contracts { pub(super) async fn new( - web3: &DynWeb3, + web3: &Web3, chain: Chain, addresses: Addresses, block_stream: CurrentBlockWatcher, diff --git a/crates/driver/src/infra/blockchain/gas.rs b/crates/driver/src/infra/blockchain/gas.rs index 1b4c6e49e9..0efca2937d 100644 --- a/crates/driver/src/infra/blockchain/gas.rs +++ b/crates/driver/src/infra/blockchain/gas.rs @@ -8,7 +8,7 @@ use { domain::eth, infra::{config::file::GasEstimatorType, mempool}, }, - ethcontract::dyns::DynWeb3, + ethrpc::Web3, gas_estimation::{ DEFAULT_GAS_LIMIT, DEFAULT_TIME_LIMIT, @@ -31,7 +31,7 @@ pub struct GasPriceEstimator { impl GasPriceEstimator { pub async fn new( - web3: &DynWeb3, + web3: &Web3, gas_estimator_type: &GasEstimatorType, mempools: &[mempool::Config], ) -> Result { @@ -53,7 +53,7 @@ impl GasPriceEstimator { .await .map_err(Error::GasPrice)?, ), - GasEstimatorType::Web3 => Arc::new(web3.clone()), + GasEstimatorType::Web3 => Arc::new(web3.legacy.clone()), }; let additional_tip = mempools .iter() diff --git a/crates/driver/src/infra/blockchain/mod.rs b/crates/driver/src/infra/blockchain/mod.rs index 959db0378c..1216dc59f2 100644 --- a/crates/driver/src/infra/blockchain/mod.rs +++ b/crates/driver/src/infra/blockchain/mod.rs @@ -2,8 +2,8 @@ use { self::contracts::ContractAt, crate::{boundary, domain::eth}, chain::Chain, - ethcontract::{dyns::DynWeb3, errors::ExecutionError}, - ethrpc::block_stream::CurrentBlockWatcher, + ethcontract::errors::ExecutionError, + ethrpc::{Web3, block_stream::CurrentBlockWatcher}, shared::account_balances::{BalanceSimulator, SimulationError}, std::{fmt, sync::Arc, time::Duration}, thiserror::Error, @@ -14,12 +14,11 @@ use { pub mod contracts; pub mod gas; pub mod token; - pub use self::{contracts::Contracts, gas::GasPriceEstimator}; /// An Ethereum RPC connection. pub struct Rpc { - web3: DynWeb3, + web3: Web3, chain: Chain, args: RpcArgs, } @@ -50,7 +49,7 @@ impl Rpc { } /// Returns a reference to the underlying web3 client. - pub fn web3(&self) -> &DynWeb3 { + pub fn web3(&self) -> &Web3 { &self.web3 } } @@ -66,7 +65,7 @@ pub enum RpcError { /// The Ethereum blockchain. #[derive(Clone)] pub struct Ethereum { - web3: DynWeb3, + web3: Web3, inner: Arc, } @@ -311,7 +310,7 @@ impl Ethereum { .map(|gas| gas.effective().0.0) } - pub fn web3(&self) -> &DynWeb3 { + pub fn web3(&self) -> &Web3 { &self.web3 } } diff --git a/crates/driver/src/infra/mempool/mod.rs b/crates/driver/src/infra/mempool/mod.rs index 22262defee..5a341ce4bf 100644 --- a/crates/driver/src/infra/mempool/mod.rs +++ b/crates/driver/src/infra/mempool/mod.rs @@ -4,7 +4,7 @@ use { domain::{competition, eth, mempools}, infra, }, - ethcontract::dyns::DynWeb3, + ethrpc::Web3, }; #[derive(Debug, Clone)] @@ -56,7 +56,7 @@ pub enum RevertProtection { #[derive(Debug, Clone)] pub struct Mempool { - transport: DynWeb3, + transport: Web3, config: Config, } @@ -67,7 +67,7 @@ impl std::fmt::Display for Mempool { } impl Mempool { - pub fn new(config: Config, transport: DynWeb3) -> Self { + pub fn new(config: Config, transport: Web3) -> Self { let transport = match &config.kind { Kind::Public { .. } => transport, // Flashbots Protect RPC fallback doesn't support buffered transport @@ -84,7 +84,7 @@ impl Mempool { gas: competition::solution::settlement::Gas, solver: &infra::Solver, ) -> Result { - ethcontract::transaction::TransactionBuilder::new(self.transport.clone()) + ethcontract::transaction::TransactionBuilder::new(self.transport.legacy.clone()) .from(solver.account().clone()) .to(tx.to.into()) .gas_price(ethcontract::GasPrice::Eip1559 { diff --git a/crates/driver/src/tests/setup/blockchain.rs b/crates/driver/src/tests/setup/blockchain.rs index 40e140986e..1ed1688a53 100644 --- a/crates/driver/src/tests/setup/blockchain.rs +++ b/crates/driver/src/tests/setup/blockchain.rs @@ -7,7 +7,8 @@ use { }, tests::{self, boundary, cases::EtherExt}, }, - ethcontract::{PrivateKey, Web3, dyns::DynWeb3, transport::DynTransport}, + ethcontract::PrivateKey, + ethrpc::Web3, futures::Future, secp256k1::SecretKey, serde_json::json, @@ -30,7 +31,7 @@ pub struct Pair { #[derive(Debug)] pub struct Blockchain { pub trader_secret_key: SecretKey, - pub web3: Web3, + pub web3: Web3, pub web3_url: String, pub tokens: HashMap<&'static str, contracts::ERC20Mintable>, pub weth: contracts::WETH9, @@ -212,9 +213,7 @@ impl Blockchain { // later let node = Node::new(&config.rpc_args).await; - let web3 = Web3::new(DynTransport::new( - web3::transports::Http::new(&node.url()).expect("valid URL"), - )); + let web3 = Web3::new_from_url(&node.url()); let main_trader_account = ethcontract::Account::Offline( ethcontract::PrivateKey::from_slice(config.main_trader_secret_key.as_ref()).unwrap(), @@ -250,7 +249,7 @@ impl Blockchain { .unwrap(); wait_for( &web3, - ethcontract::transaction::TransactionBuilder::new(web3.clone()) + ethcontract::transaction::TransactionBuilder::new(web3.legacy.clone()) .from(primary_account(&web3).await) .to(weth.address()) .value(balance / 5) @@ -922,11 +921,11 @@ impl Blockchain { } } -async fn primary_address(web3: &DynWeb3) -> ethcontract::H160 { +async fn primary_address(web3: &Web3) -> ethcontract::H160 { web3.eth().accounts().await.unwrap()[0] } -async fn primary_account(web3: &DynWeb3) -> ethcontract::Account { +async fn primary_account(web3: &Web3) -> ethcontract::Account { ethcontract::Account::Local(web3.eth().accounts().await.unwrap()[0], None) } @@ -1012,7 +1011,7 @@ impl Drop for Node { /// introduces a subtle race condition, so it's necessary to /// wait for transactions to be confirmed before proceeding with the test. When /// switching from geth back to hardhat, this function can be removed. -pub async fn wait_for(web3: &DynWeb3, fut: impl Future) -> T { +pub async fn wait_for(web3: &Web3, fut: impl Future) -> T { let block = web3.eth().block_number().await.unwrap().as_u64(); let result = fut.await; wait_for_block(web3, block + 1).await; @@ -1020,7 +1019,7 @@ pub async fn wait_for(web3: &DynWeb3, fut: impl Future) -> T { } /// Waits for the block height to be at least the specified value. -pub async fn wait_for_block(web3: &DynWeb3, block: u64) { +pub async fn wait_for_block(web3: &Web3, block: u64) { tokio::time::timeout(std::time::Duration::from_secs(15), async { loop { let next_block = web3.eth().block_number().await.unwrap().as_u64(); @@ -1035,7 +1034,7 @@ pub async fn wait_for_block(web3: &DynWeb3, block: u64) { } /// Sets code at a specific address for testing. -pub async fn set_code(web3: &DynWeb3, address: eth::H160, code: &[u8]) { +pub async fn set_code(web3: &Web3, address: eth::H160, code: &[u8]) { use web3::Transport; web3.transport() diff --git a/crates/e2e/src/setup/mod.rs b/crates/e2e/src/setup/mod.rs index daf7cd0169..59e2ff2eea 100644 --- a/crates/e2e/src/setup/mod.rs +++ b/crates/e2e/src/setup/mod.rs @@ -10,7 +10,7 @@ use { crate::nodes::{NODE_HOST, Node}, anyhow::{Result, anyhow}, ethcontract::futures::FutureExt, - shared::ethrpc::{Web3, create_test_transport}, + ethrpc::Web3, std::{ future::Future, io::Write, @@ -212,8 +212,7 @@ async fn run( let _ = node_panic_handle.lock().unwrap().take(); })); - let http = create_test_transport(NODE_HOST); - let web3 = Web3::new(http); + let web3 = Web3::new_from_url(NODE_HOST); services::clear_database().await; // Hack: the closure may actually be unwind unsafe; moreover, `catch_unwind` diff --git a/crates/e2e/src/setup/onchain_components/mod.rs b/crates/e2e/src/setup/onchain_components/mod.rs index 66b19dee5c..33d52cbe12 100644 --- a/crates/e2e/src/setup/onchain_components/mod.rs +++ b/crates/e2e/src/setup/onchain_components/mod.rs @@ -583,7 +583,7 @@ impl OnchainComponents { pub async fn send_wei(&self, to: H160, amount: U256) { let balance_before = self.web3.eth().balance(to, None).await.unwrap(); - let receipt = TransactionBuilder::new(self.web3.clone()) + let receipt = TransactionBuilder::new(self.web3.legacy.clone()) .value(amount) .to(to) .send() diff --git a/crates/ethrpc/Cargo.toml b/crates/ethrpc/Cargo.toml index e89ba3efab..6654e3ad78 100644 --- a/crates/ethrpc/Cargo.toml +++ b/crates/ethrpc/Cargo.toml @@ -11,7 +11,7 @@ path = "src/lib.rs" doctest = false [dependencies] -alloy = { workspace = true, default-features = false, features = ["json-rpc", "providers", "rpc-client", "transports"] } +alloy = { workspace = true, default-features = false, features = ["json-rpc", "providers", "rpc-client", "transports", "reqwest"] } anyhow = { workspace = true } async-trait = { workspace = true } futures = { workspace = true } diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index b054e198e2..6d50815323 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -2,3 +2,23 @@ mod buffering; mod instrumentation; pub use instrumentation::ProviderLabelingExt; +use { + crate::AlloyProvider, + alloy::{ + providers::{Provider, ProviderBuilder}, + rpc::client::ClientBuilder, + }, + buffering::BatchCallLayer, + instrumentation::{InstrumentationLayer, LabelingLayer}, +}; + +pub fn provider(url: &str) -> AlloyProvider { + let rpc = ClientBuilder::default() + .layer(LabelingLayer { + label: "main".into(), + }) + .layer(InstrumentationLayer) + .layer(BatchCallLayer::new(Default::default())) + .http(url.parse().unwrap()); + ProviderBuilder::new().connect_client(rpc).erased() +} diff --git a/crates/ethrpc/src/block_stream/mod.rs b/crates/ethrpc/src/block_stream/mod.rs index 6977a12a4c..7f732b4f16 100644 --- a/crates/ethrpc/src/block_stream/mod.rs +++ b/crates/ethrpc/src/block_stream/mod.rs @@ -120,12 +120,18 @@ pub async fn current_block_stream( ) -> Result { // Build new Web3 specifically for the current block stream to avoid batching // requests together on chains with a very high block frequency. - let web3 = Web3::new(Web3Transport::new(HttpTransport::new( + let web3 = web3::Web3::new(Web3Transport::new(HttpTransport::new( Default::default(), - url, + url.clone(), "block_stream".into(), ))); + let web3 = crate::Web3 { + legacy: web3, + // TODO: replace this with an unbuffered alloy provider + alloy: crate::alloy::provider(url.as_str()), + }; let web3 = instrument_with_label(&web3, "base_currentBlockStream".into()); + let first_block = web3.current_block().await?; tracing::debug!(number=%first_block.number, hash=?first_block.hash, "polled block"); @@ -244,7 +250,7 @@ pub trait BlockRetrieving: Debug + Send + Sync + 'static { } #[async_trait::async_trait] -impl BlockRetrieving for Web3 { +impl BlockRetrieving for crate::Web3 { async fn current_block(&self) -> Result { get_block_at_id(self, BlockNumber::Latest.into()) .await? @@ -403,7 +409,6 @@ pub async fn next_block(current_block: &CurrentBlockWatcher) -> BlockInfo { mod tests { use { super::*, - crate::create_env_test_transport, futures::StreamExt, tokio::time::{Duration, timeout}, }; @@ -434,8 +439,7 @@ mod tests { #[tokio::test] #[ignore] async fn current_blocks_test() { - let transport = create_env_test_transport(); - let web3 = Web3::new(transport); + let web3 = Web3::new_from_env(); // single block let range = RangeInclusive::try_new(5, 5).unwrap(); diff --git a/crates/ethrpc/src/extensions.rs b/crates/ethrpc/src/extensions.rs index 31eb2c70fa..815bc34fd7 100644 --- a/crates/ethrpc/src/extensions.rs +++ b/crates/ethrpc/src/extensions.rs @@ -140,19 +140,12 @@ pub struct CallFrame { #[cfg(test)] mod tests { - use { - super::*, - crate::{Web3, create_env_test_transport}, - hex_literal::hex, - maplit::hashmap, - web3::types::BlockNumber, - }; + use {super::*, crate::Web3, hex_literal::hex, maplit::hashmap, web3::types::BlockNumber}; #[ignore] #[tokio::test] async fn can_call_with_state_override() { - let transport = create_env_test_transport(); - let web3 = Web3::new(transport); + let web3 = Web3::new_from_env(); let address = H160(hex!("EeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE")); let output = web3 diff --git a/crates/ethrpc/src/instrumented.rs b/crates/ethrpc/src/instrumented.rs index 03d8301b3c..d81fc14b0c 100644 --- a/crates/ethrpc/src/instrumented.rs +++ b/crates/ethrpc/src/instrumented.rs @@ -1,6 +1,6 @@ use { + crate::alloy::ProviderLabelingExt, ethcontract::{ - dyns::DynWeb3, jsonrpc::types::{Call, Value}, transport::DynTransport, }, @@ -72,13 +72,16 @@ impl InstrumentedTransport { } /// Adds metrics for RPC requests using the provided label. -pub fn instrument_with_label(web3: &DynWeb3, label: String) -> DynWeb3 { +pub fn instrument_with_label(web3: &crate::Web3, label: String) -> crate::Web3 { let transport = web3.transport().clone(); let instrumented = match transport.downcast::() { - Some(instrumented) => instrumented.with_additional_label(label), - _ => InstrumentedTransport::new(label, transport), + Some(instrumented) => instrumented.with_additional_label(label.clone()), + _ => InstrumentedTransport::new(label.clone(), transport), }; - web3::Web3::new(DynTransport::new(instrumented)) + crate::Web3 { + legacy: web3::Web3::new(DynTransport::new(instrumented)), + alloy: web3.alloy.labeled(label), + } } #[derive(Debug)] diff --git a/crates/ethrpc/src/lib.rs b/crates/ethrpc/src/lib.rs index 21abad5aae..eea5f99a32 100644 --- a/crates/ethrpc/src/lib.rs +++ b/crates/ethrpc/src/lib.rs @@ -10,16 +10,55 @@ pub mod multicall; use { self::{buffered::BufferedTransport, http::HttpTransport}, - ethcontract::{batch::CallBatch, dyns::DynWeb3, transport::DynTransport}, + ::alloy::providers::DynProvider, + ethcontract::{batch::CallBatch, transport::DynTransport}, reqwest::{Client, Url}, std::{num::NonZeroUsize, time::Duration}, + web3::Transport, }; pub const MAX_BATCH_SIZE: usize = 100; -pub type Web3 = DynWeb3; pub type Web3Transport = DynTransport; pub type Web3CallBatch = CallBatch; +pub type AlloyProvider = DynProvider; + +/// This is just a thin wrapper around providers (clients communicating +/// with the blockchain) to aid the migration from `web3` to `alloy-provider`. +/// It's able to dereference into the current provider (`web3`) but already +/// providers access to the new provider (`alloy`). That way we should be able +/// to convert each call site to use the new provider bit by bit instead of +/// having to everything at once. +#[derive(Debug, Clone)] +pub struct Web3 { + pub legacy: web3::Web3, + pub alloy: AlloyProvider, +} + +impl std::ops::Deref for Web3 { + type Target = web3::Web3; + + fn deref(&self) -> &Self::Target { + &self.legacy + } +} + +impl Web3 { + // for tests + pub fn new_from_env() -> Self { + let url = &std::env::var("NODE_URL").unwrap(); + Self::new_from_url(url) + } + + pub fn new_from_url(url: &str) -> Self { + let legacy_transport = create_test_transport(url); + let web3 = web3::Web3::new(legacy_transport); + Self { + legacy: web3, + alloy: crate::alloy::provider(url), + } + } +} #[derive(Debug, Clone)] pub struct Config { @@ -59,7 +98,7 @@ impl Default for Config { Self { ethrpc_max_batch_size: 20, ethrpc_max_concurrent_requests: 10, - ethrpc_batch_delay: Default::default(), + ethrpc_batch_delay: Duration::from_millis(5), } } } @@ -78,11 +117,14 @@ pub fn web3( None => Web3Transport::new(http), }; let instrumented = instrumented::InstrumentedTransport::new(name.to_string(), transport); - Web3::new(Web3Transport::new(instrumented)) + Web3 { + legacy: web3::Web3::new(Web3Transport::new(instrumented)), + alloy: alloy::provider(url.as_str()), + } } /// Convenience method to create a transport from a URL. -pub fn create_test_transport(url: &str) -> Web3Transport { +fn create_test_transport(url: &str) -> Web3Transport { let http_transport = HttpTransport::new( Client::builder() .timeout(Duration::from_secs(10)) @@ -95,8 +137,3 @@ pub fn create_test_transport(url: &str) -> Web3Transport { let instrumented = instrumented::InstrumentedTransport::new("test".into(), dyn_transport); Web3Transport::new(instrumented) } - -/// Like above but takes url from the environment NODE_URL. -pub fn create_env_test_transport() -> Web3Transport { - create_test_transport(&std::env::var("NODE_URL").unwrap()) -} diff --git a/crates/ethrpc/src/mock.rs b/crates/ethrpc/src/mock.rs index f5143d010e..514285e883 100644 --- a/crates/ethrpc/src/mock.rs +++ b/crates/ethrpc/src/mock.rs @@ -1,8 +1,9 @@ //! Mockable Web3 transport implementation. use { + crate::Web3, + alloy::providers::{Provider, ProviderBuilder, mock::Asserter}, ethcontract::{ - Web3, futures::future::{self, Ready}, jsonrpc::{Call, Id, MethodCall, Params}, web3::{self, BatchTransport, RequestId, Transport}, @@ -20,7 +21,15 @@ use { }; pub fn web3() -> Web3 { - Web3::new(MockTransport::new()) + Web3 { + legacy: web3::Web3::new(MockTransport::new()), + // this will not behave like the original mock transport but it's only used + // in one place so let's keep this for now and fix it when we switch to + // alloy in the 1 place that uses the mock provider. + alloy: ProviderBuilder::new() + .connect_mocked_client(Asserter::new()) + .erased(), + } } /// An intermediate trait used for `mockall` to automatically generate a mock diff --git a/crates/ethrpc/src/multicall.rs b/crates/ethrpc/src/multicall.rs index 74548db7cc..2b465dac8b 100644 --- a/crates/ethrpc/src/multicall.rs +++ b/crates/ethrpc/src/multicall.rs @@ -216,11 +216,7 @@ where #[cfg(test)] mod tests { - use { - super::*, - crate::{Web3, create_env_test_transport}, - std::fmt::Debug, - }; + use {super::*, crate::Web3, std::fmt::Debug}; macro_rules! data { ($x:literal) => {{ ::hex_literal::hex!($x).to_vec() }}; @@ -311,7 +307,7 @@ mod tests { #[ignore] #[tokio::test] async fn execute_multicall() { - let web3 = Web3::new(create_env_test_transport()); + let web3 = Web3::new_from_env(); let results = web3 .eth() .multicall( @@ -376,7 +372,7 @@ mod tests { #[ignore] #[tokio::test] async fn calls_are_unrelated() { - let web3 = Web3::new(create_env_test_transport()); + let web3 = Web3::new_from_env(); let results = web3 .eth() .multicall( diff --git a/crates/refunder/src/refund_service.rs b/crates/refunder/src/refund_service.rs index a73f7d479f..849f5f161e 100644 --- a/crates/refunder/src/refund_service.rs +++ b/crates/refunder/src/refund_service.rs @@ -55,7 +55,7 @@ impl RefundService { submitter: Submitter { web3: web3.clone(), account, - gas_estimator: Box::new(web3), + gas_estimator: Box::new(web3.legacy), gas_parameters_of_last_tx: None, nonce_of_last_submission: None, }, diff --git a/crates/shared/src/account_balances/simulation.rs b/crates/shared/src/account_balances/simulation.rs index f9fa4b6e08..583781ab35 100644 --- a/crates/shared/src/account_balances/simulation.rs +++ b/crates/shared/src/account_balances/simulation.rs @@ -161,16 +161,12 @@ impl BalanceFetching for Balances { #[cfg(test)] mod tests { - use { - super::*, - crate::ethrpc::{self, Web3}, - model::order::SellTokenSource, - }; + use {super::*, ethrpc::Web3, model::order::SellTokenSource}; #[ignore] #[tokio::test] async fn test_for_user() { - let web3 = Web3::new(ethrpc::create_env_test_transport()); + let web3 = Web3::new_from_env(); let settlement = contracts::GPv2Settlement::at(&web3, addr!("9008d19f58aabd9ed0d60971565aa8510560ab41")); let balances = contracts::support::Balances::at( diff --git a/crates/shared/src/bad_token/trace_call.rs b/crates/shared/src/bad_token/trace_call.rs index 82a4df6ad3..e71769dbb3 100644 --- a/crates/shared/src/bad_token/trace_call.rs +++ b/crates/shared/src/bad_token/trace_call.rs @@ -375,11 +375,11 @@ mod tests { solver_finder::AutoUpdatingSolverTokenOwnerFinder, }, }, - ethrpc::create_env_test_transport, sources::{BaselineSource, uniswap_v2}, }, chain::Chain, contracts::{BalancerV2Vault, IUniswapV3Factory}, + ethrpc::Web3, hex_literal::hex, std::{env, time::Duration}, web3::types::{ @@ -528,8 +528,7 @@ mod tests { async fn mainnet_tokens() { // observe::tracing::initialize("orderbook::bad_token=debug, // shared::transport=debug", tracing::level_filters::LevelFilter::OFF); - let http = create_env_test_transport(); - let web3 = Web3::new(http); + let web3 = Web3::new_from_env(); let version = web3.eth().chain_id().await.unwrap().to_string(); let base_tokens = &[ @@ -772,8 +771,7 @@ mod tests { #[ignore] async fn mainnet_univ3() { observe::tracing::initialize(&observe::Config::default().with_env_filter("shared=debug")); - let http = create_env_test_transport(); - let web3 = Web3::new(http); + let web3 = Web3::new_from_env(); let base_tokens = vec![testlib::tokens::WETH]; let settlement = contracts::GPv2Settlement::deployed(&web3).await.unwrap(); let factory = IUniswapV3Factory::deployed(&web3).await.unwrap(); @@ -900,8 +898,7 @@ mod tests { // Force the cache to update at least once. solver_token_finder.update().await.unwrap(); - let http = create_env_test_transport(); - let web3 = Web3::new(http); + let web3 = Web3::new_from_env(); let settlement = contracts::GPv2Settlement::deployed(&web3).await.unwrap(); let finder = Arc::new(TokenOwnerFinder { diff --git a/crates/shared/src/code_simulation.rs b/crates/shared/src/code_simulation.rs index 4e7538e9f2..b45fb87ecb 100644 --- a/crates/shared/src/code_simulation.rs +++ b/crates/shared/src/code_simulation.rs @@ -256,15 +256,16 @@ impl CodeSimulating for Web3ThenTenderly { mod tests { use { super::*, - crate::{ethrpc::create_env_test_transport, tenderly_api::TenderlyHttpApi}, + crate::tenderly_api::TenderlyHttpApi, ethcontract::H256, + ethrpc::Web3, hex_literal::hex, maplit::hashmap, std::time::Duration, }; async fn test_simulators() -> Vec> { - let web3 = Web3::new(create_env_test_transport()); + let web3 = Web3::new_from_env(); let network_id = web3.eth().chain_id().await.unwrap().to_string(); vec![ @@ -368,7 +369,7 @@ mod tests { #[tokio::test] #[ignore] async fn tenderly_state_override_conversion() { - let web3 = Web3::new(create_env_test_transport()); + let web3 = Web3::new_from_env(); let network_id = web3.eth().chain_id().await.unwrap().to_string(); let tenderly = TenderlyCodeSimulator::new(TenderlyHttpApi::test_from_env(), network_id) .save(true, true); diff --git a/crates/shared/src/ethrpc.rs b/crates/shared/src/ethrpc.rs index cdc58f7553..2bf9993ba2 100644 --- a/crates/shared/src/ethrpc.rs +++ b/crates/shared/src/ethrpc.rs @@ -1,10 +1,4 @@ -pub use ethrpc::{ - Web3, - Web3CallBatch, - Web3Transport, - create_env_test_transport, - create_test_transport, -}; +pub use ethrpc::{Web3, Web3CallBatch, Web3Transport}; use { crate::http_client::HttpClientFactory, reqwest::Url, diff --git a/crates/shared/src/event_handling.rs b/crates/shared/src/event_handling.rs index abb17282ca..0f5ad64a76 100644 --- a/crates/shared/src/event_handling.rs +++ b/crates/shared/src/event_handling.rs @@ -622,11 +622,7 @@ mod tests { super::*, contracts::{GPv2Settlement, gpv2_settlement}, ethcontract::{BlockNumber, H256}, - ethrpc::{ - Web3, - block_stream::block_number_to_block_number_hash, - create_env_test_transport, - }, + ethrpc::{Web3, block_stream::block_number_to_block_number_hash}, std::str::FromStr, }; @@ -781,8 +777,7 @@ mod tests { #[tokio::test] #[ignore] async fn past_events_by_block_hashes_test() { - let transport = create_env_test_transport(); - let web3 = Web3::new(transport); + let web3 = Web3::new_from_env(); let contract = GPv2Settlement::deployed(&web3).await.unwrap(); let storage = EventStorage { events: vec![] }; let blocks = vec![ @@ -828,8 +823,7 @@ mod tests { #[tokio::test] #[ignore] async fn update_events_test() { - let transport = create_env_test_transport(); - let web3 = Web3::new(transport); + let web3 = Web3::new_from_env(); let contract = GPv2Settlement::deployed(&web3).await.unwrap(); let storage = EventStorage { events: vec![] }; let current_block = web3.eth().block_number().await.unwrap(); @@ -860,8 +854,7 @@ mod tests { #[ignore] async fn multiple_new_blocks_but_no_reorg_test() { tracing_subscriber::fmt::init(); - let transport = create_env_test_transport(); - let web3 = Web3::new(transport); + let web3 = Web3::new_from_env(); let contract = GPv2Settlement::deployed(&web3).await.unwrap(); let storage = EventStorage { events: vec![] }; let current_block = web3.eth().block_number().await.unwrap(); @@ -893,8 +886,7 @@ mod tests { #[tokio::test] #[ignore] async fn optional_block_skipping() { - let transport = create_env_test_transport(); - let web3 = Web3::new(transport); + let web3 = Web3::new_from_env(); let contract = GPv2Settlement::deployed(&web3).await.unwrap(); let current_block = web3.eth().block_number().await.unwrap(); diff --git a/crates/shared/src/gas_price_estimation/mod.rs b/crates/shared/src/gas_price_estimation/mod.rs index 10dfec62f2..7e80ce29b3 100644 --- a/crates/shared/src/gas_price_estimation/mod.rs +++ b/crates/shared/src/gas_price_estimation/mod.rs @@ -54,7 +54,7 @@ pub async fn create_priority_estimator( url.clone(), ))); } - GasEstimatorType::Web3 => estimators.push(Box::new(web3.clone())), + GasEstimatorType::Web3 => estimators.push(Box::new(web3.legacy.clone())), GasEstimatorType::Native => { match NativeGasEstimator::new(web3.transport().clone(), None).await { Ok(estimator) => estimators.push(Box::new(estimator)), diff --git a/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs b/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs index 5430bc0338..f92cad6003 100644 --- a/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs +++ b/crates/shared/src/price_estimation/trade_verifier/balance_overrides/detector.rs @@ -175,7 +175,7 @@ pub enum DetectionError { #[cfg(test)] mod tests { - use {super::*, ethrpc::create_env_test_transport, web3::Web3}; + use {super::*, ethrpc::Web3}; /// Tests that we can detect storage slots by probing the first /// n slots or by checking hardcoded known slots. @@ -183,7 +183,7 @@ mod tests { #[ignore] #[tokio::test] async fn detects_storage_slots_mainnet() { - let detector = Detector::new(Arc::new(Web3::new(create_env_test_transport())), 60); + let detector = Detector::new(Arc::new(Web3::new_from_env()), 60); let storage = detector .detect(addr!("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")) @@ -215,7 +215,7 @@ mod tests { #[ignore] #[tokio::test] async fn detects_storage_slots_arbitrum() { - let detector = Detector::new(Arc::new(Web3::new(create_env_test_transport())), 60); + let detector = Detector::new(Arc::new(Web3::new_from_env()), 60); // all bridged tokens on arbitrum require a ton of probing let storage = detector diff --git a/crates/shared/src/sources/swapr.rs b/crates/shared/src/sources/swapr.rs index ac79cec907..1543cdea07 100644 --- a/crates/shared/src/sources/swapr.rs +++ b/crates/shared/src/sources/swapr.rs @@ -53,7 +53,7 @@ mod tests { use { super::*, crate::{ - ethrpc::{Web3, create_env_test_transport}, + ethrpc::Web3, recent_block_cache::Block, sources::{BaselineSource, uniswap_v2}, }, @@ -104,8 +104,7 @@ mod tests { #[tokio::test] #[ignore] async fn fetch_swapr_pool() { - let transport = create_env_test_transport(); - let web3 = Web3::new(transport); + let web3 = Web3::new_from_env(); let version = web3.eth().chain_id().await.unwrap().to_string(); let pool_fetcher = uniswap_v2::UniV2BaselineSourceParameters::from_baseline_source( BaselineSource::Swapr, diff --git a/crates/shared/src/sources/uniswap_v2/mod.rs b/crates/shared/src/sources/uniswap_v2/mod.rs index cc5162b794..b04b1a7b30 100644 --- a/crates/shared/src/sources/uniswap_v2/mod.rs +++ b/crates/shared/src/sources/uniswap_v2/mod.rs @@ -214,8 +214,7 @@ mod tests { #[tokio::test] #[ignore] async fn baseline_mainnet() { - let http = crate::ethrpc::create_env_test_transport(); - let web3 = Web3::new(http); + let web3 = ethrpc::Web3::new_from_env(); let version = web3.eth().chain_id().await.unwrap().to_string(); assert_eq!(version, "1", "test must be run with mainnet node"); let test = |source, token0, token1, expected| { @@ -248,8 +247,7 @@ mod tests { #[tokio::test] #[ignore] async fn baseline_sepolia() { - let http = crate::ethrpc::create_env_test_transport(); - let web3 = Web3::new(http); + let web3 = ethrpc::Web3::new_from_env(); let version = web3.eth().chain_id().await.unwrap().to_string(); assert_eq!(version, "11155111", "test must be run with mainnet node"); let test = |source, token0, token1, expected| { @@ -269,8 +267,7 @@ mod tests { #[tokio::test] #[ignore] async fn baseline_xdai() { - let http = crate::ethrpc::create_env_test_transport(); - let web3 = Web3::new(http); + let web3 = ethrpc::Web3::new_from_env(); let version = web3.eth().chain_id().await.unwrap().to_string(); assert_eq!(version, "100", "test must be run with xdai node"); let test = |source, token0, token1, expected| { diff --git a/crates/shared/src/sources/uniswap_v3/event_fetching.rs b/crates/shared/src/sources/uniswap_v3/event_fetching.rs index 13ffdfd04a..88c4b2158c 100644 --- a/crates/shared/src/sources/uniswap_v3/event_fetching.rs +++ b/crates/shared/src/sources/uniswap_v3/event_fetching.rs @@ -80,7 +80,7 @@ impl EventRetrieving for UniswapV3PoolEventFetcher { type Event = UniswapV3Event; fn get_events(&self) -> DynAllEventsBuilder { - let mut events = DynAllEventsBuilder::new(self.0.clone(), H160::default(), None); + let mut events = DynAllEventsBuilder::new(self.0.legacy.clone(), H160::default(), None); let events_signatures = vec![H256(SWAP_TOPIC), H256(BURN_TOPIC), H256(MINT_TOPIC)]; events.filter = events .filter diff --git a/crates/solver/src/interactions/allowances.rs b/crates/solver/src/interactions/allowances.rs index 7191d1b2cc..29e1056892 100644 --- a/crates/solver/src/interactions/allowances.rs +++ b/crates/solver/src/interactions/allowances.rs @@ -193,7 +193,7 @@ impl AllowanceManaging for AllowanceManager { } async fn fetch_allowances( - web3: ethcontract::Web3, + web3: Web3, erc20: Arc, owner: H160, spender_tokens: HashMap>, From db820f4a997636f6542bc76818adcc573c53a7d2 Mon Sep 17 00:00:00 2001 From: MartinquaXD Date: Wed, 27 Aug 2025 14:20:31 +0000 Subject: [PATCH 02/34] Implement conversion helpers --- crates/ethrpc/src/alloy/conversions.rs | 91 ++++++++++++++++++++++++++ crates/ethrpc/src/alloy/mod.rs | 1 + 2 files changed, 92 insertions(+) create mode 100644 crates/ethrpc/src/alloy/conversions.rs diff --git a/crates/ethrpc/src/alloy/conversions.rs b/crates/ethrpc/src/alloy/conversions.rs new file mode 100644 index 0000000000..496abc78a6 --- /dev/null +++ b/crates/ethrpc/src/alloy/conversions.rs @@ -0,0 +1,91 @@ +///////////////////////////////// +// Conversions to the alloy types +///////////////////////////////// + +pub trait ToAlloy { + /// The corresponding Alloy type. + type To; + + /// Converts the legacy type to the corresponding Alloy type. + fn to_alloy(self) -> Self::To; +} + +impl ToAlloy for primitive_types::U256 { + type To = alloy::primitives::U256; + + fn to_alloy(self) -> Self::To { + let mut buf = [0u8; 32]; + self.to_little_endian(&mut buf); + alloy::primitives::U256::from_le_bytes(buf) + } +} + +impl ToAlloy for primitive_types::U512 { + type To = alloy::primitives::U512; + + fn to_alloy(self) -> Self::To { + let mut buf = [0u8; 64]; + self.to_little_endian(&mut buf); + alloy::primitives::U512::from_le_bytes(buf) + } +} + +impl ToAlloy for primitive_types::H160 { + type To = alloy::primitives::Address; + + fn to_alloy(self) -> Self::To { + alloy::primitives::Address(self.0.into()) + } +} + +impl ToAlloy for primitive_types::H256 { + type To = alloy::primitives::aliases::B256; + + fn to_alloy(self) -> Self::To { + alloy::primitives::aliases::B256::new(self.0) + } +} + +////////////////////////////////// +// Conversions to the legacy types +////////////////////////////////// + +pub trait ToLegacy { + /// The corresponding legacy type. + type To; + + /// Converts the alloy type to the corresponding legacy type. + fn to_legacy(self) -> Self::To; +} + +impl ToLegacy for alloy::primitives::U256 { + type To = primitive_types::U256; + + fn to_legacy(self) -> Self::To { + primitive_types::U256(self.into_limbs()) + } +} + +impl ToLegacy for alloy::primitives::U512 { + type To = primitive_types::U512; + + fn to_legacy(self) -> Self::To { + primitive_types::U512(self.into_limbs()) + } +} + +impl ToLegacy for alloy::primitives::Address { + type To = primitive_types::H160; + + fn to_legacy(self) -> Self::To { + primitive_types::H160(self.into()) + } +} + +impl ToAlloy for alloy::primitives::aliases::B256 { + type To = primitive_types::H256; + + fn to_alloy(self) -> Self::To { + primitive_types::H256(self.into()) + } +} diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 6d50815323..af760aa3b0 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -1,4 +1,5 @@ mod buffering; +pub mod conversions; mod instrumentation; pub use instrumentation::ProviderLabelingExt; From 2f35ad5a20140d6ef4532c184964c324c218f739 Mon Sep 17 00:00:00 2001 From: MartinquaXD Date: Mon, 21 Jul 2025 07:58:10 +0000 Subject: [PATCH 03/34] Helpers to generate alloy bindings --- Cargo.lock | 46 ++++++++++++++++++++++ Cargo.toml | 1 + crates/contracts/Cargo.toml | 3 ++ crates/contracts/src/alloy.rs | 72 +++++++++++++++++++++++++++++++++++ crates/contracts/src/lib.rs | 1 + 5 files changed, 123 insertions(+) create mode 100644 crates/contracts/src/alloy.rs diff --git a/Cargo.lock b/Cargo.lock index 9b58cc7e73..a42aeaebd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,6 +95,7 @@ version = "1.0.17" source = "git+https://github.com/alloy-rs/alloy?rev=c15a4a3c04ce15bfa3796cc449f8407200b7599f#c15a4a3c04ce15bfa3796cc449f8407200b7599f" dependencies = [ "alloy-consensus", + "alloy-contract", "alloy-core", "alloy-eips", "alloy-json-rpc", @@ -153,14 +154,53 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-contract" +version = "1.0.17" +source = "git+https://github.com/alloy-rs/alloy?rev=c15a4a3c04ce15bfa3796cc449f8407200b7599f#c15a4a3c04ce15bfa3796cc449f8407200b7599f" +dependencies = [ + "alloy-consensus", + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives", + "alloy-provider", + "alloy-rpc-types-eth", + "alloy-sol-types", + "alloy-transport", + "futures", + "futures-util", + "serde_json", + "thiserror 2.0.12", +] + [[package]] name = "alloy-core" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad31216895d27d307369daa1393f5850b50bbbd372478a9fa951c095c210627e" dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-types", +] + +[[package]] +name = "alloy-dyn-abi" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b95b3deca680efc7e9cba781f1a1db352fa1ea50e6384a514944dcf4419e652" +dependencies = [ + "alloy-json-abi", "alloy-primitives", + "alloy-sol-type-parser", "alloy-sol-types", + "itoa", + "serde", + "serde_json", + "winnow 0.7.11", ] [[package]] @@ -466,6 +506,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34d99282e7c9ef14eb62727981a985a01869e586d1dec729d3bb33679094c100" dependencies = [ + "alloy-json-abi", "alloy-sol-macro-input", "const-hex", "heck 0.5.0", @@ -484,12 +525,14 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda029f955b78e493360ee1d7bd11e1ab9f2a220a5715449babc79d6d0a01105" dependencies = [ + "alloy-json-abi", "const-hex", "dunce", "heck 0.5.0", "macro-string", "proc-macro2", "quote", + "serde_json", "syn 2.0.104", "syn-solidity", ] @@ -2143,9 +2186,12 @@ dependencies = [ name = "contracts" version = "0.1.0" dependencies = [ + "alloy", "anyhow", "ethcontract", "ethcontract-generate", + "maplit", + "paste", "serde", "serde_json", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 3bcb2ef4b9..7c2335c461 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,6 +81,7 @@ opentelemetry = { version = "0.30", features = ["tracing"] } opentelemetry-otlp = "0.30" opentelemetry_sdk = "0.30" orderbook = { path = "crates/orderbook" } +paste = "1.0" pin-project-lite = "0.2.14" rate-limit = { path = "crates/rate-limit" } refunder = { path = "crates/refunder" } diff --git a/crates/contracts/Cargo.toml b/crates/contracts/Cargo.toml index bf0ad07ba1..facce3a849 100644 --- a/crates/contracts/Cargo.toml +++ b/crates/contracts/Cargo.toml @@ -22,6 +22,9 @@ bin = [ ] [dependencies] +alloy = { workspace = true, features = ["sol-types", "json", "contract"] } +paste = { workspace = true } +maplit = { workspace = true } ethcontract = { workspace = true } serde = { workspace = true } diff --git a/crates/contracts/src/alloy.rs b/crates/contracts/src/alloy.rs new file mode 100644 index 0000000000..266faadaff --- /dev/null +++ b/crates/contracts/src/alloy.rs @@ -0,0 +1,72 @@ +pub use alloy::providers::DynProvider as Provider; + +/// Extension trait to attach some useful functions to the contract instance. +pub trait InstanceExt: Sized { + /// Crates a contract instance at the expected address for the current + /// network. + fn deployed( + provider: &Provider, + ) -> impl std::future::Future> + Send; +} + +#[macro_export] +macro_rules! bindings { + ($contract:ident, $($deployment_info:expr)?) => { + paste::paste! { + // Generate the main bindings in a private module. That allows + // us to re-export all items in our own module while also adding + // some items ourselves. + #[allow(non_snake_case)] + mod [<$contract Private>] { + alloy::sol!( + #[allow(missing_docs)] + #[sol(rpc)] + $contract, + concat!("./artifacts/", stringify!($contract), ".json"), + ); + } + + #[allow(non_snake_case)] + pub mod $contract { + use alloy::providers::DynProvider; + + pub use super::[<$contract Private>]::*; + pub type Instance = $contract::[<$contract Instance>]; + + $( + use { + std::{sync::LazyLock, collections::HashMap}, + alloy::{ + providers::Provider, + primitives::{address, Address}, + }, + anyhow::{Context, Result}, + }; + + pub static DEPLOYMENT_INFO: LazyLock> = LazyLock::new(|| { + $deployment_info + }); + + impl $crate::alloy::InstanceExt for Instance { + fn deployed(provider: &DynProvider) -> impl Future> + Send { + async move { + let chain_id = provider + .get_chain_id() + .await + .context("could not fetch current chain id")?; + let address = DEPLOYMENT_INFO + .get(&chain_id) + .with_context(|| format!("no deployment info for chain {chain_id:?}"))?; + + Ok(Instance::new( + address.clone(), + provider.clone(), + )) + } + } + } + )* + } + } + }; +} diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index 57fae4fd11..2b1a4d1996 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -1,6 +1,7 @@ #![allow(clippy::let_unit_value)] pub use ethcontract; +pub mod alloy; pub mod errors; use { anyhow::{Result, anyhow, bail}, From 490af2d2d571fbcf3242098c865e64c451f5c85f Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 13:26:48 +0300 Subject: [PATCH 04/34] 0x bindings --- crates/contracts/build.rs | 35 ---- crates/contracts/src/lib.rs | 122 ++++++++++-- .../driver/src/boundary/liquidity/zeroex.rs | 3 +- .../competition/solution/interaction.rs | 13 +- crates/driver/src/domain/liquidity/zeroex.rs | 54 +++--- crates/driver/src/infra/solver/dto/auction.rs | 3 +- crates/e2e/tests/e2e/liquidity.rs | 140 +++++++------- crates/solver/src/interactions/zeroex.rs | 55 +++--- crates/solver/src/liquidity/zeroex.rs | 175 +++++++++--------- 9 files changed, 338 insertions(+), 262 deletions(-) diff --git a/crates/contracts/build.rs b/crates/contracts/build.rs index 4d0fcfd084..a70ffdaf36 100644 --- a/crates/contracts/build.rs +++ b/crates/contracts/build.rs @@ -1447,41 +1447,6 @@ fn main() { .add_network_str(LENS, "0xc3A5b857Ba82a2586A45a8B59ECc3AA50Bc3D0e3") // Not available on Gnosis Chain }); - generate_contract_with_config("IZeroEx", |builder| { - // - // - builder - .add_network_str(MAINNET, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") - .add_network_str(SEPOLIA, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") - .add_network_str(ARBITRUM_ONE, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") - .add_network_str(BASE, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") - .add_network_str(AVALANCHE, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") - .add_network_str(BNB, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") - .add_network_str(OPTIMISM, "0xdef1abe32c034e558cdd535791643c58a13acc10") - .add_network_str(POLYGON, "0xdef1c0ded9bec7f1a1670819833240f027b25eff") - // Not available on Lens - .add_method_alias( - "_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[],bool,\ - address))", - "_transform_erc_20", - ) - .add_method_alias( - "_fillRfqOrder((address,address,uint128,uint128,address,address,address,bytes32,\ - uint64,uint256),(uint8,uint8,bytes32,bytes32),uint128,address,bool,address)", - "_fill_rfq_order", - ) - .add_method_alias( - "_fillLimitOrder((address,address,uint128,uint128,uint128,address,address,address,\ - address,bytes32,uint64,uint256),(uint8,uint8,bytes32,bytes32),uint128,address,\ - address)", - "_fill_limit_order", - ) - .add_method_alias( - "_fillOtcOrder((address,address,uint128,uint128,address,address,address,uint256),\ - (uint8,uint8,bytes32,bytes32),uint128,address,bool,address)", - "_fill_otc_order", - ) - }); generate_contract_with_config("CowProtocolToken", |builder| { builder .add_network_str(MAINNET, "0xDEf1CA1fb7FBcDC777520aa7f396b4E015F497aB") diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index 2b1a4d1996..e7b828d1e8 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -11,6 +11,68 @@ use { }, }; +#[macro_export] +macro_rules! bindings { + ($contract:ident, $($deployment_info:expr)?) => { + paste::paste! { + // Generate the main bindings in a private module. That allows + // us to re-export all items in our own module while also adding + // some items ourselves. + #[allow(non_snake_case)] + mod [<$contract Private>] { + alloy::sol!( + #[allow(missing_docs, clippy::too_many_arguments)] + #[sol(rpc)] + $contract, + concat!("./artifacts/", stringify!($contract), ".json"), + ); + } + + #[allow(non_snake_case)] + pub mod $contract { + use alloy::providers::DynProvider; + + pub use super::[<$contract Private>]::*; + pub type Instance = $contract::[<$contract Instance>]; + + $( + use { + std::{sync::LazyLock, collections::HashMap}, + alloy::{ + providers::Provider, + primitives::{address, Address}, + }, + anyhow::{Context, Result}, + }; + + pub static DEPLOYMENT_INFO: LazyLock> = LazyLock::new(|| { + $deployment_info + }); + + impl $crate::alloy::InstanceExt for Instance { + fn deployed(provider: &DynProvider) -> impl Future> + Send { + async move { + let chain_id = provider + .get_chain_id() + .await + .context("could not fetch current chain id")?; + let address = DEPLOYMENT_INFO + .get(&chain_id) + .with_context(|| format!("no deployment info for chain {chain_id:?}"))?; + + Ok(Instance::new( + address.clone(), + provider.clone(), + )) + } + } + } + )* + } + } + }; +} + pub fn deployment(contract: &Contract, chain_id: u64) -> Result<&Network> { contract .networks @@ -98,7 +160,6 @@ include_contracts! { IUniswapLikePair; IUniswapLikeRouter; IUniswapV3Factory; - IZeroEx; PancakeRouter; Permit2; ChainalysisOracle; @@ -133,20 +194,51 @@ pub mod test { } } +const MAINNET: u64 = 1; +#[allow(dead_code)] +const GOERLI: u64 = 5; +#[allow(dead_code)] +const GNOSIS: u64 = 100; +const SEPOLIA: u64 = 11155111; +const ARBITRUM_ONE: u64 = 42161; +const BASE: u64 = 8453; +const POLYGON: u64 = 137; +const AVALANCHE: u64 = 43114; +const BNB: u64 = 56; +const OPTIMISM: u64 = 10; +#[allow(dead_code)] +const LENS: u64 = 232; + +pub mod alloy { + pub use alloy::providers::DynProvider as AlloyProvider; + + /// Extension trait to attach some useful functions to the contract instance. + pub trait InstanceExt: Sized { + /// Crates a contract instance at the expected address for the current + /// network. + fn deployed( + provider: &AlloyProvider, + ) -> impl std::future::Future> + Send; + } + + bindings!( + IZeroex, + maplit::hashmap! { + crate::MAINNET => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::SEPOLIA => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::ARBITRUM_ONE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::BASE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::AVALANCHE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::BNB => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::OPTIMISM => address!("0xdef1abe32c034e558cdd535791643c58a13acc10"), + crate::POLYGON => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + // Not available on Lens + } + ); +} + #[cfg(test)] mod tests { - const MAINNET: u64 = 1; - const GOERLI: u64 = 5; - const GNOSIS: u64 = 100; - const SEPOLIA: u64 = 11155111; - const ARBITRUM_ONE: u64 = 42161; - const BASE: u64 = 8453; - const POLYGON: u64 = 137; - const AVALANCHE: u64 = 43114; - const BNB: u64 = 56; - const OPTIMISM: u64 = 10; - const LENS: u64 = 232; - use { super::*, ethcontract::{ @@ -249,10 +341,6 @@ mod tests { assert_has_deployment_address!(BalancerV2WeightedPoolFactory for *network); } - for network in &[MAINNET, SEPOLIA, ARBITRUM_ONE] { - assert_has_deployment_address!(IZeroEx for *network); - } - for network in &[MAINNET, GOERLI, GNOSIS, ARBITRUM_ONE] { assert_has_deployment_address!(BalancerV2StablePoolFactoryV2 for *network); } diff --git a/crates/driver/src/boundary/liquidity/zeroex.rs b/crates/driver/src/boundary/liquidity/zeroex.rs index 3500fb1f3a..34367f3643 100644 --- a/crates/driver/src/boundary/liquidity/zeroex.rs +++ b/crates/driver/src/boundary/liquidity/zeroex.rs @@ -7,6 +7,7 @@ use { infra::{self, Ethereum}, }, anyhow::anyhow, + contracts::alloy::InstanceExt, ethrpc::block_stream::CurrentBlockWatcher, shared::{ http_client::HttpClientFactory, @@ -85,7 +86,7 @@ pub async fn collector( let eth = eth.with_metric_label("zeroex".into()); let settlement = eth.contracts().settlement().clone(); let web3 = eth.web3().clone(); - let contract = contracts::IZeroEx::deployed(&web3).await?; + let contract = contracts::alloy::IZeroex::Instance::deployed(&web3.alloy).await?; let http_client_factory = &HttpClientFactory::new(&shared::http_client::Arguments { http_timeout: config.http_timeout, }); diff --git a/crates/driver/src/domain/competition/solution/interaction.rs b/crates/driver/src/domain/competition/solution/interaction.rs index 92bde6226a..d1f90c51fd 100644 --- a/crates/driver/src/domain/competition/solution/interaction.rs +++ b/crates/driver/src/domain/competition/solution/interaction.rs @@ -1,6 +1,9 @@ -use crate::{ - domain::{self, eth, liquidity}, - util::Bytes, +use { + crate::{ + domain::{self, eth, liquidity}, + util::Bytes, + }, + ethrpc::alloy::conversions::ToLegacy, }; /// Interaction with a smart contract which is needed to execute this solution @@ -42,7 +45,7 @@ impl Interaction { liquidity::Kind::BalancerV2Stable(pool) => pool.vault.into(), liquidity::Kind::BalancerV2Weighted(pool) => pool.vault.into(), liquidity::Kind::Swapr(pool) => pool.base.router.into(), - liquidity::Kind::ZeroEx(pool) => pool.zeroex.address().into(), + liquidity::Kind::ZeroEx(pool) => pool.zeroex.address().to_legacy(), }; // As a gas optimization, we always approve the max amount possible. This // minimizes the number of approvals necessary, and therefore @@ -52,7 +55,7 @@ impl Interaction { vec![ eth::Allowance { token: interaction.input.token, - spender: address, + spender: address.into(), amount: eth::U256::max_value(), } .into(), diff --git a/crates/driver/src/domain/liquidity/zeroex.rs b/crates/driver/src/domain/liquidity/zeroex.rs index 3dd7e56f12..2df0e6effe 100644 --- a/crates/driver/src/domain/liquidity/zeroex.rs +++ b/crates/driver/src/domain/liquidity/zeroex.rs @@ -1,8 +1,8 @@ use { crate::domain::{eth, liquidity}, anyhow::anyhow, - contracts::IZeroEx, - ethcontract::Bytes, + contracts::alloy::IZeroex, + ethrpc::alloy::conversions::{ToAlloy, ToLegacy}, primitive_types::{H160, H256, U256}, std::sync::Arc, }; @@ -19,7 +19,7 @@ pub struct LimitOrder { /// Scaled amounts according to how much of the partially fillable amounts /// were already used in the order. pub fillable: Amounts, - pub zeroex: Arc, + pub zeroex: Arc, } #[derive(Clone, Debug)] @@ -48,27 +48,27 @@ pub struct ZeroExSignature { impl LimitOrder { pub fn to_interaction(&self, input: &liquidity::MaxInput) -> anyhow::Result { - let method = self.zeroex.fill_or_kill_limit_order( - ( - self.order.maker_token, - self.order.taker_token, - self.order.amounts.maker, - self.order.amounts.taker, - self.order.taker_token_fee_amount, - self.order.maker, - self.order.taker, - self.order.sender, - self.order.fee_recipient, - Bytes(self.order.pool.0), - self.order.expiry, - self.order.salt, - ), - ( - self.order.signature.signature_type, - self.order.signature.v, - Bytes(self.order.signature.r.0), - Bytes(self.order.signature.s.0), - ), + let method = self.zeroex.fillOrKillLimitOrder( + IZeroex::LibNativeOrder::LimitOrder { + makerToken: self.order.maker_token.to_alloy(), + takerToken: self.order.taker_token.to_alloy(), + makerAmount: self.order.amounts.maker, + takerAmount: self.order.amounts.taker, + takerTokenFeeAmount: self.order.taker_token_fee_amount, + maker: self.order.maker.to_alloy(), + taker: self.order.taker.to_alloy(), + sender: self.order.sender.to_alloy(), + feeRecipient: self.order.fee_recipient.to_alloy(), + pool: self.order.pool.to_alloy(), + expiry: self.order.expiry, + salt: self.order.salt.to_alloy(), + }, + IZeroex::LibSignature::Signature { + signatureType: self.order.signature.signature_type, + v: self.order.signature.v, + r: self.order.signature.r.to_alloy(), + s: self.order.signature.s.to_alloy(), + }, input .0 .amount @@ -76,12 +76,12 @@ impl LimitOrder { .try_into() .map_err(|_| anyhow!("executed amount does not fit into u128"))?, ); - let calldata = method.tx.data.ok_or(anyhow!("no calldata"))?; + let calldata = method.calldata(); Ok(eth::Interaction { - target: self.zeroex.address().into(), + target: self.zeroex.address().to_legacy().into(), value: 0.into(), - call_data: calldata.0.into(), + call_data: calldata.to_vec().into(), }) } } diff --git a/crates/driver/src/infra/solver/dto/auction.rs b/crates/driver/src/infra/solver/dto/auction.rs index cc19111bab..b1b8f30cc1 100644 --- a/crates/driver/src/infra/solver/dto/auction.rs +++ b/crates/driver/src/infra/solver/dto/auction.rs @@ -12,6 +12,7 @@ use { util::conv::{rational_to_big_decimal, u256::U256Ext}, }, app_data::AppDataHash, + ethrpc::alloy::conversions::ToLegacy, model::order::{BuyTokenDestination, SellTokenSource}, std::collections::HashMap, }; @@ -294,7 +295,7 @@ pub fn new( solvers_dto::auction::Liquidity::LimitOrder( solvers_dto::auction::ForeignLimitOrder { id: liquidity.id.0.to_string(), - address: limit_order.zeroex.address(), + address: limit_order.zeroex.address().to_legacy(), gas_estimate: liquidity.gas.into(), hash: Default::default(), maker_token: limit_order.order.maker_token, diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index f94123a968..b8a3fc48fb 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -1,6 +1,9 @@ use { chrono::{NaiveDateTime, Utc}, - contracts::{ERC20, IZeroEx, i_zero_ex::Contract}, + contracts::{ + ERC20, + alloy::{IZeroex, InstanceExt}, + }, driver::domain::eth::H160, e2e::{ api::zeroex::{Eip712TypedZeroExOrder, ZeroExApi}, @@ -19,15 +22,11 @@ use { }, tx, }, - ethcontract::{ - Account, - Bytes, - H256, - errors::MethodError, - prelude::U256, - transaction::TransactionResult, + ethcontract::{Account, H256, prelude::U256}, + ethrpc::{ + Web3, + alloy::conversions::{ToAlloy, ToLegacy}, }, - ethrpc::Web3, hex_literal::hex, model::{ order::{OrderCreation, OrderKind}, @@ -75,7 +74,7 @@ async fn zero_ex_liquidity(web3: Web3) { .unwrap(), ); - let zeroex = IZeroEx::deployed(&web3).await.unwrap(); + let zeroex = IZeroex::Instance::deployed(&web3.alloy).await.unwrap(); let amount = to_wei_with_exp(5, 8); @@ -100,11 +99,11 @@ async fn zero_ex_liquidity(web3: Web3) { tx!( zeroex_maker.account(), // With a lower amount 0x contract shows much lower fillable amount - token_usdt.approve(zeroex.address(), amount * 4) + token_usdt.approve(zeroex.address().to_legacy(), amount * 4) ); tx!( solver.account(), - token_usdc.approve(zeroex.address(), amount) + token_usdc.approve(zeroex.address().to_legacy(), amount) ); let order = OrderCreation { @@ -126,7 +125,7 @@ async fn zero_ex_liquidity(web3: Web3) { let zeroex_liquidity_orders = create_zeroex_liquidity_orders( order.clone(), zeroex_maker.clone(), - zeroex.address(), + zeroex.address().to_legacy(), chain_id, onchain.contracts().weth.address(), ); @@ -235,12 +234,12 @@ async fn zero_ex_liquidity(web3: Web3) { maker: zeroex_maker.address(), taker: Default::default(), sender: Default::default(), - fee_recipient: zeroex.address(), + fee_recipient: zeroex.address().to_legacy(), pool: H256::default(), expiry: NaiveDateTime::MAX.and_utc().timestamp() as u64, salt: U256::from(Utc::now().timestamp()), } - .to_order_record(chain_id, zeroex.address(), zeroex_maker); + .to_order_record(chain_id, zeroex.address().to_legacy(), zeroex_maker); fill_or_kill_zeroex_limit_order(&zeroex, &zeroex_order, solver.account().clone()) .await .unwrap(); @@ -325,67 +324,76 @@ struct ZeroExOrderAmounts { } async fn get_zeroex_order_amounts( - zeroex: &Contract, + zeroex: &IZeroex::Instance, zeroex_order: &shared::zeroex_api::OrderRecord, -) -> Result { - zeroex - .get_limit_order_relevant_state( - ( - zeroex_order.order().maker_token, - zeroex_order.order().taker_token, - zeroex_order.order().maker_amount, - zeroex_order.order().taker_amount, - zeroex_order.order().taker_token_fee_amount, - zeroex_order.order().maker, - zeroex_order.order().taker, - zeroex_order.order().sender, - zeroex_order.order().fee_recipient, - Bytes(zeroex_order.order().pool.0), - zeroex_order.order().expiry, - zeroex_order.order().salt, - ), - ( - zeroex_order.order().signature.signature_type, - zeroex_order.order().signature.v, - Bytes(zeroex_order.order().signature.r.0), - Bytes(zeroex_order.order().signature.s.0), - ), +) -> anyhow::Result { + Ok(zeroex + .getLimitOrderRelevantState( + IZeroex::LibNativeOrder::LimitOrder { + makerToken: zeroex_order.order().maker_token.to_alloy(), + takerToken: zeroex_order.order().taker_token.to_alloy(), + makerAmount: zeroex_order.order().maker_amount, + takerAmount: zeroex_order.order().taker_amount, + takerTokenFeeAmount: zeroex_order.order().taker_token_fee_amount, + maker: zeroex_order.order().maker.to_alloy(), + taker: zeroex_order.order().taker.to_alloy(), + sender: zeroex_order.order().sender.to_alloy(), + feeRecipient: zeroex_order.order().fee_recipient.to_alloy(), + pool: zeroex_order.order().pool.to_alloy(), + expiry: zeroex_order.order().expiry, + salt: zeroex_order.order().salt.to_alloy(), + }, + IZeroex::LibSignature::Signature { + signatureType: zeroex_order.order().signature.signature_type, + v: zeroex_order.order().signature.v, + r: zeroex_order.order().signature.r.to_alloy(), + s: zeroex_order.order().signature.s.to_alloy(), + }, ) .call() .await - .map(|((_, _, filled), fillable, _)| ZeroExOrderAmounts { filled, fillable }) + .map( + |res /* ((_, _, filled), fillable, _) */| ZeroExOrderAmounts { + filled: res.orderInfo.takerTokenFilledAmount, + fillable: res.actualFillableTakerTokenAmount, + }, + )?) } async fn fill_or_kill_zeroex_limit_order( - zeroex: &Contract, + zeroex: &IZeroex::Instance, zeroex_order: &shared::zeroex_api::OrderRecord, from_account: Account, -) -> Result { - zeroex - .fill_or_kill_limit_order( - ( - zeroex_order.order().maker_token, - zeroex_order.order().taker_token, - zeroex_order.order().maker_amount, - zeroex_order.order().taker_amount, - zeroex_order.order().taker_token_fee_amount, - zeroex_order.order().maker, - zeroex_order.order().taker, - zeroex_order.order().sender, - zeroex_order.order().fee_recipient, - Bytes(zeroex_order.order().pool.0), - zeroex_order.order().expiry, - zeroex_order.order().salt, - ), - ( - zeroex_order.order().signature.signature_type, - zeroex_order.order().signature.v, - Bytes(zeroex_order.order().signature.r.0), - Bytes(zeroex_order.order().signature.s.0), - ), +) -> anyhow::Result { + let tx_hash = zeroex + .fillOrKillLimitOrder( + IZeroex::LibNativeOrder::LimitOrder { + makerToken: zeroex_order.order().maker_token.to_alloy(), + takerToken: zeroex_order.order().taker_token.to_alloy(), + makerAmount: zeroex_order.order().maker_amount, + takerAmount: zeroex_order.order().taker_amount, + takerTokenFeeAmount: zeroex_order.order().taker_token_fee_amount, + maker: zeroex_order.order().maker.to_alloy(), + taker: zeroex_order.order().taker.to_alloy(), + sender: zeroex_order.order().sender.to_alloy(), + feeRecipient: zeroex_order.order().fee_recipient.to_alloy(), + pool: zeroex_order.order().pool.to_alloy(), + expiry: zeroex_order.order().expiry, + salt: zeroex_order.order().salt.to_alloy(), + }, + IZeroex::LibSignature::Signature { + signatureType: zeroex_order.order().signature.signature_type, + v: zeroex_order.order().signature.v, + r: zeroex_order.order().signature.r.to_alloy(), + s: zeroex_order.order().signature.s.to_alloy(), + }, zeroex_order.order().taker_amount, ) - .from(from_account) + .from(from_account.address().to_alloy()) .send() - .await + .await? + .tx_hash() + .to_alloy(); + + Ok(tx_hash) } diff --git a/crates/solver/src/interactions/zeroex.rs b/crates/solver/src/interactions/zeroex.rs index 37925542de..3daafa1bee 100644 --- a/crates/solver/src/interactions/zeroex.rs +++ b/crates/solver/src/interactions/zeroex.rs @@ -1,6 +1,7 @@ use { - contracts::IZeroEx, + contracts::alloy::IZeroex, ethcontract::Bytes, + ethrpc::alloy::conversions::{ToAlloy, ToLegacy}, shared::{ interaction::{EncodedInteraction, Interaction}, zeroex_api::Order, @@ -12,35 +13,39 @@ use { pub struct ZeroExInteraction { pub order: Order, pub taker_token_fill_amount: u128, - pub zeroex: Arc, + pub zeroex: Arc, } impl Interaction for ZeroExInteraction { fn encode(&self) -> EncodedInteraction { - let method = self.zeroex.fill_or_kill_limit_order( - ( - self.order.maker_token, - self.order.taker_token, - self.order.maker_amount, - self.order.taker_amount, - self.order.taker_token_fee_amount, - self.order.maker, - self.order.taker, - self.order.sender, - self.order.fee_recipient, - Bytes(self.order.pool.0), - self.order.expiry, - self.order.salt, - ), - ( - self.order.signature.signature_type, - self.order.signature.v, - Bytes(self.order.signature.r.0), - Bytes(self.order.signature.s.0), - ), + let method = self.zeroex.fillOrKillLimitOrder( + IZeroex::LibNativeOrder::LimitOrder { + makerToken: self.order.maker_token.to_alloy(), + takerToken: self.order.taker_token.to_alloy(), + makerAmount: self.order.maker_amount, + takerAmount: self.order.taker_amount, + takerTokenFeeAmount: self.order.taker_token_fee_amount, + maker: self.order.maker.to_alloy(), + taker: self.order.taker.to_alloy(), + sender: self.order.sender.to_alloy(), + feeRecipient: self.order.fee_recipient.to_alloy(), + pool: self.order.pool.to_alloy(), + expiry: self.order.expiry, + salt: self.order.salt.to_alloy(), + }, + IZeroex::LibSignature::Signature { + signatureType: self.order.signature.signature_type, + v: self.order.signature.v, + r: self.order.signature.r.to_alloy(), + s: self.order.signature.s.to_alloy(), + }, self.taker_token_fill_amount, ); - let calldata = method.tx.data.expect("no calldata").0; - (self.zeroex.address(), 0.into(), Bytes(calldata)) + let calldata = method.calldata(); + ( + self.zeroex.address().to_legacy(), + 0.into(), + Bytes(calldata.to_vec()), + ) } } diff --git a/crates/solver/src/liquidity/zeroex.rs b/crates/solver/src/liquidity/zeroex.rs index 58d41afa3f..fee95c6a20 100644 --- a/crates/solver/src/liquidity/zeroex.rs +++ b/crates/solver/src/liquidity/zeroex.rs @@ -11,8 +11,11 @@ use { }, anyhow::Result, arc_swap::ArcSwap, - contracts::{GPv2Settlement, IZeroEx}, - ethrpc::block_stream::{CurrentBlockWatcher, into_stream}, + contracts::{GPv2Settlement, alloy::IZeroex}, + ethrpc::{ + alloy::conversions::ToLegacy, + block_stream::{CurrentBlockWatcher, into_stream}, + }, futures::StreamExt, itertools::Itertools, model::{TokenPair, order::OrderKind}, @@ -34,7 +37,7 @@ type OrderBuckets = HashMap<(H160, H160), Vec>; type OrderbookCache = ArcSwap; pub struct ZeroExLiquidity { - pub zeroex: Arc, + pub zeroex: Arc, pub allowance_manager: Box, pub orderbook_cache: Arc, } @@ -43,7 +46,7 @@ impl ZeroExLiquidity { pub async fn new( web3: Web3, api: Arc, - zeroex: IZeroEx, + zeroex: IZeroex::Instance, gpv2: GPv2Settlement, blocks_stream: CurrentBlockWatcher, ) -> Self { @@ -144,7 +147,7 @@ impl LiquidityCollecting for ZeroExLiquidity { let allowances = Arc::new( self.allowance_manager - .get_allowances(tokens, self.zeroex.address()) + .get_allowances(tokens, self.zeroex.address().to_legacy()) .await?, ); @@ -211,7 +214,7 @@ fn get_useful_orders( #[derive(Clone)] pub struct OrderSettlementHandler { pub order_record: OrderRecord, - pub zeroex: Arc, + pub zeroex: Arc, allowances: Arc, } @@ -248,12 +251,12 @@ impl SettlementHandling for OrderSettlementHandler { pub mod tests { use { super::*, - crate::interactions::allowances::Approval, - maplit::hashmap, + // crate::interactions::allowances::Approval, + // maplit::hashmap, shared::{ baseline_solver::BaseTokens, - http_solver::model::InternalizationStrategy, - interaction::Interaction, + // http_solver::model::InternalizationStrategy, + // interaction::Interaction, zeroex_api::{self, OrderMetadata}, }, }; @@ -386,80 +389,82 @@ pub mod tests { assert_eq!(filtered_zeroex_orders[1].order().taker_amount, 10_000_000); } - #[tokio::test] - async fn interaction_encodes_approval_when_insufficient() { - let sell_token = H160::from_low_u64_be(1); - let zeroex = Arc::new(contracts::dummy_contract!(IZeroEx, H160::default())); - let allowances = Allowances::new(zeroex.address(), hashmap! { sell_token => 99.into() }); - let order_record = OrderRecord::new( - zeroex_api::Order { - taker_amount: 100, - taker_token: sell_token, - ..Default::default() - }, - OrderMetadata::default(), - ); - let handler = OrderSettlementHandler { - order_record: order_record.clone(), - zeroex: zeroex.clone(), - allowances: Arc::new(allowances), - }; - let mut encoder = SettlementEncoder::default(); - let execution = LimitOrderExecution::new(100.into(), 0.into()); - handler.encode(execution, &mut encoder).unwrap(); - let [_, interactions, _] = encoder - .finish(InternalizationStrategy::SkipInternalizableInteraction) - .interactions; - assert_eq!( - interactions, - [ - Approval { - token: sell_token, - spender: zeroex.address(), - } - .encode(), - ZeroExInteraction { - order: order_record.order().clone(), - taker_token_fill_amount: 100, - zeroex: zeroex.clone(), - } - .encode(), - ], - ); - } + // #[tokio::test] + // async fn interaction_encodes_approval_when_insufficient() { + // let sell_token = H160::from_low_u64_be(1); + // let zeroex = Arc::new(contracts::dummy_contract!(IZeroex::Instance, + // H160::default())); let allowances = + // Allowances::new(zeroex.address(), hashmap! { sell_token => 99.into() }); + // let order_record = OrderRecord::new( + // zeroex_api::Order { + // taker_amount: 100, + // taker_token: sell_token, + // ..Default::default() + // }, + // OrderMetadata::default(), + // ); + // let handler = OrderSettlementHandler { + // order_record: order_record.clone(), + // zeroex: zeroex.clone(), + // allowances: Arc::new(allowances), + // }; + // let mut encoder = SettlementEncoder::default(); + // let execution = LimitOrderExecution::new(100.into(), 0.into()); + // handler.encode(execution, &mut encoder).unwrap(); + // let [_, interactions, _] = encoder + // .finish(InternalizationStrategy::SkipInternalizableInteraction) + // .interactions; + // assert_eq!( + // interactions, + // [ + // Approval { + // token: sell_token, + // spender: zeroex.address(), + // } + // .encode(), + // ZeroExInteraction { + // order: order_record.order().clone(), + // taker_token_fill_amount: 100, + // zeroex: zeroex.clone(), + // } + // .encode(), + // ], + // ); + // } - #[tokio::test] - async fn interaction_encodes_no_approval_when_sufficient() { - let sell_token = H160::from_low_u64_be(1); - let zeroex = Arc::new(contracts::dummy_contract!(IZeroEx, H160::default())); - let allowances = Allowances::new(zeroex.address(), hashmap! { sell_token => 100.into() }); - let order_record = OrderRecord::new( - zeroex_api::Order { - taker_amount: 100, - taker_token: sell_token, - ..Default::default() - }, - OrderMetadata::default(), - ); - let handler = OrderSettlementHandler { - order_record: order_record.clone(), - zeroex: zeroex.clone(), - allowances: Arc::new(allowances), - }; - let mut encoder = SettlementEncoder::default(); - let execution = LimitOrderExecution::new(100.into(), 0.into()); - handler.encode(execution, &mut encoder).unwrap(); - let [_, interactions, _] = encoder - .finish(InternalizationStrategy::SkipInternalizableInteraction) - .interactions; - assert_eq!( - interactions, - [ZeroExInteraction { - order: order_record.order().clone(), - taker_token_fill_amount: 100, - zeroex: zeroex.clone(), - } - .encode()], - ); - } + // #[tokio::test] + // async fn interaction_encodes_no_approval_when_sufficient() { + // let sell_token = H160::from_low_u64_be(1); + // let zeroex = Arc::new(contracts::dummy_contract!(IZeroEx, + // H160::default())); let allowances = + // Allowances::new(zeroex.address(), hashmap! { sell_token => 100.into() }); + // let order_record = OrderRecord::new( + // zeroex_api::Order { + // taker_amount: 100, + // taker_token: sell_token, + // ..Default::default() + // }, + // OrderMetadata::default(), + // ); + // let handler = OrderSettlementHandler { + // order_record: order_record.clone(), + // zeroex: zeroex.clone(), + // allowances: Arc::new(allowances), + // }; + // let mut encoder = SettlementEncoder::default(); + // let execution = LimitOrderExecution::new(100.into(), 0.into()); + // handler.encode(execution, &mut encoder).unwrap(); + // let [_, interactions, _] = encoder + // .finish(InternalizationStrategy::SkipInternalizableInteraction) + // .interactions; + // assert_eq!( + // interactions, + // [ZeroExInteraction { + // order: order_record.order().clone(), + // taker_token_fill_amount: 100, + // zeroex: zeroex.clone(), + // } + // .encode()], + // ); + // } } From 2729c5a6294fec0405e8c16dbd4bc6963db0528f Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 13:37:39 +0300 Subject: [PATCH 05/34] Uncomment test --- crates/solver/src/liquidity/zeroex.rs | 173 ++++++++++++++------------ 1 file changed, 92 insertions(+), 81 deletions(-) diff --git a/crates/solver/src/liquidity/zeroex.rs b/crates/solver/src/liquidity/zeroex.rs index fee95c6a20..baf774434e 100644 --- a/crates/solver/src/liquidity/zeroex.rs +++ b/crates/solver/src/liquidity/zeroex.rs @@ -251,12 +251,13 @@ impl SettlementHandling for OrderSettlementHandler { pub mod tests { use { super::*, - // crate::interactions::allowances::Approval, - // maplit::hashmap, + crate::interactions::allowances::Approval, + ethrpc::{alloy, alloy::conversions::ToAlloy}, + maplit::hashmap, shared::{ baseline_solver::BaseTokens, - // http_solver::model::InternalizationStrategy, - // interaction::Interaction, + http_solver::model::InternalizationStrategy, + interaction::Interaction, zeroex_api::{self, OrderMetadata}, }, }; @@ -389,82 +390,92 @@ pub mod tests { assert_eq!(filtered_zeroex_orders[1].order().taker_amount, 10_000_000); } - // #[tokio::test] - // async fn interaction_encodes_approval_when_insufficient() { - // let sell_token = H160::from_low_u64_be(1); - // let zeroex = Arc::new(contracts::dummy_contract!(IZeroex::Instance, - // H160::default())); let allowances = - // Allowances::new(zeroex.address(), hashmap! { sell_token => 99.into() }); - // let order_record = OrderRecord::new( - // zeroex_api::Order { - // taker_amount: 100, - // taker_token: sell_token, - // ..Default::default() - // }, - // OrderMetadata::default(), - // ); - // let handler = OrderSettlementHandler { - // order_record: order_record.clone(), - // zeroex: zeroex.clone(), - // allowances: Arc::new(allowances), - // }; - // let mut encoder = SettlementEncoder::default(); - // let execution = LimitOrderExecution::new(100.into(), 0.into()); - // handler.encode(execution, &mut encoder).unwrap(); - // let [_, interactions, _] = encoder - // .finish(InternalizationStrategy::SkipInternalizableInteraction) - // .interactions; - // assert_eq!( - // interactions, - // [ - // Approval { - // token: sell_token, - // spender: zeroex.address(), - // } - // .encode(), - // ZeroExInteraction { - // order: order_record.order().clone(), - // taker_token_fill_amount: 100, - // zeroex: zeroex.clone(), - // } - // .encode(), - // ], - // ); - // } + #[tokio::test] + async fn interaction_encodes_approval_when_insufficient() { + let sell_token = H160::from_low_u64_be(1); + let zeroex = Arc::new(IZeroex::Instance::new( + H160::default().to_alloy(), + alloy::provider("http:://localhost:8545"), + )); + let allowances = Allowances::new( + zeroex.address().to_legacy(), + hashmap! { sell_token => 99.into() }, + ); + let order_record = OrderRecord::new( + zeroex_api::Order { + taker_amount: 100, + taker_token: sell_token, + ..Default::default() + }, + OrderMetadata::default(), + ); + let handler = OrderSettlementHandler { + order_record: order_record.clone(), + zeroex: zeroex.clone(), + allowances: Arc::new(allowances), + }; + let mut encoder = SettlementEncoder::default(); + let execution = LimitOrderExecution::new(100.into(), 0.into()); + handler.encode(execution, &mut encoder).unwrap(); + let [_, interactions, _] = encoder + .finish(InternalizationStrategy::SkipInternalizableInteraction) + .interactions; + assert_eq!( + interactions, + [ + Approval { + token: sell_token, + spender: zeroex.address().to_legacy(), + } + .encode(), + ZeroExInteraction { + order: order_record.order().clone(), + taker_token_fill_amount: 100, + zeroex: zeroex.clone(), + } + .encode(), + ], + ); + } - // #[tokio::test] - // async fn interaction_encodes_no_approval_when_sufficient() { - // let sell_token = H160::from_low_u64_be(1); - // let zeroex = Arc::new(contracts::dummy_contract!(IZeroEx, - // H160::default())); let allowances = - // Allowances::new(zeroex.address(), hashmap! { sell_token => 100.into() }); - // let order_record = OrderRecord::new( - // zeroex_api::Order { - // taker_amount: 100, - // taker_token: sell_token, - // ..Default::default() - // }, - // OrderMetadata::default(), - // ); - // let handler = OrderSettlementHandler { - // order_record: order_record.clone(), - // zeroex: zeroex.clone(), - // allowances: Arc::new(allowances), - // }; - // let mut encoder = SettlementEncoder::default(); - // let execution = LimitOrderExecution::new(100.into(), 0.into()); - // handler.encode(execution, &mut encoder).unwrap(); - // let [_, interactions, _] = encoder - // .finish(InternalizationStrategy::SkipInternalizableInteraction) - // .interactions; - // assert_eq!( - // interactions, - // [ZeroExInteraction { - // order: order_record.order().clone(), - // taker_token_fill_amount: 100, - // zeroex: zeroex.clone(), - // } - // .encode()], - // ); - // } + #[tokio::test] + async fn interaction_encodes_no_approval_when_sufficient() { + let sell_token = H160::from_low_u64_be(1); + let zeroex = Arc::new(IZeroex::Instance::new( + H160::default().to_alloy(), + alloy::provider("http:://localhost:8545"), + )); + let allowances = Allowances::new( + zeroex.address().to_legacy(), + hashmap! { sell_token => 100.into() }, + ); + let order_record = OrderRecord::new( + zeroex_api::Order { + taker_amount: 100, + taker_token: sell_token, + ..Default::default() + }, + OrderMetadata::default(), + ); + let handler = OrderSettlementHandler { + order_record: order_record.clone(), + zeroex: zeroex.clone(), + allowances: Arc::new(allowances), + }; + let mut encoder = SettlementEncoder::default(); + let execution = LimitOrderExecution::new(100.into(), 0.into()); + handler.encode(execution, &mut encoder).unwrap(); + let [_, interactions, _] = encoder + .finish(InternalizationStrategy::SkipInternalizableInteraction) + .interactions; + assert_eq!( + interactions, + [ZeroExInteraction { + order: order_record.order().clone(), + taker_token_fill_amount: 100, + zeroex: zeroex.clone(), + } + .encode()], + ); + } } From 008369192946f30917bfd0e567186b4f50a90715 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 13:39:38 +0300 Subject: [PATCH 06/34] Fix --- crates/contracts/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index e7b828d1e8..fbfa87cef4 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -24,7 +24,7 @@ macro_rules! bindings { #[allow(missing_docs, clippy::too_many_arguments)] #[sol(rpc)] $contract, - concat!("./artifacts/", stringify!($contract), ".json"), + concat!("artifacts/", stringify!($contract), ".json"), ); } From 9099e98ed18404f79fc2328e4360ad1f88da579a Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 13:48:45 +0300 Subject: [PATCH 07/34] Naming --- crates/contracts/artifacts/{IZeroEx.json => IZeroex.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename crates/contracts/artifacts/{IZeroEx.json => IZeroex.json} (100%) diff --git a/crates/contracts/artifacts/IZeroEx.json b/crates/contracts/artifacts/IZeroex.json similarity index 100% rename from crates/contracts/artifacts/IZeroEx.json rename to crates/contracts/artifacts/IZeroex.json From 99f516a11fe7136e4e0cc3face7ad870f062852e Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 13:49:31 +0300 Subject: [PATCH 08/34] Revert "Fix" This reverts commit e99ee638c7a8f846fa4621c377eff1e057f01437. --- crates/contracts/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index fbfa87cef4..e7b828d1e8 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -24,7 +24,7 @@ macro_rules! bindings { #[allow(missing_docs, clippy::too_many_arguments)] #[sol(rpc)] $contract, - concat!("artifacts/", stringify!($contract), ".json"), + concat!("./artifacts/", stringify!($contract), ".json"), ); } From ed083439aaa6172e931b7cf72787b98a3fc8db5a Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 14:37:36 +0300 Subject: [PATCH 09/34] Dummy provider --- crates/ethrpc/src/alloy/mod.rs | 9 ++++++++- crates/solver/src/liquidity/zeroex.rs | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index af760aa3b0..a918bbcdc7 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -6,7 +6,7 @@ pub use instrumentation::ProviderLabelingExt; use { crate::AlloyProvider, alloy::{ - providers::{Provider, ProviderBuilder}, + providers::{Provider, ProviderBuilder, mock}, rpc::client::ClientBuilder, }, buffering::BatchCallLayer, @@ -23,3 +23,10 @@ pub fn provider(url: &str) -> AlloyProvider { .http(url.parse().unwrap()); ProviderBuilder::new().connect_client(rpc).erased() } + +pub fn dummy_provider() -> AlloyProvider { + let asserter = mock::Asserter::new(); + ProviderBuilder::new() + .connect_mocked_client(asserter) + .erased() +} diff --git a/crates/solver/src/liquidity/zeroex.rs b/crates/solver/src/liquidity/zeroex.rs index baf774434e..47d663024a 100644 --- a/crates/solver/src/liquidity/zeroex.rs +++ b/crates/solver/src/liquidity/zeroex.rs @@ -395,7 +395,7 @@ pub mod tests { let sell_token = H160::from_low_u64_be(1); let zeroex = Arc::new(IZeroex::Instance::new( H160::default().to_alloy(), - alloy::provider("http:://localhost:8545"), + alloy::dummy_provider(), )); let allowances = Allowances::new( zeroex.address().to_legacy(), @@ -443,7 +443,7 @@ pub mod tests { let sell_token = H160::from_low_u64_be(1); let zeroex = Arc::new(IZeroex::Instance::new( H160::default().to_alloy(), - alloy::provider("http:://localhost:8545"), + alloy::dummy_provider(), )); let allowances = Allowances::new( zeroex.address().to_legacy(), From 83c3a089ee5d14d12d9405483c2153af4838b027 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 16:57:26 +0300 Subject: [PATCH 10/34] Fix --- Cargo.lock | 18 ++++++++++++++++ crates/e2e/Cargo.toml | 1 + crates/e2e/tests/e2e/liquidity.rs | 36 ++++++++++++++++++++----------- crates/ethrpc/Cargo.toml | 2 +- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a42aeaebd8..ed63e6bc03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,6 +102,8 @@ dependencies = [ "alloy-network", "alloy-provider", "alloy-rpc-client", + "alloy-signer", + "alloy-signer-local", "alloy-transport", "alloy-transport-http", ] @@ -486,6 +488,21 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "alloy-signer-local" +version = "1.0.17" +source = "git+https://github.com/alloy-rs/alloy?rev=c15a4a3c04ce15bfa3796cc449f8407200b7599f#c15a4a3c04ce15bfa3796cc449f8407200b7599f" +dependencies = [ + "alloy-consensus", + "alloy-network", + "alloy-primitives", + "alloy-signer", + "async-trait", + "k256", + "rand 0.8.5", + "thiserror 2.0.12", +] + [[package]] name = "alloy-sol-macro" version = "1.2.1" @@ -2703,6 +2720,7 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" name = "e2e" version = "1.0.0" dependencies = [ + "alloy", "anyhow", "app-data", "autopilot", diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index 6772a8395a..51751dfbc2 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" license = "MIT OR Apache-2.0" [dependencies] +alloy = { workspace = true, default-features = false, features = ["json-rpc", "providers", "rpc-client", "transports", "reqwest", "signers", "signer-local"] } app-data = { workspace = true } anyhow = { workspace = true } autopilot = { workspace = true } diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index b8a3fc48fb..69dd1ebed0 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -1,4 +1,9 @@ use { + ::alloy::{ + eips::Encodable2718, + network::{EthereumWallet, TransactionBuilder}, + providers::Provider, + }, chrono::{NaiveDateTime, Utc}, contracts::{ ERC20, @@ -352,12 +357,10 @@ async fn get_zeroex_order_amounts( ) .call() .await - .map( - |res /* ((_, _, filled), fillable, _) */| ZeroExOrderAmounts { - filled: res.orderInfo.takerTokenFilledAmount, - fillable: res.actualFillableTakerTokenAmount, - }, - )?) + .map(|response| ZeroExOrderAmounts { + filled: response.orderInfo.takerTokenFilledAmount, + fillable: response.actualFillableTakerTokenAmount, + })?) } async fn fill_or_kill_zeroex_limit_order( @@ -365,7 +368,14 @@ async fn fill_or_kill_zeroex_limit_order( zeroex_order: &shared::zeroex_api::OrderRecord, from_account: Account, ) -> anyhow::Result { - let tx_hash = zeroex + let signer = match from_account { + Account::Offline(pk, _) => { + ::alloy::signers::local::PrivateKeySigner::from_slice(&pk.secret_bytes())? + } + _ => unimplemented!(), + }; + let wallet = EthereumWallet::from(signer); + let request = zeroex .fillOrKillLimitOrder( IZeroex::LibNativeOrder::LimitOrder { makerToken: zeroex_order.order().maker_token.to_alloy(), @@ -389,11 +399,13 @@ async fn fill_or_kill_zeroex_limit_order( }, zeroex_order.order().taker_amount, ) - .from(from_account.address().to_alloy()) - .send() + .into_transaction_request(); + let tx_envelope = request.build(&wallet).await?; + + Ok(zeroex + .provider() + .send_raw_transaction(&tx_envelope.encoded_2718()) .await? .tx_hash() - .to_alloy(); - - Ok(tx_hash) + .to_alloy()) } diff --git a/crates/ethrpc/Cargo.toml b/crates/ethrpc/Cargo.toml index 6654e3ad78..97a1840cfc 100644 --- a/crates/ethrpc/Cargo.toml +++ b/crates/ethrpc/Cargo.toml @@ -11,7 +11,7 @@ path = "src/lib.rs" doctest = false [dependencies] -alloy = { workspace = true, default-features = false, features = ["json-rpc", "providers", "rpc-client", "transports", "reqwest"] } +alloy = { workspace = true, default-features = false, features = ["json-rpc", "providers", "rpc-client", "transports", "reqwest", "signers", "signer-local"] } anyhow = { workspace = true } async-trait = { workspace = true } futures = { workspace = true } From 9dab16177ed9472f6877121ae059d9c3b527247d Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 18:40:07 +0300 Subject: [PATCH 11/34] Fix after merge --- crates/contracts/src/alloy.rs | 30 +++++++++++- crates/contracts/src/lib.rs | 90 ----------------------------------- 2 files changed, 29 insertions(+), 91 deletions(-) diff --git a/crates/contracts/src/alloy.rs b/crates/contracts/src/alloy.rs index 266faadaff..82c0d6a49b 100644 --- a/crates/contracts/src/alloy.rs +++ b/crates/contracts/src/alloy.rs @@ -1,3 +1,31 @@ +pub mod networks { + pub const MAINNET: u64 = 1; + pub const GNOSIS: u64 = 100; + pub const SEPOLIA: u64 = 11155111; + pub const ARBITRUM_ONE: u64 = 42161; + pub const BASE: u64 = 8453; + pub const POLYGON: u64 = 137; + pub const AVALANCHE: u64 = 43114; + pub const BNB: u64 = 56; + pub const OPTIMISM: u64 = 10; + pub const LENS: u64 = 232; +} + +crate::bindings!( + IZeroex, + maplit::hashmap! { + crate::MAINNET => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::SEPOLIA => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::ARBITRUM_ONE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::BASE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::AVALANCHE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::BNB => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::OPTIMISM => address!("0xdef1abe32c034e558cdd535791643c58a13acc10"), + crate::POLYGON => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + // Not available on Lens + } +); + pub use alloy::providers::DynProvider as Provider; /// Extension trait to attach some useful functions to the contract instance. @@ -19,7 +47,7 @@ macro_rules! bindings { #[allow(non_snake_case)] mod [<$contract Private>] { alloy::sol!( - #[allow(missing_docs)] + #[allow(missing_docs, clippy::too_many_arguments)] #[sol(rpc)] $contract, concat!("./artifacts/", stringify!($contract), ".json"), diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index e7b828d1e8..646f7cfa57 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -11,68 +11,6 @@ use { }, }; -#[macro_export] -macro_rules! bindings { - ($contract:ident, $($deployment_info:expr)?) => { - paste::paste! { - // Generate the main bindings in a private module. That allows - // us to re-export all items in our own module while also adding - // some items ourselves. - #[allow(non_snake_case)] - mod [<$contract Private>] { - alloy::sol!( - #[allow(missing_docs, clippy::too_many_arguments)] - #[sol(rpc)] - $contract, - concat!("./artifacts/", stringify!($contract), ".json"), - ); - } - - #[allow(non_snake_case)] - pub mod $contract { - use alloy::providers::DynProvider; - - pub use super::[<$contract Private>]::*; - pub type Instance = $contract::[<$contract Instance>]; - - $( - use { - std::{sync::LazyLock, collections::HashMap}, - alloy::{ - providers::Provider, - primitives::{address, Address}, - }, - anyhow::{Context, Result}, - }; - - pub static DEPLOYMENT_INFO: LazyLock> = LazyLock::new(|| { - $deployment_info - }); - - impl $crate::alloy::InstanceExt for Instance { - fn deployed(provider: &DynProvider) -> impl Future> + Send { - async move { - let chain_id = provider - .get_chain_id() - .await - .context("could not fetch current chain id")?; - let address = DEPLOYMENT_INFO - .get(&chain_id) - .with_context(|| format!("no deployment info for chain {chain_id:?}"))?; - - Ok(Instance::new( - address.clone(), - provider.clone(), - )) - } - } - } - )* - } - } - }; -} - pub fn deployment(contract: &Contract, chain_id: u64) -> Result<&Network> { contract .networks @@ -209,34 +147,6 @@ const OPTIMISM: u64 = 10; #[allow(dead_code)] const LENS: u64 = 232; -pub mod alloy { - pub use alloy::providers::DynProvider as AlloyProvider; - - /// Extension trait to attach some useful functions to the contract instance. - pub trait InstanceExt: Sized { - /// Crates a contract instance at the expected address for the current - /// network. - fn deployed( - provider: &AlloyProvider, - ) -> impl std::future::Future> + Send; - } - - bindings!( - IZeroex, - maplit::hashmap! { - crate::MAINNET => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::SEPOLIA => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::ARBITRUM_ONE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::BASE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::AVALANCHE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::BNB => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::OPTIMISM => address!("0xdef1abe32c034e558cdd535791643c58a13acc10"), - crate::POLYGON => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - // Not available on Lens - } - ); -} - #[cfg(test)] mod tests { use { From f0234052cf1ec718566814538001699b28305996 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 27 Aug 2025 19:14:09 +0300 Subject: [PATCH 12/34] Fix --- crates/e2e/tests/e2e/liquidity.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 69dd1ebed0..10bb27ffc9 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -368,14 +368,14 @@ async fn fill_or_kill_zeroex_limit_order( zeroex_order: &shared::zeroex_api::OrderRecord, from_account: Account, ) -> anyhow::Result { - let signer = match from_account { + let signer = match &from_account { Account::Offline(pk, _) => { - ::alloy::signers::local::PrivateKeySigner::from_slice(&pk.secret_bytes())? + alloy::signers::local::PrivateKeySigner::from_slice(&pk.secret_bytes())? } _ => unimplemented!(), }; let wallet = EthereumWallet::from(signer); - let request = zeroex + let tx = zeroex .fillOrKillLimitOrder( IZeroex::LibNativeOrder::LimitOrder { makerToken: zeroex_order.order().maker_token.to_alloy(), @@ -399,12 +399,22 @@ async fn fill_or_kill_zeroex_limit_order( }, zeroex_order.order().taker_amount, ) - .into_transaction_request(); - let tx_envelope = request.build(&wallet).await?; + .into_transaction_request() + .nonce( + zeroex + .provider() + .get_transaction_count(from_account.address().to_alloy()) + .await?, + ) + .with_gas_limit(21_000) + .with_max_priority_fee_per_gas(1_000_000_000) + .with_max_fee_per_gas(20_000_000_000) + .build(&wallet) + .await?; Ok(zeroex .provider() - .send_raw_transaction(&tx_envelope.encoded_2718()) + .send_raw_transaction(&tx.encoded_2718()) .await? .tx_hash() .to_alloy()) From 0526166558185a7b843b60d7adff5fba02c74ed0 Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 1 Sep 2025 13:28:17 +0300 Subject: [PATCH 13/34] Ugly fix --- crates/e2e/tests/e2e/liquidity.rs | 43 ++++++++++----------------- crates/ethrpc/src/alloy/mod.rs | 20 +++++++++++++ crates/ethrpc/src/block_stream/mod.rs | 1 + crates/ethrpc/src/instrumented.rs | 1 + crates/ethrpc/src/lib.rs | 3 ++ crates/ethrpc/src/mock.rs | 1 + 6 files changed, 42 insertions(+), 27 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 10bb27ffc9..02f5d67b73 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -30,7 +30,10 @@ use { ethcontract::{Account, H256, prelude::U256}, ethrpc::{ Web3, - alloy::conversions::{ToAlloy, ToLegacy}, + alloy::{ + conversions::{ToAlloy, ToLegacy}, + provider_with_account, + }, }, hex_literal::hex, model::{ @@ -79,7 +82,12 @@ async fn zero_ex_liquidity(web3: Web3) { .unwrap(), ); - let zeroex = IZeroex::Instance::deployed(&web3.alloy).await.unwrap(); + let signer = match &solver.account() { + Account::Offline(pk, _) => pk.secret_bytes(), + _ => unimplemented!(), + }; + let zeroex_provider = provider_with_account(&web3.node_url, &signer); + let zeroex = IZeroex::Instance::deployed(&zeroex_provider).await.unwrap(); let amount = to_wei_with_exp(5, 8); @@ -368,14 +376,7 @@ async fn fill_or_kill_zeroex_limit_order( zeroex_order: &shared::zeroex_api::OrderRecord, from_account: Account, ) -> anyhow::Result { - let signer = match &from_account { - Account::Offline(pk, _) => { - alloy::signers::local::PrivateKeySigner::from_slice(&pk.secret_bytes())? - } - _ => unimplemented!(), - }; - let wallet = EthereumWallet::from(signer); - let tx = zeroex + let tx_hash = zeroex .fillOrKillLimitOrder( IZeroex::LibNativeOrder::LimitOrder { makerToken: zeroex_order.order().maker_token.to_alloy(), @@ -399,23 +400,11 @@ async fn fill_or_kill_zeroex_limit_order( }, zeroex_order.order().taker_amount, ) - .into_transaction_request() - .nonce( - zeroex - .provider() - .get_transaction_count(from_account.address().to_alloy()) - .await?, - ) - .with_gas_limit(21_000) - .with_max_priority_fee_per_gas(1_000_000_000) - .with_max_fee_per_gas(20_000_000_000) - .build(&wallet) + .from(from_account.address().to_alloy()) + .send() + .await? + .watch() .await?; - Ok(zeroex - .provider() - .send_raw_transaction(&tx.encoded_2718()) - .await? - .tx_hash() - .to_alloy()) + Ok(tx_hash.to_alloy()) } diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index a918bbcdc7..16c801dec6 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -6,8 +6,10 @@ pub use instrumentation::ProviderLabelingExt; use { crate::AlloyProvider, alloy::{ + network::EthereumWallet, providers::{Provider, ProviderBuilder, mock}, rpc::client::ClientBuilder, + signers::local::PrivateKeySigner, }, buffering::BatchCallLayer, instrumentation::{InstrumentationLayer, LabelingLayer}, @@ -24,6 +26,24 @@ pub fn provider(url: &str) -> AlloyProvider { ProviderBuilder::new().connect_client(rpc).erased() } +pub fn provider_with_account(url: &str, private_key: &[u8; 32]) -> AlloyProvider { + let rpc = ClientBuilder::default() + .layer(LabelingLayer { + label: "main".into(), + }) + .layer(InstrumentationLayer) + .layer(BatchCallLayer::new(Default::default())) + .http(url.parse().unwrap()); + + let signer = PrivateKeySigner::from_slice(private_key).unwrap(); + let wallet = EthereumWallet::new(signer); + + ProviderBuilder::new() + .wallet(wallet) + .connect_client(rpc) + .erased() +} + pub fn dummy_provider() -> AlloyProvider { let asserter = mock::Asserter::new(); ProviderBuilder::new() diff --git a/crates/ethrpc/src/block_stream/mod.rs b/crates/ethrpc/src/block_stream/mod.rs index 7f732b4f16..f60971c464 100644 --- a/crates/ethrpc/src/block_stream/mod.rs +++ b/crates/ethrpc/src/block_stream/mod.rs @@ -129,6 +129,7 @@ pub async fn current_block_stream( legacy: web3, // TODO: replace this with an unbuffered alloy provider alloy: crate::alloy::provider(url.as_str()), + node_url: url.to_string(), }; let web3 = instrument_with_label(&web3, "base_currentBlockStream".into()); diff --git a/crates/ethrpc/src/instrumented.rs b/crates/ethrpc/src/instrumented.rs index d81fc14b0c..305154001a 100644 --- a/crates/ethrpc/src/instrumented.rs +++ b/crates/ethrpc/src/instrumented.rs @@ -81,6 +81,7 @@ pub fn instrument_with_label(web3: &crate::Web3, label: String) -> crate::Web3 { crate::Web3 { legacy: web3::Web3::new(DynTransport::new(instrumented)), alloy: web3.alloy.labeled(label), + node_url: web3.node_url.clone(), } } diff --git a/crates/ethrpc/src/lib.rs b/crates/ethrpc/src/lib.rs index eea5f99a32..f30bb7c4ae 100644 --- a/crates/ethrpc/src/lib.rs +++ b/crates/ethrpc/src/lib.rs @@ -33,6 +33,7 @@ pub type AlloyProvider = DynProvider; pub struct Web3 { pub legacy: web3::Web3, pub alloy: AlloyProvider, + pub node_url: String, } impl std::ops::Deref for Web3 { @@ -56,6 +57,7 @@ impl Web3 { Self { legacy: web3, alloy: crate::alloy::provider(url), + node_url: url.to_string(), } } } @@ -120,6 +122,7 @@ pub fn web3( Web3 { legacy: web3::Web3::new(Web3Transport::new(instrumented)), alloy: alloy::provider(url.as_str()), + node_url: url.to_string(), } } diff --git a/crates/ethrpc/src/mock.rs b/crates/ethrpc/src/mock.rs index 514285e883..3941c9bf9f 100644 --- a/crates/ethrpc/src/mock.rs +++ b/crates/ethrpc/src/mock.rs @@ -29,6 +29,7 @@ pub fn web3() -> Web3 { alloy: ProviderBuilder::new() .connect_mocked_client(Asserter::new()) .erased(), + node_url: "mock://".to_string(), } } From 0d2db7c00f54b2a49a81a21bb51eeb46db2ab0f5 Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 1 Sep 2025 13:46:28 +0300 Subject: [PATCH 14/34] Fix after merge --- .../competition/solution/interaction.rs | 4 +- crates/driver/src/domain/liquidity/zeroex.rs | 24 ++++---- crates/driver/src/infra/solver/dto/auction.rs | 4 +- crates/e2e/tests/e2e/liquidity.rs | 61 +++++++++---------- crates/solver/src/interactions/zeroex.rs | 24 ++++---- crates/solver/src/liquidity/zeroex.rs | 16 ++--- 6 files changed, 64 insertions(+), 69 deletions(-) diff --git a/crates/driver/src/domain/competition/solution/interaction.rs b/crates/driver/src/domain/competition/solution/interaction.rs index d1f90c51fd..b51d310f55 100644 --- a/crates/driver/src/domain/competition/solution/interaction.rs +++ b/crates/driver/src/domain/competition/solution/interaction.rs @@ -3,7 +3,7 @@ use { domain::{self, eth, liquidity}, util::Bytes, }, - ethrpc::alloy::conversions::ToLegacy, + ethrpc::alloy::conversions::IntoLegacy, }; /// Interaction with a smart contract which is needed to execute this solution @@ -45,7 +45,7 @@ impl Interaction { liquidity::Kind::BalancerV2Stable(pool) => pool.vault.into(), liquidity::Kind::BalancerV2Weighted(pool) => pool.vault.into(), liquidity::Kind::Swapr(pool) => pool.base.router.into(), - liquidity::Kind::ZeroEx(pool) => pool.zeroex.address().to_legacy(), + liquidity::Kind::ZeroEx(pool) => pool.zeroex.address().into_legacy(), }; // As a gas optimization, we always approve the max amount possible. This // minimizes the number of approvals necessary, and therefore diff --git a/crates/driver/src/domain/liquidity/zeroex.rs b/crates/driver/src/domain/liquidity/zeroex.rs index 2df0e6effe..cfb7085432 100644 --- a/crates/driver/src/domain/liquidity/zeroex.rs +++ b/crates/driver/src/domain/liquidity/zeroex.rs @@ -2,7 +2,7 @@ use { crate::domain::{eth, liquidity}, anyhow::anyhow, contracts::alloy::IZeroex, - ethrpc::alloy::conversions::{ToAlloy, ToLegacy}, + ethrpc::alloy::conversions::{IntoAlloy, IntoLegacy}, primitive_types::{H160, H256, U256}, std::sync::Arc, }; @@ -50,24 +50,24 @@ impl LimitOrder { pub fn to_interaction(&self, input: &liquidity::MaxInput) -> anyhow::Result { let method = self.zeroex.fillOrKillLimitOrder( IZeroex::LibNativeOrder::LimitOrder { - makerToken: self.order.maker_token.to_alloy(), - takerToken: self.order.taker_token.to_alloy(), + makerToken: self.order.maker_token.into_alloy(), + takerToken: self.order.taker_token.into_alloy(), makerAmount: self.order.amounts.maker, takerAmount: self.order.amounts.taker, takerTokenFeeAmount: self.order.taker_token_fee_amount, - maker: self.order.maker.to_alloy(), - taker: self.order.taker.to_alloy(), - sender: self.order.sender.to_alloy(), - feeRecipient: self.order.fee_recipient.to_alloy(), - pool: self.order.pool.to_alloy(), + maker: self.order.maker.into_alloy(), + taker: self.order.taker.into_alloy(), + sender: self.order.sender.into_alloy(), + feeRecipient: self.order.fee_recipient.into_alloy(), + pool: self.order.pool.into_alloy(), expiry: self.order.expiry, - salt: self.order.salt.to_alloy(), + salt: self.order.salt.into_alloy(), }, IZeroex::LibSignature::Signature { signatureType: self.order.signature.signature_type, v: self.order.signature.v, - r: self.order.signature.r.to_alloy(), - s: self.order.signature.s.to_alloy(), + r: self.order.signature.r.into_alloy(), + s: self.order.signature.s.into_alloy(), }, input .0 @@ -79,7 +79,7 @@ impl LimitOrder { let calldata = method.calldata(); Ok(eth::Interaction { - target: self.zeroex.address().to_legacy().into(), + target: self.zeroex.address().into_legacy().into(), value: 0.into(), call_data: calldata.to_vec().into(), }) diff --git a/crates/driver/src/infra/solver/dto/auction.rs b/crates/driver/src/infra/solver/dto/auction.rs index b1b8f30cc1..9698a5da95 100644 --- a/crates/driver/src/infra/solver/dto/auction.rs +++ b/crates/driver/src/infra/solver/dto/auction.rs @@ -12,7 +12,7 @@ use { util::conv::{rational_to_big_decimal, u256::U256Ext}, }, app_data::AppDataHash, - ethrpc::alloy::conversions::ToLegacy, + ethrpc::alloy::conversions::IntoLegacy, model::order::{BuyTokenDestination, SellTokenSource}, std::collections::HashMap, }; @@ -295,7 +295,7 @@ pub fn new( solvers_dto::auction::Liquidity::LimitOrder( solvers_dto::auction::ForeignLimitOrder { id: liquidity.id.0.to_string(), - address: limit_order.zeroex.address().to_legacy(), + address: limit_order.zeroex.address().into_legacy(), gas_estimate: liquidity.gas.into(), hash: Default::default(), maker_token: limit_order.order.maker_token, diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 02f5d67b73..e3c4cf2985 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -1,9 +1,4 @@ use { - ::alloy::{ - eips::Encodable2718, - network::{EthereumWallet, TransactionBuilder}, - providers::Provider, - }, chrono::{NaiveDateTime, Utc}, contracts::{ ERC20, @@ -31,7 +26,7 @@ use { ethrpc::{ Web3, alloy::{ - conversions::{ToAlloy, ToLegacy}, + conversions::{IntoAlloy, IntoLegacy}, provider_with_account, }, }, @@ -112,11 +107,11 @@ async fn zero_ex_liquidity(web3: Web3) { tx!( zeroex_maker.account(), // With a lower amount 0x contract shows much lower fillable amount - token_usdt.approve(zeroex.address().to_legacy(), amount * 4) + token_usdt.approve(zeroex.address().into_legacy(), amount * 4) ); tx!( solver.account(), - token_usdc.approve(zeroex.address().to_legacy(), amount) + token_usdc.approve(zeroex.address().into_legacy(), amount) ); let order = OrderCreation { @@ -138,7 +133,7 @@ async fn zero_ex_liquidity(web3: Web3) { let zeroex_liquidity_orders = create_zeroex_liquidity_orders( order.clone(), zeroex_maker.clone(), - zeroex.address().to_legacy(), + zeroex.address().into_legacy(), chain_id, onchain.contracts().weth.address(), ); @@ -247,12 +242,12 @@ async fn zero_ex_liquidity(web3: Web3) { maker: zeroex_maker.address(), taker: Default::default(), sender: Default::default(), - fee_recipient: zeroex.address().to_legacy(), + fee_recipient: zeroex.address().into_legacy(), pool: H256::default(), expiry: NaiveDateTime::MAX.and_utc().timestamp() as u64, salt: U256::from(Utc::now().timestamp()), } - .to_order_record(chain_id, zeroex.address().to_legacy(), zeroex_maker); + .to_order_record(chain_id, zeroex.address().into_legacy(), zeroex_maker); fill_or_kill_zeroex_limit_order(&zeroex, &zeroex_order, solver.account().clone()) .await .unwrap(); @@ -343,24 +338,24 @@ async fn get_zeroex_order_amounts( Ok(zeroex .getLimitOrderRelevantState( IZeroex::LibNativeOrder::LimitOrder { - makerToken: zeroex_order.order().maker_token.to_alloy(), - takerToken: zeroex_order.order().taker_token.to_alloy(), + makerToken: zeroex_order.order().maker_token.into_alloy(), + takerToken: zeroex_order.order().taker_token.into_alloy(), makerAmount: zeroex_order.order().maker_amount, takerAmount: zeroex_order.order().taker_amount, takerTokenFeeAmount: zeroex_order.order().taker_token_fee_amount, - maker: zeroex_order.order().maker.to_alloy(), - taker: zeroex_order.order().taker.to_alloy(), - sender: zeroex_order.order().sender.to_alloy(), - feeRecipient: zeroex_order.order().fee_recipient.to_alloy(), - pool: zeroex_order.order().pool.to_alloy(), + maker: zeroex_order.order().maker.into_alloy(), + taker: zeroex_order.order().taker.into_alloy(), + sender: zeroex_order.order().sender.into_alloy(), + feeRecipient: zeroex_order.order().fee_recipient.into_alloy(), + pool: zeroex_order.order().pool.into_alloy(), expiry: zeroex_order.order().expiry, - salt: zeroex_order.order().salt.to_alloy(), + salt: zeroex_order.order().salt.into_alloy(), }, IZeroex::LibSignature::Signature { signatureType: zeroex_order.order().signature.signature_type, v: zeroex_order.order().signature.v, - r: zeroex_order.order().signature.r.to_alloy(), - s: zeroex_order.order().signature.s.to_alloy(), + r: zeroex_order.order().signature.r.into_alloy(), + s: zeroex_order.order().signature.s.into_alloy(), }, ) .call() @@ -379,32 +374,32 @@ async fn fill_or_kill_zeroex_limit_order( let tx_hash = zeroex .fillOrKillLimitOrder( IZeroex::LibNativeOrder::LimitOrder { - makerToken: zeroex_order.order().maker_token.to_alloy(), - takerToken: zeroex_order.order().taker_token.to_alloy(), + makerToken: zeroex_order.order().maker_token.into_alloy(), + takerToken: zeroex_order.order().taker_token.into_alloy(), makerAmount: zeroex_order.order().maker_amount, takerAmount: zeroex_order.order().taker_amount, takerTokenFeeAmount: zeroex_order.order().taker_token_fee_amount, - maker: zeroex_order.order().maker.to_alloy(), - taker: zeroex_order.order().taker.to_alloy(), - sender: zeroex_order.order().sender.to_alloy(), - feeRecipient: zeroex_order.order().fee_recipient.to_alloy(), - pool: zeroex_order.order().pool.to_alloy(), + maker: zeroex_order.order().maker.into_alloy(), + taker: zeroex_order.order().taker.into_alloy(), + sender: zeroex_order.order().sender.into_alloy(), + feeRecipient: zeroex_order.order().fee_recipient.into_alloy(), + pool: zeroex_order.order().pool.into_alloy(), expiry: zeroex_order.order().expiry, - salt: zeroex_order.order().salt.to_alloy(), + salt: zeroex_order.order().salt.into_alloy(), }, IZeroex::LibSignature::Signature { signatureType: zeroex_order.order().signature.signature_type, v: zeroex_order.order().signature.v, - r: zeroex_order.order().signature.r.to_alloy(), - s: zeroex_order.order().signature.s.to_alloy(), + r: zeroex_order.order().signature.r.into_alloy(), + s: zeroex_order.order().signature.s.into_alloy(), }, zeroex_order.order().taker_amount, ) - .from(from_account.address().to_alloy()) + .from(from_account.address().into_alloy()) .send() .await? .watch() .await?; - Ok(tx_hash.to_alloy()) + Ok(tx_hash.into_alloy()) } diff --git a/crates/solver/src/interactions/zeroex.rs b/crates/solver/src/interactions/zeroex.rs index 3daafa1bee..5890b8052a 100644 --- a/crates/solver/src/interactions/zeroex.rs +++ b/crates/solver/src/interactions/zeroex.rs @@ -1,7 +1,7 @@ use { contracts::alloy::IZeroex, ethcontract::Bytes, - ethrpc::alloy::conversions::{ToAlloy, ToLegacy}, + ethrpc::alloy::conversions::{IntoAlloy, IntoLegacy}, shared::{ interaction::{EncodedInteraction, Interaction}, zeroex_api::Order, @@ -20,30 +20,30 @@ impl Interaction for ZeroExInteraction { fn encode(&self) -> EncodedInteraction { let method = self.zeroex.fillOrKillLimitOrder( IZeroex::LibNativeOrder::LimitOrder { - makerToken: self.order.maker_token.to_alloy(), - takerToken: self.order.taker_token.to_alloy(), + makerToken: self.order.maker_token.into_alloy(), + takerToken: self.order.taker_token.into_alloy(), makerAmount: self.order.maker_amount, takerAmount: self.order.taker_amount, takerTokenFeeAmount: self.order.taker_token_fee_amount, - maker: self.order.maker.to_alloy(), - taker: self.order.taker.to_alloy(), - sender: self.order.sender.to_alloy(), - feeRecipient: self.order.fee_recipient.to_alloy(), - pool: self.order.pool.to_alloy(), + maker: self.order.maker.into_alloy(), + taker: self.order.taker.into_alloy(), + sender: self.order.sender.into_alloy(), + feeRecipient: self.order.fee_recipient.into_alloy(), + pool: self.order.pool.into_alloy(), expiry: self.order.expiry, - salt: self.order.salt.to_alloy(), + salt: self.order.salt.into_alloy(), }, IZeroex::LibSignature::Signature { signatureType: self.order.signature.signature_type, v: self.order.signature.v, - r: self.order.signature.r.to_alloy(), - s: self.order.signature.s.to_alloy(), + r: self.order.signature.r.into_alloy(), + s: self.order.signature.s.into_alloy(), }, self.taker_token_fill_amount, ); let calldata = method.calldata(); ( - self.zeroex.address().to_legacy(), + self.zeroex.address().into_legacy(), 0.into(), Bytes(calldata.to_vec()), ) diff --git a/crates/solver/src/liquidity/zeroex.rs b/crates/solver/src/liquidity/zeroex.rs index 47d663024a..4b2dd6af03 100644 --- a/crates/solver/src/liquidity/zeroex.rs +++ b/crates/solver/src/liquidity/zeroex.rs @@ -13,7 +13,7 @@ use { arc_swap::ArcSwap, contracts::{GPv2Settlement, alloy::IZeroex}, ethrpc::{ - alloy::conversions::ToLegacy, + alloy::conversions::IntoLegacy, block_stream::{CurrentBlockWatcher, into_stream}, }, futures::StreamExt, @@ -147,7 +147,7 @@ impl LiquidityCollecting for ZeroExLiquidity { let allowances = Arc::new( self.allowance_manager - .get_allowances(tokens, self.zeroex.address().to_legacy()) + .get_allowances(tokens, self.zeroex.address().into_legacy()) .await?, ); @@ -252,7 +252,7 @@ pub mod tests { use { super::*, crate::interactions::allowances::Approval, - ethrpc::{alloy, alloy::conversions::ToAlloy}, + ethrpc::{alloy, alloy::conversions::IntoAlloy}, maplit::hashmap, shared::{ baseline_solver::BaseTokens, @@ -394,11 +394,11 @@ pub mod tests { async fn interaction_encodes_approval_when_insufficient() { let sell_token = H160::from_low_u64_be(1); let zeroex = Arc::new(IZeroex::Instance::new( - H160::default().to_alloy(), + H160::default().into_alloy(), alloy::dummy_provider(), )); let allowances = Allowances::new( - zeroex.address().to_legacy(), + zeroex.address().into_legacy(), hashmap! { sell_token => 99.into() }, ); let order_record = OrderRecord::new( @@ -425,7 +425,7 @@ pub mod tests { [ Approval { token: sell_token, - spender: zeroex.address().to_legacy(), + spender: zeroex.address().into_legacy(), } .encode(), ZeroExInteraction { @@ -442,11 +442,11 @@ pub mod tests { async fn interaction_encodes_no_approval_when_sufficient() { let sell_token = H160::from_low_u64_be(1); let zeroex = Arc::new(IZeroex::Instance::new( - H160::default().to_alloy(), + H160::default().into_alloy(), alloy::dummy_provider(), )); let allowances = Allowances::new( - zeroex.address().to_legacy(), + zeroex.address().into_legacy(), hashmap! { sell_token => 100.into() }, ); let order_record = OrderRecord::new( From eb99133d43d9e45e15f9fcf045a836a4f725bd26 Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 1 Sep 2025 13:54:10 +0300 Subject: [PATCH 15/34] Redundant changes --- crates/contracts/src/alloy.rs | 17 +++++++++-------- crates/contracts/src/lib.rs | 19 ++++--------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/crates/contracts/src/alloy.rs b/crates/contracts/src/alloy.rs index 82c0d6a49b..1b40131be3 100644 --- a/crates/contracts/src/alloy.rs +++ b/crates/contracts/src/alloy.rs @@ -1,5 +1,6 @@ pub mod networks { pub const MAINNET: u64 = 1; + pub const GOERLI: u64 = 5; pub const GNOSIS: u64 = 100; pub const SEPOLIA: u64 = 11155111; pub const ARBITRUM_ONE: u64 = 42161; @@ -14,14 +15,14 @@ pub mod networks { crate::bindings!( IZeroex, maplit::hashmap! { - crate::MAINNET => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::SEPOLIA => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::ARBITRUM_ONE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::BASE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::AVALANCHE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::BNB => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::OPTIMISM => address!("0xdef1abe32c034e558cdd535791643c58a13acc10"), - crate::POLYGON => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::alloy::networks::MAINNET => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::alloy::networks::SEPOLIA => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::alloy::networks::ARBITRUM_ONE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::alloy::networks::BASE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::alloy::networks::AVALANCHE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::alloy::networks::BNB => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + crate::alloy::networks::OPTIMISM => address!("0xdef1abe32c034e558cdd535791643c58a13acc10"), + crate::alloy::networks::POLYGON => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), // Not available on Lens } ); diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index 646f7cfa57..deaa0684ec 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -132,23 +132,12 @@ pub mod test { } } -const MAINNET: u64 = 1; -#[allow(dead_code)] -const GOERLI: u64 = 5; -#[allow(dead_code)] -const GNOSIS: u64 = 100; -const SEPOLIA: u64 = 11155111; -const ARBITRUM_ONE: u64 = 42161; -const BASE: u64 = 8453; -const POLYGON: u64 = 137; -const AVALANCHE: u64 = 43114; -const BNB: u64 = 56; -const OPTIMISM: u64 = 10; -#[allow(dead_code)] -const LENS: u64 = 232; - #[cfg(test)] mod tests { + use crate::alloy::networks::{ + ARBITRUM_ONE, AVALANCHE, BASE, BNB, GNOSIS, GOERLI, LENS, MAINNET, OPTIMISM, POLYGON, + SEPOLIA, + }; use { super::*, ethcontract::{ From 6a5c4a0ff8176eb9610317985d01255d46e82c97 Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 1 Sep 2025 14:01:09 +0300 Subject: [PATCH 16/34] Naming --- crates/e2e/tests/e2e/liquidity.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index e3c4cf2985..274fc3758c 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -77,11 +77,11 @@ async fn zero_ex_liquidity(web3: Web3) { .unwrap(), ); - let signer = match &solver.account() { + let signer_pk = match &solver.account() { Account::Offline(pk, _) => pk.secret_bytes(), _ => unimplemented!(), }; - let zeroex_provider = provider_with_account(&web3.node_url, &signer); + let zeroex_provider = provider_with_account(&web3.node_url, &signer_pk); let zeroex = IZeroex::Instance::deployed(&zeroex_provider).await.unwrap(); let amount = to_wei_with_exp(5, 8); From 26e0a6c1a693a73de8990ae30f4e7b5c46b16f89 Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 1 Sep 2025 15:25:56 +0300 Subject: [PATCH 17/34] Avoid unwrap --- crates/e2e/tests/e2e/liquidity.rs | 2 +- crates/ethrpc/src/alloy/mod.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 274fc3758c..71e7c7e1ee 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -81,7 +81,7 @@ async fn zero_ex_liquidity(web3: Web3) { Account::Offline(pk, _) => pk.secret_bytes(), _ => unimplemented!(), }; - let zeroex_provider = provider_with_account(&web3.node_url, &signer_pk); + let zeroex_provider = provider_with_account(&web3.node_url, &signer_pk).unwrap(); let zeroex = IZeroex::Instance::deployed(&zeroex_provider).await.unwrap(); let amount = to_wei_with_exp(5, 8); diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 16c801dec6..3bcca3f78e 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -26,7 +26,7 @@ pub fn provider(url: &str) -> AlloyProvider { ProviderBuilder::new().connect_client(rpc).erased() } -pub fn provider_with_account(url: &str, private_key: &[u8; 32]) -> AlloyProvider { +pub fn provider_with_account(url: &str, private_key: &[u8; 32]) -> anyhow::Result { let rpc = ClientBuilder::default() .layer(LabelingLayer { label: "main".into(), @@ -35,13 +35,13 @@ pub fn provider_with_account(url: &str, private_key: &[u8; 32]) -> AlloyProvider .layer(BatchCallLayer::new(Default::default())) .http(url.parse().unwrap()); - let signer = PrivateKeySigner::from_slice(private_key).unwrap(); + let signer = PrivateKeySigner::from_slice(private_key)?; let wallet = EthereumWallet::new(signer); - ProviderBuilder::new() + Ok(ProviderBuilder::new() .wallet(wallet) .connect_client(rpc) - .erased() + .erased()) } pub fn dummy_provider() -> AlloyProvider { From 9f6a2ce48a58e00ea7b52b3fb0fe318e3201f8dd Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 1 Sep 2025 15:32:09 +0300 Subject: [PATCH 18/34] Use PrivateKey --- crates/e2e/tests/e2e/liquidity.rs | 2 +- crates/ethrpc/src/alloy/mod.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 71e7c7e1ee..e514376e75 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -78,7 +78,7 @@ async fn zero_ex_liquidity(web3: Web3) { ); let signer_pk = match &solver.account() { - Account::Offline(pk, _) => pk.secret_bytes(), + Account::Offline(pk, _) => pk.clone(), _ => unimplemented!(), }; let zeroex_provider = provider_with_account(&web3.node_url, &signer_pk).unwrap(); diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 3bcca3f78e..670b7aa713 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -12,6 +12,7 @@ use { signers::local::PrivateKeySigner, }, buffering::BatchCallLayer, + ethcontract::PrivateKey, instrumentation::{InstrumentationLayer, LabelingLayer}, }; @@ -26,7 +27,7 @@ pub fn provider(url: &str) -> AlloyProvider { ProviderBuilder::new().connect_client(rpc).erased() } -pub fn provider_with_account(url: &str, private_key: &[u8; 32]) -> anyhow::Result { +pub fn provider_with_account(url: &str, private_key: &PrivateKey) -> anyhow::Result { let rpc = ClientBuilder::default() .layer(LabelingLayer { label: "main".into(), @@ -35,7 +36,7 @@ pub fn provider_with_account(url: &str, private_key: &[u8; 32]) -> anyhow::Resul .layer(BatchCallLayer::new(Default::default())) .http(url.parse().unwrap()); - let signer = PrivateKeySigner::from_slice(private_key)?; + let signer = PrivateKeySigner::from_slice(&private_key.secret_bytes())?; let wallet = EthereumWallet::new(signer); Ok(ProviderBuilder::new() From d85cfd93b8bde68aa9bffcf97156da30cc0f94d2 Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 2 Sep 2025 09:18:26 +0300 Subject: [PATCH 19/34] Fix --- Cargo.lock | 5 +++-- crates/contracts/src/alloy.rs | 16 ++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b77bdb6bb9..1e4c360699 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -504,8 +504,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.0.17" -source = "git+https://github.com/alloy-rs/alloy?rev=c15a4a3c04ce15bfa3796cc449f8407200b7599f#c15a4a3c04ce15bfa3796cc449f8407200b7599f" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83ae7d854db5b7cdd5b9ed7ad13d1e5e034cdd8be85ffef081f61dc6c9e18351" dependencies = [ "alloy-consensus", "alloy-network", diff --git a/crates/contracts/src/alloy.rs b/crates/contracts/src/alloy.rs index 7955287570..57e04e7435 100644 --- a/crates/contracts/src/alloy.rs +++ b/crates/contracts/src/alloy.rs @@ -28,14 +28,14 @@ crate::bindings!( crate::bindings!( IZeroex, maplit::hashmap! { - crate::alloy::networks::MAINNET => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::alloy::networks::SEPOLIA => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::alloy::networks::ARBITRUM_ONE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::alloy::networks::BASE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::alloy::networks::AVALANCHE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::alloy::networks::BNB => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), - crate::alloy::networks::OPTIMISM => address!("0xdef1abe32c034e558cdd535791643c58a13acc10"), - crate::alloy::networks::POLYGON => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + MAINNET => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + SEPOLIA => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + ARBITRUM_ONE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + BASE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + AVALANCHE => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + BNB => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), + OPTIMISM => address!("0xdef1abe32c034e558cdd535791643c58a13acc10"), + POLYGON => address!("0xdef1c0ded9bec7f1a1670819833240f027b25eff"), // Not available on Lens } ); From 4ce10f45eef4b71241ac94467b74dd347a93acb1 Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 2 Sep 2025 18:49:22 +0300 Subject: [PATCH 20/34] Drop GOERLI --- crates/contracts/src/alloy.rs | 1 - crates/contracts/src/lib.rs | 27 +++++++++++---------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/crates/contracts/src/alloy.rs b/crates/contracts/src/alloy.rs index 57e04e7435..6d4a64ee45 100644 --- a/crates/contracts/src/alloy.rs +++ b/crates/contracts/src/alloy.rs @@ -1,6 +1,5 @@ pub mod networks { pub const MAINNET: u64 = 1; - pub const GOERLI: u64 = 5; pub const GNOSIS: u64 = 100; pub const SEPOLIA: u64 = 11155111; pub const ARBITRUM_ONE: u64 = 42161; diff --git a/crates/contracts/src/lib.rs b/crates/contracts/src/lib.rs index e087f3c3d8..01235123c1 100644 --- a/crates/contracts/src/lib.rs +++ b/crates/contracts/src/lib.rs @@ -134,8 +134,7 @@ pub mod test { #[cfg(test)] mod tests { use crate::alloy::networks::{ - ARBITRUM_ONE, AVALANCHE, BASE, BNB, GNOSIS, GOERLI, LENS, MAINNET, OPTIMISM, POLYGON, - SEPOLIA, + ARBITRUM_ONE, AVALANCHE, BASE, BNB, GNOSIS, LENS, MAINNET, OPTIMISM, POLYGON, SEPOLIA, }; use { super::*, @@ -198,17 +197,17 @@ mod tests { }}; } - for network in &[MAINNET, GOERLI, GNOSIS, SEPOLIA, ARBITRUM_ONE] { + for network in &[MAINNET, GNOSIS, SEPOLIA, ARBITRUM_ONE] { assert_has_deployment_address!(GPv2Settlement for *network); assert_has_deployment_address!(WETH9 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, SEPOLIA] { + for network in &[MAINNET, GNOSIS, SEPOLIA] { assert_has_deployment_address!(CowProtocolToken for *network); } - for network in &[MAINNET, GOERLI, GNOSIS, ARBITRUM_ONE] { + for network in &[MAINNET, GNOSIS, ARBITRUM_ONE] { assert_has_deployment_address!(SushiSwapRouter for *network); assert_has_deployment_address!(UniswapV2Factory for *network); assert_has_deployment_address!(UniswapV2Router02 for *network); @@ -226,7 +225,7 @@ mod tests { assert_has_deployment_address!(UniswapV3SwapRouterV2 for *network); assert_has_deployment_address!(IUniswapV3Factory for *network); } - for network in &[MAINNET, GOERLI, ARBITRUM_ONE] { + for network in &[MAINNET, ARBITRUM_ONE] { assert_has_deployment_address!(BalancerV2WeightedPool2TokensFactory for *network); assert_has_deployment_address!(BalancerV2LiquidityBootstrappingPoolFactory for *network); } @@ -235,11 +234,9 @@ mod tests { assert_has_deployment_address!(PancakeRouter for *network); } - for network in &[MAINNET, GOERLI] { - assert_has_deployment_address!(BalancerV2WeightedPoolFactory for *network); - } + assert_has_deployment_address!(BalancerV2WeightedPoolFactory for MAINNET); - for network in &[MAINNET, GOERLI, GNOSIS, ARBITRUM_ONE] { + for network in &[MAINNET, GNOSIS, ARBITRUM_ONE] { assert_has_deployment_address!(BalancerV2StablePoolFactoryV2 for *network); } @@ -268,17 +265,15 @@ mod tests { }}; } - for network in &[MAINNET, GOERLI, GNOSIS, SEPOLIA, ARBITRUM_ONE] { + for network in &[MAINNET, GNOSIS, SEPOLIA, ARBITRUM_ONE] { assert_has_deployment_information!(GPv2Settlement for *network); assert_has_deployment_information!(BalancerV2Vault for *network); } - for network in &[MAINNET, GOERLI] { - assert_has_deployment_information!(BalancerV2WeightedPoolFactory for *network); - } - for network in &[MAINNET, GOERLI, ARBITRUM_ONE] { + assert_has_deployment_information!(BalancerV2WeightedPoolFactory for MAINNET); + for network in &[MAINNET, ARBITRUM_ONE] { assert_has_deployment_information!(BalancerV2WeightedPool2TokensFactory for *network); } - for network in &[MAINNET, GOERLI, GNOSIS, ARBITRUM_ONE] { + for network in &[MAINNET, GNOSIS, ARBITRUM_ONE] { assert_has_deployment_information!(BalancerV2StablePoolFactoryV2 for *network); } } From 94732a44e0d67e4db5efde4570c5abaada2904eb Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 2 Sep 2025 18:53:36 +0300 Subject: [PATCH 21/34] todos --- crates/driver/src/domain/liquidity/zeroex.rs | 1 + crates/solver/src/interactions/zeroex.rs | 1 + crates/solver/src/liquidity/zeroex.rs | 2 ++ 3 files changed, 4 insertions(+) diff --git a/crates/driver/src/domain/liquidity/zeroex.rs b/crates/driver/src/domain/liquidity/zeroex.rs index cfb7085432..93d8ac31ca 100644 --- a/crates/driver/src/domain/liquidity/zeroex.rs +++ b/crates/driver/src/domain/liquidity/zeroex.rs @@ -19,6 +19,7 @@ pub struct LimitOrder { /// Scaled amounts according to how much of the partially fillable amounts /// were already used in the order. pub fillable: Amounts, + // todo: remove Arc pub zeroex: Arc, } diff --git a/crates/solver/src/interactions/zeroex.rs b/crates/solver/src/interactions/zeroex.rs index 5890b8052a..a93dcb7c46 100644 --- a/crates/solver/src/interactions/zeroex.rs +++ b/crates/solver/src/interactions/zeroex.rs @@ -13,6 +13,7 @@ use { pub struct ZeroExInteraction { pub order: Order, pub taker_token_fill_amount: u128, + // todo: remove Arc pub zeroex: Arc, } diff --git a/crates/solver/src/liquidity/zeroex.rs b/crates/solver/src/liquidity/zeroex.rs index 4b2dd6af03..9f6f592b4d 100644 --- a/crates/solver/src/liquidity/zeroex.rs +++ b/crates/solver/src/liquidity/zeroex.rs @@ -37,6 +37,7 @@ type OrderBuckets = HashMap<(H160, H160), Vec>; type OrderbookCache = ArcSwap; pub struct ZeroExLiquidity { + // todo: remove Arc pub zeroex: Arc, pub allowance_manager: Box, pub orderbook_cache: Arc, @@ -214,6 +215,7 @@ fn get_useful_orders( #[derive(Clone)] pub struct OrderSettlementHandler { pub order_record: OrderRecord, + // todo: remove Arc pub zeroex: Arc, allowances: Arc, } From edd8e3a3965591dc54668b57e128f78b0c3a3b7b Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 2 Sep 2025 19:12:16 +0300 Subject: [PATCH 22/34] test-util feature --- crates/e2e/Cargo.toml | 2 +- crates/ethrpc/Cargo.toml | 3 +++ crates/ethrpc/src/alloy/mod.rs | 13 ++++++++----- crates/solver/Cargo.toml | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index 51751dfbc2..32fea84c25 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -18,7 +18,7 @@ contracts = { workspace = true } database = { workspace = true } driver = { workspace = true } ethcontract = { workspace = true } -ethrpc = { workspace = true } +ethrpc = { workspace = true, features = ["test-util"] } futures = { workspace = true } hex = { workspace = true } hex-literal = { workspace = true } diff --git a/crates/ethrpc/Cargo.toml b/crates/ethrpc/Cargo.toml index 97a1840cfc..99745b20d9 100644 --- a/crates/ethrpc/Cargo.toml +++ b/crates/ethrpc/Cargo.toml @@ -42,3 +42,6 @@ testlib = { workspace = true } [lints] workspace = true + +[features] +test-util = [] diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 670b7aa713..4773403f9e 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -6,15 +6,17 @@ pub use instrumentation::ProviderLabelingExt; use { crate::AlloyProvider, alloy::{ - network::EthereumWallet, - providers::{Provider, ProviderBuilder, mock}, + providers::{Provider, ProviderBuilder}, rpc::client::ClientBuilder, - signers::local::PrivateKeySigner, }, buffering::BatchCallLayer, - ethcontract::PrivateKey, instrumentation::{InstrumentationLayer, LabelingLayer}, }; +#[cfg(any(test, feature = "test-util"))] +use { + alloy::{network::EthereumWallet, providers::mock, signers::local::PrivateKeySigner}, + ethcontract::PrivateKey, +}; pub fn provider(url: &str) -> AlloyProvider { let rpc = ClientBuilder::default() @@ -27,13 +29,13 @@ pub fn provider(url: &str) -> AlloyProvider { ProviderBuilder::new().connect_client(rpc).erased() } +#[cfg(any(test, feature = "test-util"))] pub fn provider_with_account(url: &str, private_key: &PrivateKey) -> anyhow::Result { let rpc = ClientBuilder::default() .layer(LabelingLayer { label: "main".into(), }) .layer(InstrumentationLayer) - .layer(BatchCallLayer::new(Default::default())) .http(url.parse().unwrap()); let signer = PrivateKeySigner::from_slice(&private_key.secret_bytes())?; @@ -45,6 +47,7 @@ pub fn provider_with_account(url: &str, private_key: &PrivateKey) -> anyhow::Res .erased()) } +#[cfg(any(test, feature = "test-util"))] pub fn dummy_provider() -> AlloyProvider { let asserter = mock::Asserter::new(); ProviderBuilder::new() diff --git a/crates/solver/Cargo.toml b/crates/solver/Cargo.toml index deeec8329c..7287247122 100644 --- a/crates/solver/Cargo.toml +++ b/crates/solver/Cargo.toml @@ -16,7 +16,7 @@ arc-swap = { workspace = true } async-trait = { workspace = true } contracts = { workspace = true } ethcontract = { workspace = true } -ethrpc = { workspace = true } +ethrpc = { workspace = true, features = ["test-util"] } futures = { workspace = true } observe = { workspace = true } hex = { workspace = true } From 596718f509aac2491b13694d81323e157e1b190a Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 2 Sep 2025 19:18:26 +0300 Subject: [PATCH 23/34] cargo.lock --- Cargo.lock | 140 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc31803db5..bfb5ee019b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7413bbf62c40b5db916ad5a1c382df1affe42080e148d69932bb7f0a12f32e" +checksum = "5b6b7b6a501cba311fdb8f7d7798a6d9ca8a5bec16609f1629efeafbac68476e" dependencies = [ "alloy-consensus", "alloy-contract", @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7345077623aaa080fc06735ac13b8fa335125c8550f9c4f64135a5bf6f79967" +checksum = "fec84ecc0f92bb13b2955d04d3d6bd638415f17069f7ed802de819642fa3a73c" dependencies = [ "alloy-eips", "alloy-primitives", @@ -139,7 +139,7 @@ dependencies = [ "k256", "once_cell", "rand 0.8.5", - "secp256k1 0.30.0", + "secp256k1 0.31.1", "serde", "serde_with", "thiserror 2.0.16", @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501f83565d28bdb9d6457dd3b5d646e19db37709d0f27608a26a1839052ddade" +checksum = "e7e953646f3d5bde9ddf26a0387a35e435044f8728602dc1cb5b9f5cadb642bd" dependencies = [ "alloy-consensus", "alloy-eips", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c36bb4173892aeeba1c6b9e4eff923fa3fe8583f6d3e07afe1cbc5a96a853a" +checksum = "25a411d7b472b11ceb953741faf26bad31dcac8236e2df84078951a6951561c4" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -247,9 +247,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c219a87fb386a75780ddbdbbced242477321887e426b0f946c05815ceabe5e09" +checksum = "9d9ebd288f87aa496179b83471f5b00bcd01def4048714234d3ddbf97a6b9dd2" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -281,9 +281,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "334555c323fa2bb98f1d4c242b62da9de8c715557a2ed680a76cefbcac19fefd" +checksum = "5b9d9bedc5c977a179ef037ccadb2e711718118446b0a0cead3427fd5b6712b3" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -296,9 +296,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ea377c9650203d7a7da9e8dee7f04906b49a9253f554b110edd7972e75ef34" +checksum = "30c6bffd937626c66734750f022d1808ccf6d5432969044dfde973cae99930d8" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -322,9 +322,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f9ab9a9e92c49a357edaee2d35deea0a32ac8f313cfa37448f04e7e029c9d9" +checksum = "0bf37162ea3d9809750c6279e09e1012124fc797b02ffb0651974a505f7f88ff" dependencies = [ "alloy-consensus", "alloy-eips", @@ -362,9 +362,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a85361c88c16116defbd98053e3d267054d6b82729cdbef0236f7881590f924" +checksum = "bf52603a852c8040686e45649f1211987fa6c96885174a5c4a31a1e07c1ddef7" dependencies = [ "alloy-chains", "alloy-consensus", @@ -386,7 +386,7 @@ dependencies = [ "either", "futures", "futures-utils-wasm", - "lru 0.13.0", + "lru 0.16.0", "parking_lot", "pin-project", "reqwest 0.12.23", @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743fc964abb0106e454e9e8683fb0809fb32940270ef586a58e913531360b302" +checksum = "87118d5dc24e682978fb51e3dc1cccb3ef3021e4b98825a357c3efb9256187d5" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -446,9 +446,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97372c51a14a804fb9c17010e3dd6c117f7866620b264e24b64d2259be44bcdf" +checksum = "953599f7a753a6d17296c21b40e15248b69b5845e8764b2fef696e2e012a3f84" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -457,9 +457,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672286c19528007df058bafd82c67e23247b4b3ebbc538cbddc705a82d8a930f" +checksum = "0177e49c5d9dffbd8a427cbe757e202e5ef71718d5a8ae7d6858b6e3f448131b" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -478,9 +478,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aae653f049267ae7e040eab6c9b9a417064ca1a6cb21e3dd59b9f1131ef048f" +checksum = "743e0fe099fe90a07215ae08413b271b8fac12fca6880c85326ce61341566e6f" dependencies = [ "alloy-primitives", "serde", @@ -489,9 +489,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97cedce202f848592b96f7e891503d3adb33739c4e76904da73574290141b93" +checksum = "236cfc2c09ca2af29a2b0e622247c38e47657da97fc9636d5fbe64b6020026c6" dependencies = [ "alloy-primitives", "async-trait", @@ -504,9 +504,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ae7d854db5b7cdd5b9ed7ad13d1e5e034cdd8be85ffef081f61dc6c9e18351" +checksum = "626cdb6bb897a09e74d7e502e1834eac83dc0fd94bbb4c9e2cf342dba7f037a9" dependencies = [ "alloy-consensus", "alloy-network", @@ -515,7 +515,7 @@ dependencies = [ "async-trait", "k256", "rand 0.8.5", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -593,9 +593,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08b383bc903c927635e39e1dae7df2180877d93352d1abd389883665a598afc" +checksum = "a568f574d8d11fc054e3a32f19f476fdcc4db9216246b1db0b2ecad157a6f963" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -617,9 +617,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e58dee1f7763ef302074b645fc4f25440637c09a60e8de234b62993f06c0ae3" +checksum = "df4c00f7c7c6af5660423e6747d22f04ca7e019371eae2dc6535c17b1d636469" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -648,12 +648,12 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14809f908822dbff0dc472c77ca4aa129ab12e22fd9bff2dd1ef54603e68e3d" +checksum = "40696658bb1ac21f742107185fc2b0f60695598e4f16695e5bd24f4cfc0ddc29" dependencies = [ "alloy-primitives", - "darling", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.106", @@ -2592,8 +2592,18 @@ version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -2610,13 +2620,39 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "serde", + "strsim", + "syn 2.0.106", +] + [[package]] name = "darling_macro" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core", + "darling_core 0.20.11", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", "quote", "syn 2.0.106", ] @@ -4521,9 +4557,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.13.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" +checksum = "86ea4e65087ff52f3862caff188d489f1fab49a0cb09e01b2e3f1a617b10aaed" dependencies = [ "hashbrown 0.15.5", ] @@ -6354,13 +6390,13 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.30.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +checksum = "2c3c81b43dc2d8877c216a3fccf76677ee1ebccd429566d3e67447290d0c42b2" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", - "secp256k1-sys 0.10.1", + "rand 0.9.2", + "secp256k1-sys 0.11.0", "serde", ] @@ -6375,9 +6411,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +checksum = "dcb913707158fadaf0d8702c2db0e857de66eb003ccfdda5924b5f5ac98efb38" dependencies = [ "cc", ] @@ -6531,7 +6567,7 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" dependencies = [ - "darling", + "darling 0.20.11", "proc-macro2", "quote", "syn 2.0.106", From eda40d69e35a4a0c8f7a933e5a915757ef630345 Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 2 Sep 2025 19:22:39 +0300 Subject: [PATCH 24/34] Update alloy --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4973695824..00c39b1447 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["crates/*"] [workspace.dependencies] -alloy = { version = "1.0.27", default-features = false } +alloy = { version = "1.0.28", default-features = false } anyhow = "=1.0.76" async-trait = "0.1.80" axum = "0.6" From 1482cdae35b75c0077d9f798d2f0064368a3aeba Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 2 Sep 2025 19:28:09 +0300 Subject: [PATCH 25/34] Avoid unwrap --- crates/ethrpc/src/alloy/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 4773403f9e..dbe0984022 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -36,7 +36,7 @@ pub fn provider_with_account(url: &str, private_key: &PrivateKey) -> anyhow::Res label: "main".into(), }) .layer(InstrumentationLayer) - .http(url.parse().unwrap()); + .http(url.parse()?); let signer = PrivateKeySigner::from_slice(&private_key.secret_bytes())?; let wallet = EthereumWallet::new(signer); From fdca0c59a70139ce47ffcdfe4bf9b0dcefa0bb83 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 10:49:42 +0300 Subject: [PATCH 26/34] Adjust dependencies --- crates/e2e/Cargo.toml | 3 ++- crates/solver/Cargo.toml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index 32fea84c25..b922de1242 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -18,7 +18,7 @@ contracts = { workspace = true } database = { workspace = true } driver = { workspace = true } ethcontract = { workspace = true } -ethrpc = { workspace = true, features = ["test-util"] } +ethrpc = { workspace = true } futures = { workspace = true } hex = { workspace = true } hex-literal = { workspace = true } @@ -42,6 +42,7 @@ warp = { workspace = true } web3 = { workspace = true, features = ["http"] } [dev-dependencies] +ethrpc = { workspace = true, features = ["test-util"] } refunder = { workspace = true } [lints] diff --git a/crates/solver/Cargo.toml b/crates/solver/Cargo.toml index 7287247122..dfbeaa950f 100644 --- a/crates/solver/Cargo.toml +++ b/crates/solver/Cargo.toml @@ -16,7 +16,7 @@ arc-swap = { workspace = true } async-trait = { workspace = true } contracts = { workspace = true } ethcontract = { workspace = true } -ethrpc = { workspace = true, features = ["test-util"] } +ethrpc = { workspace = true } futures = { workspace = true } observe = { workspace = true } hex = { workspace = true } @@ -40,6 +40,7 @@ web3 = { workspace = true } [dev-dependencies] derivative = { workspace = true } +ethrpc = { workspace = true, features = ["test-util"] } tokio = { workspace = true, features = ["test-util"] } testlib = { workspace = true } From a819b64723e771c79f765d70dc0f9f8725b5ba04 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 14:15:27 +0300 Subject: [PATCH 27/34] Fix and update alloy --- Cargo.lock | 151 +++++++++++++++++++++-------------------------------- Cargo.toml | 2 +- 2 files changed, 61 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b73f4f5e16..3cffc270c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6b7b6a501cba311fdb8f7d7798a6d9ca8a5bec16609f1629efeafbac68476e" +checksum = "754e8b511978ec78b3bf71140d2692fa8b67a09e44a9742487ab21dec616f953" dependencies = [ "alloy-consensus", "alloy-contract", @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec84ecc0f92bb13b2955d04d3d6bd638415f17069f7ed802de819642fa3a73c" +checksum = "1816584b0c17e3ab5781d7044b07d5b884cf8fe005811b4ae2cded266e0e8c87" dependencies = [ "alloy-eips", "alloy-primitives", @@ -140,7 +140,7 @@ dependencies = [ "k256", "once_cell", "rand 0.8.5", - "secp256k1 0.31.1", + "secp256k1 0.30.0", "serde", "serde_with", "thiserror 2.0.16", @@ -148,9 +148,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e953646f3d5bde9ddf26a0387a35e435044f8728602dc1cb5b9f5cadb642bd" +checksum = "dbb74c249b00a0e5005efc2aa3ef48c805b278cad848b544d5f53cb266f45976" dependencies = [ "alloy-consensus", "alloy-eips", @@ -162,9 +162,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a411d7b472b11ceb953741faf26bad31dcac8236e2df84078951a6951561c4" +checksum = "b5cabcc7fdf60c92df94889d6e1b73814ecf47e99a6554f6dd7f75b45aa9d7fa" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d9ebd288f87aa496179b83471f5b00bcd01def4048714234d3ddbf97a6b9dd2" +checksum = "82cee87eceefee136d68bba6d7202745c218346f28f0b96ce83b8061c991ddad" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9bedc5c977a179ef037ccadb2e711718118446b0a0cead3427fd5b6712b3" +checksum = "eb4dc62df1be5c5f103f66ac8f25bf4d34e7b812e642159918466bb4c0f8e9a9" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c6bffd937626c66734750f022d1808ccf6d5432969044dfde973cae99930d8" +checksum = "54e07a4331293a40c1a2fff58739c6da826cd86e3e76cd339af5d99b5e085344" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -323,9 +323,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf37162ea3d9809750c6279e09e1012124fc797b02ffb0651974a505f7f88ff" +checksum = "237f507e38aac68d95389fbfba451a8d18cbdb51c971bc78f643de54bb15e395" dependencies = [ "alloy-consensus", "alloy-eips", @@ -363,9 +363,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf52603a852c8040686e45649f1211987fa6c96885174a5c4a31a1e07c1ddef7" +checksum = "040b10bb781540585e87a1e9f9a0c4f54f49674114f33aa05c9a50cf3c92e26c" dependencies = [ "alloy-chains", "alloy-consensus", @@ -387,7 +387,7 @@ dependencies = [ "either", "futures", "futures-utils-wasm", - "lru 0.16.0", + "lru 0.13.0", "parking_lot", "pin-project", "reqwest 0.12.23", @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87118d5dc24e682978fb51e3dc1cccb3ef3021e4b98825a357c3efb9256187d5" +checksum = "c353b166a2cfb39167ead4f8ec335acdb439ad2a436245bccc218022fe28ca65" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -447,9 +447,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953599f7a753a6d17296c21b40e15248b69b5845e8764b2fef696e2e012a3f84" +checksum = "9f81c39d47eac1904e378a8079e2903bc1ddb3d9e73d5461c0db6c215d9d7ec1" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -458,9 +458,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177e49c5d9dffbd8a427cbe757e202e5ef71718d5a8ae7d6858b6e3f448131b" +checksum = "b1a21e2b9b9da3f21351b9a34f820aa0580d5709aa821e8bfd26411649750f34" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -479,9 +479,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743e0fe099fe90a07215ae08413b271b8fac12fca6880c85326ce61341566e6f" +checksum = "432bbb99cfa037b8a50deb4128da7bfc3d094a6b2ac6e9220bf89b1408c5e269" dependencies = [ "alloy-primitives", "serde", @@ -490,9 +490,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236cfc2c09ca2af29a2b0e622247c38e47657da97fc9636d5fbe64b6020026c6" +checksum = "e4b97ec9efdf375ada378d03404e8515c4e04694481fbb8c9e636313130fd734" dependencies = [ "alloy-primitives", "async-trait", @@ -505,9 +505,9 @@ dependencies = [ [[package]] name = "alloy-signer-aws" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "544ad11c2e392bdb24e924281636913e7ef1487e21b117a90de72aebf84b974e" +checksum = "2f8b4eb19ae08377f376dc531a9152fbacbbc4c5494b11a26448c7c1b4fdbaee" dependencies = [ "alloy-consensus", "alloy-network", @@ -523,25 +523,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626cdb6bb897a09e74d7e502e1834eac83dc0fd94bbb4c9e2cf342dba7f037a9" -dependencies = [ - "alloy-consensus", - "alloy-network", - "alloy-primitives", - "alloy-signer", - "async-trait", - "k256", - "rand 0.8.5", - "thiserror 2.0.16", -] - -[[package]] -name = "alloy-signer-local" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626cdb6bb897a09e74d7e502e1834eac83dc0fd94bbb4c9e2cf342dba7f037a9" +checksum = "63e6e5b61817be1dfca20a7738eb09c9a85c333ef34ed0ae6946bdff077245fa" dependencies = [ "alloy-consensus", "alloy-network", @@ -628,9 +612,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a568f574d8d11fc054e3a32f19f476fdcc4db9216246b1db0b2ecad157a6f963" +checksum = "7c48ab8f6beec1d32754043ad3b4da077e80ba78fd762acfb16a8460336887a2" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -652,9 +636,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df4c00f7c7c6af5660423e6747d22f04ca7e019371eae2dc6535c17b1d636469" +checksum = "27e6b0b1188a87bbfbb5adf5ad7dcd0744e03fe3184e8ef683ec29846d884bee" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -683,9 +667,9 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40696658bb1ac21f742107185fc2b0f60695598e4f16695e5bd24f4cfc0ddc29" +checksum = "81901009f4ebb0fa0d2b37328ddec6ca420ca06289dddd714bc7ee9be3c86d4b" dependencies = [ "alloy-primitives", "darling 0.21.3", @@ -1930,9 +1914,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.46" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -1940,9 +1924,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.46" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -1952,9 +1936,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2375,21 +2359,6 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "darling_core" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "serde", - "strsim", - "syn 2.0.106", -] - [[package]] name = "darling_macro" version = "0.20.11" @@ -4283,9 +4252,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ea4e65087ff52f3862caff188d489f1fab49a0cb09e01b2e3f1a617b10aaed" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" dependencies = [ "hashbrown 0.15.5", ] @@ -6089,13 +6058,13 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.31.1" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3c81b43dc2d8877c216a3fccf76677ee1ebccd429566d3e67447290d0c42b2" +checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" dependencies = [ "bitcoin_hashes", - "rand 0.9.2", - "secp256k1-sys 0.11.0", + "rand 0.8.5", + "secp256k1-sys 0.10.1", "serde", ] @@ -6110,9 +6079,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.11.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb913707158fadaf0d8702c2db0e857de66eb003ccfdda5924b5f5ac98efb38" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ "cc", ] @@ -7046,9 +7015,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.42" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca967379f9d8eb8058d86ed467d81d03e81acd45757e4ca341c24affbe8e8e3" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" dependencies = [ "deranged", "libc", @@ -7062,15 +7031,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9108bb380861b07264b950ded55a44a14a4adc68b9f5efd85aafc3aa4d40a68" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7182799245a7264ce590b349d90338f1c1affad93d2639aed5f8f69c090b334c" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", diff --git a/Cargo.toml b/Cargo.toml index 401aa7cc99..f200fd2502 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["crates/*"] [workspace.dependencies] -alloy = { version = "1.0.28", default-features = false } +alloy = { version = "1.0.29", default-features = false } anyhow = "=1.0.76" async-trait = "0.1.80" axum = "0.6" From a83ebc9e9ca518a27f4beb9a01a61fbf40b793e2 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 14:37:11 +0300 Subject: [PATCH 28/34] Use the account converter --- crates/e2e/tests/e2e/liquidity.rs | 16 ++++++++++------ crates/ethrpc/src/alloy/mod.rs | 16 ++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index e514376e75..dbc116d664 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -26,8 +26,8 @@ use { ethrpc::{ Web3, alloy::{ - conversions::{IntoAlloy, IntoLegacy}, - provider_with_account, + conversions::{IntoAlloy, IntoLegacy, TryIntoAlloyAsync}, + provider_with_signer, }, }, hex_literal::hex, @@ -77,11 +77,15 @@ async fn zero_ex_liquidity(web3: Web3) { .unwrap(), ); - let signer_pk = match &solver.account() { - Account::Offline(pk, _) => pk.clone(), - _ => unimplemented!(), + let zeroex_provider = { + let signer = solver.account().clone().try_into_alloy().await.unwrap(); + match signer { + ethrpc::alloy::conversions::Account::Signer(signer) => { + provider_with_signer(&web3.node_url, signer).unwrap() + } + ethrpc::alloy::conversions::Account::Address(_) => web3.alloy.clone(), + } }; - let zeroex_provider = provider_with_account(&web3.node_url, &signer_pk).unwrap(); let zeroex = IZeroex::Instance::deployed(&zeroex_provider).await.unwrap(); let amount = to_wei_with_exp(5, 8); diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index dbe0984022..8754e08f89 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -2,21 +2,20 @@ mod buffering; pub mod conversions; mod instrumentation; +#[cfg(any(test, feature = "test-util"))] +use alloy::{network::EthereumWallet, providers::mock}; pub use instrumentation::ProviderLabelingExt; use { crate::AlloyProvider, alloy::{ + network::TxSigner, + primitives::Signature, providers::{Provider, ProviderBuilder}, rpc::client::ClientBuilder, }, buffering::BatchCallLayer, instrumentation::{InstrumentationLayer, LabelingLayer}, }; -#[cfg(any(test, feature = "test-util"))] -use { - alloy::{network::EthereumWallet, providers::mock, signers::local::PrivateKeySigner}, - ethcontract::PrivateKey, -}; pub fn provider(url: &str) -> AlloyProvider { let rpc = ClientBuilder::default() @@ -30,15 +29,16 @@ pub fn provider(url: &str) -> AlloyProvider { } #[cfg(any(test, feature = "test-util"))] -pub fn provider_with_account(url: &str, private_key: &PrivateKey) -> anyhow::Result { +pub fn provider_with_signer( + url: &str, + signer: Box + Send + Sync + 'static>, +) -> anyhow::Result { let rpc = ClientBuilder::default() .layer(LabelingLayer { label: "main".into(), }) .layer(InstrumentationLayer) .http(url.parse()?); - - let signer = PrivateKeySigner::from_slice(&private_key.secret_bytes())?; let wallet = EthereumWallet::new(signer); Ok(ProviderBuilder::new() From 1adb6c433ad687379d834c16e201036996b4d4e4 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 14:40:49 +0300 Subject: [PATCH 29/34] pub use conversions::Account --- crates/e2e/tests/e2e/liquidity.rs | 4 ++-- crates/ethrpc/src/alloy/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index dbc116d664..5b1ce0f024 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -80,10 +80,10 @@ async fn zero_ex_liquidity(web3: Web3) { let zeroex_provider = { let signer = solver.account().clone().try_into_alloy().await.unwrap(); match signer { - ethrpc::alloy::conversions::Account::Signer(signer) => { + ethrpc::alloy::Account::Signer(signer) => { provider_with_signer(&web3.node_url, signer).unwrap() } - ethrpc::alloy::conversions::Account::Address(_) => web3.alloy.clone(), + ethrpc::alloy::Account::Address(_) => web3.alloy.clone(), } }; let zeroex = IZeroex::Instance::deployed(&zeroex_provider).await.unwrap(); diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 8754e08f89..816a01f8d6 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -4,7 +4,6 @@ mod instrumentation; #[cfg(any(test, feature = "test-util"))] use alloy::{network::EthereumWallet, providers::mock}; -pub use instrumentation::ProviderLabelingExt; use { crate::AlloyProvider, alloy::{ @@ -16,6 +15,7 @@ use { buffering::BatchCallLayer, instrumentation::{InstrumentationLayer, LabelingLayer}, }; +pub use {conversions::Account, instrumentation::ProviderLabelingExt}; pub fn provider(url: &str) -> AlloyProvider { let rpc = ClientBuilder::default() From f12d34ba0afcab1dfbb111616e3116212a4419dd Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 16:27:11 +0300 Subject: [PATCH 30/34] ProviderSignerExt --- crates/e2e/tests/e2e/liquidity.rs | 8 ++------ crates/ethrpc/src/alloy/mod.rs | 26 +++++++++++++++++++++++++- crates/ethrpc/src/lib.rs | 3 --- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 5b1ce0f024..50d9df35de 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -26,6 +26,7 @@ use { ethrpc::{ Web3, alloy::{ + ProviderSignerExt, conversions::{IntoAlloy, IntoLegacy, TryIntoAlloyAsync}, provider_with_signer, }, @@ -79,12 +80,7 @@ async fn zero_ex_liquidity(web3: Web3) { let zeroex_provider = { let signer = solver.account().clone().try_into_alloy().await.unwrap(); - match signer { - ethrpc::alloy::Account::Signer(signer) => { - provider_with_signer(&web3.node_url, signer).unwrap() - } - ethrpc::alloy::Account::Address(_) => web3.alloy.clone(), - } + web3.alloy.with_signer(signer) }; let zeroex = IZeroex::Instance::deployed(&zeroex_provider).await.unwrap(); diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 816a01f8d6..0c9936ee51 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -10,7 +10,7 @@ use { network::TxSigner, primitives::Signature, providers::{Provider, ProviderBuilder}, - rpc::client::ClientBuilder, + rpc::client::{ClientBuilder, RpcClient}, }, buffering::BatchCallLayer, instrumentation::{InstrumentationLayer, LabelingLayer}, @@ -54,3 +54,27 @@ pub fn dummy_provider() -> AlloyProvider { .connect_mocked_client(asserter) .erased() } + +pub trait ProviderSignerExt { + /// Creates a new provider with the given signer. + fn with_signer(&self, signer: Account) -> Self; +} + +impl ProviderSignerExt for AlloyProvider { + fn with_signer(&self, signer: Account) -> Self { + let Account::Signer(signer) = signer else { + // Otherwise an unlocked account is used, not need to change anything. + return self.clone(); + }; + + let is_local = self.client().is_local(); + let transport = self.client().transport().clone(); + let wallet = EthereumWallet::new(signer); + let client = RpcClient::new(transport, is_local); + + ProviderBuilder::new() + .wallet(wallet) + .connect_client(client) + .erased() + } +} diff --git a/crates/ethrpc/src/lib.rs b/crates/ethrpc/src/lib.rs index f30bb7c4ae..eea5f99a32 100644 --- a/crates/ethrpc/src/lib.rs +++ b/crates/ethrpc/src/lib.rs @@ -33,7 +33,6 @@ pub type AlloyProvider = DynProvider; pub struct Web3 { pub legacy: web3::Web3, pub alloy: AlloyProvider, - pub node_url: String, } impl std::ops::Deref for Web3 { @@ -57,7 +56,6 @@ impl Web3 { Self { legacy: web3, alloy: crate::alloy::provider(url), - node_url: url.to_string(), } } } @@ -122,7 +120,6 @@ pub fn web3( Web3 { legacy: web3::Web3::new(Web3Transport::new(instrumented)), alloy: alloy::provider(url.as_str()), - node_url: url.to_string(), } } From ffc623effb1e7a72698f9489dfd62b711f834347 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 16:31:43 +0300 Subject: [PATCH 31/34] Fix --- crates/e2e/tests/e2e/liquidity.rs | 1 - crates/ethrpc/src/alloy/mod.rs | 21 --------------------- crates/ethrpc/src/block_stream/mod.rs | 1 - crates/ethrpc/src/instrumented.rs | 1 - crates/ethrpc/src/mock.rs | 1 - 5 files changed, 25 deletions(-) diff --git a/crates/e2e/tests/e2e/liquidity.rs b/crates/e2e/tests/e2e/liquidity.rs index 50d9df35de..2c1468a576 100644 --- a/crates/e2e/tests/e2e/liquidity.rs +++ b/crates/e2e/tests/e2e/liquidity.rs @@ -28,7 +28,6 @@ use { alloy::{ ProviderSignerExt, conversions::{IntoAlloy, IntoLegacy, TryIntoAlloyAsync}, - provider_with_signer, }, }, hex_literal::hex, diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 0c9936ee51..1a4e086881 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -7,8 +7,6 @@ use alloy::{network::EthereumWallet, providers::mock}; use { crate::AlloyProvider, alloy::{ - network::TxSigner, - primitives::Signature, providers::{Provider, ProviderBuilder}, rpc::client::{ClientBuilder, RpcClient}, }, @@ -28,25 +26,6 @@ pub fn provider(url: &str) -> AlloyProvider { ProviderBuilder::new().connect_client(rpc).erased() } -#[cfg(any(test, feature = "test-util"))] -pub fn provider_with_signer( - url: &str, - signer: Box + Send + Sync + 'static>, -) -> anyhow::Result { - let rpc = ClientBuilder::default() - .layer(LabelingLayer { - label: "main".into(), - }) - .layer(InstrumentationLayer) - .http(url.parse()?); - let wallet = EthereumWallet::new(signer); - - Ok(ProviderBuilder::new() - .wallet(wallet) - .connect_client(rpc) - .erased()) -} - #[cfg(any(test, feature = "test-util"))] pub fn dummy_provider() -> AlloyProvider { let asserter = mock::Asserter::new(); diff --git a/crates/ethrpc/src/block_stream/mod.rs b/crates/ethrpc/src/block_stream/mod.rs index f60971c464..7f732b4f16 100644 --- a/crates/ethrpc/src/block_stream/mod.rs +++ b/crates/ethrpc/src/block_stream/mod.rs @@ -129,7 +129,6 @@ pub async fn current_block_stream( legacy: web3, // TODO: replace this with an unbuffered alloy provider alloy: crate::alloy::provider(url.as_str()), - node_url: url.to_string(), }; let web3 = instrument_with_label(&web3, "base_currentBlockStream".into()); diff --git a/crates/ethrpc/src/instrumented.rs b/crates/ethrpc/src/instrumented.rs index 305154001a..d81fc14b0c 100644 --- a/crates/ethrpc/src/instrumented.rs +++ b/crates/ethrpc/src/instrumented.rs @@ -81,7 +81,6 @@ pub fn instrument_with_label(web3: &crate::Web3, label: String) -> crate::Web3 { crate::Web3 { legacy: web3::Web3::new(DynTransport::new(instrumented)), alloy: web3.alloy.labeled(label), - node_url: web3.node_url.clone(), } } diff --git a/crates/ethrpc/src/mock.rs b/crates/ethrpc/src/mock.rs index 3941c9bf9f..514285e883 100644 --- a/crates/ethrpc/src/mock.rs +++ b/crates/ethrpc/src/mock.rs @@ -29,7 +29,6 @@ pub fn web3() -> Web3 { alloy: ProviderBuilder::new() .connect_mocked_client(Asserter::new()) .erased(), - node_url: "mock://".to_string(), } } From 3e84da2e46fbdfe3438aa40c476e0d9ec2c484ee Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 16:33:53 +0300 Subject: [PATCH 32/34] Fix --- crates/ethrpc/src/alloy/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/ethrpc/src/alloy/mod.rs b/crates/ethrpc/src/alloy/mod.rs index 1a4e086881..d3db19bf39 100644 --- a/crates/ethrpc/src/alloy/mod.rs +++ b/crates/ethrpc/src/alloy/mod.rs @@ -3,10 +3,11 @@ pub mod conversions; mod instrumentation; #[cfg(any(test, feature = "test-util"))] -use alloy::{network::EthereumWallet, providers::mock}; +use alloy::providers::mock; use { crate::AlloyProvider, alloy::{ + network::EthereumWallet, providers::{Provider, ProviderBuilder}, rpc::client::{ClientBuilder, RpcClient}, }, From 274204c368727ee7d2ab290a1d09cdc01152e200 Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 3 Sep 2025 16:35:33 +0300 Subject: [PATCH 33/34] Redundant dependency --- crates/e2e/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index b922de1242..51751dfbc2 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -42,7 +42,6 @@ warp = { workspace = true } web3 = { workspace = true, features = ["http"] } [dev-dependencies] -ethrpc = { workspace = true, features = ["test-util"] } refunder = { workspace = true } [lints] From 417b209834b85b4bb2e61440c631842eee1f6eb8 Mon Sep 17 00:00:00 2001 From: ilya Date: Thu, 4 Sep 2025 11:52:52 +0300 Subject: [PATCH 34/34] Alloy v1.0.30 --- Cargo.lock | 134 ++++++++++++++++++++++++++++++++++------------------- Cargo.toml | 2 +- 2 files changed, 87 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 180d7008b2..175a5f2a93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7413bbf62c40b5db916ad5a1c382df1affe42080e148d69932bb7f0a12f32e" +checksum = "2e2a5d689ccd182f1d138a61f081841b905034e0089f5278f6c200f2bcdab00a" dependencies = [ "alloy-consensus", "alloy-contract", @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7345077623aaa080fc06735ac13b8fa335125c8550f9c4f64135a5bf6f79967" +checksum = "d213580c17d239ae83c0d897ac3315db7cda83d2d4936a9823cc3517552f2e24" dependencies = [ "alloy-eips", "alloy-primitives", @@ -148,9 +148,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501f83565d28bdb9d6457dd3b5d646e19db37709d0f27608a26a1839052ddade" +checksum = "81443e3b8dccfeac7cd511aced15928c97ff253f4177acbb97de97178e543f6c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -162,9 +162,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c36bb4173892aeeba1c6b9e4eff923fa3fe8583f6d3e07afe1cbc5a96a853a" +checksum = "de217ab604f1bcfa2e3b0aff86d50812d5931d47522f9f0a949cc263ec2d108e" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c219a87fb386a75780ddbdbbced242477321887e426b0f946c05815ceabe5e09" +checksum = "2a15b4b0f6bab47aae017d52bb5a739bda381553c09fb9918b7172721ef5f5de" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "334555c323fa2bb98f1d4c242b62da9de8c715557a2ed680a76cefbcac19fefd" +checksum = "f8882ec8e4542cfd02aadc6dccbe90caa73038f60016d936734eb6ced53d2167" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ea377c9650203d7a7da9e8dee7f04906b49a9253f554b110edd7972e75ef34" +checksum = "51d6d87d588bda509881a7a66ae77c86514bd1193ac30fbff0e0f24db95eb5a5" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -323,9 +323,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f9ab9a9e92c49a357edaee2d35deea0a32ac8f313cfa37448f04e7e029c9d9" +checksum = "5b14fa9ba5774e0b30ae6a04176d998211d516c8af69c9c530af7c6c42a8c508" dependencies = [ "alloy-consensus", "alloy-eips", @@ -363,9 +363,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a85361c88c16116defbd98053e3d267054d6b82729cdbef0236f7881590f924" +checksum = "475a5141313c3665b75d818be97d5fa3eb5e0abb7e832e9767edd94746db28e3" dependencies = [ "alloy-chains", "alloy-consensus", @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743fc964abb0106e454e9e8683fb0809fb32940270ef586a58e913531360b302" +checksum = "25289674cd8c58fcca2568b5350423cb0dd7bca8c596c5e2869bfe4c5c57ed14" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -447,9 +447,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97372c51a14a804fb9c17010e3dd6c117f7866620b264e24b64d2259be44bcdf" +checksum = "01bac57c987c93773787619e20f89167db74d460a2d1d40f591d94fb7c22c379" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -458,9 +458,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672286c19528007df058bafd82c67e23247b4b3ebbc538cbddc705a82d8a930f" +checksum = "1cd1e1b4dcdf13eaa96343e5c0dafc2d2e8ce5d20b90347169d46a1df0dec210" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -479,9 +479,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aae653f049267ae7e040eab6c9b9a417064ca1a6cb21e3dd59b9f1131ef048f" +checksum = "f1b3b1078b8775077525bc9fe9f6577e815ceaecd6c412a4f3b4d8aa2836e8f6" dependencies = [ "alloy-primitives", "serde", @@ -490,9 +490,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97cedce202f848592b96f7e891503d3adb33739c4e76904da73574290141b93" +checksum = "10ab1b8d4649bf7d0db8ab04e31658a6cc20364d920795484d886c35bed3bab4" dependencies = [ "alloy-primitives", "async-trait", @@ -505,15 +505,16 @@ dependencies = [ [[package]] name = "alloy-signer-aws" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd40e8f6dc5e19a04314714be91b582736964d776a1ef11d665c097a5429a14" +checksum = "a46118173eb381b2911202a83dc4f39267027b0fe7d3533449f5e4ebc0eadcab" dependencies = [ "alloy-consensus", "alloy-network", "alloy-primitives", "alloy-signer", "async-trait", + "aws-config", "aws-sdk-kms", "k256", "spki", @@ -523,9 +524,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ae7d854db5b7cdd5b9ed7ad13d1e5e034cdd8be85ffef081f61dc6c9e18351" +checksum = "7bdeec36c8d9823102b571b3eab8b323e053dc19c12da14a9687bd474129bf2a" dependencies = [ "alloy-consensus", "alloy-network", @@ -612,9 +613,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08b383bc903c927635e39e1dae7df2180877d93352d1abd389883665a598afc" +checksum = "dce5129146a76ca6139a19832c75ad408857a56bcd18cd2c684183b8eacd78d8" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -636,9 +637,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e58dee1f7763ef302074b645fc4f25440637c09a60e8de234b62993f06c0ae3" +checksum = "e2379d998f46d422ec8ef2b61603bc28cda931e5e267aea1ebe71f62da61d101" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -667,12 +668,12 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.27" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14809f908822dbff0dc472c77ca4aa129ab12e22fd9bff2dd1ef54603e68e3d" +checksum = "3b5becb9c269a7d05a2f28d549f86df5a5dbc923e2667eff84fdecac8cda534c" dependencies = [ "alloy-primitives", - "darling", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.104", @@ -2174,8 +2175,18 @@ version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.9", + "darling_macro 0.20.9", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -2192,13 +2203,39 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "serde", + "strsim", + "syn 2.0.104", +] + [[package]] name = "darling_macro" version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ - "darling_core", + "darling_core 0.20.9", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", "quote", "syn 2.0.104", ] @@ -2463,6 +2500,7 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" name = "e2e" version = "1.0.0" dependencies = [ + "alloy", "anyhow", "app-data", "autopilot", @@ -4891,7 +4929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools 0.12.1", "proc-macro2", "quote", "syn 2.0.104", @@ -5672,18 +5710,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -5756,7 +5794,7 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" dependencies = [ - "darling", + "darling 0.20.9", "proc-macro2", "quote", "syn 2.0.104", diff --git a/Cargo.toml b/Cargo.toml index a5032e76b5..144cb6cfef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["crates/*"] [workspace.dependencies] -alloy = { version = "1.0.29", default-features = false } +alloy = { version = "1.0.30", default-features = false } anyhow = "=1.0.76" async-trait = "0.1.80" axum = "0.6"