diff --git a/Cargo.lock b/Cargo.lock index 38f6f630699ee..ee89149c5edb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,6 +323,7 @@ dependencies = [ "bytes", "ethers-core", "foundry-evm", + "foundry-utils", "hash-db", "hash256-std-hasher", "keccak-hasher", @@ -1025,6 +1026,7 @@ dependencies = [ "foundry-common", "foundry-config", "foundry-evm", + "foundry-utils", "once_cell", "regex", "reqwest", diff --git a/crates/anvil/core/Cargo.toml b/crates/anvil/core/Cargo.toml index 3b49e4bc5819e..196d5d7f0add8 100644 --- a/crates/anvil/core/Cargo.toml +++ b/crates/anvil/core/Cargo.toml @@ -12,6 +12,7 @@ repository.workspace = true [dependencies] # foundry internal foundry-evm = { path = "../../evm" } +foundry-utils = { path = "../../utils"} revm = { workspace = true, default-features = false, features = ["std", "serde", "memory_limit"] } diff --git a/crates/anvil/core/src/eth/proof.rs b/crates/anvil/core/src/eth/proof.rs index a0714ab29e2df..733cd044f634a 100644 --- a/crates/anvil/core/src/eth/proof.rs +++ b/crates/anvil/core/src/eth/proof.rs @@ -5,7 +5,7 @@ use ethers_core::{ types::{H256, U256}, utils::rlp, }; -use foundry_evm::utils::b256_to_h256; +use foundry_utils::types::ToEthers; use revm::primitives::KECCAK_EMPTY; // reexport for convenience pub use ethers_core::types::{EIP1186ProofResponse as AccountProof, StorageProof}; @@ -29,7 +29,7 @@ impl Default for BasicAccount { BasicAccount { balance: 0.into(), nonce: 0.into(), - code_hash: b256_to_h256(KECCAK_EMPTY), + code_hash: KECCAK_EMPTY.to_ethers(), storage_root: KECCAK_NULL_RLP, } } diff --git a/crates/anvil/core/src/eth/receipt.rs b/crates/anvil/core/src/eth/receipt.rs index 5b3a15eee0690..cebcd0735f629 100644 --- a/crates/anvil/core/src/eth/receipt.rs +++ b/crates/anvil/core/src/eth/receipt.rs @@ -6,7 +6,7 @@ use ethers_core::{ rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}, }, }; -use foundry_evm::utils::{b160_to_h160, b256_to_h256, h160_to_b160, h256_to_b256}; +use foundry_utils::types::{ToAlloy, ToEthers}; #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "fastrlp", derive(open_fastrlp::RlpEncodable, open_fastrlp::RlpDecodable))] @@ -21,8 +21,8 @@ impl From for Log { fn from(log: revm::primitives::Log) -> Self { let revm::primitives::Log { address, topics, data } = log; Log { - address: b160_to_h160(address), - topics: topics.into_iter().map(b256_to_h256).collect(), + address: address.to_ethers(), + topics: topics.into_iter().map(|h| h.to_ethers()).collect(), data: ethers_core::types::Bytes(data.0), } } @@ -32,8 +32,8 @@ impl From for revm::primitives::Log { fn from(log: Log) -> Self { let Log { address, topics, data } = log; revm::primitives::Log { - address: h160_to_b160(address), - topics: topics.into_iter().map(h256_to_b256).collect(), + address: address.to_alloy(), + topics: topics.into_iter().map(|t| t.to_alloy()).collect(), data: alloy_primitives::Bytes(data.0), } } diff --git a/crates/anvil/core/src/eth/transaction/mod.rs b/crates/anvil/core/src/eth/transaction/mod.rs index 159471613c3bf..925f715febae5 100644 --- a/crates/anvil/core/src/eth/transaction/mod.rs +++ b/crates/anvil/core/src/eth/transaction/mod.rs @@ -14,10 +14,8 @@ use ethers_core::{ rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}, }, }; -use foundry_evm::{ - trace::CallTraceArena, - utils::{h160_to_b160, u256_to_ru256}, -}; +use foundry_evm::trace::CallTraceArena; +use foundry_utils::types::ToAlloy; use revm::{ interpreter::InstructionResult, primitives::{CreateScheme, TransactTo, TxEnv}, @@ -1188,7 +1186,7 @@ impl PendingTransaction { pub fn to_revm_tx_env(&self) -> TxEnv { fn transact_to(kind: &TransactionKind) -> TransactTo { match kind { - TransactionKind::Call(c) => TransactTo::Call(h160_to_b160(*c)), + TransactionKind::Call(c) => TransactTo::Call((*c).to_alloy()), TransactionKind::Create => TransactTo::Create(CreateScheme::Create), } } @@ -1199,13 +1197,13 @@ impl PendingTransaction { let chain_id = tx.chain_id(); let LegacyTransaction { nonce, gas_price, gas_limit, value, kind, input, .. } = tx; TxEnv { - caller: h160_to_b160(caller), + caller: caller.to_alloy(), transact_to: transact_to(kind), data: alloy_primitives::Bytes(input.0.clone()), chain_id, nonce: Some(nonce.as_u64()), - value: u256_to_ru256(*value), - gas_price: u256_to_ru256(*gas_price), + value: (*value).to_alloy(), + gas_price: (*gas_price).to_alloy(), gas_priority_fee: None, gas_limit: gas_limit.as_u64(), access_list: vec![], @@ -1225,13 +1223,13 @@ impl PendingTransaction { .. } = tx; TxEnv { - caller: h160_to_b160(caller), + caller: (caller).to_alloy(), transact_to: transact_to(kind), data: alloy_primitives::Bytes(input.0.clone()), chain_id: Some(*chain_id), nonce: Some(nonce.as_u64()), - value: u256_to_ru256(*value), - gas_price: u256_to_ru256(*gas_price), + value: (*value).to_alloy(), + gas_price: (*gas_price).to_alloy(), gas_priority_fee: None, gas_limit: gas_limit.as_u64(), access_list: to_revm_access_list(access_list.0.clone()), @@ -1252,14 +1250,14 @@ impl PendingTransaction { .. } = tx; TxEnv { - caller: h160_to_b160(caller), + caller: (caller).to_alloy(), transact_to: transact_to(kind), data: alloy_primitives::Bytes(input.0.clone()), chain_id: Some(*chain_id), nonce: Some(nonce.as_u64()), - value: u256_to_ru256(*value), - gas_price: u256_to_ru256(*max_fee_per_gas), - gas_priority_fee: Some(u256_to_ru256(*max_priority_fee_per_gas)), + value: (*value).to_alloy(), + gas_price: (*max_fee_per_gas).to_alloy(), + gas_priority_fee: Some((*max_priority_fee_per_gas).to_alloy()), gas_limit: gas_limit.as_u64(), access_list: to_revm_access_list(access_list.0.clone()), ..Default::default() diff --git a/crates/anvil/core/src/eth/utils.rs b/crates/anvil/core/src/eth/utils.rs index 7ee856195cd1f..ffc1286d272a5 100644 --- a/crates/anvil/core/src/eth/utils.rs +++ b/crates/anvil/core/src/eth/utils.rs @@ -6,7 +6,8 @@ use ethers_core::{ rlp::{Encodable, RlpStream}, }, }; -use foundry_evm::utils::{h160_to_b160, h256_to_u256_be, u256_to_ru256}; +use foundry_evm::utils::h256_to_u256_be; +use foundry_utils::types::ToAlloy; pub fn enveloped(id: u8, v: &T, s: &mut RlpStream) { let encoded = rlp::encode(v); @@ -26,8 +27,8 @@ pub fn to_revm_access_list(list: Vec) -> Vec<(rAddress, Vec let gas_limit = if self.disable_block_gas_limit || block.gas_limit.is_zero() { - u256_to_ru256(u64::MAX.into()) + rU256::from(u64::MAX) } else { - u256_to_ru256(block.gas_limit) + block.gas_limit.to_alloy() }; env.block = BlockEnv { number: rU256::from(fork_block_number), - timestamp: u256_to_ru256(block.timestamp), - difficulty: u256_to_ru256(block.difficulty), + timestamp: block.timestamp.to_alloy(), + difficulty: block.difficulty.to_alloy(), // ensures prevrandao is set - prevrandao: Some(block.mix_hash.unwrap_or_default()).map(h256_to_b256), + prevrandao: Some(block.mix_hash.unwrap_or_default()).map(|h| h.to_alloy()), gas_limit, // Keep previous `coinbase` and `basefee` value coinbase: env.block.coinbase, @@ -904,7 +903,7 @@ latest block number: {latest_block}" if self.base_fee.is_none() { if let Some(base_fee) = block.base_fee_per_gas { self.base_fee = Some(base_fee); - env.block.basefee = u256_to_ru256(base_fee); + env.block.basefee = base_fee.to_alloy(); // this is the base fee of the current block, but we need the base fee of // the next block let next_block_base_fee = fees.get_next_block_base_fee_per_gas( @@ -995,7 +994,7 @@ latest block number: {latest_block}" let genesis = GenesisConfig { timestamp: self.get_genesis_timestamp(), - balance: u256_to_ru256(self.genesis_balance), + balance: self.genesis_balance.to_alloy(), accounts: self.genesis_accounts.iter().map(|acc| acc.address()).collect(), fork_genesis_account_infos: Arc::new(Default::default()), genesis_init: self.genesis.clone(), @@ -1019,7 +1018,7 @@ latest block number: {latest_block}" // if the option is not disabled and we are not forking. if !self.disable_default_create2_deployer && self.eth_rpc_url.is_none() { backend - .set_create2_deployer(b160_to_h160(DEFAULT_CREATE2_DEPLOYER)) + .set_create2_deployer(DEFAULT_CREATE2_DEPLOYER.to_ethers()) .await .expect("Failed to create default create2 deployer"); } diff --git a/crates/anvil/src/eth/api.rs b/crates/anvil/src/eth/api.rs index 5c2d107b1ce39..c705ce81ee484 100644 --- a/crates/anvil/src/eth/api.rs +++ b/crates/anvil/src/eth/api.rs @@ -64,8 +64,8 @@ use foundry_evm::{ interpreter::{return_ok, return_revert, InstructionResult}, primitives::BlockEnv, }, - utils::ru256_to_u256, }; +use foundry_utils::types::ToEthers; use futures::channel::mpsc::Receiver; use parking_lot::RwLock; use std::{collections::HashSet, sync::Arc, time::Duration}; @@ -2063,7 +2063,7 @@ impl EthApi { // get the highest possible gas limit, either the request's set value or the currently // configured gas limit - let mut highest_gas_limit = request.gas.unwrap_or(ru256_to_u256(block_env.gas_limit)); + let mut highest_gas_limit = request.gas.unwrap_or(block_env.gas_limit.to_ethers()); // check with the funds of the sender if let Some(from) = request.from { diff --git a/crates/anvil/src/eth/backend/executor.rs b/crates/anvil/src/eth/backend/executor.rs index ddbfb7f9d1931..8cbf6381163df 100644 --- a/crates/anvil/src/eth/backend/executor.rs +++ b/crates/anvil/src/eth/backend/executor.rs @@ -25,11 +25,9 @@ use foundry_evm::{ primitives::{BlockEnv, CfgEnv, EVMError, Env, ExecutionResult, Output, SpecId}, }, trace::{node::CallTraceNode, CallTraceArena}, - utils::{ - b160_to_h160, eval_to_instruction_result, h160_to_b160, halt_to_instruction_result, - ru256_to_u256, - }, + utils::{eval_to_instruction_result, halt_to_instruction_result}, }; +use foundry_utils::types::{ToAlloy, ToEthers}; use std::sync::Arc; use tracing::{trace, warn}; @@ -121,7 +119,7 @@ impl<'a, DB: Db + ?Sized, Validator: TransactionValidator> TransactionExecutor<' let block_number = self.block_env.number; let difficulty = self.block_env.difficulty; let beneficiary = self.block_env.coinbase; - let timestamp = ru256_to_u256(self.block_env.timestamp).as_u64(); + let timestamp = self.block_env.timestamp.to_ethers().as_u64(); let base_fee = if (self.cfg_env.spec_id as u8) >= (SpecId::LONDON as u8) { Some(self.block_env.basefee) } else { @@ -164,7 +162,7 @@ impl<'a, DB: Db + ?Sized, Validator: TransactionValidator> TransactionExecutor<' transaction_index, from: *transaction.pending_transaction.sender(), to: transaction.pending_transaction.transaction.to().copied(), - contract_address: contract_address.map(b160_to_h160), + contract_address: contract_address.map(|c| c.to_ethers()), logs, logs_bloom: *receipt.logs_bloom(), traces: CallTraceArena { arena: traces }, @@ -186,19 +184,19 @@ impl<'a, DB: Db + ?Sized, Validator: TransactionValidator> TransactionExecutor<' let partial_header = PartialHeader { parent_hash, - beneficiary: b160_to_h160(beneficiary), + beneficiary: beneficiary.to_ethers(), state_root: self.db.maybe_state_root().unwrap_or_default(), receipts_root, logs_bloom: bloom, - difficulty: ru256_to_u256(difficulty), - number: ru256_to_u256(block_number), - gas_limit: ru256_to_u256(gas_limit), + difficulty: difficulty.to_ethers(), + number: block_number.to_ethers(), + gas_limit: gas_limit.to_ethers(), gas_used: cumulative_gas_used, timestamp, extra_data: Default::default(), mix_hash: Default::default(), nonce: Default::default(), - base_fee: base_fee.map(ru256_to_u256), + base_fee: base_fee.map(|b| b.to_ethers()), }; let block = Block::new(partial_header, transactions.clone(), ommers); @@ -231,14 +229,14 @@ impl<'a, 'b, DB: Db + ?Sized, Validator: TransactionValidator> Iterator fn next(&mut self) -> Option { let transaction = self.pending.next()?; let sender = *transaction.pending_transaction.sender(); - let account = match self.db.basic(h160_to_b160(sender)).map(|acc| acc.unwrap_or_default()) { + let account = match self.db.basic(sender.to_alloy()).map(|acc| acc.unwrap_or_default()) { Ok(account) => account, Err(err) => return Some(TransactionExecutionOutcome::DatabaseError(transaction, err)), }; let env = self.env_for(&transaction.pending_transaction); // check that we comply with the block's gas limit let max_gas = self.gas_used.saturating_add(U256::from(env.tx.gas_limit)); - if max_gas > ru256_to_u256(env.block.gas_limit) { + if max_gas > env.block.gas_limit.to_ethers() { return Some(TransactionExecutionOutcome::Exhausted(transaction)) } diff --git a/crates/anvil/src/eth/backend/genesis.rs b/crates/anvil/src/eth/backend/genesis.rs index 25cc3207dc97a..a9bca220ec016 100644 --- a/crates/anvil/src/eth/backend/genesis.rs +++ b/crates/anvil/src/eth/backend/genesis.rs @@ -15,8 +15,8 @@ use foundry_evm::{ DatabaseRef, }, revm::primitives::{AccountInfo, Bytecode, KECCAK_EMPTY}, - utils::{b160_to_h160, ru256_to_u256, u256_to_ru256}, }; +use foundry_utils::types::{ToAlloy, ToEthers}; use parking_lot::Mutex; use std::{collections::HashMap, sync::Arc}; use tokio::sync::RwLockWriteGuard; @@ -104,7 +104,7 @@ pub(crate) struct AtGenesisStateDb<'a> { impl<'a> DatabaseRef for AtGenesisStateDb<'a> { type Error = DatabaseError; fn basic(&self, address: B160) -> DatabaseResult> { - if let Some(acc) = self.accounts.get(&b160_to_h160(address)).cloned() { + if let Some(acc) = self.accounts.get(&(address.to_ethers())).cloned() { return Ok(Some(acc)) } self.db.basic(address) @@ -121,14 +121,14 @@ impl<'a> DatabaseRef for AtGenesisStateDb<'a> { if let Some(acc) = self .genesis .as_ref() - .and_then(|genesis| genesis.alloc.accounts.get(&b160_to_h160(address))) + .and_then(|genesis| genesis.alloc.accounts.get(&(address.to_ethers()))) { let value = acc .storage - .get(&H256::from_uint(&ru256_to_u256(index))) + .get(&H256::from_uint(&(index.to_ethers()))) .copied() .unwrap_or_default(); - return Ok(u256_to_ru256(value.into_uint())) + return Ok(value.into_uint().to_alloy()) } self.db.storage(address, index) } diff --git a/crates/anvil/src/eth/backend/mem/fork_db.rs b/crates/anvil/src/eth/backend/mem/fork_db.rs index bb6b4e1bd91f4..caff8da45a8cc 100644 --- a/crates/anvil/src/eth/backend/mem/fork_db.rs +++ b/crates/anvil/src/eth/backend/mem/fork_db.rs @@ -13,8 +13,8 @@ use foundry_evm::{ fork::database::ForkDbSnapshot, }, revm::Database, - utils::{b160_to_h160, h160_to_b160, h256_to_b256, ru256_to_u256, u256_to_ru256}, }; +use foundry_utils::types::{ToAlloy, ToEthers}; /// Implement the helper for the fork database impl Db for ForkedDatabase { @@ -24,12 +24,12 @@ impl Db for ForkedDatabase { fn set_storage_at(&mut self, address: Address, slot: U256, val: U256) -> DatabaseResult<()> { // this ensures the account is loaded first - let _ = Database::basic(self, h160_to_b160(address))?; + let _ = Database::basic(self, address.to_alloy())?; self.database_mut().set_storage_at(address, slot, val) } fn insert_block_hash(&mut self, number: U256, hash: H256) { - self.inner().block_hashes().write().insert(u256_to_ru256(number), h256_to_b256(hash)); + self.inner().block_hashes().write().insert(number.to_alloy(), hash.to_alloy()); } fn dump_state(&self) -> DatabaseResult> { @@ -47,15 +47,15 @@ impl Db for ForkedDatabase { } .to_checked(); Ok(( - b160_to_h160(k), + k.to_ethers(), SerializableAccountRecord { nonce: v.info.nonce, - balance: ru256_to_u256(v.info.balance), + balance: v.info.balance.to_ethers(), code: code.bytes()[..code.len()].to_vec().into(), storage: v .storage .into_iter() - .map(|kv| (ru256_to_u256(kv.0), ru256_to_u256(kv.1))) + .map(|kv| (kv.0.to_ethers(), kv.1.to_ethers())) .collect(), }, )) @@ -65,11 +65,11 @@ impl Db for ForkedDatabase { } fn snapshot(&mut self) -> U256 { - ru256_to_u256(self.insert_snapshot()) + self.insert_snapshot().to_ethers() } fn revert(&mut self, id: U256) -> bool { - self.revert_snapshot(u256_to_ru256(id)) + self.revert_snapshot(id.to_alloy()) } fn current_state(&self) -> StateDb { diff --git a/crates/anvil/src/eth/backend/mem/in_memory_db.rs b/crates/anvil/src/eth/backend/mem/in_memory_db.rs index 23733f168a38e..cd23529166185 100644 --- a/crates/anvil/src/eth/backend/mem/in_memory_db.rs +++ b/crates/anvil/src/eth/backend/mem/in_memory_db.rs @@ -9,7 +9,7 @@ use crate::{ Address, U256, }; use ethers::prelude::H256; -use foundry_evm::utils::{b160_to_h160, h160_to_b160, h256_to_b256, ru256_to_u256, u256_to_ru256}; +use foundry_utils::types::{ToAlloy, ToEthers}; use tracing::{trace, warn}; // reexport for convenience @@ -19,19 +19,15 @@ pub use foundry_evm::executor::{backend::MemDb, DatabaseRef}; impl Db for MemDb { fn insert_account(&mut self, address: Address, account: AccountInfo) { - self.inner.insert_account_info(h160_to_b160(address), account) + self.inner.insert_account_info(address.to_alloy(), account) } fn set_storage_at(&mut self, address: Address, slot: U256, val: U256) -> DatabaseResult<()> { - self.inner.insert_account_storage( - h160_to_b160(address), - u256_to_ru256(slot), - u256_to_ru256(val), - ) + self.inner.insert_account_storage(address.to_alloy(), slot.to_alloy(), val.to_alloy()) } fn insert_block_hash(&mut self, number: U256, hash: H256) { - self.inner.block_hashes.insert(u256_to_ru256(number), h256_to_b256(hash)); + self.inner.block_hashes.insert(number.to_alloy(), hash.to_alloy()); } fn dump_state(&self) -> DatabaseResult> { @@ -48,15 +44,15 @@ impl Db for MemDb { } .to_checked(); Ok(( - b160_to_h160(k), + k.to_ethers(), SerializableAccountRecord { nonce: v.info.nonce, - balance: ru256_to_u256(v.info.balance), + balance: v.info.balance.to_ethers(), code: code.bytes()[..code.len()].to_vec().into(), storage: v .storage .into_iter() - .map(|k| (ru256_to_u256(k.0), ru256_to_u256(k.1))) + .map(|k| (k.0.to_ethers(), k.1.to_ethers())) .collect(), }, )) @@ -70,11 +66,11 @@ impl Db for MemDb { fn snapshot(&mut self) -> U256 { let id = self.snapshots.insert(self.inner.clone()); trace!(target: "backend::memdb", "Created new snapshot {}", id); - ru256_to_u256(id) + id.to_ethers() } fn revert(&mut self, id: U256) -> bool { - if let Some(snapshot) = self.snapshots.remove(u256_to_ru256(id)) { + if let Some(snapshot) = self.snapshots.remove(id.to_alloy()) { self.inner = snapshot; trace!(target: "backend::memdb", "Reverted snapshot {}", id); true @@ -99,7 +95,7 @@ impl MaybeHashDatabase for MemDb { } fn maybe_account_db(&self, addr: Address) -> Option<(AsHashDB, H256)> { - if let Some(acc) = self.inner.accounts.get(&h160_to_b160(addr)) { + if let Some(acc) = self.inner.accounts.get(&addr.to_alloy()) { Some(storage_trie_db(&acc.storage)) } else { Some(storage_trie_db(&Default::default())) @@ -132,8 +128,8 @@ mod tests { use foundry_evm::{ executor::{backend::MemDb, DatabaseRef}, revm::primitives::{Bytecode, KECCAK_EMPTY}, - utils::h160_to_b160, }; + use foundry_utils::types::ToAlloy; use std::{collections::BTreeMap, str::FromStr}; // verifies that all substantial aspects of a loaded account remain the state after an account @@ -167,13 +163,13 @@ mod tests { load_db.load_state(state).unwrap(); - let loaded_account = load_db.basic(h160_to_b160(test_addr)).unwrap().unwrap(); + let loaded_account = load_db.basic(test_addr.to_alloy()).unwrap().unwrap(); assert_eq!(loaded_account.balance, rU256::from(123456)); assert_eq!(load_db.code_by_hash(loaded_account.code_hash).unwrap(), contract_code); assert_eq!(loaded_account.nonce, 1234); assert_eq!( - load_db.storage(h160_to_b160(test_addr), rU256::from(1234567)).unwrap(), + load_db.storage(test_addr.to_alloy(), rU256::from(1234567)).unwrap(), rU256::from(1) ); } @@ -233,21 +229,15 @@ mod tests { db.load_state(new_state).unwrap(); - let loaded_account = db.basic(h160_to_b160(test_addr)).unwrap().unwrap(); - let loaded_account2 = db.basic(h160_to_b160(test_addr2)).unwrap().unwrap(); + let loaded_account = db.basic(test_addr.to_alloy()).unwrap().unwrap(); + let loaded_account2 = db.basic(test_addr2.to_alloy()).unwrap().unwrap(); assert_eq!(loaded_account2.nonce, 1); assert_eq!(loaded_account.balance, rU256::from(100100)); assert_eq!(db.code_by_hash(loaded_account.code_hash).unwrap(), contract_code); assert_eq!(loaded_account.nonce, 1234); - assert_eq!( - db.storage(h160_to_b160(test_addr), rU256::from(1234567)).unwrap(), - rU256::from(1) - ); - assert_eq!( - db.storage(h160_to_b160(test_addr), rU256::from(1234568)).unwrap(), - rU256::from(5) - ); + assert_eq!(db.storage(test_addr.to_alloy(), rU256::from(1234567)).unwrap(), rU256::from(1)); + assert_eq!(db.storage(test_addr.to_alloy(), rU256::from(1234568)).unwrap(), rU256::from(5)); } } diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs index b04dde23f98c9..2cd1cf35de3a1 100644 --- a/crates/anvil/src/eth/backend/mem/mod.rs +++ b/crates/anvil/src/eth/backend/mem/mod.rs @@ -71,11 +71,9 @@ use foundry_evm::{ TransactTo, TxEnv, KECCAK_EMPTY, }, }, - utils::{ - b160_to_h160, eval_to_instruction_result, h160_to_b160, h256_to_b256, - halt_to_instruction_result, ru256_to_u256, u256_to_h256_be, u256_to_ru256, - }, + utils::{eval_to_instruction_result, halt_to_instruction_result, u256_to_h256_be}, }; +use foundry_utils::types::{ToAlloy, ToEthers}; use futures::channel::mpsc::{unbounded, UnboundedSender}; use hash_db::HashDB; use parking_lot::{Mutex, RwLock}; @@ -264,7 +262,7 @@ impl Backend { // accounts concurrently by spawning the job to a new task genesis_accounts_futures.push(tokio::task::spawn(async move { let db = db.read().await; - let info = db.basic(h160_to_b160(address))?.unwrap_or_default(); + let info = db.basic(address.to_alloy())?.unwrap_or_default(); Ok::<_, DatabaseError>((address, info)) })); } @@ -338,7 +336,7 @@ impl Backend { /// Returns the `AccountInfo` from the database pub async fn get_account(&self, address: Address) -> DatabaseResult { - Ok(self.db.read().await.basic(h160_to_b160(address))?.unwrap_or_default()) + Ok(self.db.read().await.basic(address.to_alloy())?.unwrap_or_default()) } /// Whether we're forked off some remote client @@ -369,18 +367,18 @@ impl Backend { env.block = BlockEnv { number: rU256::from(fork_block_number), - timestamp: u256_to_ru256(fork_block.timestamp), - gas_limit: u256_to_ru256(fork_block.gas_limit), - difficulty: u256_to_ru256(fork_block.difficulty), - prevrandao: fork_block.mix_hash.map(h256_to_b256), + timestamp: fork_block.timestamp.to_alloy(), + gas_limit: fork_block.gas_limit.to_alloy(), + difficulty: fork_block.difficulty.to_alloy(), + prevrandao: fork_block.mix_hash.map(|h| h.to_alloy()), // Keep previous `coinbase` and `basefee` value coinbase: env.block.coinbase, basefee: env.block.basefee, ..Default::default() }; - self.time.reset(ru256_to_u256(env.block.timestamp).as_u64()); - self.fees.set_base_fee(ru256_to_u256(env.block.basefee)); + self.time.reset((env.block.timestamp.to_ethers()).as_u64()); + self.fees.set_base_fee(env.block.basefee.to_ethers()); // also reset the total difficulty self.blockchain.storage.write().total_difficulty = fork.total_difficulty(); @@ -451,12 +449,12 @@ impl Backend { /// Sets the block number pub fn set_block_number(&self, number: U256) { let mut env = self.env.write(); - env.block.number = u256_to_ru256(number); + env.block.number = number.to_alloy(); } /// Returns the client coinbase address. pub fn coinbase(&self) -> Address { - b160_to_h160(self.env.read().block.coinbase) + self.env.read().block.coinbase.to_ethers() } /// Returns the client coinbase address. @@ -466,7 +464,7 @@ impl Backend { /// Returns balance of the given account. pub async fn current_balance(&self, address: Address) -> DatabaseResult { - Ok(self.get_account(address).await?.balance).map(ru256_to_u256) + Ok(self.get_account(address).await?.balance.to_ethers()) } /// Returns balance of the given account. @@ -476,7 +474,7 @@ impl Backend { /// Sets the coinbase address pub fn set_coinbase(&self, address: Address) { - self.env.write().block.coinbase = h160_to_b160(address); + self.env.write().block.coinbase = address.to_alloy(); } /// Sets the nonce of the given address @@ -542,12 +540,12 @@ impl Backend { /// Returns the block gas limit pub fn gas_limit(&self) -> U256 { - ru256_to_u256(self.env.read().block.gas_limit) + self.env.read().block.gas_limit.to_ethers() } /// Sets the block gas limit pub fn set_gas_limit(&self, gas_limit: U256) { - self.env.write().block.gas_limit = u256_to_ru256(gas_limit); + self.env.write().block.gas_limit = gas_limit.to_alloy(); } /// Returns the current base fee @@ -686,7 +684,7 @@ impl Backend { let mut env = self.env.read().clone(); // increase block number for this block env.block.number = env.block.number.saturating_add(rU256::from(1)); - env.block.basefee = u256_to_ru256(self.base_fee()); + env.block.basefee = self.base_fee().to_alloy(); env.block.timestamp = rU256::from(self.time.current_call_timestamp()); env } @@ -713,7 +711,7 @@ impl Backend { }; let state = result_and_state.state; let state: revm::primitives::HashMap = - state.into_iter().map(|kv| (b160_to_h160(kv.0), kv.1)).collect(); + state.into_iter().map(|kv| (kv.0.to_ethers(), kv.1)).collect(); let (exit_reason, gas_used, out, logs) = match result_and_state.result { ExecutionResult::Success { reason, gas_used, logs, output, .. } => { (eval_to_instruction_result(reason), gas_used, Some(output), Some(logs)) @@ -802,7 +800,7 @@ impl Backend { // increase block number for this block env.block.number = env.block.number.saturating_add(rU256::from(1)); - env.block.basefee = u256_to_ru256(current_base_fee); + env.block.basefee = current_base_fee.to_alloy(); env.block.timestamp = rU256::from(self.time.next_timestamp()); let best_hash = self.blockchain.storage.read().best_hash; @@ -839,7 +837,7 @@ impl Backend { let BlockInfo { block, transactions, receipts } = block; let header = block.header.clone(); - let block_number: U64 = ru256_to_u256(env.block.number).as_u64().into(); + let block_number: U64 = (env.block.number.to_ethers()).as_u64().into(); trace!( target: "backend", @@ -985,7 +983,7 @@ impl Backend { overrides: Option, ) -> Result<(InstructionResult, Option, u64, State), BlockchainError> { self.with_database_at(block_request, |state, block| { - let block_number = ru256_to_u256(block.number).as_u64(); + let block_number = (block.number.to_ethers()).as_u64(); let (exit, out, gas, state) = match overrides { None => self.call_with_state(state, request, fee_details, block), Some(overrides) => { @@ -1008,7 +1006,7 @@ impl Backend { let FeeDetails { gas_price, max_fee_per_gas, max_priority_fee_per_gas } = fee_details; - let gas_limit = gas.unwrap_or(ru256_to_u256(block_env.gas_limit)); + let gas_limit = gas.unwrap_or(block_env.gas_limit.to_ethers()); let mut env = self.env.read().clone(); env.block = block_env; // we want to disable this in eth_call, since this is common practice used by other node @@ -1016,22 +1014,22 @@ impl Backend { env.cfg.disable_block_gas_limit = true; if let Some(base) = max_fee_per_gas { - env.block.basefee = u256_to_ru256(base); + env.block.basefee = base.to_alloy(); } let gas_price = gas_price.or(max_fee_per_gas).unwrap_or_else(|| self.gas_price()); let caller = from.unwrap_or_default(); env.tx = TxEnv { - caller: h160_to_b160(caller), + caller: caller.to_alloy(), gas_limit: gas_limit.as_u64(), - gas_price: u256_to_ru256(gas_price), - gas_priority_fee: max_priority_fee_per_gas.map(u256_to_ru256), + gas_price: gas_price.to_alloy(), + gas_priority_fee: max_priority_fee_per_gas.map(|f| f.to_alloy()), transact_to: match to { - Some(addr) => TransactTo::Call(h160_to_b160(addr)), + Some(addr) => TransactTo::Call(addr.to_alloy()), None => TransactTo::Create(CreateScheme::Create), }, - value: value.map(u256_to_ru256).unwrap_or_default(), + value: value.unwrap_or_default().to_alloy(), data: data.unwrap_or_default().to_vec().into(), chain_id: None, nonce: nonce.map(|n| n.as_u64()), @@ -1075,7 +1073,7 @@ impl Backend { }; let state = result_and_state.state; let state: revm::primitives::HashMap = - state.into_iter().map(|kv| (b160_to_h160(kv.0), kv.1)).collect(); + state.into_iter().map(|kv| (kv.0.to_ethers(), kv.1)).collect(); let (exit_reason, gas_used, out) = match result_and_state.result { ExecutionResult::Success { reason, gas_used, output, .. } => { (eval_to_instruction_result(reason), gas_used, Some(output)) @@ -1141,15 +1139,15 @@ impl Backend { let to = if let Some(to) = request.to { to } else { - let nonce = state.basic(h160_to_b160(from))?.unwrap_or_default().nonce; + let nonce = state.basic(from.to_alloy())?.unwrap_or_default().nonce; get_contract_address(from, nonce) }; let mut tracer = AccessListTracer::new( AccessList(request.access_list.clone().unwrap_or_default()), - h160_to_b160(from), - h160_to_b160(to), - self.precompiles().into_iter().map(h160_to_b160).collect(), + from.to_alloy(), + to.to_alloy(), + self.precompiles().into_iter().map(|p| p.to_alloy()).collect(), ); let mut evm = revm::EVM::new(); @@ -1588,15 +1586,13 @@ impl Backend { .with_pending_block(pool_transactions, |state, block| { let block = block.block; let block = BlockEnv { - number: u256_to_ru256(block.header.number), - coinbase: h160_to_b160(block.header.beneficiary), + number: block.header.number.to_alloy(), + coinbase: block.header.beneficiary.to_alloy(), timestamp: rU256::from(block.header.timestamp), - difficulty: u256_to_ru256(block.header.difficulty), - prevrandao: Some(block.header.mix_hash).map(h256_to_b256), - basefee: u256_to_ru256( - block.header.base_fee_per_gas.unwrap_or_default(), - ), - gas_limit: u256_to_ru256(block.header.gas_limit), + difficulty: block.header.difficulty.to_alloy(), + prevrandao: Some(block.header.mix_hash).map(|h| h.to_alloy()), + basefee: block.header.base_fee_per_gas.unwrap_or_default().to_alloy(), + gas_limit: block.header.gas_limit.to_alloy(), ..Default::default() }; f(state, block) @@ -1609,7 +1605,7 @@ impl Backend { }; let block_number: U256 = self.convert_block_number(block_number).into(); - if u256_to_ru256(block_number) < self.env.read().block.number { + if block_number.to_alloy() < self.env.read().block.number { { let mut states = self.states.write(); @@ -1618,13 +1614,13 @@ impl Backend { .and_then(|block| Some((states.get(&block.header.hash())?, block))) { let block = BlockEnv { - number: u256_to_ru256(block.header.number), - coinbase: h160_to_b160(block.header.beneficiary), + number: block.header.number.to_alloy(), + coinbase: block.header.beneficiary.to_alloy(), timestamp: rU256::from(block.header.timestamp), - difficulty: u256_to_ru256(block.header.difficulty), - prevrandao: Some(block.header.mix_hash).map(h256_to_b256), - basefee: u256_to_ru256(block.header.base_fee_per_gas.unwrap_or_default()), - gas_limit: u256_to_ru256(block.header.gas_limit), + difficulty: block.header.difficulty.to_alloy(), + prevrandao: Some(block.header.mix_hash).map(|h| h.to_alloy()), + basefee: block.header.base_fee_per_gas.unwrap_or_default().to_alloy(), + gas_limit: block.header.gas_limit.to_alloy(), ..Default::default() }; return Ok(f(Box::new(state), block)) @@ -1642,9 +1638,9 @@ impl Backend { let db = self.db.read().await; let gen_db = self.genesis.state_db_at_genesis(Box::new(&*db)); - block.number = u256_to_ru256(block_number); + block.number = block_number.to_alloy(); block.timestamp = rU256::from(fork.timestamp()); - block.basefee = u256_to_ru256(fork.base_fee().unwrap_or_default()); + block.basefee = fork.base_fee().unwrap_or_default().to_alloy(); return Ok(f(Box::new(&gen_db), block)) } @@ -1652,7 +1648,7 @@ impl Backend { warn!(target: "backend", "Not historic state found for block={}", block_number); return Err(BlockchainError::BlockOutOfRange( - ru256_to_u256(self.env.read().block.number).as_u64(), + self.env.read().block.number.to_ethers().as_u64(), block_number.as_u64(), )) } @@ -1670,8 +1666,8 @@ impl Backend { ) -> Result { self.with_database_at(block_request, |db, _| { trace!(target: "backend", "get storage for {:?} at {:?}", address, index); - let val = db.storage(h160_to_b160(address), u256_to_ru256(index))?; - Ok(u256_to_h256_be(ru256_to_u256(val))) + let val = db.storage(address.to_alloy(), index.to_alloy())?; + Ok(u256_to_h256_be(val.to_ethers())) }) .await? } @@ -1697,7 +1693,7 @@ impl Backend { D: DatabaseRef, { trace!(target: "backend", "get code for {:?}", address); - let account = state.basic(h160_to_b160(address))?.unwrap_or_default(); + let account = state.basic(address.to_alloy())?.unwrap_or_default(); if account.code_hash == KECCAK_EMPTY { // if the code hash is `KECCAK_EMPTY`, we check no further return Ok(Default::default()) @@ -1731,7 +1727,7 @@ impl Backend { D: DatabaseRef, { trace!(target: "backend", "get balance for {:?}", address); - Ok(state.basic(h160_to_b160(address))?.unwrap_or_default().balance).map(ru256_to_u256) + Ok(state.basic(address.to_alloy())?.unwrap_or_default().balance.to_ethers()) } /// Returns the nonce of the address @@ -1754,7 +1750,7 @@ impl Backend { }; self.with_database_at(final_block_request, |db, _| { trace!(target: "backend", "get nonce for {:?}", address); - Ok(db.basic(h160_to_b160(address))?.unwrap_or_default().nonce.into()) + Ok(db.basic(address.to_alloy())?.unwrap_or_default().nonce.into()) }) .await? } @@ -2196,7 +2192,7 @@ impl TransactionValidator for Backend { } // Check gas limit, iff block gas limit is set. - if !env.cfg.disable_block_gas_limit && tx.gas_limit() > ru256_to_u256(env.block.gas_limit) { + if !env.cfg.disable_block_gas_limit && tx.gas_limit() > env.block.gas_limit.to_ethers() { warn!(target: "backend", "[{:?}] gas too high", tx.hash()); return Err(InvalidTransactionError::GasTooHigh(ErrDetail { detail: String::from("tx.gas_limit > env.block.gas_limit"), @@ -2212,7 +2208,7 @@ impl TransactionValidator for Backend { } if (env.cfg.spec_id as u8) >= (SpecId::LONDON as u8) { - if tx.gas_price() < ru256_to_u256(env.block.basefee) { + if tx.gas_price() < env.block.basefee.to_ethers() { warn!(target: "backend", "max fee per gas={}, too low, block basefee={}",tx.gas_price(), env.block.basefee); return Err(InvalidTransactionError::FeeCapTooLow) } @@ -2236,7 +2232,7 @@ impl TransactionValidator for Backend { InvalidTransactionError::InsufficientFunds })?; - if account.balance < u256_to_ru256(req_funds) { + if account.balance < req_funds.to_alloy() { warn!(target: "backend", "[{:?}] insufficient allowance={}, required={} account={:?}", tx.hash(), account.balance, req_funds, *pending.sender()); return Err(InvalidTransactionError::InsufficientFunds) } diff --git a/crates/anvil/src/eth/backend/mem/state.rs b/crates/anvil/src/eth/backend/mem/state.rs index ad90b6bddb192..81e2789a42b84 100644 --- a/crates/anvil/src/eth/backend/mem/state.rs +++ b/crates/anvil/src/eth/backend/mem/state.rs @@ -5,7 +5,6 @@ use alloy_primitives::{Address as rAddress, U256 as rU256}; use anvil_core::eth::{state::StateOverride, trie::RefSecTrieDBMut}; use bytes::Bytes; use ethers::{ - abi::ethereum_types::BigEndianHash, types::H256, utils::{rlp, rlp::RlpStream}, }; @@ -15,9 +14,9 @@ use foundry_evm::{ db::{CacheDB, DbAccount}, primitives::{AccountInfo, Bytecode, Log}, }, - utils::{b160_to_h160, b256_to_h256, h160_to_b160, ru256_to_u256, u256_to_ru256}, HashMap as Map, }; +use foundry_utils::types::{ToAlloy, ToEthers}; use memory_db::HashKey; use trie_db::TrieMut; @@ -28,9 +27,9 @@ pub fn log_rlp_hash(logs: Vec) -> H256 { let mut stream = RlpStream::new(); stream.begin_unbounded_list(); for log in logs { - let topics = log.topics.into_iter().map(b256_to_h256).collect::>(); + let topics = log.topics.into_iter().map(|t| t.to_ethers()).collect::>(); stream.begin_list(3); - stream.append(&b160_to_h160(log.address)); + stream.append(&(log.address.to_ethers())); stream.append_list(&topics); stream.append(&log.data.0); } @@ -51,9 +50,9 @@ pub fn storage_trie_db(storage: &Map) -> (AsHashDB, H256) { let mut trie = RefSecTrieDBMut::new(&mut db, &mut root); for (k, v) in storage.iter().filter(|(_k, v)| *v != &rU256::from(0)) { let mut temp: [u8; 32] = [0; 32]; - ru256_to_u256(*k).to_big_endian(&mut temp); + (*k).to_ethers().to_big_endian(&mut temp); let key = H256::from(temp); - let value = rlp::encode(&ru256_to_u256(*v)); + let value = rlp::encode(&(*v).to_ethers()); trie.insert(key.as_bytes(), value.as_ref()).unwrap(); } } @@ -102,7 +101,7 @@ pub fn state_merkle_trie_root(accounts: &Map) -> H256 { pub fn trie_account_rlp(info: &AccountInfo, storage: &Map) -> Bytes { let mut stream = RlpStream::new_list(4); stream.append(&info.nonce); - stream.append(&ru256_to_u256(info.balance)); + stream.append(&info.balance.to_ethers()); stream.append(&storage_trie_db(storage).1); stream.append(&info.code_hash.as_slice()); stream.out().freeze() @@ -118,7 +117,7 @@ where { let mut cache_db = CacheDB::new(state); for (account, account_overrides) in overrides.iter() { - let mut account_info = cache_db.basic(h160_to_b160(*account))?.unwrap_or_default(); + let mut account_info = cache_db.basic((*account).to_alloy())?.unwrap_or_default(); if let Some(nonce) = account_overrides.nonce { account_info.nonce = nonce; @@ -127,10 +126,10 @@ where account_info.code = Some(Bytecode::new_raw(code.to_vec().into())); } if let Some(balance) = account_overrides.balance { - account_info.balance = u256_to_ru256(balance); + account_info.balance = balance.to_alloy(); } - cache_db.insert_account_info(h160_to_b160(*account), account_info); + cache_db.insert_account_info((*account).to_alloy(), account_info); // We ensure that not both state and state_diff are set. // If state is set, we must mark the account as "NewlyCreated", so that the old storage @@ -144,21 +143,19 @@ where (None, None) => (), (Some(new_account_state), None) => { cache_db.replace_account_storage( - h160_to_b160(*account), + (*account).to_alloy(), new_account_state .iter() - .map(|(key, value)| { - (u256_to_ru256(key.into_uint()), u256_to_ru256(value.into_uint())) - }) + .map(|(key, value)| (key.to_alloy().into(), (value.to_alloy().into()))) .collect(), )?; } (None, Some(account_state_diff)) => { for (key, value) in account_state_diff.iter() { cache_db.insert_account_storage( - h160_to_b160(*account), - u256_to_ru256(key.into_uint()), - u256_to_ru256(value.into_uint()), + (*account).to_alloy(), + key.to_alloy().into(), + value.to_alloy().into(), )?; } } diff --git a/crates/anvil/src/eth/backend/mem/storage.rs b/crates/anvil/src/eth/backend/mem/storage.rs index bbd379c30fe50..39b885e47f5f2 100644 --- a/crates/anvil/src/eth/backend/mem/storage.rs +++ b/crates/anvil/src/eth/backend/mem/storage.rs @@ -15,10 +15,8 @@ use ethers::{ prelude::{BlockId, BlockNumber, DefaultFrame, Trace, H256, H256 as TxHash, U64}, types::{ActionType, Bytes, GethDebugTracingOptions, TransactionReceipt, U256}, }; -use foundry_evm::{ - revm::{interpreter::InstructionResult, primitives::Env}, - utils::{b160_to_h160, ru256_to_u256}, -}; +use foundry_evm::revm::{interpreter::InstructionResult, primitives::Env}; +use foundry_utils::types::ToEthers; use parking_lot::RwLock; use std::{ collections::{HashMap, VecDeque}, @@ -229,9 +227,9 @@ impl BlockchainStorage { let partial_header = PartialHeader { timestamp, base_fee, - gas_limit: ru256_to_u256(env.block.gas_limit), - beneficiary: b160_to_h160(env.block.coinbase), - difficulty: ru256_to_u256(env.block.difficulty), + gas_limit: env.block.gas_limit.to_ethers(), + beneficiary: env.block.coinbase.to_ethers(), + difficulty: env.block.difficulty.to_ethers(), ..Default::default() }; let block = Block::new::(partial_header, vec![], vec![]); @@ -432,8 +430,8 @@ mod tests { db::DatabaseRef, primitives::{AccountInfo, U256 as rU256}, }, - utils::h160_to_b160, }; + use foundry_utils::types::ToAlloy; #[test] fn test_interval_update() { @@ -463,7 +461,7 @@ mod tests { let loaded = storage.get(&one).unwrap(); - let acc = loaded.basic(h160_to_b160(addr)).unwrap().unwrap(); + let acc = loaded.basic(addr.to_alloy()).unwrap().unwrap(); assert_eq!(acc.balance, rU256::from(1337u64)); } @@ -493,7 +491,7 @@ mod tests { let hash = H256::from_uint(&U256::from(idx)); let addr = Address::from(hash); let loaded = storage.get(&hash).unwrap(); - let acc = loaded.basic(h160_to_b160(addr)).unwrap().unwrap(); + let acc = loaded.basic(addr.to_alloy()).unwrap().unwrap(); let balance = (idx * 2) as u64; assert_eq!(acc.balance, rU256::from(balance)); } diff --git a/crates/anvil/src/genesis.rs b/crates/anvil/src/genesis.rs index 52deb5b27b0a0..56cba8360483e 100644 --- a/crates/anvil/src/genesis.rs +++ b/crates/anvil/src/genesis.rs @@ -5,10 +5,8 @@ use ethers::{ types::{serde_helpers::*, Address, Bytes, H256, U256}, }; use foundry_common::errors::FsPathError; -use foundry_evm::{ - revm::primitives::{Bytecode, Env, KECCAK_EMPTY, U256 as rU256}, - utils::{h160_to_b160, u256_to_ru256}, -}; +use foundry_evm::revm::primitives::{Bytecode, Env, KECCAK_EMPTY, U256 as rU256}; +use foundry_utils::types::ToAlloy; use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeMap, HashMap}, @@ -92,13 +90,13 @@ impl Genesis { env.block.timestamp = rU256::from(timestamp); } if let Some(base_fee) = self.base_fee_per_gas { - env.block.basefee = u256_to_ru256(base_fee); + env.block.basefee = base_fee.to_alloy(); } if let Some(number) = self.number { env.block.number = rU256::from(number); } if let Some(coinbase) = self.coinbase { - env.block.coinbase = h160_to_b160(coinbase); + env.block.coinbase = coinbase.to_alloy(); } env.block.difficulty = rU256::from(self.difficulty); env.block.gas_limit = rU256::from(self.gas_limit); @@ -144,7 +142,7 @@ impl From for AccountInfo { let GenesisAccount { code, balance, nonce, .. } = acc; let code = code.map(|code| Bytecode::new_raw(code.to_vec().into())); AccountInfo { - balance: u256_to_ru256(balance), + balance: balance.to_alloy(), nonce: nonce.unwrap_or_default(), code_hash: code.as_ref().map(|code| code.hash_slow()).unwrap_or(KECCAK_EMPTY), code, diff --git a/crates/anvil/tests/it/fork.rs b/crates/anvil/tests/it/fork.rs index 2ea81e2519d1b..6165929ae8510 100644 --- a/crates/anvil/tests/it/fork.rs +++ b/crates/anvil/tests/it/fork.rs @@ -15,8 +15,7 @@ use ethers::{ }; use foundry_common::get_http_provider; use foundry_config::Config; -use foundry_evm::utils::{h160_to_b160, u256_to_ru256}; -use foundry_utils::{rpc, rpc::next_http_rpc_endpoint}; +use foundry_utils::{rpc, rpc::next_http_rpc_endpoint, types::ToAlloy}; use futures::StreamExt; use std::{sync::Arc, time::Duration}; @@ -278,9 +277,9 @@ async fn test_separate_states() { let fork = api.get_fork().unwrap(); let fork_db = fork.database.read().await; - let acc = fork_db.inner().db().accounts.read().get(&h160_to_b160(addr)).cloned().unwrap(); + let acc = fork_db.inner().db().accounts.read().get(&addr.to_alloy()).cloned().unwrap(); - assert_eq!(acc.balance, u256_to_ru256(remote_balance)) + assert_eq!(acc.balance, remote_balance.to_alloy()) } #[tokio::test(flavor = "multi_thread")] diff --git a/crates/anvil/tests/it/proof/mod.rs b/crates/anvil/tests/it/proof/mod.rs index e56e8169ba8af..a85a1bacacf51 100644 --- a/crates/anvil/tests/it/proof/mod.rs +++ b/crates/anvil/tests/it/proof/mod.rs @@ -7,11 +7,12 @@ use ethers::{ }; use anvil_core::eth::proof::{AccountProof, BasicAccount}; +use foundry_utils::types::ToEthers; use crate::proof::eip1186::verify_proof; use anvil_core::eth::trie::ExtensionLayout; use ethers::utils::{keccak256, rlp}; -use foundry_evm::{revm::primitives::KECCAK_EMPTY, utils::b256_to_h256}; +use foundry_evm::revm::primitives::KECCAK_EMPTY; mod eip1186; @@ -32,7 +33,7 @@ async fn can_get_proof() { nonce: 0.into(), balance: 0.into(), storage_root: proof.storage_hash, - code_hash: b256_to_h256(KECCAK_EMPTY), + code_hash: KECCAK_EMPTY.to_ethers(), }; let rlp_account = rlp::encode(&account); diff --git a/crates/cast/bin/cmd/call.rs b/crates/cast/bin/cmd/call.rs index 08e759610be68..bb7f05195e010 100644 --- a/crates/cast/bin/cmd/call.rs +++ b/crates/cast/bin/cmd/call.rs @@ -11,11 +11,8 @@ use foundry_cli::{ }; use foundry_common::runtime_client::RuntimeClient; use foundry_config::{find_project_root_path, Config}; -use foundry_evm::{ - executor::opts::EvmOpts, - trace::TracingExecutor, - utils::{h160_to_b160, u256_to_ru256}, -}; +use foundry_evm::{executor::opts::EvmOpts, trace::TracingExecutor}; +use foundry_utils::types::ToAlloy; use std::str::FromStr; type Provider = ethers::providers::Provider; @@ -159,9 +156,9 @@ impl CallArgs { .await; let trace = match executor.deploy( - h160_to_b160(sender), + sender.to_alloy(), code.into_bytes().into(), - u256_to_ru256(value.unwrap_or(U256::zero())), + value.unwrap_or(U256::zero()).to_alloy(), None, ) { Ok(deploy_result) => TraceResult::from(deploy_result), @@ -196,10 +193,10 @@ impl CallArgs { let (tx, _) = builder.build(); let trace = TraceResult::from(executor.call_raw_committing( - h160_to_b160(sender), - h160_to_b160(tx.to_addr().copied().expect("an address to be here")), + sender.to_alloy(), + tx.to_addr().copied().expect("an address to be here").to_alloy(), tx.data().cloned().unwrap_or_default().to_vec().into(), - u256_to_ru256(tx.value().copied().unwrap_or_default()), + tx.value().copied().unwrap_or_default().to_alloy(), )?); handle_traces(trace, &config, chain, labels, verbose, debug).await?; diff --git a/crates/cast/bin/cmd/run.rs b/crates/cast/bin/cmd/run.rs index 919195337b25a..4ab9299511755 100644 --- a/crates/cast/bin/cmd/run.rs +++ b/crates/cast/bin/cmd/run.rs @@ -12,8 +12,8 @@ use foundry_evm::{ executor::{inspector::cheatcodes::util::configure_tx_env, opts::EvmOpts, EvmError}, revm::primitives::U256 as rU256, trace::TracingExecutor, - utils::{h160_to_b160, h256_to_b256, u256_to_ru256}, }; +use foundry_utils::types::ToAlloy; use tracing::trace; const ARBITRUM_SENDER: H160 = H160([ @@ -117,12 +117,12 @@ impl RunArgs { let block = provider.get_block_with_txs(tx_block_number).await?; if let Some(ref block) = block { - env.block.timestamp = u256_to_ru256(block.timestamp); - env.block.coinbase = h160_to_b160(block.author.unwrap_or_default()); - env.block.difficulty = u256_to_ru256(block.difficulty); - env.block.prevrandao = block.mix_hash.map(h256_to_b256); - env.block.basefee = u256_to_ru256(block.base_fee_per_gas.unwrap_or_default()); - env.block.gas_limit = u256_to_ru256(block.gas_limit); + env.block.timestamp = block.timestamp.to_alloy(); + env.block.coinbase = block.author.unwrap_or_default().to_alloy(); + env.block.difficulty = block.difficulty.to_alloy(); + env.block.prevrandao = block.mix_hash.map(|h| h.to_alloy()); + env.block.basefee = block.base_fee_per_gas.unwrap_or_default().to_alloy(); + env.block.gas_limit = block.gas_limit.to_alloy(); } // Set the state to the moment right before the transaction diff --git a/crates/chisel/Cargo.toml b/crates/chisel/Cargo.toml index 043e3424bfd37..43fa2f5a53573 100644 --- a/crates/chisel/Cargo.toml +++ b/crates/chisel/Cargo.toml @@ -23,6 +23,7 @@ foundry-evm.workspace = true foundry-config.workspace = true foundry-cli.workspace = true foundry-common.workspace = true +foundry-utils.workspace = true forge-fmt.workspace = true # ethers diff --git a/crates/chisel/src/executor.rs b/crates/chisel/src/executor.rs index 073f2c6cc2998..eb86917dd54ef 100644 --- a/crates/chisel/src/executor.rs +++ b/crates/chisel/src/executor.rs @@ -16,8 +16,8 @@ use eyre::{Result, WrapErr}; use foundry_evm::{ decode::decode_console_logs, executor::{inspector::CheatsConfig, Backend, ExecutorBuilder}, - utils::ru256_to_u256, }; +use foundry_utils::types::ToEthers; use solang_parser::pt::{self, CodeLocation}; use yansi::Paint; @@ -223,7 +223,7 @@ impl SessionSource { // the file compiled correctly, thus the last stack item must be the memory offset of // the `bytes memory inspectoor` value - let mut offset = ru256_to_u256(*stack.data().last().unwrap()).as_usize(); + let mut offset = stack.data().last().unwrap().to_ethers().as_usize(); let mem = memory.data(); let len = U256::from(&mem[offset..offset + 32]).as_usize(); offset += 32; diff --git a/crates/chisel/src/runner.rs b/crates/chisel/src/runner.rs index 72b888b4e984c..e0e1cfa57300c 100644 --- a/crates/chisel/src/runner.rs +++ b/crates/chisel/src/runner.rs @@ -12,8 +12,8 @@ use foundry_evm::{ executor::{DeployResult, Executor, RawCallResult}, revm::primitives::U256 as rU256, trace::{CallTraceArena, TraceKind}, - utils::{b160_to_h160, h160_to_b160, u256_to_ru256}, }; +use foundry_utils::types::{ToAlloy, ToEthers}; use revm::interpreter::{return_ok, InstructionResult}; use std::collections::BTreeMap; @@ -94,18 +94,17 @@ impl ChiselRunner { /// contract. pub fn run(&mut self, bytecode: Bytes) -> Result<(Address, ChiselResult)> { // Set the sender's balance to [U256::MAX] for deployment of the REPL contract. - self.executor.set_balance(h160_to_b160(self.sender), rU256::MAX)?; + self.executor.set_balance(self.sender.to_alloy(), rU256::MAX)?; // Deploy an instance of the REPL contract // We don't care about deployment traces / logs here let DeployResult { address, .. } = self .executor - .deploy(h160_to_b160(self.sender), bytecode.0.into(), rU256::ZERO, None) + .deploy(self.sender.to_alloy(), bytecode.0.into(), rU256::ZERO, None) .map_err(|err| eyre::eyre!("Failed to deploy REPL contract:\n{}", err))?; // Reset the sender's balance to the initial balance for calls. - self.executor - .set_balance(h160_to_b160(self.sender), u256_to_ru256(self.initial_balance))?; + self.executor.set_balance(self.sender.to_alloy(), self.initial_balance.to_alloy())?; // Append the input to the `RUN_SELECTOR` to form the calldata let mut calldata = RUN_SELECTOR.to_vec(); @@ -115,9 +114,9 @@ impl ChiselRunner { // Call the "run()" function of the REPL contract let call_res = - self.call(self.sender, b160_to_h160(address), Bytes::from(calldata), 0.into(), true); + self.call(self.sender, address.to_ethers(), Bytes::from(calldata), 0.into(), true); - call_res.map(|res| (b160_to_h160(address), res)) + call_res.map(|res| (address.to_ethers(), res)) } /// Executes the call @@ -145,10 +144,10 @@ impl ChiselRunner { }; let mut res = self.executor.call_raw( - h160_to_b160(from), - h160_to_b160(to), + from.to_alloy(), + to.to_alloy(), calldata.0.clone().into(), - u256_to_ru256(value), + value.to_alloy(), )?; let mut gas_used = res.gas_used; if matches!(res.exit_reason, return_ok!()) { @@ -166,10 +165,10 @@ impl ChiselRunner { let mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2; self.executor.env.tx.gas_limit = mid_gas_limit; let res = self.executor.call_raw( - h160_to_b160(from), - h160_to_b160(to), + from.to_alloy(), + to.to_alloy(), calldata.0.clone().into(), - u256_to_ru256(value), + value.to_alloy(), )?; match res.exit_reason { InstructionResult::Revert | @@ -206,20 +205,20 @@ impl ChiselRunner { } res = self.executor.call_raw( - h160_to_b160(from), - h160_to_b160(to), + from.to_alloy(), + to.to_alloy(), calldata.0.clone().into(), - u256_to_ru256(value), + value.to_alloy(), )?; } if commit { // if explicitly requested we can now commit the call res = self.executor.call_raw_committing( - h160_to_b160(from), - h160_to_b160(to), + from.to_alloy(), + to.to_alloy(), calldata.0.clone().into(), - u256_to_ru256(value), + value.to_alloy(), )?; } @@ -238,7 +237,7 @@ impl ChiselRunner { vec![(TraceKind::Execution, traces)] }) .unwrap_or_default(), - labeled_addresses: labels.into_iter().map(|l| (b160_to_h160(l.0), l.1)).collect(), + labeled_addresses: labels.into_iter().map(|l| (l.0.to_ethers(), l.1)).collect(), address: None, state: chisel_state, }) diff --git a/crates/evm/src/executor/backend/diagnostic.rs b/crates/evm/src/executor/backend/diagnostic.rs index 66e0857288661..6f3b48a9bb707 100644 --- a/crates/evm/src/executor/backend/diagnostic.rs +++ b/crates/evm/src/executor/backend/diagnostic.rs @@ -1,7 +1,4 @@ -use crate::{ - executor::{backend::LocalForkId, inspector::Cheatcodes}, - utils::b160_to_h160, -}; +use crate::executor::{backend::LocalForkId, inspector::Cheatcodes}; use alloy_primitives::Address; use foundry_common::fmt::UIfmt; use foundry_utils::types::ToEthers; @@ -43,7 +40,7 @@ impl RevertDiagnostic { ) } RevertDiagnostic::ContractDoesNotExist { contract, persistent, .. } => { - let contract_label = get_label(&b160_to_h160(*contract)); + let contract_label = get_label(&contract.to_ethers()); if *persistent { format!("Contract {contract_label} does not exist") } else { diff --git a/crates/evm/src/executor/backend/mod.rs b/crates/evm/src/executor/backend/mod.rs index 768d8767b49bb..11dee7b3c8d7e 100644 --- a/crates/evm/src/executor/backend/mod.rs +++ b/crates/evm/src/executor/backend/mod.rs @@ -8,7 +8,6 @@ use crate::{ inspector::{cheatcodes::Cheatcodes, DEFAULT_CREATE2_DEPLOYER}, snapshot::Snapshots, }, - utils::{b256_to_h256, h160_to_b160, h256_to_b256, ru256_to_u256, u256_to_ru256, u64_to_ru64}, CALLER, TEST_CONTRACT_ADDRESS, }; use alloy_primitives::{b256, Address, B256, U256, U64}; @@ -17,6 +16,7 @@ use ethers::{ types::{BlockNumber, Transaction}, utils::keccak256, }; +use foundry_utils::types::{ToAlloy, ToEthers}; pub use in_memory_db::MemDb; use revm::{ db::{CacheDB, DatabaseRef}, @@ -858,10 +858,10 @@ impl Backend { let full_block = fork .db .db - .get_full_block(BlockNumber::Number(ru256_to_u256(env.block.number).as_u64().into()))?; + .get_full_block(BlockNumber::Number(env.block.number.to_ethers().as_u64().into()))?; for tx in full_block.transactions.into_iter() { - if tx.hash().eq(&b256_to_h256(tx_hash)) { + if tx.hash().eq(&tx_hash.to_ethers()) { // found the target transaction return Ok(Some(tx)) } @@ -1150,13 +1150,13 @@ impl DatabaseExt for Backend { self.roll_fork(Some(id), fork_block.to(), env, journaled_state)?; // update the block's env accordingly - env.block.timestamp = u256_to_ru256(block.timestamp); - env.block.coinbase = h160_to_b160(block.author.unwrap_or_default()); - env.block.difficulty = u256_to_ru256(block.difficulty); - env.block.prevrandao = block.mix_hash.map(h256_to_b256); - env.block.basefee = u256_to_ru256(block.base_fee_per_gas.unwrap_or_default()); - env.block.gas_limit = u256_to_ru256(block.gas_limit); - env.block.number = block.number.map(u64_to_ru64).unwrap_or(fork_block).to(); + env.block.timestamp = block.timestamp.to_alloy(); + env.block.coinbase = block.author.unwrap_or_default().to_alloy(); + env.block.difficulty = block.difficulty.to_alloy(); + env.block.prevrandao = block.mix_hash.map(|h| h.to_alloy()); + env.block.basefee = block.base_fee_per_gas.unwrap_or_default().to_alloy(); + env.block.gas_limit = block.gas_limit.to_alloy(); + env.block.number = block.number.map(|n| n.to_alloy()).unwrap_or(fork_block).to(); // replay all transactions that came before let env = env.clone(); diff --git a/crates/evm/src/executor/fork/backend.rs b/crates/evm/src/executor/fork/backend.rs index ade1e6382363a..b589f0c2ad0c8 100644 --- a/crates/evm/src/executor/fork/backend.rs +++ b/crates/evm/src/executor/fork/backend.rs @@ -1,10 +1,7 @@ //! Smart caching and deduplication of requests when using a forking provider -use crate::{ - executor::{ - backend::error::{DatabaseError, DatabaseResult}, - fork::{cache::FlushJsonBlockCacheDB, BlockchainDb}, - }, - utils::{b160_to_h160, b256_to_h256, h256_to_b256, u256_to_ru256}, +use crate::executor::{ + backend::error::{DatabaseError, DatabaseResult}, + fork::{cache::FlushJsonBlockCacheDB, BlockchainDb}, }; use alloy_primitives::{Address, Bytes, B256, U256}; use ethers::{ @@ -14,6 +11,7 @@ use ethers::{ utils::keccak256, }; use foundry_common::NON_ARCHIVE_NODE_WARNING; +use foundry_utils::types::{ToAlloy, ToEthers}; use futures::{ channel::mpsc::{channel, Receiver, Sender}, stream::Stream, @@ -194,12 +192,12 @@ where let idx_req = B256::from(idx); let storage = provider .get_storage_at( - NameOrAddress::Address(b160_to_h160(address)), - b256_to_h256(idx_req), + NameOrAddress::Address(address.to_ethers()), + idx_req.to_ethers(), block_id, ) .await; - let storage = storage.map(|storage| storage.into_uint()).map(u256_to_ru256); + let storage = storage.map(|storage| storage.into_uint()).map(|s| s.to_alloy()); (storage, address, idx) }); self.pending_requests.push(ProviderRequest::Storage(fut)); @@ -214,12 +212,12 @@ where let block_id = self.block_id; let fut = Box::pin(async move { let balance = - provider.get_balance(NameOrAddress::Address(b160_to_h160(address)), block_id); + provider.get_balance(NameOrAddress::Address(address.to_ethers()), block_id); let nonce = provider - .get_transaction_count(NameOrAddress::Address(b160_to_h160(address)), block_id); - let code = provider.get_code(NameOrAddress::Address(b160_to_h160(address)), block_id); + .get_transaction_count(NameOrAddress::Address(address.to_ethers()), block_id); + let code = provider.get_code(NameOrAddress::Address(address.to_ethers()), block_id); let resp = tokio::try_join!(balance, nonce, code).map(|(balance, nonce, code)| { - (u256_to_ru256(balance), u256_to_ru256(nonce), Bytes::from(code.0)) + (balance.to_alloy(), nonce.to_alloy(), Bytes::from(code.0)) }); (resp, address) }); @@ -254,7 +252,7 @@ where fn request_transaction(&mut self, tx: B256, sender: TransactionSender) { let provider = self.provider.clone(); let fut = Box::pin(async move { - let block = provider.get_transaction(b256_to_h256(tx)).await; + let block = provider.get_transaction(tx.to_ethers()).await; (sender, block, tx) }); @@ -282,14 +280,14 @@ where warn!(target: "backendhandler", ?number, "block not found"); // if no block was returned then the block does not exist, in which case // we return empty hash - Ok(b256_to_h256(KECCAK_EMPTY)) + Ok(KECCAK_EMPTY.to_ethers()) } Err(err) => { error!(target: "backendhandler", ?err, ?number, "failed to get block"); Err(err) } }; - (block_hash.map(h256_to_b256), number) + (block_hash.map(|h| h.to_alloy()), number) }); self.pending_requests.push(ProviderRequest::BlockHash(fut)); } diff --git a/crates/evm/src/executor/fork/init.rs b/crates/evm/src/executor/fork/init.rs index 09c607bedb54e..f04a19a89cb80 100644 --- a/crates/evm/src/executor/fork/init.rs +++ b/crates/evm/src/executor/fork/init.rs @@ -1,6 +1,4 @@ -use crate::utils::{ - apply_chain_and_block_specific_env_changes, h160_to_b160, h256_to_b256, u256_to_ru256, -}; +use crate::utils::apply_chain_and_block_specific_env_changes; use alloy_primitives::{Address, U256}; use ethers::{ providers::Middleware, @@ -8,6 +6,7 @@ use ethers::{ }; use eyre::WrapErr; use foundry_common::NON_ARCHIVE_NODE_WARNING; +use foundry_utils::types::ToAlloy; use futures::TryFutureExt; use revm::primitives::{BlockEnv, CfgEnv, Env, TxEnv}; @@ -71,18 +70,18 @@ where let mut env = Env { cfg, block: BlockEnv { - number: u256_to_ru256(block.number.expect("block number not found").as_u64().into()), - timestamp: u256_to_ru256(block.timestamp), - coinbase: h160_to_b160(block.author.unwrap_or_default()), - difficulty: u256_to_ru256(block.difficulty), - prevrandao: Some(block.mix_hash.map(h256_to_b256).unwrap_or_default()), - basefee: u256_to_ru256(block.base_fee_per_gas.unwrap_or_default()), - gas_limit: u256_to_ru256(block.gas_limit), + number: U256::from(block.number.expect("block number not found").as_u64()), + timestamp: block.timestamp.to_alloy(), + coinbase: block.author.unwrap_or_default().to_alloy(), + difficulty: block.difficulty.to_alloy(), + prevrandao: Some(block.mix_hash.map(|h| h.to_alloy()).unwrap_or_default()), + basefee: block.base_fee_per_gas.unwrap_or_default().to_alloy(), + gas_limit: block.gas_limit.to_alloy(), ..Default::default() }, tx: TxEnv { caller: origin, - gas_price: gas_price.map(U256::from).unwrap_or(u256_to_ru256(fork_gas_price)), + gas_price: gas_price.map(U256::from).unwrap_or(fork_gas_price.to_alloy()), chain_id: Some(override_chain_id.unwrap_or(rpc_chain_id.as_u64())), gas_limit: block.gas_limit.as_u64(), ..Default::default() diff --git a/crates/evm/src/executor/fork/multi.rs b/crates/evm/src/executor/fork/multi.rs index f2dafbfc333c1..2393cd450c075 100644 --- a/crates/evm/src/executor/fork/multi.rs +++ b/crates/evm/src/executor/fork/multi.rs @@ -3,9 +3,8 @@ //! The design is similar to the single `SharedBackend`, `BackendHandler` but supports multiple //! concurrently active pairs at once. -use crate::{ - executor::fork::{BackendHandler, BlockchainDb, BlockchainDbMeta, CreateFork, SharedBackend}, - utils::ru256_to_u256, +use crate::executor::fork::{ + BackendHandler, BlockchainDb, BlockchainDbMeta, CreateFork, SharedBackend, }; use ethers::{ abi::{AbiDecode, AbiEncode, AbiError}, @@ -14,6 +13,7 @@ use ethers::{ }; use foundry_common::{runtime_client::RuntimeClient, ProviderBuilder}; use foundry_config::Config; +use foundry_utils::types::ToEthers; use futures::{ channel::mpsc::{channel, Receiver, Sender}, stream::{Fuse, Stream}, @@ -497,7 +497,7 @@ async fn create_fork( let number = block .number .map(|num| num.as_u64()) - .unwrap_or_else(|| ru256_to_u256(meta.block_env.number).as_u64()); + .unwrap_or_else(|| meta.block_env.number.to_ethers().as_u64()); // determine the cache path if caching is enabled let cache_path = if fork.enable_caching { diff --git a/crates/evm/src/executor/inspector/access_list.rs b/crates/evm/src/executor/inspector/access_list.rs index 108b90ff1f0dd..5deaa800b0cb7 100644 --- a/crates/evm/src/executor/inspector/access_list.rs +++ b/crates/evm/src/executor/inspector/access_list.rs @@ -1,13 +1,12 @@ use alloy_primitives::{Address, B256}; use ethers::types::transaction::eip2930::{AccessList, AccessListItem}; +use foundry_utils::types::{ToAlloy, ToEthers}; use hashbrown::{HashMap, HashSet}; use revm::{ interpreter::{opcode, InstructionResult, Interpreter}, Database, EVMData, Inspector, }; -use crate::utils::{b160_to_h160, b256_to_h256, h160_to_b160, h256_to_b256}; - /// An inspector that collects touched accounts and storage slots. #[derive(Default, Debug)] pub struct AccessListTracer { @@ -29,8 +28,8 @@ impl AccessListTracer { .iter() .map(|v| { ( - h160_to_b160(v.address), - v.storage_keys.iter().copied().map(h256_to_b256).collect(), + v.address.to_alloy(), + v.storage_keys.iter().copied().map(|v| v.to_alloy()).collect(), ) }) .collect(), @@ -41,8 +40,8 @@ impl AccessListTracer { self.access_list .iter() .map(|(address, slots)| AccessListItem { - address: b160_to_h160(*address), - storage_keys: slots.iter().copied().map(b256_to_h256).collect(), + address: address.to_ethers(), + storage_keys: slots.iter().copied().map(|k| k.to_ethers()).collect(), }) .collect::>(), ) diff --git a/crates/evm/src/executor/inspector/cheatcodes/env.rs b/crates/evm/src/executor/inspector/cheatcodes/env.rs index 5afa17285ba03..1e96024cce9c9 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/env.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/env.rs @@ -9,17 +9,16 @@ use crate::{ DealRecord, }, }, - utils::{b160_to_h160, h160_to_b160, ru256_to_u256, u256_to_ru256}, }; use alloy_dyn_abi::DynSolValue; -use alloy_primitives::{Bytes, B256}; +use alloy_primitives::{Bytes, B256, U256 as rU256}; use ethers::{ abi::{self, RawLog, Token, Tokenizable, Tokenize}, signers::{LocalWallet, Signer}, types::{Address, U256}, }; use foundry_config::Config; -use foundry_utils::types::ToAlloy; +use foundry_utils::types::{ToAlloy, ToEthers}; use revm::{ primitives::{Bytecode, SpecId, KECCAK_EMPTY}, Database, EVMData, @@ -323,7 +322,7 @@ fn add_breakpoint(state: &mut Cheatcodes, caller: Address, inner: &str, add: boo // mark the slots of an account and the account address as cold fn cool_account(data: &mut EVMData<'_, DB>, address: Address) -> Result { - if let Some(account) = data.journaled_state.state.get_mut(&h160_to_b160(address)) { + if let Some(account) = data.journaled_state.state.get_mut(&address.to_alloy()) { if account.is_touched() { account.unmark_touch(); } @@ -342,7 +341,7 @@ pub fn apply( ) -> Result> { let result = match call { HEVMCalls::Warp(inner) => { - data.env.block.timestamp = u256_to_ru256(inner.0); + data.env.block.timestamp = inner.0.to_alloy(); Bytes::new() } HEVMCalls::Difficulty(inner) => { @@ -352,7 +351,7 @@ pub fn apply( use `prevrandao` instead. \ For more information, please see https://eips.ethereum.org/EIPS/eip-4399" ); - data.env.block.difficulty = u256_to_ru256(inner.0); + data.env.block.difficulty = inner.0.to_alloy(); Bytes::new() } HEVMCalls::Prevrandao(inner) => { @@ -366,27 +365,27 @@ pub fn apply( Bytes::new() } HEVMCalls::Roll(inner) => { - data.env.block.number = u256_to_ru256(inner.0); + data.env.block.number = inner.0.to_alloy(); Bytes::new() } HEVMCalls::Fee(inner) => { - data.env.block.basefee = u256_to_ru256(inner.0); + data.env.block.basefee = inner.0.to_alloy(); Bytes::new() } HEVMCalls::Coinbase(inner) => { - data.env.block.coinbase = h160_to_b160(inner.0); + data.env.block.coinbase = inner.0.to_alloy(); Bytes::new() } HEVMCalls::Store(inner) => { ensure!(!is_potential_precompile(inner.0), "Store cannot be used on precompile addresses (N < 10). Please use an address bigger than 10 instead"); - data.journaled_state.load_account(h160_to_b160(inner.0), data.db)?; + data.journaled_state.load_account(inner.0.to_alloy(), data.db)?; // ensure the account is touched - data.journaled_state.touch(&h160_to_b160(inner.0)); + data.journaled_state.touch(&inner.0.to_alloy()); data.journaled_state.sstore( - h160_to_b160(inner.0), - u256_to_ru256(inner.1.into()), - u256_to_ru256(inner.2.into()), + inner.0.to_alloy(), + rU256::from_be_bytes(inner.1), + rU256::from_be_bytes(inner.2), data.db, )?; Bytes::new() @@ -394,10 +393,10 @@ pub fn apply( HEVMCalls::Load(inner) => { ensure!(!is_potential_precompile(inner.0), "Load cannot be used on precompile addresses (N < 10). Please use an address bigger than 10 instead"); // TODO: Does this increase gas usage? - data.journaled_state.load_account(h160_to_b160(inner.0), data.db)?; + data.journaled_state.load_account(inner.0.to_alloy(), data.db)?; let (val, _) = data.journaled_state.sload( - h160_to_b160(inner.0), - u256_to_ru256(inner.1.into()), + inner.0.to_alloy(), + rU256::from_be_bytes(inner.1), data.db, )?; DynSolValue::from(val).encode_single().into() @@ -410,9 +409,9 @@ pub fn apply( let code = inner.1.clone(); trace!(address=?inner.0, code=?hex::encode(&code), "etch cheatcode"); // TODO: Does this increase gas usage? - data.journaled_state.load_account(h160_to_b160(inner.0), data.db)?; + data.journaled_state.load_account(inner.0.to_alloy(), data.db)?; data.journaled_state.set_code( - h160_to_b160(inner.0), + inner.0.to_alloy(), Bytecode::new_raw(alloy_primitives::Bytes(code.0)).to_checked(), ); Bytes::new() @@ -425,19 +424,19 @@ pub fn apply( // record the deal let record = DealRecord { address: who, - old_balance: ru256_to_u256(account.info.balance), + old_balance: account.info.balance.to_ethers(), new_balance: value, }; state.eth_deals.push(record); - account.info.balance = u256_to_ru256(value); + account.info.balance = value.to_alloy(); })?; Bytes::new() } HEVMCalls::Prank0(inner) => prank( state, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), inner.0, None, data.journaled_state.depth(), @@ -446,7 +445,7 @@ pub fn apply( HEVMCalls::Prank1(inner) => prank( state, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), inner.0, Some(inner.1), data.journaled_state.depth(), @@ -455,7 +454,7 @@ pub fn apply( HEVMCalls::StartPrank0(inner) => prank( state, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), inner.0, None, data.journaled_state.depth(), @@ -464,7 +463,7 @@ pub fn apply( HEVMCalls::StartPrank1(inner) => prank( state, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), inner.0, Some(inner.1), data.journaled_state.depth(), @@ -475,7 +474,7 @@ pub fn apply( state.prank = None; Bytes::new() } - HEVMCalls::ReadCallers(_) => read_callers(state, b160_to_h160(data.env.tx.caller)), + HEVMCalls::ReadCallers(_) => read_callers(state, data.env.tx.caller.to_ethers()), HEVMCalls::Record(_) => { start_record(state); Bytes::new() @@ -532,7 +531,7 @@ pub fn apply( // [function getNonce(address)] returns the current nonce of a given ETH address HEVMCalls::GetNonce1(inner) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, @@ -540,16 +539,16 @@ pub fn apply( // TODO: this is probably not a good long-term solution since it might mess up the gas // calculations - data.journaled_state.load_account(h160_to_b160(inner.0), data.db)?; + data.journaled_state.load_account(inner.0.to_alloy(), data.db)?; // we can safely unwrap because `load_account` insert inner.0 to DB. - let account = data.journaled_state.state().get(&h160_to_b160(inner.0)).unwrap(); + let account = data.journaled_state.state().get(&inner.0.to_alloy()).unwrap(); DynSolValue::from(account.info.nonce).encode_single().into() } // [function getNonce(Wallet)] returns the current nonce of the Wallet's ETH address HEVMCalls::GetNonce0(inner) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, @@ -557,10 +556,10 @@ pub fn apply( // TODO: this is probably not a good long-term solution since it might mess up the gas // calculations - data.journaled_state.load_account(h160_to_b160(inner.0.addr), data.db)?; + data.journaled_state.load_account(inner.0.addr.to_alloy(), data.db)?; // we can safely unwrap because `load_account` insert inner.0 to DB. - let account = data.journaled_state.state().get(&h160_to_b160(inner.0.addr)).unwrap(); + let account = data.journaled_state.state().get(&inner.0.addr.to_alloy()).unwrap(); DynSolValue::from(account.info.nonce.to_alloy()).encode_single().into() } HEVMCalls::ChainId(inner) => { @@ -569,28 +568,28 @@ pub fn apply( Bytes::new() } HEVMCalls::TxGasPrice(inner) => { - data.env.tx.gas_price = u256_to_ru256(inner.0); + data.env.tx.gas_price = inner.0.to_alloy(); Bytes::new() } HEVMCalls::Broadcast0(_) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, )?; broadcast( state, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), data.journaled_state.depth(), true, )? } HEVMCalls::Broadcast1(inner) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, @@ -599,14 +598,14 @@ pub fn apply( state, inner.0, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), data.journaled_state.depth(), true, )? } HEVMCalls::Broadcast2(inner) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, @@ -615,7 +614,7 @@ pub fn apply( state, inner.0, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), data.env.cfg.chain_id.into(), data.journaled_state.depth(), true, @@ -623,23 +622,23 @@ pub fn apply( } HEVMCalls::StartBroadcast0(_) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, )?; broadcast( state, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), data.journaled_state.depth(), false, )? } HEVMCalls::StartBroadcast1(inner) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, @@ -648,14 +647,14 @@ pub fn apply( state, inner.0, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), data.journaled_state.depth(), false, )? } HEVMCalls::StartBroadcast2(inner) => { correct_sender_nonce( - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), &mut data.journaled_state, &mut data.db, state, @@ -664,7 +663,7 @@ pub fn apply( state, inner.0, caller, - b160_to_h160(data.env.tx.caller), + data.env.tx.caller.to_ethers(), data.env.cfg.chain_id.into(), data.journaled_state.depth(), false, diff --git a/crates/evm/src/executor/inspector/cheatcodes/expect.rs b/crates/evm/src/executor/inspector/cheatcodes/expect.rs index 10f9983de7904..2ed5d88dc57f5 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/expect.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/expect.rs @@ -1,12 +1,15 @@ use super::{bail, ensure, fmt_err, Cheatcodes, Result}; -use crate::{abi::HEVMCalls, executor::backend::DatabaseExt, utils::h160_to_b160}; +use crate::{abi::HEVMCalls, executor::backend::DatabaseExt}; use alloy_primitives::Bytes; use ethers::{ abi::{AbiDecode, RawLog}, contract::Lazy, types::{Address, H160, U256}, }; -use foundry_utils::error::{ERROR_PREFIX, REVERT_PREFIX}; +use foundry_utils::{ + error::{ERROR_PREFIX, REVERT_PREFIX}, + types::ToAlloy, +}; use revm::{ interpreter::{return_ok, InstructionResult}, primitives::Bytecode, @@ -484,7 +487,7 @@ pub fn apply( } HEVMCalls::MockCall0(inner) => { // TODO: Does this increase gas usage? - if let Err(err) = data.journaled_state.load_account(h160_to_b160(inner.0), data.db) { + if let Err(err) = data.journaled_state.load_account(inner.0.to_alloy(), data.db) { return Some(Err(err.into())) } @@ -492,7 +495,7 @@ pub fn apply( // check Solidity might perform. let empty_bytecode = data .journaled_state - .account(h160_to_b160(inner.0)) + .account(inner.0.to_alloy()) .info .code .as_ref() @@ -501,7 +504,7 @@ pub fn apply( let code = Bytecode::new_raw(alloy_primitives::Bytes(bytes::Bytes::from_static(&[0u8]))) .to_checked(); - data.journaled_state.set_code(h160_to_b160(inner.0), code); + data.journaled_state.set_code(inner.0.to_alloy(), code); } state.mocked_calls.entry(inner.0).or_default().insert( MockCallDataContext { calldata: inner.1.clone().0.into(), value: None }, @@ -513,7 +516,7 @@ pub fn apply( Ok(Bytes::new()) } HEVMCalls::MockCall1(inner) => { - if let Err(err) = data.journaled_state.load_account(h160_to_b160(inner.0), data.db) { + if let Err(err) = data.journaled_state.load_account(inner.0.to_alloy(), data.db) { return Some(Err(err.into())) } diff --git a/crates/evm/src/executor/inspector/cheatcodes/fork.rs b/crates/evm/src/executor/inspector/cheatcodes/fork.rs index 447b04b561743..a29bca651bf50 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/fork.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/fork.rs @@ -4,7 +4,7 @@ use crate::{ executor::{ backend::DatabaseExt, fork::CreateFork, inspector::cheatcodes::ext::value_to_token, }, - utils::{h160_to_b160, ru256_to_u256, u256_to_ru256, RuntimeOrHandle}, + utils::RuntimeOrHandle, }; use alloy_primitives::{Bytes, B256, U256}; use ethers::{ @@ -14,6 +14,7 @@ use ethers::{ }; use foundry_abi::hevm::{EthGetLogsCall, RpcCall}; use foundry_common::ProviderBuilder; +use foundry_utils::types::{ToAlloy, ToEthers}; use revm::EVMData; use serde_json::Value; @@ -43,49 +44,49 @@ pub fn apply( HEVMCalls::CreateSelectFork2(fork) => { create_select_fork_at_transaction(state, data, fork.0.clone(), fork.1.into()) } - HEVMCalls::SelectFork(fork_id) => select_fork(state, data, u256_to_ru256(fork_id.0)), + HEVMCalls::SelectFork(fork_id) => select_fork(state, data, fork_id.0.to_alloy()), HEVMCalls::MakePersistent0(acc) => { - data.db.add_persistent_account(h160_to_b160(acc.0)); + data.db.add_persistent_account(acc.0.to_alloy()); Ok(Bytes::new()) } HEVMCalls::MakePersistent1(acc) => { data.db.extend_persistent_accounts( - (acc.0.clone().into_iter().map(h160_to_b160)).collect::>(), + (acc.0.clone().into_iter().map(|acc| acc.to_alloy())).collect::>(), ); Ok(Bytes::new()) } HEVMCalls::MakePersistent2(acc) => { - data.db.add_persistent_account(h160_to_b160(acc.0)); - data.db.add_persistent_account(h160_to_b160(acc.1)); + data.db.add_persistent_account(acc.0.to_alloy()); + data.db.add_persistent_account(acc.1.to_alloy()); Ok(Bytes::new()) } HEVMCalls::MakePersistent3(acc) => { - data.db.add_persistent_account(h160_to_b160(acc.0)); - data.db.add_persistent_account(h160_to_b160(acc.1)); - data.db.add_persistent_account(h160_to_b160(acc.2)); + data.db.add_persistent_account(acc.0.to_alloy()); + data.db.add_persistent_account(acc.1.to_alloy()); + data.db.add_persistent_account(acc.2.to_alloy()); Ok(Bytes::new()) } HEVMCalls::IsPersistent(acc) => { - Ok(data.db.is_persistent(&h160_to_b160(acc.0)).encode().into()) + Ok(data.db.is_persistent(&acc.0.to_alloy()).encode().into()) } HEVMCalls::RevokePersistent0(acc) => { - data.db.remove_persistent_account(&h160_to_b160(acc.0)); + data.db.remove_persistent_account(&acc.0.to_alloy()); Ok(Bytes::new()) } HEVMCalls::RevokePersistent1(acc) => { data.db.remove_persistent_accounts( - acc.0.clone().into_iter().map(h160_to_b160).collect::>(), + acc.0.clone().into_iter().map(|acc| acc.to_alloy()).collect::>(), ); Ok(Bytes::new()) } HEVMCalls::ActiveFork(_) => data .db .active_fork_id() - .map(|id| ru256_to_u256(id).encode().into()) + .map(|id| id.to_ethers().encode().into()) .ok_or_else(|| fmt_err!("No active fork")), HEVMCalls::RollFork0(fork) => data .db - .roll_fork(None, u256_to_ru256(fork.0), data.env, &mut data.journaled_state) + .roll_fork(None, fork.0.to_alloy(), data.env, &mut data.journaled_state) .map(empty) .map_err(Into::into), HEVMCalls::RollFork1(fork) => data @@ -96,8 +97,8 @@ pub fn apply( HEVMCalls::RollFork2(fork) => data .db .roll_fork( - Some(fork.0).map(u256_to_ru256), - u256_to_ru256(fork.1), + Some(fork.0).map(|id| id.to_alloy()), + fork.1.to_alloy(), data.env, &mut data.journaled_state, ) @@ -106,7 +107,7 @@ pub fn apply( HEVMCalls::RollFork3(fork) => data .db .roll_fork_to_transaction( - Some(fork.0).map(u256_to_ru256), + Some(fork.0).map(|f| f.to_alloy()), fork.1.into(), data.env, &mut data.journaled_state, @@ -139,7 +140,7 @@ pub fn apply( Ok(urls.encode().into()) } HEVMCalls::AllowCheatcodes(addr) => { - data.db.allow_cheatcode_access(h160_to_b160(addr.0)); + data.db.allow_cheatcode_access(addr.0.to_alloy()); Ok(Bytes::new()) } HEVMCalls::Transact0(inner) => data @@ -150,7 +151,7 @@ pub fn apply( HEVMCalls::Transact1(inner) => data .db .transact( - Some(u256_to_ru256(inner.0)), + Some(inner.0.to_alloy()), inner.1.into(), data.env, &mut data.journaled_state, @@ -198,7 +199,7 @@ fn create_select_fork( let fork = create_fork_request(state, url_or_alias, block, data)?; let id = data.db.create_select_fork(fork, data.env, &mut data.journaled_state)?; - Ok(ru256_to_u256(id).encode().into()) + Ok(id.to_ethers().encode().into()) } /// Creates a new fork @@ -210,7 +211,7 @@ fn create_fork( ) -> Result { let fork = create_fork_request(state, url_or_alias, block, data)?; let id = data.db.create_fork(fork)?; - Ok(ru256_to_u256(id).encode().into()) + Ok(id.to_ethers().encode().into()) } /// Creates and then also selects the new fork at the given transaction fn create_select_fork_at_transaction( @@ -233,7 +234,7 @@ fn create_select_fork_at_transaction( &mut data.journaled_state, transaction, )?; - Ok(ru256_to_u256(id).encode().into()) + Ok(id.to_ethers().encode().into()) } /// Creates a new fork at the given transaction @@ -245,7 +246,7 @@ fn create_fork_at_transaction( ) -> Result { let fork = create_fork_request(state, url_or_alias, None, data)?; let id = data.db.create_fork_at_transaction(fork, transaction)?; - Ok(ru256_to_u256(id).encode().into()) + Ok(id.to_ethers().encode().into()) } /// Creates the request object for a new fork request @@ -271,9 +272,7 @@ fn create_fork_request( /// Equivalent to eth_getLogs but on a cheatcode. fn eth_getlogs(data: &EVMData, inner: &EthGetLogsCall) -> Result { let url = data.db.active_fork_url().ok_or(fmt_err!("No active fork url found"))?; - if u256_to_ru256(inner.0) > U256::from(u64::MAX) || - u256_to_ru256(inner.1) > U256::from(u64::MAX) - { + if inner.0.to_alloy() > U256::from(u64::MAX) || inner.1.to_alloy() > U256::from(u64::MAX) { return Err(fmt_err!("Blocks in block range must be less than 2^64 - 1")) } // Cannot possibly have more than 4 topics in the topics array. diff --git a/crates/evm/src/executor/inspector/cheatcodes/mapping.rs b/crates/evm/src/executor/inspector/cheatcodes/mapping.rs index 4d34b5f3373fb..dd041075ae568 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/mapping.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/mapping.rs @@ -1,11 +1,11 @@ use super::Cheatcodes; -use crate::utils::{b160_to_h160, ru256_to_u256}; use alloy_primitives::Bytes; use ethers::{ abi::{self, Token}, types::{Address, U256}, utils::keccak256, }; +use foundry_utils::types::ToEthers; use revm::{ interpreter::{opcode, Interpreter}, Database, EVMData, @@ -101,7 +101,7 @@ pub fn on_evm_step( let result = U256::from(keccak256(interpreter.memory.get_slice(offset, 0x40))); mapping_slots - .entry(b160_to_h160(address)) + .entry(address.to_ethers()) .or_default() .seen_sha3 .insert(result, (low, high)); @@ -109,10 +109,10 @@ pub fn on_evm_step( } opcode::SSTORE => { if let Some(mapping_slots) = - mapping_slots.get_mut(&b160_to_h160(interpreter.contract.address)) + mapping_slots.get_mut(&interpreter.contract.address.to_ethers()) { if let Ok(slot) = interpreter.stack.peek(0) { - mapping_slots.insert(ru256_to_u256(slot)); + mapping_slots.insert(slot.to_ethers()); } } } diff --git a/crates/evm/src/executor/inspector/cheatcodes/mod.rs b/crates/evm/src/executor/inspector/cheatcodes/mod.rs index 58a85fdda8a73..dde13e5e35c68 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/mod.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/mod.rs @@ -10,7 +10,6 @@ use crate::{ backend::DatabaseExt, inspector::cheatcodes::env::RecordedLogs, CHEATCODE_ADDRESS, HARDHAT_CONSOLE_ADDRESS, }, - utils::{b160_to_h160, b256_to_h256, h160_to_b160, ru256_to_u256, u256_to_ru256}, }; use alloy_primitives::{Address as rAddress, Bytes, B256}; use ethers::{ @@ -21,7 +20,10 @@ use ethers::{ }, }; use foundry_common::evm::Breakpoints; -use foundry_utils::error::SolError; +use foundry_utils::{ + error::SolError, + types::{ToAlloy, ToEthers}, +}; use itertools::Itertools; use revm::{ interpreter::{opcode, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter}, @@ -220,7 +222,7 @@ impl Cheatcodes { // ensure the caller is allowed to execute cheatcodes, // but only if the backend is in forking mode - data.db.ensure_cheatcode_access_forking_mode(h160_to_b160(caller))?; + data.db.ensure_cheatcode_access_forking_mode(caller.to_alloy())?; let opt = env::apply(self, data, caller, &decoded) .transpose() @@ -285,8 +287,8 @@ impl Cheatcodes { // This will prevent overflow issues in revm's [`JournaledState::journal_revert`] routine // which rolls back any transfers. while let Some(record) = self.eth_deals.pop() { - if let Some(acc) = data.journaled_state.state.get_mut(&h160_to_b160(record.address)) { - acc.info.balance = u256_to_ru256(record.old_balance); + if let Some(acc) = data.journaled_state.state.get_mut(&record.address.to_alloy()) { + acc.info.balance = record.old_balance.to_alloy(); } } } @@ -305,7 +307,7 @@ impl Inspector for Cheatcodes { data.env.block = block; } if let Some(gas_price) = self.gas_price.take() { - data.env.tx.gas_price = u256_to_ru256(gas_price); + data.env.tx.gas_price = gas_price.to_alloy(); } InstructionResult::Continue @@ -382,9 +384,9 @@ impl Inspector for Cheatcodes { let key = try_or_continue!(interpreter.stack().peek(0)); storage_accesses .reads - .entry(b160_to_h160(interpreter.contract().address)) + .entry(interpreter.contract().address.to_ethers()) .or_insert_with(Vec::new) - .push(ru256_to_u256(key)); + .push(key.to_ethers()); } opcode::SSTORE => { let key = try_or_continue!(interpreter.stack().peek(0)); @@ -392,14 +394,14 @@ impl Inspector for Cheatcodes { // An SSTORE does an SLOAD internally storage_accesses .reads - .entry(b160_to_h160(interpreter.contract().address)) + .entry(interpreter.contract().address.to_ethers()) .or_insert_with(Vec::new) - .push(ru256_to_u256(key)); + .push(key.to_ethers()); storage_accesses .writes - .entry(b160_to_h160(interpreter.contract().address)) + .entry(interpreter.contract().address.to_ethers()) .or_insert_with(Vec::new) - .push(ru256_to_u256(key)); + .push(key.to_ethers()); } _ => (), } @@ -427,7 +429,7 @@ impl Inspector for Cheatcodes { opcode::MSTORE => { // The offset of the mstore operation is at the top of the stack. - let offset = ru256_to_u256(try_or_continue!(interpreter.stack().peek(0))).as_u64(); + let offset = try_or_continue!(interpreter.stack().peek(0)).to_ethers().as_u64(); // If none of the allowed ranges contain [offset, offset + 32), memory has been // unexpectedly mutated. @@ -440,7 +442,7 @@ impl Inspector for Cheatcodes { } opcode::MSTORE8 => { // The offset of the mstore8 operation is at the top of the stack. - let offset = ru256_to_u256(try_or_continue!(interpreter.stack().peek(0))).as_u64(); + let offset = try_or_continue!(interpreter.stack().peek(0)).to_ethers().as_u64(); // If none of the allowed ranges contain the offset, memory has been // unexpectedly mutated. @@ -456,7 +458,7 @@ impl Inspector for Cheatcodes { opcode::MLOAD => { // The offset of the mload operation is at the top of the stack - let offset = ru256_to_u256(try_or_continue!(interpreter.stack().peek(0))).as_u64(); + let offset = try_or_continue!(interpreter.stack().peek(0)).to_ethers().as_u64(); // If the offset being loaded is >= than the memory size, the // memory is being expanded. If none of the allowed ranges contain @@ -475,10 +477,10 @@ impl Inspector for Cheatcodes { $(opcode::$opcode => { // The destination offset of the operation is at the top of the stack. - let dest_offset = ru256_to_u256(try_or_continue!(interpreter.stack().peek($offset_depth))).as_u64(); + let dest_offset = try_or_continue!(interpreter.stack().peek($offset_depth)).to_ethers().as_u64(); // The size of the data that will be copied is the third item on the stack. - let size = ru256_to_u256(try_or_continue!(interpreter.stack().peek($size_depth))).as_u64(); + let size = try_or_continue!(interpreter.stack().peek($size_depth)).to_ethers().as_u64(); // If none of the allowed ranges contain [dest_offset, dest_offset + size), // memory outside of the expected ranges has been touched. If the opcode @@ -547,19 +549,19 @@ impl Inspector for Cheatcodes { handle_expect_emit( self, RawLog { - topics: topics.iter().copied().map(b256_to_h256).collect_vec(), + topics: topics.iter().copied().map(|t| t.to_ethers()).collect_vec(), data: data.to_vec(), }, - &b160_to_h160(*address), + &address.to_ethers(), ); } // Stores this log if `recordLogs` has been called if let Some(storage_recorded_logs) = &mut self.recorded_logs { storage_recorded_logs.entries.push(Log { - emitter: b160_to_h160(*address), + emitter: address.to_ethers(), inner: RawLog { - topics: topics.iter().copied().map(b256_to_h256).collect_vec(), + topics: topics.iter().copied().map(|t| t.to_ethers()).collect_vec(), data: data.to_vec(), }, }); @@ -573,7 +575,7 @@ impl Inspector for Cheatcodes { ) -> (InstructionResult, Gas, alloy_primitives::Bytes) { if call.contract == CHEATCODE_ADDRESS { let gas = Gas::new(call.gas_limit); - match self.apply_cheatcode(data, b160_to_h160(call.context.caller), call) { + match self.apply_cheatcode(data, call.context.caller.to_ethers(), call) { Ok(retdata) => (InstructionResult::Return, gas, alloy_primitives::Bytes(retdata.0)), Err(err) => { (InstructionResult::Revert, gas, alloy_primitives::Bytes(err.encode_error().0)) @@ -584,7 +586,7 @@ impl Inspector for Cheatcodes { // Grab the different calldatas expected. if let Some(expected_calls_for_target) = - self.expected_calls.get_mut(&(b160_to_h160(call.contract))) + self.expected_calls.get_mut(&(call.contract.to_ethers())) { // Match every partial/full calldata for (calldata, (expected, actual_count)) in expected_calls_for_target.iter_mut() { @@ -596,7 +598,7 @@ impl Inspector for Cheatcodes { // The value matches, if provided expected .value - .map_or(true, |value| value == ru256_to_u256(call.transfer.value)) && + .map_or(true, |value| value == call.transfer.value.to_ethers()) && // The gas matches, if provided expected.gas.map_or(true, |gas| gas == call.gas_limit) && // The minimum gas matches, if provided @@ -608,10 +610,10 @@ impl Inspector for Cheatcodes { } // Handle mocked calls - if let Some(mocks) = self.mocked_calls.get(&b160_to_h160(call.contract)) { + if let Some(mocks) = self.mocked_calls.get(&call.contract.to_ethers()) { let ctx = MockCallDataContext { calldata: call.input.clone().0.into(), - value: Some(call.transfer.value).map(ru256_to_u256), + value: Some(call.transfer.value).map(|v| v.to_ethers()), }; if let Some(mock_retdata) = mocks.get(&ctx) { return ( @@ -622,8 +624,7 @@ impl Inspector for Cheatcodes { } else if let Some((_, mock_retdata)) = mocks.iter().find(|(mock, _)| { mock.calldata.len() <= call.input.len() && *mock.calldata == call.input[..mock.calldata.len()] && - mock.value - .map_or(true, |value| value == ru256_to_u256(call.transfer.value)) + mock.value.map_or(true, |value| value == call.transfer.value.to_ethers()) }) { return ( mock_retdata.ret_type, @@ -636,19 +637,19 @@ impl Inspector for Cheatcodes { // Apply our prank if let Some(prank) = &self.prank { if data.journaled_state.depth() >= prank.depth && - call.context.caller == h160_to_b160(prank.prank_caller) + call.context.caller == prank.prank_caller.to_alloy() { let mut prank_applied = false; // At the target depth we set `msg.sender` if data.journaled_state.depth() == prank.depth { - call.context.caller = h160_to_b160(prank.new_caller); - call.transfer.source = h160_to_b160(prank.new_caller); + call.context.caller = prank.new_caller.to_alloy(); + call.transfer.source = prank.new_caller.to_alloy(); prank_applied = true; } // At the target depth, or deeper, we set `tx.origin` if let Some(new_origin) = prank.new_origin { - data.env.tx.caller = h160_to_b160(new_origin); + data.env.tx.caller = new_origin.to_alloy(); prank_applied = true; } @@ -668,15 +669,15 @@ impl Inspector for Cheatcodes { // We do this because any subsequent contract calls *must* exist on chain and // we only want to grab *this* call, not internal ones if data.journaled_state.depth() == broadcast.depth && - call.context.caller == h160_to_b160(broadcast.original_caller) + call.context.caller == broadcast.original_caller.to_alloy() { // At the target depth we set `msg.sender` & tx.origin. // We are simulating the caller as being an EOA, so *both* must be set to the // broadcast.origin. - data.env.tx.caller = h160_to_b160(broadcast.new_origin); + data.env.tx.caller = broadcast.new_origin.to_alloy(); - call.context.caller = h160_to_b160(broadcast.new_origin); - call.transfer.source = h160_to_b160(broadcast.new_origin); + call.context.caller = broadcast.new_origin.to_alloy(); + call.transfer.source = broadcast.new_origin.to_alloy(); // Add a `legacy` transaction to the VecDeque. We use a legacy transaction here // because we only need the from, to, value, and data. We can later change this // into 1559, in the cli package, relatively easily once we @@ -684,7 +685,7 @@ impl Inspector for Cheatcodes { if !call.is_static { if let Err(err) = data .journaled_state - .load_account(h160_to_b160(broadcast.new_origin), data.db) + .load_account(broadcast.new_origin.to_alloy(), data.db) { return ( InstructionResult::Revert, @@ -698,15 +699,15 @@ impl Inspector for Cheatcodes { let account = data .journaled_state .state() - .get_mut(&h160_to_b160(broadcast.new_origin)) + .get_mut(&broadcast.new_origin.to_alloy()) .unwrap(); self.broadcastable_transactions.push_back(BroadcastableTransaction { rpc: data.db.active_fork_url(), transaction: TypedTransaction::Legacy(TransactionRequest { from: Some(broadcast.new_origin), - to: Some(NameOrAddress::Address(b160_to_h160(call.contract))), - value: Some(call.transfer.value).map(ru256_to_u256), + to: Some(NameOrAddress::Address(call.contract.to_ethers())), + value: Some(call.transfer.value).map(|v| v.to_ethers()), data: Some(call.input.clone().0).map(ethers::types::Bytes), nonce: Some(account.info.nonce.into()), gas: if is_fixed_gas_limit { @@ -762,7 +763,7 @@ impl Inspector for Cheatcodes { // Clean up pranks if let Some(prank) = &self.prank { if data.journaled_state.depth() == prank.depth { - data.env.tx.caller = h160_to_b160(prank.prank_origin); + data.env.tx.caller = prank.prank_origin.to_alloy(); // Clean single-call prank once we have returned to the original depth if prank.single_call { @@ -774,7 +775,7 @@ impl Inspector for Cheatcodes { // Clean up broadcast if let Some(broadcast) = &self.broadcast { if data.journaled_state.depth() == broadcast.depth { - data.env.tx.caller = h160_to_b160(broadcast.original_origin); + data.env.tx.caller = broadcast.original_origin.to_alloy(); // Clean single-call broadcast once we have returned to the original depth if broadcast.single_call { @@ -971,16 +972,16 @@ impl Inspector for Cheatcodes { // Apply our prank if let Some(prank) = &self.prank { if data.journaled_state.depth() >= prank.depth && - call.caller == h160_to_b160(prank.prank_caller) + call.caller == prank.prank_caller.to_alloy() { // At the target depth we set `msg.sender` if data.journaled_state.depth() == prank.depth { - call.caller = h160_to_b160(prank.new_caller); + call.caller = prank.new_caller.to_alloy(); } // At the target depth, or deeper, we set `tx.origin` if let Some(new_origin) = prank.new_origin { - data.env.tx.caller = h160_to_b160(new_origin); + data.env.tx.caller = new_origin.to_alloy(); } } } @@ -988,10 +989,10 @@ impl Inspector for Cheatcodes { // Apply our broadcast if let Some(broadcast) = &self.broadcast { if data.journaled_state.depth() >= broadcast.depth && - call.caller == h160_to_b160(broadcast.original_caller) + call.caller == broadcast.original_caller.to_alloy() { if let Err(err) = - data.journaled_state.load_account(h160_to_b160(broadcast.new_origin), data.db) + data.journaled_state.load_account(broadcast.new_origin.to_alloy(), data.db) { return ( InstructionResult::Revert, @@ -1001,7 +1002,7 @@ impl Inspector for Cheatcodes { ) } - data.env.tx.caller = h160_to_b160(broadcast.new_origin); + data.env.tx.caller = broadcast.new_origin.to_alloy(); if data.journaled_state.depth() == broadcast.depth { let (bytecode, to, nonce) = match process_create( @@ -1028,7 +1029,7 @@ impl Inspector for Cheatcodes { transaction: TypedTransaction::Legacy(TransactionRequest { from: Some(broadcast.new_origin), to, - value: Some(call.value).map(ru256_to_u256), + value: Some(call.value).map(|v| v.to_ethers()), data: Some(bytecode.into()), nonce: Some(nonce.into()), gas: if is_fixed_gas_limit { @@ -1063,7 +1064,7 @@ impl Inspector for Cheatcodes { // Clean up pranks if let Some(prank) = &self.prank { if data.journaled_state.depth() == prank.depth { - data.env.tx.caller = h160_to_b160(prank.prank_origin); + data.env.tx.caller = prank.prank_origin.to_alloy(); // Clean single-call prank once we have returned to the original depth if prank.single_call { @@ -1075,7 +1076,7 @@ impl Inspector for Cheatcodes { // Clean up broadcasts if let Some(broadcast) = &self.broadcast { if data.journaled_state.depth() == broadcast.depth { - data.env.tx.caller = h160_to_b160(broadcast.original_origin); + data.env.tx.caller = broadcast.original_origin.to_alloy(); // Clean single-call broadcast once we have returned to the original depth if broadcast.single_call { @@ -1096,7 +1097,7 @@ impl Inspector for Cheatcodes { ) { Ok((address, retdata)) => ( InstructionResult::Return, - address.map(h160_to_b160), + address.map(|a| a.to_alloy()), remaining_gas, alloy_primitives::Bytes(retdata.0), ), diff --git a/crates/evm/src/executor/inspector/cheatcodes/snapshot.rs b/crates/evm/src/executor/inspector/cheatcodes/snapshot.rs index 1449155ad5afa..b68ea9e5d366d 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/snapshot.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/snapshot.rs @@ -1,10 +1,7 @@ use super::Result; -use crate::{ - abi::HEVMCalls, - executor::backend::DatabaseExt, - utils::{ru256_to_u256, u256_to_ru256}, -}; +use crate::{abi::HEVMCalls, executor::backend::DatabaseExt}; use ethers::abi::AbiEncode; +use foundry_utils::types::{ToAlloy, ToEthers}; use revm::EVMData; /// Handles fork related cheatcodes @@ -12,11 +9,11 @@ use revm::EVMData; pub fn apply(data: &mut EVMData<'_, DB>, call: &HEVMCalls) -> Option { Some(match call { HEVMCalls::Snapshot(_) => { - Ok(ru256_to_u256(data.db.snapshot(&data.journaled_state, data.env)).encode().into()) + Ok((data.db.snapshot(&data.journaled_state, data.env)).to_ethers().encode().into()) } HEVMCalls::RevertTo(snapshot) => { let res = if let Some(journaled_state) = - data.db.revert(u256_to_ru256(snapshot.0), &data.journaled_state, data.env) + data.db.revert(snapshot.0.to_alloy(), &data.journaled_state, data.env) { // we reset the evm's journaled_state to the state of the snapshot previous state data.journaled_state = journaled_state; diff --git a/crates/evm/src/executor/inspector/cheatcodes/util.rs b/crates/evm/src/executor/inspector/cheatcodes/util.rs index c59937a3a7c10..721dd6493c945 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/util.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/util.rs @@ -4,7 +4,7 @@ use crate::{ error::{DatabaseError, DatabaseResult}, DatabaseExt, }, - utils::{b160_to_h160, h160_to_b160, h256_to_u256_be, ru256_to_u256, u256_to_ru256}, + utils::h256_to_u256_be, }; use alloy_primitives::Address as rAddress; use bytes::{BufMut, Bytes, BytesMut}; @@ -18,6 +18,7 @@ use ethers::{ types::{transaction::eip2718::TypedTransaction, NameOrAddress, U256}, }; use foundry_common::RpcUrl; +use foundry_utils::types::{ToAlloy, ToEthers}; use revm::{ interpreter::CreateInputs, primitives::{Account, TransactTo}, @@ -43,10 +44,10 @@ pub type BroadcastableTransactions = VecDeque; /// Configures the env for the transaction pub fn configure_tx_env(env: &mut revm::primitives::Env, tx: &Transaction) { - env.tx.caller = h160_to_b160(tx.from); + env.tx.caller = tx.from.to_alloy(); env.tx.gas_limit = tx.gas.as_u64(); - env.tx.gas_price = u256_to_ru256(tx.gas_price.unwrap_or_default()); - env.tx.gas_priority_fee = tx.max_priority_fee_per_gas.map(u256_to_ru256); + env.tx.gas_price = tx.gas_price.unwrap_or_default().to_alloy(); + env.tx.gas_priority_fee = tx.max_priority_fee_per_gas.map(|g| g.to_alloy()); env.tx.nonce = Some(tx.nonce.as_u64()); env.tx.access_list = tx .access_list @@ -56,15 +57,15 @@ pub fn configure_tx_env(env: &mut revm::primitives::Env, tx: &Transaction) { .into_iter() .map(|item| { ( - h160_to_b160(item.address), - item.storage_keys.into_iter().map(h256_to_u256_be).map(u256_to_ru256).collect(), + item.address.to_alloy(), + item.storage_keys.into_iter().map(h256_to_u256_be).map(|g| g.to_alloy()).collect(), ) }) .collect(); - env.tx.value = u256_to_ru256(tx.value); + env.tx.value = tx.value.to_alloy(); env.tx.data = alloy_primitives::Bytes(tx.input.0.clone()); env.tx.transact_to = - tx.to.map(h160_to_b160).map(TransactTo::Call).unwrap_or_else(TransactTo::create) + tx.to.map(|tx| tx.to_alloy()).map(TransactTo::Call).unwrap_or_else(TransactTo::create) } /// Applies the given function `f` to the `revm::Account` belonging to the `addr` @@ -79,7 +80,7 @@ pub fn with_journaled_account( where F: FnMut(&mut Account) -> R, { - let addr = h160_to_b160(addr); + let addr = addr.to_alloy(); journaled_state.load_account(addr, db)?; journaled_state.touch(&addr); let account = journaled_state.state.get_mut(&addr).expect("account loaded;"); @@ -95,7 +96,7 @@ pub fn process_create( where DB: Database, { - let broadcast_sender = h160_to_b160(broadcast_sender); + let broadcast_sender = broadcast_sender.to_alloy(); match call.scheme { revm::primitives::CreateScheme::Create => { call.caller = broadcast_sender; @@ -133,7 +134,7 @@ where // Proxy deployer requires the data to be on the following format `salt.init_code` let mut calldata = BytesMut::with_capacity(32 + bytecode.len()); - let salt = ru256_to_u256(salt); + let salt = salt.to_ethers(); let mut salt_bytes = [0u8; 32]; salt.to_big_endian(&mut salt_bytes); calldata.put_slice(&salt_bytes); @@ -141,7 +142,7 @@ where Ok(( calldata.freeze(), - Some(NameOrAddress::Address(b160_to_h160(DEFAULT_CREATE2_DEPLOYER))), + Some(NameOrAddress::Address(DEFAULT_CREATE2_DEPLOYER.to_ethers())), nonce, )) } @@ -170,8 +171,8 @@ pub fn check_if_fixed_gas_limit( // time of the call, which should be rather close to configured gas limit. // TODO: Find a way to reliably make this determination. (for example by // generating it in the compilation or evm simulation process) - U256::from(data.env.tx.gas_limit) > ru256_to_u256(data.env.block.gas_limit) && - U256::from(call_gas_limit) <= ru256_to_u256(data.env.block.gas_limit) + U256::from(data.env.tx.gas_limit) > data.env.block.gas_limit.to_ethers() && + U256::from(call_gas_limit) <= data.env.block.gas_limit.to_ethers() // Transfers in forge scripts seem to be estimated at 2300 by revm leading to "Intrinsic // gas too low" failure when simulated on chain && call_gas_limit > 2300 diff --git a/crates/evm/src/executor/inspector/coverage.rs b/crates/evm/src/executor/inspector/coverage.rs index 1a549de04e95d..ba8dadc5f8564 100644 --- a/crates/evm/src/executor/inspector/coverage.rs +++ b/crates/evm/src/executor/inspector/coverage.rs @@ -1,8 +1,6 @@ -use crate::{ - coverage::{HitMap, HitMaps}, - utils::b256_to_h256, -}; +use crate::coverage::{HitMap, HitMaps}; use bytes::Bytes; +use foundry_utils::types::ToEthers; use revm::{ interpreter::{InstructionResult, Interpreter}, Database, EVMData, Inspector, @@ -21,7 +19,7 @@ impl Inspector for CoverageCollector { interpreter: &mut Interpreter, _: &mut EVMData<'_, DB>, ) -> InstructionResult { - let hash = b256_to_h256(interpreter.contract.hash); + let hash = interpreter.contract.hash.to_ethers(); self.maps.entry(hash).or_insert_with(|| { HitMap::new(Bytes::copy_from_slice( interpreter.contract.bytecode.original_bytecode_slice(), @@ -37,7 +35,7 @@ impl Inspector for CoverageCollector { interpreter: &mut Interpreter, _: &mut EVMData<'_, DB>, ) -> InstructionResult { - let hash = b256_to_h256(interpreter.contract.hash); + let hash = interpreter.contract.hash.to_ethers(); self.maps.entry(hash).and_modify(|map| map.hit(interpreter.program_counter())); InstructionResult::Continue diff --git a/crates/evm/src/executor/inspector/fuzzer.rs b/crates/evm/src/executor/inspector/fuzzer.rs index be46192c92974..3c873b5673859 100644 --- a/crates/evm/src/executor/inspector/fuzzer.rs +++ b/crates/evm/src/executor/inspector/fuzzer.rs @@ -1,8 +1,9 @@ use crate::{ fuzz::{invariant::RandomCallGenerator, strategies::EvmFuzzState}, - utils::{self, b160_to_h160, h160_to_b160}, + utils, }; use alloy_primitives::Bytes; +use foundry_utils::types::{ToAlloy, ToEthers}; use revm::{ interpreter::{CallInputs, CallScheme, Gas, InstructionResult, Interpreter}, Database, EVMData, Inspector, @@ -79,7 +80,7 @@ impl Fuzzer { let mut state = self.fuzz_state.write(); for slot in interpreter.stack().data() { - state.values_mut().insert(utils::u256_to_h256_be(utils::ru256_to_u256(*slot)).into()); + state.values_mut().insert(utils::u256_to_h256_be(slot.to_ethers()).into()); } // TODO: disabled for now since it's flooding the dictionary @@ -95,21 +96,21 @@ impl Fuzzer { fn override_call(&mut self, call: &mut CallInputs) { if let Some(ref mut call_generator) = self.call_generator { // We only override external calls which are not coming from the test contract. - if call.context.caller != h160_to_b160(call_generator.test_address) && + if call.context.caller != call_generator.test_address.to_alloy() && call.context.scheme == CallScheme::Call && !call_generator.used { // There's only a 30% chance that an override happens. - if let Some((sender, (contract, input))) = call_generator - .next(b160_to_h160(call.context.caller), b160_to_h160(call.contract)) + if let Some((sender, (contract, input))) = + call_generator.next(call.context.caller.to_ethers(), call.contract.to_ethers()) { *call.input = input.0; - call.context.caller = h160_to_b160(sender); - call.contract = h160_to_b160(contract); + call.context.caller = sender.to_alloy(); + call.contract = contract.to_alloy(); // TODO: in what scenarios can the following be problematic - call.context.code_address = h160_to_b160(contract); - call.context.address = h160_to_b160(contract); + call.context.code_address = contract.to_alloy(); + call.context.address = contract.to_alloy(); call_generator.used = true; } diff --git a/crates/evm/src/executor/inspector/logs.rs b/crates/evm/src/executor/inspector/logs.rs index 56b9897a7aaa8..a0c1d8be2adf0 100644 --- a/crates/evm/src/executor/inspector/logs.rs +++ b/crates/evm/src/executor/inspector/logs.rs @@ -1,6 +1,5 @@ -use crate::{ - executor::{patch_hardhat_console_selector, HardhatConsoleCalls, HARDHAT_CONSOLE_ADDRESS}, - utils::{b160_to_h160, b256_to_h256}, +use crate::executor::{ + patch_hardhat_console_selector, HardhatConsoleCalls, HARDHAT_CONSOLE_ADDRESS, }; use alloy_primitives::{Address, Bytes, B256}; use ethers::{ @@ -8,6 +7,7 @@ use ethers::{ types::{Bytes as ethersBytes, Log, H256}, }; use foundry_macros::ConsoleFmt; +use foundry_utils::types::ToEthers; use revm::{ interpreter::{CallInputs, Gas, InstructionResult}, Database, EVMData, Inspector, @@ -45,8 +45,8 @@ impl LogCollector { impl Inspector for LogCollector { fn log(&mut self, _: &mut EVMData<'_, DB>, address: &Address, topics: &[B256], data: &Bytes) { self.logs.push(Log { - address: b160_to_h160(*address), - topics: topics.iter().copied().map(b256_to_h256).collect(), + address: address.to_ethers(), + topics: topics.iter().copied().map(|t| t.to_ethers()).collect(), data: ethersBytes::from(data.clone().0), ..Default::default() }); diff --git a/crates/evm/src/executor/inspector/stack.rs b/crates/evm/src/executor/inspector/stack.rs index 5c97b6ca8e4f7..3cd392521c407 100644 --- a/crates/evm/src/executor/inspector/stack.rs +++ b/crates/evm/src/executor/inspector/stack.rs @@ -6,10 +6,10 @@ use crate::{ debug::DebugArena, executor::{backend::DatabaseExt, inspector::CoverageCollector}, trace::CallTraceArena, - utils::{h160_to_b160, ru256_to_u256}, }; use alloy_primitives::{Address, Bytes, B256, U256}; use ethers::{signers::LocalWallet, types::Log}; +use foundry_utils::types::{ToAlloy, ToEthers}; use revm::{ interpreter::{ return_revert, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, Memory, Stack, @@ -242,7 +242,7 @@ impl InspectorStack { #[inline] pub fn set_gas_price(&mut self, gas_price: U256) { if let Some(cheatcodes) = &mut self.cheatcodes { - cheatcodes.gas_price = Some(gas_price).map(ru256_to_u256); + cheatcodes.gas_price = Some(gas_price).map(|g| g.to_ethers()); } } @@ -303,12 +303,7 @@ impl InspectorStack { .cheatcodes .as_ref() .map(|cheatcodes| { - cheatcodes - .labels - .clone() - .into_iter() - .map(|l| (h160_to_b160(l.0), l.1)) - .collect() + cheatcodes.labels.clone().into_iter().map(|l| (l.0.to_alloy(), l.1)).collect() }) .unwrap_or_default(), traces: self.tracer.map(|tracer| tracer.traces), diff --git a/crates/evm/src/executor/inspector/tracer.rs b/crates/evm/src/executor/inspector/tracer.rs index 392ae6c1a6196..349df0f8eeee8 100644 --- a/crates/evm/src/executor/inspector/tracer.rs +++ b/crates/evm/src/executor/inspector/tracer.rs @@ -5,11 +5,11 @@ use crate::{ CallTrace, CallTraceArena, CallTraceStep, LogCallOrder, RawOrDecodedCall, RawOrDecodedLog, RawOrDecodedReturnData, }, - utils::{b160_to_h160, b256_to_h256, ru256_to_u256}, CallKind, }; use alloy_primitives::{Address, Bytes, B256, U256}; use ethers::abi::RawLog; +use foundry_utils::types::ToEthers; use revm::{ interpreter::{ opcode, return_ok, CallInputs, CallScheme, CreateInputs, Gas, InstructionResult, @@ -46,12 +46,12 @@ impl Tracer { 0, CallTrace { depth, - address: b160_to_h160(address), + address: address.to_ethers(), kind, data: RawOrDecodedCall::Raw(data.into()), - value: ru256_to_u256(value), + value: value.to_ethers(), status: InstructionResult::Continue, - caller: b160_to_h160(caller), + caller: caller.to_ethers(), ..Default::default() }, )); @@ -74,7 +74,7 @@ impl Tracer { trace.output = RawOrDecodedReturnData::Raw(output.into()); if let Some(address) = address { - trace.address = b160_to_h160(address); + trace.address = address.to_ethers(); } } @@ -89,7 +89,7 @@ impl Tracer { depth: data.journaled_state.depth(), pc: interp.program_counter(), op: OpCode(interp.current_opcode()), - contract: b160_to_h160(interp.contract.address), + contract: interp.contract.address.to_ethers(), stack: interp.stack.clone(), memory: interp.memory.clone(), gas: interp.gas.remaining(), @@ -124,7 +124,7 @@ impl Tracer { Some(JournalEntry::StorageChange { address, key, .. }), ) => { let value = data.journaled_state.state[address].storage[key].present_value(); - Some((ru256_to_u256(*key), ru256_to_u256(value))) + Some((key.to_ethers(), value.to_ethers())) } _ => None, }; @@ -163,7 +163,7 @@ impl Inspector for Tracer { #[inline] fn log(&mut self, _: &mut EVMData<'_, DB>, _: &Address, topics: &[B256], data: &Bytes) { let node = &mut self.traces.arena[*self.trace_stack.last().expect("no ongoing trace")]; - let topics: Vec<_> = topics.iter().copied().map(b256_to_h256).collect(); + let topics: Vec<_> = topics.iter().copied().map(|t| t.to_ethers()).collect(); node.ordering.push(LogCallOrder::Log(node.logs.len())); node.logs.push(RawOrDecodedLog::Raw(RawLog { topics, data: data.to_vec() })); } diff --git a/crates/evm/src/fuzz/invariant/error.rs b/crates/evm/src/fuzz/invariant/error.rs index b917a1ca83a08..89d95da4a1c77 100644 --- a/crates/evm/src/fuzz/invariant/error.rs +++ b/crates/evm/src/fuzz/invariant/error.rs @@ -4,7 +4,6 @@ use crate::{ executor::{Executor, RawCallResult}, fuzz::{invariant::set_up_inner_replay, *}, trace::{load_contracts, TraceKind, Traces}, - utils::h160_to_b160, CALLER, }; use ethers::abi::Function; @@ -108,8 +107,8 @@ impl InvariantFuzzError { for (sender, (addr, bytes)) in calls.iter() { let call_result = executor .call_raw_committing( - h160_to_b160(*sender), - h160_to_b160(*addr), + sender.to_alloy(), + addr.to_alloy(), bytes.0.clone().into(), U256::ZERO, ) @@ -138,7 +137,7 @@ impl InvariantFuzzError { // Checks the invariant. if let Some(func) = &self.func { let error_call_result = executor - .call_raw(CALLER, h160_to_b160(self.addr), func.0.clone().into(), U256::ZERO) + .call_raw(CALLER, self.addr.to_alloy(), func.0.clone().into(), U256::ZERO) .expect("bad call to evm"); traces.push((TraceKind::Execution, error_call_result.traces.clone().unwrap())); @@ -174,8 +173,8 @@ impl InvariantFuzzError { executor .call_raw_committing( - h160_to_b160(*sender), - h160_to_b160(*addr), + sender.to_alloy(), + addr.to_alloy(), bytes.0.clone().into(), U256::ZERO, ) @@ -184,7 +183,7 @@ impl InvariantFuzzError { // Checks the invariant. If we exit before the last call, all the better. if let Some(func) = &self.func { let error_call_result = executor - .call_raw(CALLER, h160_to_b160(self.addr), func.0.clone().into(), U256::ZERO) + .call_raw(CALLER, self.addr.to_alloy(), func.0.clone().into(), U256::ZERO) .expect("bad call to evm"); if error_call_result.reverted { diff --git a/crates/evm/src/fuzz/invariant/executor.rs b/crates/evm/src/fuzz/invariant/executor.rs index a16a51c224595..a1b9faee9b0d4 100644 --- a/crates/evm/src/fuzz/invariant/executor.rs +++ b/crates/evm/src/fuzz/invariant/executor.rs @@ -16,13 +16,14 @@ use crate::{ }, FuzzCase, FuzzedCases, }, - utils::{b160_to_h160, get_function, h160_to_b160}, + utils::get_function, CALLER, }; use ethers::abi::{Abi, Address, Detokenize, FixedBytes, Tokenizable, TokenizableItem}; use eyre::{eyre, ContextCompat, Result}; use foundry_common::contracts::{ContractsByAddress, ContractsByArtifact}; use foundry_config::{FuzzDictionaryConfig, InvariantConfig}; +use foundry_utils::types::{ToAlloy, ToEthers}; use parking_lot::{Mutex, RwLock}; use proptest::{ strategy::{BoxedStrategy, Strategy, ValueTree}, @@ -149,8 +150,8 @@ impl<'a> InvariantExecutor<'a> { // Executes the call from the randomly generated sequence. let call_result = executor .call_raw( - h160_to_b160(*sender), - h160_to_b160(*address), + sender.to_alloy(), + address.to_alloy(), calldata.0.clone().into(), rU256::ZERO, ) @@ -424,8 +425,8 @@ impl<'a> InvariantExecutor<'a> { .into_iter() .filter(|(addr, (identifier, _))| { *addr != invariant_address && - *addr != b160_to_h160(CHEATCODE_ADDRESS) && - *addr != b160_to_h160(HARDHAT_CONSOLE_ADDRESS) && + *addr != CHEATCODE_ADDRESS.to_ethers() && + *addr != HARDHAT_CONSOLE_ADDRESS.to_ethers() && (selected.is_empty() || selected.contains(addr)) && (self.artifact_filters.targeted.is_empty() || self.artifact_filters.targeted.contains_key(identifier)) && @@ -567,7 +568,7 @@ impl<'a> InvariantExecutor<'a> { if let Some(func) = abi.functions().find(|func| func.name == method_name) { if let Ok(call_result) = self.executor.call::, _, _>( CALLER, - h160_to_b160(address), + address.to_alloy(), func.clone(), (), rU256::ZERO, @@ -599,7 +600,7 @@ fn collect_data( // Verify it has no code. let mut has_code = false; if let Some(Some(code)) = - state_changeset.get(&h160_to_b160(*sender)).map(|account| account.info.code.as_ref()) + state_changeset.get(&sender.to_alloy()).map(|account| account.info.code.as_ref()) { has_code = !code.is_empty(); } @@ -607,14 +608,14 @@ fn collect_data( // We keep the nonce changes to apply later. let mut sender_changeset = None; if !has_code { - sender_changeset = state_changeset.remove(&h160_to_b160(*sender)); + sender_changeset = state_changeset.remove(&sender.to_alloy()); } collect_state_from_call(&call_result.logs, &*state_changeset, fuzz_state, config); // Re-add changes if let Some(changed) = sender_changeset { - state_changeset.insert(h160_to_b160(*sender), changed); + state_changeset.insert(sender.to_alloy(), changed); } } @@ -637,7 +638,7 @@ fn can_continue( // Detect handler assertion failures first. let handlers_failed = targeted_contracts.lock().iter().any(|contract| { - !executor.is_success(h160_to_b160(*contract.0), false, state_changeset.clone(), false) + !executor.is_success(contract.0.to_alloy(), false, state_changeset.clone(), false) }); // Assert invariants IFF the call did not revert and the handlers did not fail. diff --git a/crates/evm/src/fuzz/invariant/mod.rs b/crates/evm/src/fuzz/invariant/mod.rs index 38761753ecb72..7072382797c6c 100644 --- a/crates/evm/src/fuzz/invariant/mod.rs +++ b/crates/evm/src/fuzz/invariant/mod.rs @@ -4,7 +4,6 @@ use crate::{ executor::Executor, fuzz::*, trace::{load_contracts, TraceKind, Traces}, - utils::h160_to_b160, CALLER, }; use ethers::{ @@ -69,7 +68,7 @@ pub fn assert_invariants( let mut call_result = executor .call_raw( CALLER, - h160_to_b160(invariant_contract.address), + invariant_contract.address.to_alloy(), func.encode_input(&[]).expect("invariant should have no inputs").into(), U256::ZERO, ) @@ -78,7 +77,7 @@ pub fn assert_invariants( // This will panic and get caught by the executor let is_err = call_result.reverted || !executor.is_success( - h160_to_b160(invariant_contract.address), + invariant_contract.address.to_alloy(), call_result.reverted, call_result.state_changeset.take().expect("we should have a state changeset"), false, @@ -122,8 +121,8 @@ pub fn replay_run( for (sender, (addr, bytes)) in inputs.iter() { let call_result = executor .call_raw_committing( - h160_to_b160(*sender), - h160_to_b160(*addr), + sender.to_alloy(), + addr.to_alloy(), bytes.0.clone().into(), U256::ZERO, ) @@ -142,7 +141,7 @@ pub fn replay_run( let error_call_result = executor .call_raw( CALLER, - h160_to_b160(invariant_contract.address), + invariant_contract.address.to_alloy(), func.encode_input(&[]).expect("invariant should have no inputs").into(), U256::ZERO, ) diff --git a/crates/evm/src/fuzz/mod.rs b/crates/evm/src/fuzz/mod.rs index 9ff21ef33b791..c22b00ed460cd 100644 --- a/crates/evm/src/fuzz/mod.rs +++ b/crates/evm/src/fuzz/mod.rs @@ -4,7 +4,6 @@ use crate::{ decode::{self, decode_console_logs}, executor::{Executor, RawCallResult}, trace::CallTraceArena, - utils::{b160_to_h160, h160_to_b160}, }; use alloy_primitives::U256; use error::{FuzzError, ASSUME_MAGIC_RETURN_CODE}; @@ -15,6 +14,7 @@ use ethers::{ use eyre::Result; use foundry_common::{calc, contracts::ContractsByAddress}; use foundry_config::FuzzConfig; +use foundry_utils::types::{ToAlloy, ToEthers}; pub use proptest::test_runner::Reason; use proptest::test_runner::{TestCaseError, TestError, TestRunner}; use serde::{Deserialize, Serialize}; @@ -152,7 +152,7 @@ impl<'a> FuzzedExecutor<'a> { counterexample: None, decoded_logs: decode_console_logs(&call.logs), logs: call.logs, - labeled_addresses: call.labels.into_iter().map(|l| (b160_to_h160(l.0), l.1)).collect(), + labeled_addresses: call.labels.into_iter().map(|l| (l.0.to_ethers(), l.1)).collect(), traces: if run_result.is_ok() { traces.into_inner() } else { call.traces.clone() }, coverage: coverage.into_inner(), }; @@ -202,8 +202,8 @@ impl<'a> FuzzedExecutor<'a> { let call = self .executor .call_raw( - h160_to_b160(self.sender), - h160_to_b160(address), + self.sender.to_alloy(), + address.to_alloy(), calldata.0.clone().into(), U256::ZERO, ) @@ -232,7 +232,7 @@ impl<'a> FuzzedExecutor<'a> { .map_or_else(Default::default, |cheats| cheats.breakpoints.clone()); let success = self.executor.is_success( - h160_to_b160(address), + address.to_alloy(), call.reverted, state_changeset.clone(), should_fail, diff --git a/crates/evm/src/fuzz/strategies/state.rs b/crates/evm/src/fuzz/strategies/state.rs index 7a8439b36da9e..85584b4fed4cc 100644 --- a/crates/evm/src/fuzz/strategies/state.rs +++ b/crates/evm/src/fuzz/strategies/state.rs @@ -2,7 +2,7 @@ use super::fuzz_param_from_state; use crate::{ executor::StateChangeset, fuzz::invariant::{ArtifactFilters, FuzzRunIdentifiedContracts}, - utils::{self, b160_to_h160, ru256_to_u256}, + utils, }; use bytes::Bytes; use ethers::{ @@ -11,6 +11,7 @@ use ethers::{ }; use foundry_common::contracts::{ContractsByAddress, ContractsByArtifact}; use foundry_config::FuzzDictionaryConfig; +use foundry_utils::types::ToEthers; use hashbrown::HashSet; use parking_lot::RwLock; use proptest::prelude::{BoxedStrategy, Strategy}; @@ -100,7 +101,7 @@ pub fn build_initial_state( let mut state = FuzzDictionary::default(); for (address, account) in db.accounts.iter() { - let address: Address = b160_to_h160(*address); + let address: Address = address.to_ethers(); // Insert basic account information state.values_mut().insert(H256::from(address).into()); @@ -118,8 +119,8 @@ pub fn build_initial_state( if config.include_storage { // Insert storage for (slot, value) in &account.storage { - let slot = ru256_to_u256(*slot); - let value = ru256_to_u256(*value); + let slot = slot.to_ethers(); + let value = value.to_ethers(); state.values_mut().insert(utils::u256_to_h256_be(slot).into()); state.values_mut().insert(utils::u256_to_h256_be(value).into()); // also add the value below and above the storage value to the dictionary. @@ -157,13 +158,13 @@ pub fn collect_state_from_call( for (address, account) in state_changeset { // Insert basic account information - state.values_mut().insert(H256::from(b160_to_h160(*address)).into()); + state.values_mut().insert(H256::from(address.to_ethers()).into()); if config.include_push_bytes && state.addresses.len() < config.max_fuzz_dictionary_addresses { // Insert push bytes if let Some(code) = &account.info.code { - if state.addresses_mut().insert(b160_to_h160(*address)) { + if state.addresses_mut().insert(address.to_ethers()) { for push_byte in collect_push_bytes(code.bytes().clone().0) { state.values_mut().insert(push_byte); } @@ -174,8 +175,8 @@ pub fn collect_state_from_call( if config.include_storage && state.state_values.len() < config.max_fuzz_dictionary_values { // Insert storage for (slot, value) in &account.storage { - let slot = ru256_to_u256(*slot); - let value = ru256_to_u256(value.present_value()); + let slot = slot.to_ethers(); + let value = value.present_value().to_ethers(); state.values_mut().insert(utils::u256_to_h256_be(slot).into()); state.values_mut().insert(utils::u256_to_h256_be(value).into()); // also add the value below and above the storage value to the dictionary. @@ -267,7 +268,7 @@ pub fn collect_created_contracts( let mut writable_targeted = targeted_contracts.lock(); for (address, account) in state_changeset { - if !setup_contracts.contains_key(&b160_to_h160(*address)) { + if !setup_contracts.contains_key(&address.to_ethers()) { if let (true, Some(code)) = (&account.is_touched(), &account.info.code) { if !code.is_empty() { if let Some((artifact, (abi, _))) = project_contracts.find_by_code(code.bytes()) @@ -275,9 +276,9 @@ pub fn collect_created_contracts( if let Some(functions) = artifact_filters.get_targeted_functions(artifact, abi)? { - created_contracts.push(b160_to_h160(*address)); + created_contracts.push(address.to_ethers()); writable_targeted.insert( - b160_to_h160(*address), + address.to_ethers(), (artifact.name.clone(), abi.clone(), functions), ); } diff --git a/crates/evm/src/trace/decoder.rs b/crates/evm/src/trace/decoder.rs index 11db65c2fca10..3924c38125315 100644 --- a/crates/evm/src/trace/decoder.rs +++ b/crates/evm/src/trace/decoder.rs @@ -7,7 +7,6 @@ use crate::{ decode, executor::inspector::DEFAULT_CREATE2_DEPLOYER, trace::{node::CallTraceNode, utils}, - utils::b160_to_h160, CALLER, TEST_CONTRACT_ADDRESS, }; use ethers::{ @@ -15,6 +14,7 @@ use ethers::{ types::{H160, H256}, }; use foundry_common::{abi::get_indexed_event, SELECTOR_LEN}; +use foundry_utils::types::ToEthers; use hashbrown::HashSet; use once_cell::sync::OnceCell; use std::collections::{BTreeMap, HashMap}; @@ -157,11 +157,11 @@ impl CallTraceDecoder { contracts: Default::default(), labels: [ - (b160_to_h160(CHEATCODE_ADDRESS), "VM".to_string()), - (b160_to_h160(HARDHAT_CONSOLE_ADDRESS), "console".to_string()), - (b160_to_h160(DEFAULT_CREATE2_DEPLOYER), "Create2Deployer".to_string()), - (b160_to_h160(CALLER), "DefaultSender".to_string()), - (b160_to_h160(TEST_CONTRACT_ADDRESS), "DefaultTestContract".to_string()), + (CHEATCODE_ADDRESS.to_ethers(), "VM".to_string()), + (HARDHAT_CONSOLE_ADDRESS.to_ethers(), "console".to_string()), + (DEFAULT_CREATE2_DEPLOYER.to_ethers(), "Create2Deployer".to_string()), + (CALLER.to_ethers(), "DefaultSender".to_string()), + (TEST_CONTRACT_ADDRESS.to_ethers(), "DefaultTestContract".to_string()), ] .into(), @@ -257,7 +257,7 @@ impl CallTraceDecoder { if bytes.len() >= 4 { if let Some(funcs) = self.functions.get(&bytes[..SELECTOR_LEN]) { node.decode_function(funcs, &self.labels, &self.errors, self.verbosity); - } else if node.trace.address == b160_to_h160(DEFAULT_CREATE2_DEPLOYER) { + } else if node.trace.address == DEFAULT_CREATE2_DEPLOYER.to_ethers() { node.trace.data = RawOrDecodedCall::Decoded("create2".to_string(), String::new(), vec![]); } else if let Some(identifier) = &self.signature_identifier { diff --git a/crates/evm/src/trace/mod.rs b/crates/evm/src/trace/mod.rs index 5b7365333d7c6..fd479dc795a45 100644 --- a/crates/evm/src/trace/mod.rs +++ b/crates/evm/src/trace/mod.rs @@ -1,9 +1,5 @@ use crate::{ - abi::CHEATCODE_ADDRESS, - debug::Instruction, - trace::identifier::LocalTraceIdentifier, - utils::{b160_to_h160, ru256_to_u256}, - CallKind, + abi::CHEATCODE_ADDRESS, debug::Instruction, trace::identifier::LocalTraceIdentifier, CallKind, }; pub use decoder::{CallTraceDecoder, CallTraceDecoderBuilder}; use ethers::{ @@ -13,6 +9,7 @@ use ethers::{ }; pub use executor::TracingExecutor; use foundry_common::contracts::{ContractsByAddress, ContractsByArtifact}; +use foundry_utils::types::ToEthers; use hashbrown::HashMap; use node::CallTraceNode; use revm::interpreter::{opcode, CallContext, InstructionResult, Memory, Stack}; @@ -433,7 +430,7 @@ impl From<&CallTraceStep> for StructLog { } else { None }, - stack: Some(step.stack.data().iter().copied().map(ru256_to_u256).collect()), + stack: Some(step.stack.data().iter().copied().map(|s| s.to_ethers()).collect()), // Filled in `CallTraceArena::geth_trace` as a result of compounding all slot changes storage: None, } @@ -600,7 +597,7 @@ impl TraceKind { /// Chooses the color of the trace depending on the destination address and status of the call. fn trace_color(trace: &CallTrace) -> Color { - if trace.address == b160_to_h160(CHEATCODE_ADDRESS) { + if trace.address == CHEATCODE_ADDRESS.to_ethers() { Color::Blue } else if trace.success { Color::Green diff --git a/crates/evm/src/trace/node.rs b/crates/evm/src/trace/node.rs index 7b9a2930e9c02..dc0c58f2017d4 100644 --- a/crates/evm/src/trace/node.rs +++ b/crates/evm/src/trace/node.rs @@ -5,7 +5,6 @@ use crate::{ utils, utils::decode_cheatcode_outputs, CallTrace, LogCallOrder, RawOrDecodedCall, RawOrDecodedLog, RawOrDecodedReturnData, }, - utils::b160_to_h160, CallKind, }; use ethers::{ @@ -13,6 +12,7 @@ use ethers::{ types::{Action, Address, Call, CallResult, Create, CreateResult, Res, Suicide}, }; use foundry_common::SELECTOR_LEN; +use foundry_utils::types::ToEthers; use revm::interpreter::InstructionResult; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -110,7 +110,7 @@ impl CallTraceNode { if let RawOrDecodedCall::Raw(ref bytes) = self.trace.data { let inputs = if bytes.len() >= SELECTOR_LEN { - if self.trace.address == b160_to_h160(CHEATCODE_ADDRESS) { + if self.trace.address == CHEATCODE_ADDRESS.to_ethers() { // Try to decode cheatcode inputs in a more custom way utils::decode_cheatcode_inputs(func, bytes, errors, verbosity).unwrap_or_else( || { @@ -137,7 +137,7 @@ impl CallTraceNode { if let RawOrDecodedReturnData::Raw(bytes) = &self.trace.output { if !bytes.is_empty() && self.trace.success { - if self.trace.address == b160_to_h160(CHEATCODE_ADDRESS) { + if self.trace.address == CHEATCODE_ADDRESS.to_ethers() { if let Some(decoded) = funcs .iter() .find_map(|func| decode_cheatcode_outputs(func, bytes, verbosity)) diff --git a/crates/evm/src/utils.rs b/crates/evm/src/utils.rs index ad0b0851e5dc2..51f45070255a3 100644 --- a/crates/evm/src/utils.rs +++ b/crates/evm/src/utils.rs @@ -1,8 +1,9 @@ use ethers::{ abi::{Abi, FixedBytes, Function}, - types::{Block, Chain, H160, H256, U256}, + types::{Block, Chain, H256, U256}, }; use eyre::ContextCompat; +use foundry_utils::types::ToAlloy; use revm::{ interpreter::{opcode, opcode::spec_opcode_gas, InstructionResult}, primitives::{Eval, Halt, SpecId}, @@ -37,50 +38,6 @@ pub fn h256_to_u256_le(storage: H256) -> U256 { U256::from_little_endian(storage.as_bytes()) } -/// Small helper function to convert revm's [B160] into ethers's [H160]. -#[inline] -pub fn b160_to_h160(b: alloy_primitives::Address) -> ethers::types::H160 { - H160::from_slice(b.as_slice()) -} - -/// Small helper function to convert ethers's [H160] into revm's [B160]. -#[inline] -pub fn h160_to_b160(h: ethers::types::H160) -> alloy_primitives::Address { - alloy_primitives::Address::from_slice(h.as_bytes()) -} - -/// Small helper function to convert revm's [B256] into ethers's [H256]. -#[inline] -pub fn b256_to_h256(b: revm::primitives::B256) -> ethers::types::H256 { - ethers::types::H256(b.0) -} - -/// Small helper function to convert ether's [H256] into revm's [B256]. -#[inline] -pub fn h256_to_b256(h: ethers::types::H256) -> alloy_primitives::B256 { - alloy_primitives::B256::from_slice(h.as_bytes()) -} - -/// Small helper function to convert ether's [U256] into revm's [U256]. -#[inline] -pub fn u256_to_ru256(u: ethers::types::U256) -> revm::primitives::U256 { - let mut buffer = [0u8; 32]; - u.to_little_endian(buffer.as_mut_slice()); - revm::primitives::U256::from_le_bytes(buffer) -} - -// Small helper function to convert ethers's [U64] into alloy's [U64]. -#[inline] -pub fn u64_to_ru64(u: ethers::types::U64) -> alloy_primitives::U64 { - alloy_primitives::U64::from(u.as_u64()) -} - -/// Small helper function to convert revm's [U256] into ethers's [U256]. -#[inline] -pub fn ru256_to_u256(u: alloy_primitives::U256) -> ethers::types::U256 { - ethers::types::U256::from_little_endian(&u.as_le_bytes()) -} - /// Small helper function to convert an Eval into an InstructionResult #[inline] pub fn eval_to_instruction_result(eval: Eval) -> InstructionResult { @@ -145,7 +102,7 @@ pub fn apply_chain_and_block_specific_env_changes( // `l1BlockNumber` field if let Some(l1_block_number) = block.other.get("l1BlockNumber").cloned() { if let Ok(l1_block_number) = serde_json::from_value::(l1_block_number) { - env.block.number = u256_to_ru256(l1_block_number); + env.block.number = l1_block_number.to_alloy(); } } } diff --git a/crates/forge/bin/cmd/coverage.rs b/crates/forge/bin/cmd/coverage.rs index 473cb59ba8a2b..48e19dfd60bdd 100644 --- a/crates/forge/bin/cmd/coverage.rs +++ b/crates/forge/bin/cmd/coverage.rs @@ -27,7 +27,7 @@ use foundry_cli::{ }; use foundry_common::{compile::ProjectCompiler, evm::EvmArgs, fs}; use foundry_config::{Config, SolcReq}; -use foundry_evm::utils::{b160_to_h160, ru256_to_u256}; +use foundry_utils::types::ToEthers; use semver::Version; use std::{collections::HashMap, sync::mpsc::channel}; use tracing::trace; @@ -288,9 +288,9 @@ impl CoverageArgs { // Build the contract runner let env = evm_opts.evm_env().await?; let mut runner = MultiContractRunnerBuilder::default() - .initial_balance(ru256_to_u256(evm_opts.initial_balance)) + .initial_balance(evm_opts.initial_balance.to_ethers()) .evm_spec(config.evm_spec_id()) - .sender(b160_to_h160(evm_opts.sender)) + .sender(evm_opts.sender.to_ethers()) .with_fork(evm_opts.get_fork(&config, env.clone())) .with_cheats_config(CheatsConfig::new(&config, &evm_opts)) .with_test_options(TestOptions { fuzz: config.fuzz, ..Default::default() }) diff --git a/crates/forge/bin/cmd/script/build.rs b/crates/forge/bin/cmd/script/build.rs index aee3846933c87..fc959a240d45b 100644 --- a/crates/forge/bin/cmd/script/build.rs +++ b/crates/forge/bin/cmd/script/build.rs @@ -16,8 +16,7 @@ use foundry_common::{ compact_to_contract, compile::{self, ContractSources}, }; -use foundry_evm::utils::b160_to_h160; -use foundry_utils::{PostLinkInput, ResolvedDependency}; +use foundry_utils::{types::ToEthers, PostLinkInput, ResolvedDependency}; use std::{collections::BTreeMap, fs, str::FromStr}; use tracing::{trace, warn}; @@ -65,7 +64,7 @@ impl ScriptArgs { project, contracts, script_config.config.parsed_libraries()?, - b160_to_h160(script_config.evm_opts.sender), + script_config.evm_opts.sender.to_ethers(), script_config.sender_nonce, )?; diff --git a/crates/forge/bin/cmd/script/cmd.rs b/crates/forge/bin/cmd/script/cmd.rs index 8c602180f247a..b54a3921796b3 100644 --- a/crates/forge/bin/cmd/script/cmd.rs +++ b/crates/forge/bin/cmd/script/cmd.rs @@ -7,7 +7,7 @@ use eyre::Result; use foundry_cli::utils::LoadConfig; use foundry_common::{contracts::flatten_contracts, try_get_http_provider}; use foundry_debugger::DebuggerArgs; -use foundry_evm::utils::b160_to_h160; +use foundry_utils::types::{ToAlloy, ToEthers}; use std::sync::Arc; use tracing::trace; @@ -33,12 +33,9 @@ impl ScriptArgs { if let Some(ref fork_url) = script_config.evm_opts.fork_url { // when forking, override the sender's nonce to the onchain value - script_config.sender_nonce = foundry_utils::next_nonce( - b160_to_h160(script_config.evm_opts.sender), - fork_url, - None, - ) - .await? + script_config.sender_nonce = + foundry_utils::next_nonce(script_config.evm_opts.sender.to_ethers(), fork_url, None) + .await? } else { // if not forking, then ignore any pre-deployed library addresses script_config.config.libraries = Default::default(); @@ -71,7 +68,7 @@ impl ScriptArgs { // We need to execute the script even if just resuming, in case we need to collect private // keys from the execution. let mut result = self - .execute(&mut script_config, contract, b160_to_h160(sender), &predeploy_libraries) + .execute(&mut script_config, contract, sender.to_ethers(), &predeploy_libraries) .await?; if self.resume || (self.verify && !self.broadcast) { @@ -166,7 +163,7 @@ impl ScriptArgs { // Add predeploy libraries to the list of broadcastable transactions. let mut lib_deploy = self.create_deploy_transactions( - b160_to_h160(script_config.evm_opts.sender), + script_config.evm_opts.sender.to_ethers(), script_config.sender_nonce, &predeploy_libraries, &script_config.evm_opts.fork_url, @@ -356,7 +353,7 @@ impl ScriptArgs { } if let Some(wallets) = self.wallets.private_keys()? { if wallets.len() == 1 { - script_config.evm_opts.sender = h160_to_b160(wallets.get(0).unwrap().address()) + script_config.evm_opts.sender = wallets.get(0).unwrap().address().to_alloy() } } Ok(()) diff --git a/crates/forge/bin/cmd/script/executor.rs b/crates/forge/bin/cmd/script/executor.rs index 39915a8b3d421..e2eb27b176e63 100644 --- a/crates/forge/bin/cmd/script/executor.rs +++ b/crates/forge/bin/cmd/script/executor.rs @@ -20,7 +20,7 @@ use forge::{ }; use foundry_cli::utils::{ensure_clean_constructor, needs_setup}; use foundry_common::{shell, RpcUrl}; -use foundry_evm::utils::{b160_to_h160, ru256_to_u256}; +use foundry_utils::types::ToEthers; use futures::future::join_all; use parking_lot::RwLock; use std::{collections::VecDeque, sync::Arc}; @@ -264,7 +264,7 @@ impl ScriptArgs { rpc.clone(), self.prepare_runner( &mut script_config, - b160_to_h160(sender), + sender.to_ethers(), SimulationStage::OnChain, ) .await, @@ -324,7 +324,7 @@ impl ScriptArgs { ScriptRunner::new( builder.build(env, db), - ru256_to_u256(script_config.evm_opts.initial_balance), + script_config.evm_opts.initial_balance.to_ethers(), sender, ) } diff --git a/crates/forge/bin/cmd/script/mod.rs b/crates/forge/bin/cmd/script/mod.rs index 693eed7dad0a8..31e62e5e8c9d0 100644 --- a/crates/forge/bin/cmd/script/mod.rs +++ b/crates/forge/bin/cmd/script/mod.rs @@ -50,8 +50,8 @@ use foundry_evm::{ cheatcodes::{util::BroadcastableTransactions, BroadcastableTransaction}, DEFAULT_CREATE2_DEPLOYER, }, - utils::h160_to_b160, }; +use foundry_utils::types::ToAlloy; use futures::future; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; @@ -406,7 +406,7 @@ impl ScriptArgs { shell::println("You have more than one deployer who could predeploy libraries. Using `--sender` instead.")?; return Ok(None) } - } else if h160_to_b160(sender) != evm_opts.sender { + } else if sender.to_alloy() != evm_opts.sender { new_sender = Some(sender); } } @@ -551,7 +551,7 @@ impl ScriptArgs { // Find if it's a CREATE or CREATE2. Otherwise, skip transaction. if let Some(NameOrAddress::Address(to)) = to { - if h160_to_b160(*to) == DEFAULT_CREATE2_DEPLOYER { + if to.to_alloy() == DEFAULT_CREATE2_DEPLOYER { // Size of the salt prefix. offset = 32; } diff --git a/crates/forge/bin/cmd/script/runner.rs b/crates/forge/bin/cmd/script/runner.rs index e088a222f1a3f..56592a92c4944 100644 --- a/crates/forge/bin/cmd/script/runner.rs +++ b/crates/forge/bin/cmd/script/runner.rs @@ -10,7 +10,7 @@ use forge::{ trace::{TraceKind, Traces}, CALLER, }; -use foundry_evm::utils::{b160_to_h160, u256_to_ru256}; +use foundry_utils::types::{ToAlloy, ToEthers}; use tracing::log::trace; /// Represents which simulation stage is the script execution at. @@ -47,7 +47,7 @@ impl ScriptRunner { if !is_broadcast { if self.sender == Config::DEFAULT_SENDER { // We max out their balance so that they can deploy and make calls. - self.executor.set_balance(h160_to_b160(self.sender), rU256::MAX)?; + self.executor.set_balance(self.sender.to_alloy(), rU256::MAX)?; } if need_create2_deployer { @@ -55,7 +55,7 @@ impl ScriptRunner { } } - self.executor.set_nonce(h160_to_b160(self.sender), sender_nonce.as_u64())?; + self.executor.set_nonce(self.sender.to_alloy(), sender_nonce.as_u64())?; // We max out their balance so that they can deploy and make calls. self.executor.set_balance(CALLER, rU256::MAX)?; @@ -66,7 +66,7 @@ impl ScriptRunner { .filter_map(|code| { let DeployResult { traces, .. } = self .executor - .deploy(h160_to_b160(self.sender), code.0.clone().into(), rU256::ZERO, None) + .deploy(self.sender.to_alloy(), code.0.clone().into(), rU256::ZERO, None) .expect("couldn't deploy library"); traces @@ -87,7 +87,7 @@ impl ScriptRunner { .map_err(|err| eyre::eyre!("Failed to deploy script:\n{}", err))?; traces.extend(constructor_traces.map(|traces| (TraceKind::Deployment, traces))); - self.executor.set_balance(address, u256_to_ru256(self.initial_balance))?; + self.executor.set_balance(address, self.initial_balance.to_alloy())?; // Optionally call the `setUp` function let (success, gas_used, labeled_addresses, transactions, debug, script_wallets) = if !setup @@ -102,7 +102,7 @@ impl ScriptRunner { vec![], ) } else { - match self.executor.setup(Some(h160_to_b160(self.sender)), address) { + match self.executor.setup(Some(self.sender.to_alloy()), address) { Ok(CallResult { reverted, traces: setup_traces, @@ -159,14 +159,14 @@ impl ScriptRunner { }; Ok(( - b160_to_h160(address), + address.to_ethers(), ScriptResult { returned: bytes::Bytes::new(), success, gas_used, labeled_addresses: labeled_addresses .into_iter() - .map(|l| (b160_to_h160(l.0), l.1)) + .map(|l| (l.0.to_ethers(), l.1)) .collect::>(), transactions, logs, @@ -190,7 +190,7 @@ impl ScriptRunner { if let Some(cheatcodes) = &self.executor.inspector.cheatcodes { if !cheatcodes.corrected_nonce { self.executor.set_nonce( - h160_to_b160(self.sender), + self.sender.to_alloy(), sender_initial_nonce.as_u64() + libraries_len as u64, )?; } @@ -216,13 +216,13 @@ impl ScriptRunner { self.call(from, to, calldata.unwrap_or_default(), value.unwrap_or(U256::zero()), true) } else if to.is_none() { let (address, gas_used, logs, traces, debug) = match self.executor.deploy( - h160_to_b160(from), + from.to_alloy(), calldata.expect("No data for create transaction").0.into(), - u256_to_ru256(value.unwrap_or(U256::zero())), + value.unwrap_or(U256::zero()).to_alloy(), None, ) { Ok(DeployResult { address, gas_used, logs, traces, debug, .. }) => { - (b160_to_h160(address), gas_used, logs, traces, debug) + (address.to_ethers(), gas_used, logs, traces, debug) } Err(EvmError::Execution(err)) => { let ExecutionErr { reason, traces, gas_used, logs, debug, .. } = *err; @@ -269,10 +269,10 @@ impl ScriptRunner { commit: bool, ) -> Result { let mut res = self.executor.call_raw( - h160_to_b160(from), - h160_to_b160(to), + from.to_alloy(), + to.to_alloy(), calldata.0.clone().into(), - u256_to_ru256(value), + value.to_alloy(), )?; let mut gas_used = res.gas_used; @@ -284,10 +284,10 @@ impl ScriptRunner { if commit { gas_used = self.search_optimal_gas_usage(&res, from, to, &calldata, value)?; res = self.executor.call_raw_committing( - h160_to_b160(from), - h160_to_b160(to), + from.to_alloy(), + to.to_alloy(), calldata.0.into(), - u256_to_ru256(value), + value.to_alloy(), )?; } @@ -317,7 +317,7 @@ impl ScriptRunner { }) .unwrap_or_default(), debug: vec![debug].into_iter().collect(), - labeled_addresses: labels.into_iter().map(|l| (b160_to_h160(l.0), l.1)).collect(), + labeled_addresses: labels.into_iter().map(|l| (l.0.to_ethers(), l.1)).collect(), transactions, address: None, script_wallets, @@ -351,10 +351,10 @@ impl ScriptRunner { let mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2; self.executor.env.tx.gas_limit = mid_gas_limit; let res = self.executor.call_raw( - h160_to_b160(from), - h160_to_b160(to), + from.to_alloy(), + to.to_alloy(), calldata.0.clone().into(), - u256_to_ru256(value), + value.to_alloy(), )?; match res.exit_reason { InstructionResult::Revert | diff --git a/crates/forge/bin/cmd/script/transaction.rs b/crates/forge/bin/cmd/script/transaction.rs index 2190a835ab4f5..9b31c9cce118d 100644 --- a/crates/forge/bin/cmd/script/transaction.rs +++ b/crates/forge/bin/cmd/script/transaction.rs @@ -8,9 +8,9 @@ use ethers::{ use eyre::{ContextCompat, Result, WrapErr}; use foundry_common::{abi::format_token_raw, RpcUrl, SELECTOR_LEN}; use foundry_evm::{ - executor::inspector::DEFAULT_CREATE2_DEPLOYER, trace::CallTraceDecoder, utils::h160_to_b160, - CallKind, + executor::inspector::DEFAULT_CREATE2_DEPLOYER, trace::CallTraceDecoder, CallKind, }; +use foundry_utils::types::ToAlloy; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use tracing::error; @@ -77,7 +77,7 @@ impl TransactionWithMetadata { // Specify if any contract was directly created with this transaction if let Some(NameOrAddress::Address(to)) = metadata.transaction.to().cloned() { - if h160_to_b160(to) == DEFAULT_CREATE2_DEPLOYER { + if to.to_alloy() == DEFAULT_CREATE2_DEPLOYER { metadata.set_create( true, Address::from_slice(&result.returned), diff --git a/crates/forge/bin/cmd/test/mod.rs b/crates/forge/bin/cmd/test/mod.rs index 83e528bf1908a..7538d95eaac55 100644 --- a/crates/forge/bin/cmd/test/mod.rs +++ b/crates/forge/bin/cmd/test/mod.rs @@ -32,10 +32,8 @@ use foundry_config::{ get_available_profiles, Config, }; use foundry_debugger::DebuggerArgs; -use foundry_evm::{ - fuzz::CounterExample, - utils::{b160_to_h160, ru256_to_u256}, -}; +use foundry_evm::fuzz::CounterExample; +use foundry_utils::types::ToEthers; use regex::Regex; use std::{collections::BTreeMap, fs, sync::mpsc::channel, time::Duration}; use tracing::trace; @@ -186,9 +184,9 @@ impl TestArgs { let mut runner_builder = MultiContractRunnerBuilder::default() .set_debug(should_debug) - .initial_balance(ru256_to_u256(evm_opts.initial_balance)) + .initial_balance(evm_opts.initial_balance.to_ethers()) .evm_spec(config.evm_spec_id()) - .sender(b160_to_h160(evm_opts.sender)) + .sender(evm_opts.sender.to_ethers()) .with_fork(evm_opts.get_fork(&config, env.clone())) .with_cheats_config(CheatsConfig::new(&config, &evm_opts)) .with_test_options(test_options.clone()); diff --git a/crates/forge/src/gas_report.rs b/crates/forge/src/gas_report.rs index 24d335ab33b71..59e51e78fc888 100644 --- a/crates/forge/src/gas_report.rs +++ b/crates/forge/src/gas_report.rs @@ -5,7 +5,7 @@ use crate::{ use comfy_table::{presets::ASCII_MARKDOWN, *}; use ethers::types::U256; use foundry_common::{calc, TestFunctionExt}; -use foundry_evm::utils::b160_to_h160; +use foundry_utils::types::ToEthers; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, fmt::Display}; @@ -47,8 +47,8 @@ impl GasReport { let node = &arena.arena[node_index]; let trace = &node.trace; - if trace.address == b160_to_h160(CHEATCODE_ADDRESS) || - trace.address == b160_to_h160(HARDHAT_CONSOLE_ADDRESS) + if trace.address == CHEATCODE_ADDRESS.to_ethers() || + trace.address == HARDHAT_CONSOLE_ADDRESS.to_ethers() { return } diff --git a/crates/forge/src/multi_runner.rs b/crates/forge/src/multi_runner.rs index 32ebcd8fed5ca..e126467d0e4ea 100644 --- a/crates/forge/src/multi_runner.rs +++ b/crates/forge/src/multi_runner.rs @@ -13,9 +13,8 @@ use foundry_evm::{ ExecutorBuilder, }, revm, - utils::{b160_to_h160, ru256_to_u256}, }; -use foundry_utils::{PostLinkInput, ResolvedDependency}; +use foundry_utils::{types::ToEthers, PostLinkInput, ResolvedDependency}; use rayon::prelude::*; use revm::primitives::SpecId; use std::{ @@ -208,7 +207,7 @@ impl MultiContractRunner { executor, contract, deploy_code, - ru256_to_u256(self.evm_opts.initial_balance), + self.evm_opts.initial_balance.to_ethers(), self.sender, self.errors.as_ref(), libs, @@ -286,7 +285,7 @@ impl MultiContractRunnerBuilder { ArtifactContracts::from_iter(contracts), &mut known_contracts, Default::default(), - b160_to_h160(evm_opts.sender), + evm_opts.sender.to_ethers(), U256::one(), &mut deployable_contracts, |post_link_input| { diff --git a/crates/forge/src/result.rs b/crates/forge/src/result.rs index a7fccef0f9377..cb26320bb33a2 100644 --- a/crates/forge/src/result.rs +++ b/crates/forge/src/result.rs @@ -9,8 +9,8 @@ use foundry_evm::{ executor::EvmError, fuzz::{types::FuzzCase, CounterExample}, trace::{TraceKind, Traces}, - utils::b160_to_h160, }; +use foundry_utils::types::ToEthers; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, fmt, time::Duration}; @@ -245,7 +245,7 @@ impl TestSetup { // force the tracekind to be setup so a trace is shown. traces.extend(err.traces.map(|traces| (TraceKind::Setup, traces))); logs.extend(err.logs); - labeled_addresses.extend(err.labels.into_iter().map(|l| (b160_to_h160(l.0), l.1))); + labeled_addresses.extend(err.labels.into_iter().map(|l| (l.0.to_ethers(), l.1))); Self::failed_with(logs, traces, labeled_addresses, err.reason) } e => Self::failed_with( diff --git a/crates/forge/src/runner.rs b/crates/forge/src/runner.rs index d48138eabecb2..5e791300d71ab 100644 --- a/crates/forge/src/runner.rs +++ b/crates/forge/src/runner.rs @@ -25,9 +25,9 @@ use foundry_evm::{ CounterExample, FuzzedExecutor, }, trace::{load_contracts, TraceKind}, - utils::{b160_to_h160, h160_to_b160, u256_to_ru256}, CALLER, }; +use foundry_utils::types::{ToAlloy, ToEthers}; use proptest::test_runner::{TestError, TestRunner}; use rayon::prelude::*; use std::{ @@ -98,18 +98,18 @@ impl<'a> ContractRunner<'a> { trace!(?setup, "Setting test contract"); // We max out their balance so that they can deploy and make calls. - self.executor.set_balance(h160_to_b160(self.sender), rU256::MAX)?; + self.executor.set_balance(self.sender.to_alloy(), rU256::MAX)?; self.executor.set_balance(CALLER, rU256::MAX)?; // We set the nonce of the deployer accounts to 1 to get the same addresses as DappTools - self.executor.set_nonce(h160_to_b160(self.sender), 1)?; + self.executor.set_nonce(self.sender.to_alloy(), 1)?; // Deploy libraries let mut logs = Vec::new(); let mut traces = Vec::with_capacity(self.predeploy_libs.len()); for code in self.predeploy_libs.iter() { match self.executor.deploy( - h160_to_b160(self.sender), + self.sender.to_alloy(), code.0.clone().into(), rU256::ZERO, self.errors, @@ -126,7 +126,7 @@ impl<'a> ContractRunner<'a> { // Deploy the test contract let address = match self.executor.deploy( - h160_to_b160(self.sender), + self.sender.to_alloy(), self.code.0.clone().into(), rU256::ZERO, self.errors, @@ -143,10 +143,9 @@ impl<'a> ContractRunner<'a> { // Now we set the contracts initial balance, and we also reset `self.sender`s and `CALLER`s // balance to the initial balance we want - self.executor.set_balance(address, u256_to_ru256(self.initial_balance))?; - self.executor - .set_balance(h160_to_b160(self.sender), u256_to_ru256(self.initial_balance))?; - self.executor.set_balance(CALLER, u256_to_ru256(self.initial_balance))?; + self.executor.set_balance(address, self.initial_balance.to_alloy())?; + self.executor.set_balance(self.sender.to_alloy(), self.initial_balance.to_alloy())?; + self.executor.set_balance(CALLER, self.initial_balance.to_alloy())?; self.executor.deploy_create2_deployer()?; @@ -173,17 +172,17 @@ impl<'a> ContractRunner<'a> { logs.extend(setup_logs); TestSetup { - address: b160_to_h160(address), + address: address.to_ethers(), logs, traces, labeled_addresses: labeled_addresses .into_iter() - .map(|l| (b160_to_h160(l.0), l.1)) + .map(|l| (l.0.to_ethers(), l.1)) .collect(), reason, } } else { - TestSetup::success(b160_to_h160(address), logs, traces, Default::default()) + TestSetup::success(address.to_ethers(), logs, traces, Default::default()) }; Ok(setup) @@ -331,8 +330,8 @@ impl<'a> ContractRunner<'a> { let mut debug_arena = None; let (reverted, reason, gas, stipend, coverage, state_changeset, breakpoints) = match executor.execute_test::<(), _, _>( - h160_to_b160(self.sender), - h160_to_b160(address), + self.sender.to_alloy(), + address.to_alloy(), func.clone(), (), rU256::ZERO, @@ -353,7 +352,7 @@ impl<'a> ContractRunner<'a> { }) => { traces.extend(execution_trace.map(|traces| (TraceKind::Execution, traces))); labeled_addresses - .extend(new_labels.into_iter().map(|l| (b160_to_h160(l.0), l.1))); + .extend(new_labels.into_iter().map(|l| (l.0.to_ethers(), l.1))); logs.extend(execution_logs); debug_arena = debug; (reverted, None, gas, stipend, coverage, state_changeset, breakpoints) @@ -361,7 +360,7 @@ impl<'a> ContractRunner<'a> { Err(EvmError::Execution(err)) => { traces.extend(err.traces.map(|traces| (TraceKind::Execution, traces))); labeled_addresses - .extend(err.labels.into_iter().map(|l| (b160_to_h160(l.0), l.1))); + .extend(err.labels.into_iter().map(|l| (l.0.to_ethers(), l.1))); logs.extend(err.logs); ( err.reverted, @@ -398,7 +397,7 @@ impl<'a> ContractRunner<'a> { }; let success = executor.is_success( - h160_to_b160(setup.address), + setup.address.to_alloy(), reverted, state_changeset.expect("we should have a state changeset"), should_fail, @@ -446,8 +445,8 @@ impl<'a> ContractRunner<'a> { // First, run the test normally to see if it needs to be skipped. if let Err(EvmError::SkipError) = self.executor.clone().execute_test::<(), _, _>( - h160_to_b160(self.sender), - h160_to_b160(address), + self.sender.to_alloy(), + address.to_alloy(), func.clone(), (), rU256::ZERO, diff --git a/crates/forge/tests/it/config.rs b/crates/forge/tests/it/config.rs index 6490d7076da0f..473ea33260a84 100644 --- a/crates/forge/tests/it/config.rs +++ b/crates/forge/tests/it/config.rs @@ -13,8 +13,8 @@ use foundry_config::{ }; use foundry_evm::{ decode::decode_console_logs, executor::inspector::CheatsConfig, revm::primitives::SpecId, - utils::b160_to_h160, }; +use foundry_utils::types::ToEthers; use std::{ collections::BTreeMap, path::{Path, PathBuf}, @@ -144,7 +144,7 @@ pub fn manifest_root() -> PathBuf { /// Builds a base runner pub fn base_runner() -> MultiContractRunnerBuilder { - MultiContractRunnerBuilder::default().sender(b160_to_h160(EVM_OPTS.sender)) + MultiContractRunnerBuilder::default().sender(EVM_OPTS.sender.to_ethers()) } /// Builds a non-tracing runner diff --git a/crates/forge/tests/it/test_helpers.rs b/crates/forge/tests/it/test_helpers.rs index ac66e43a7a067..fe219b10954de 100644 --- a/crates/forge/tests/it/test_helpers.rs +++ b/crates/forge/tests/it/test_helpers.rs @@ -14,9 +14,9 @@ use foundry_evm::{ DatabaseRef, Executor, ExecutorBuilder, }, fuzz::FuzzedExecutor, - utils::{b160_to_h160, h160_to_b160, u256_to_ru256}, CALLER, }; +use foundry_utils::types::{ToAlloy, ToEthers}; use std::{path::PathBuf, str::FromStr}; pub static PROJECT: Lazy = Lazy::new(|| { @@ -65,13 +65,13 @@ pub static EVM_OPTS: Lazy = Lazy::new(|| EvmOpts { env: Env { gas_limit: 18446744073709551615, chain_id: None, - tx_origin: h160_to_b160(Config::DEFAULT_SENDER), + tx_origin: Config::DEFAULT_SENDER.to_alloy(), block_number: 1, block_timestamp: 1, ..Default::default() }, - sender: h160_to_b160(Config::DEFAULT_SENDER), - initial_balance: u256_to_ru256(U256::MAX), + sender: Config::DEFAULT_SENDER.to_alloy(), + initial_balance: U256::MAX.to_alloy(), ffi: true, memory_limit: 2u64.pow(24), ..Default::default() @@ -83,7 +83,7 @@ pub fn fuzz_executor(executor: &Executor) -> FuzzedExecutor { FuzzedExecutor::new( executor, proptest::test_runner::TestRunner::new(cfg), - b160_to_h160(CALLER), + CALLER.to_ethers(), config::test_opts().fuzz, ) } diff --git a/crates/utils/src/types.rs b/crates/utils/src/types.rs index 5f3efb593ead0..20406c9e3241b 100644 --- a/crates/utils/src/types.rs +++ b/crates/utils/src/types.rs @@ -1,7 +1,7 @@ //! Temporary utility conversion traits between ethers-rs and alloy types. -use alloy_primitives::{Address, B256, U256 as AlloyU256}; -use ethers_core::types::{H160, H256, U256}; +use alloy_primitives::{Address, B256, U256 as AlloyU256, U64 as AlloyU64}; +use ethers_core::types::{H160, H256, U256, U64}; /// Conversion trait to easily convert from ethers-rs types to alloy primitive types. pub trait ToAlloy { @@ -35,6 +35,14 @@ impl ToAlloy for U256 { } } +impl ToAlloy for U64 { + type To = AlloyU64; + + fn to_alloy(self) -> Self::To { + AlloyU64::from_limbs(self.0) + } +} + impl ToAlloy for u64 { type To = AlloyU256;