diff --git a/Cargo.lock b/Cargo.lock index b5f13b9e8e5..80d00071232 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1604,6 +1604,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.1.0", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.4.0" @@ -1778,7 +1797,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.25", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -1801,6 +1820,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.4", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -2780,7 +2800,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.25", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", @@ -2818,8 +2838,10 @@ checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" dependencies = [ "base64 0.21.7", "bytes", + "encoding_rs", "futures-core", "futures-util", + "h2 0.4.4", "http 1.1.0", "http-body 1.0.0", "http-body-util", @@ -2839,6 +2861,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -2867,6 +2890,7 @@ dependencies = [ "ethers-core", "ethers-providers", "indicatif", + "reqwest 0.12.2", "revm-interpreter", "revm-precompile", "serde", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 6b848e64724..28854e0c1c4 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -51,7 +51,7 @@ ethers-contract = { version = "2.0.14", default-features = false } anyhow = "1.0.82" criterion = "0.5" indicatif = "0.17" - +reqwest = { version = "0.12" } alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", default-features = false, features = ["reqwest"] } # needed for enabling TLS to use HTTPS connections when testing alloy DB alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git" } diff --git a/examples/uniswap_v2_usdc_swap.rs b/examples/uniswap_v2_usdc_swap.rs index dfc3441f7d8..9171da10ac7 100644 --- a/examples/uniswap_v2_usdc_swap.rs +++ b/examples/uniswap_v2_usdc_swap.rs @@ -1,15 +1,19 @@ -use alloy_provider::ProviderBuilder; +use alloy_provider::{network::Ethereum, ProviderBuilder, RootProvider}; use alloy_sol_types::{sol, SolCall, SolValue}; +use alloy_transport_http::Http; use anyhow::{anyhow, Result}; +use reqwest::Client; use revm::{ - db::{AlloyDB, CacheDB, EmptyDB, EmptyDBTyped}, + db::{AlloyDB, CacheDB}, primitives::{ address, keccak256, AccountInfo, Address, Bytes, ExecutionResult, Output, TransactTo, U256, }, - Database, Evm, + Evm, }; use std::ops::Div; -use std::{convert::Infallible, sync::Arc}; +use std::sync::Arc; + +type AlloyCacheDB = CacheDB, Ethereum, Arc>>>>; #[tokio::main] async fn main() -> Result<()> { @@ -21,8 +25,7 @@ async fn main() -> Result<()> { ) .unwrap(); let client = Arc::new(client); - let mut alloydb = AlloyDB::new(client, None); - let mut cache_db = CacheDB::new(EmptyDB::default()); + let mut cache_db = CacheDB::new(AlloyDB::new(client, None)); // Random empty account let account = address!("18B06aaF27d44B756FCF16Ca20C1f183EB49111f"); @@ -30,49 +33,9 @@ async fn main() -> Result<()> { let weth = address!("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"); let usdc = address!("a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"); let usdc_weth_pair = address!("B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"); - let uniswap_v2_router = address!("7a250d5630b4cf539739df2c5dacb4c659f2488d"); - - // USDC uses a proxy pattern so we have to fetch implementation address - let usdc_impl_slot: U256 = "0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3" - .parse() - .unwrap(); - let usdc_impl_raw = alloydb.storage(usdc, usdc_impl_slot).unwrap(); - let usdc_impl: Address = format!("{:x}", usdc_impl_raw)[24..].parse().unwrap(); - - // populate basic data - for addr in [weth, usdc, usdc_weth_pair, uniswap_v2_router, usdc_impl] { - let acc_info = alloydb.basic(addr).unwrap().unwrap(); - cache_db.insert_account_info(addr, acc_info); - } - cache_db - .insert_account_storage(usdc, usdc_impl_slot, usdc_impl_raw) - .unwrap(); - - // populate WETH balance for USDC-WETH pair let weth_balance_slot = U256::from(3); - let pair_weth_balance_slot = keccak256((usdc_weth_pair, weth_balance_slot).abi_encode()); - - let value = alloydb - .storage(weth, pair_weth_balance_slot.into()) - .unwrap(); - cache_db - .insert_account_storage(weth, pair_weth_balance_slot.into(), value) - .unwrap(); - - // populate USDC balance for USDC-WETH pair - let usdc_balance_slot = U256::from(9); - - let pair_usdc_balance_slot = keccak256((usdc_weth_pair, usdc_balance_slot).abi_encode()); - - let value = alloydb - .storage(usdc, pair_usdc_balance_slot.into()) - .unwrap(); - cache_db - .insert_account_storage(usdc, pair_usdc_balance_slot.into(), value) - .unwrap(); - // give our test account some fake WETH and ETH let one_ether = U256::from(1_000_000_000_000_000_000u128); let hashed_acc_balance_slot = keccak256((account, weth_balance_slot).abi_encode()); @@ -88,32 +51,12 @@ async fn main() -> Result<()> { }; cache_db.insert_account_info(account, acc_info); - // populate UniswapV2 pair slots - // 6 - token0 - // 7 - token1 - // 8 - (reserve0, reserve1, blockTimestampLast) - // 12 - unlocked - - let usdc_weth_pair_address = usdc_weth_pair; - let pair_acc_info = alloydb.basic(usdc_weth_pair_address).unwrap().unwrap(); - cache_db.insert_account_info(usdc_weth_pair_address, pair_acc_info); - - for i in [6, 7, 8, 12] { - let storage_slot = U256::from(i); - let value = alloydb - .storage(usdc_weth_pair_address, storage_slot) - .unwrap(); - cache_db - .insert_account_storage(usdc_weth_pair_address, storage_slot, value) - .unwrap(); - } - - let acc_weth_balance_before = balance_of(weth, account, &mut cache_db).await?; + let acc_weth_balance_before = balance_of(weth, account, &mut cache_db)?; println!("WETH balance before swap: {}", acc_weth_balance_before); - let acc_usdc_balance_before = balance_of(usdc, account, &mut cache_db).await?; + let acc_usdc_balance_before = balance_of(usdc, account, &mut cache_db)?; println!("USDC balance before swap: {}", acc_usdc_balance_before); - let (reserve0, reserve1) = get_reserves(usdc_weth_pair, &mut cache_db).await?; + let (reserve0, reserve1) = get_reserves(usdc_weth_pair, &mut cache_db)?; let amount_in = one_ether.div(U256::from(10)); @@ -121,7 +64,7 @@ async fn main() -> Result<()> { let amount_out = get_amount_out(amount_in, reserve1, reserve0, &mut cache_db).await?; // transfer WETH to USDC-WETH pair - transfer(account, usdc_weth_pair, amount_in, weth, &mut cache_db).await?; + transfer(account, usdc_weth_pair, amount_in, weth, &mut cache_db)?; // execute low-level swap without using UniswapV2 router swap( @@ -131,22 +74,17 @@ async fn main() -> Result<()> { amount_out, true, &mut cache_db, - ) - .await?; + )?; - let acc_weth_balance_after = balance_of(weth, account, &mut cache_db).await?; + let acc_weth_balance_after = balance_of(weth, account, &mut cache_db)?; println!("WETH balance after swap: {}", acc_weth_balance_after); - let acc_usdc_balance_after = balance_of(usdc, account, &mut cache_db).await?; + let acc_usdc_balance_after = balance_of(usdc, account, &mut cache_db)?; println!("USDC balance after swap: {}", acc_usdc_balance_after); Ok(()) } -async fn balance_of( - token: Address, - address: Address, - cache_db: &mut CacheDB>, -) -> Result { +fn balance_of(token: Address, address: Address, cache_db: &mut AlloyCacheDB) -> Result { sol! { function balanceOf(address account) public returns (uint256); } @@ -184,7 +122,7 @@ async fn get_amount_out( amount_in: U256, reserve_in: U256, reserve_out: U256, - cache_db: &mut CacheDB>, + cache_db: &mut AlloyCacheDB, ) -> Result { let uniswap_v2_router = address!("7a250d5630b4cf539739df2c5dacb4c659f2488d"); sol! { @@ -224,10 +162,7 @@ async fn get_amount_out( Ok(amount_out) } -async fn get_reserves( - pair_address: Address, - cache_db: &mut CacheDB>, -) -> Result<(U256, U256)> { +fn get_reserves(pair_address: Address, cache_db: &mut AlloyCacheDB) -> Result<(U256, U256)> { sol! { function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); } @@ -260,13 +195,13 @@ async fn get_reserves( Ok((reserve0, reserve1)) } -async fn swap( +fn swap( from: Address, pool_address: Address, target: Address, amount_out: U256, is_token0: bool, - cache_db: &mut CacheDB>, + cache_db: &mut AlloyCacheDB, ) -> Result<()> { sol! { function swap(uint amount0Out, uint amount1Out, address target, bytes callback) external; @@ -303,12 +238,12 @@ async fn swap( Ok(()) } -async fn transfer( +fn transfer( from: Address, to: Address, amount: U256, token: Address, - cache_db: &mut CacheDB>, + cache_db: &mut AlloyCacheDB, ) -> Result<()> { sol! { function transfer(address to, uint amount) external returns (bool);