diff --git a/Cargo.lock b/Cargo.lock
index a6c101fc7ecd3..71814f3a29e33 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2797,37 +2797,129 @@ dependencies = [
"alloy-dyn-abi",
"alloy-json-abi",
"alloy-primitives",
- "alloy-sol-types",
- "auto_impl",
"bytes",
"const-hex",
"ethers",
"eyre",
"foundry-abi",
- "foundry-block-explorers",
"foundry-common",
"foundry-compilers",
"foundry-config",
+ "foundry-evm-coverage",
+ "foundry-evm-executors",
+ "foundry-evm-fuzz",
+ "foundry-evm-traces",
"foundry-macros",
"foundry-utils",
- "futures",
"hashbrown 0.14.2",
"itertools 0.11.0",
"jsonpath_lib",
"once_cell",
- "ordered-float",
"parking_lot",
"proptest",
"revm",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "tracing",
+ "walkdir",
+]
+
+[[package]]
+name = "foundry-evm-coverage"
+version = "0.2.0"
+dependencies = [
+ "alloy-primitives",
+ "eyre",
+ "foundry-common",
+ "foundry-compilers",
+ "foundry-evm-executors",
+ "revm",
"semver 1.0.20",
+ "tracing",
+]
+
+[[package]]
+name = "foundry-evm-executors"
+version = "0.2.0"
+dependencies = [
+ "alloy-dyn-abi",
+ "alloy-json-abi",
+ "alloy-primitives",
+ "alloy-sol-types",
+ "auto_impl",
+ "const-hex",
+ "ethers",
+ "eyre",
+ "foundry-abi",
+ "foundry-common",
+ "foundry-compilers",
+ "foundry-config",
+ "foundry-utils",
+ "futures",
+ "itertools 0.11.0",
+ "once_cell",
+ "parking_lot",
+ "revm",
"serde",
"serde_json",
- "tempfile",
"thiserror",
"tokio",
"tracing",
"url",
- "walkdir",
+]
+
+[[package]]
+name = "foundry-evm-fuzz"
+version = "0.2.0"
+dependencies = [
+ "alloy-dyn-abi",
+ "alloy-json-abi",
+ "alloy-primitives",
+ "ethers",
+ "eyre",
+ "foundry-common",
+ "foundry-compilers",
+ "foundry-config",
+ "foundry-evm-coverage",
+ "foundry-evm-executors",
+ "foundry-evm-traces",
+ "foundry-utils",
+ "hashbrown 0.14.2",
+ "parking_lot",
+ "proptest",
+ "revm",
+ "serde",
+ "thiserror",
+ "tracing",
+]
+
+[[package]]
+name = "foundry-evm-traces"
+version = "0.2.0"
+dependencies = [
+ "alloy-dyn-abi",
+ "alloy-json-abi",
+ "alloy-primitives",
+ "const-hex",
+ "ethers",
+ "eyre",
+ "foundry-block-explorers",
+ "foundry-common",
+ "foundry-compilers",
+ "foundry-config",
+ "foundry-evm-executors",
+ "foundry-utils",
+ "futures",
+ "hashbrown 0.14.2",
+ "itertools 0.11.0",
+ "once_cell",
+ "ordered-float",
+ "revm",
+ "serde",
+ "tempfile",
+ "tokio",
+ "tracing",
"yansi 0.5.1",
]
@@ -2878,6 +2970,7 @@ name = "foundry-utils"
version = "0.2.0"
dependencies = [
"alloy-dyn-abi",
+ "alloy-json-abi",
"alloy-primitives",
"dunce",
"ethers-addressbook",
diff --git a/Cargo.toml b/Cargo.toml
index 72636473ad957..50d15728d76fc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -130,11 +130,18 @@ foundry-common = { path = "crates/common" }
foundry-cheatcodes = { path = "crates/cheatcodes" }
foundry-config = { path = "crates/config" }
foundry-evm = { path = "crates/evm" }
+foundry-evm-coverage = { path = "crates/evm-coverage" }
+foundry-evm-executors = { path = "crates/evm-executors" }
+foundry-evm-fuzz = { path = "crates/evm-fuzz" }
+foundry-evm-traces = { path = "crates/evm-traces" }
foundry-macros = { path = "crates/macros" }
foundry-test-utils = { path = "crates/test-utils" }
foundry-utils = { path = "crates/utils" }
foundry-debugger = { path = "crates/debugger" }
+foundry-compilers = { version = "0.1", default-features = false }
+foundry-block-explorers = { version = "0.1", default-features = false }
+
## revm
# no default features to avoid c-kzg
revm = { version = "3", default-features = false } #
@@ -159,11 +166,6 @@ alloy-json-abi = "0.4.1"
alloy-sol-types = "0.4.1"
syn-solidity = "0.4.1"
-# solc utils
-foundry-compilers = { version = "0.1", default-features = false }
-# block explorer utils
-foundry-block-explorers = { version = "0.1", default-features = false }
-
solang-parser = "=0.3.2"
## misc
@@ -204,7 +206,7 @@ ethers-etherscan = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f2
ethers-solc = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
foundry-compilers = { git = "https://github.com/foundry-rs/compilers" }
-foundry-block-explorers = { git = "https://github.com/foundry-rs/block-explorers"}
+foundry-block-explorers = { git = "https://github.com/foundry-rs/block-explorers" }
alloy-dyn-abi = { git = "https://github.com/alloy-rs/core/" }
alloy-primitives = { git = "https://github.com/alloy-rs/core/" }
diff --git a/crates/anvil/core/src/eth/subscription.rs b/crates/anvil/core/src/eth/subscription.rs
index c363f52ffc2bf..791bac2526951 100644
--- a/crates/anvil/core/src/eth/subscription.rs
+++ b/crates/anvil/core/src/eth/subscription.rs
@@ -103,7 +103,7 @@ impl fmt::Display for SubscriptionId {
}
impl fmt::Debug for SubscriptionId {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SubscriptionId::Number(num) => num.fmt(f),
SubscriptionId::String(s) => s.fmt(f),
diff --git a/crates/anvil/core/src/eth/transaction/mod.rs b/crates/anvil/core/src/eth/transaction/mod.rs
index 6cbd7e8a464a9..4edc89d08a541 100644
--- a/crates/anvil/core/src/eth/transaction/mod.rs
+++ b/crates/anvil/core/src/eth/transaction/mod.rs
@@ -14,7 +14,7 @@ use ethers_core::{
rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream},
},
};
-use foundry_evm::trace::CallTraceArena;
+use foundry_evm::traces::CallTraceArena;
use foundry_utils::types::ToAlloy;
use revm::{
interpreter::InstructionResult,
diff --git a/crates/anvil/core/src/types.rs b/crates/anvil/core/src/types.rs
index 8725b9f4a384d..0488bbe12c9f3 100644
--- a/crates/anvil/core/src/types.rs
+++ b/crates/anvil/core/src/types.rs
@@ -129,7 +129,7 @@ impl<'a> serde::Deserialize<'a> for Index {
impl<'a> serde::de::Visitor<'a> for IndexVisitor {
type Value = Index;
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "hex-encoded or decimal index")
}
diff --git a/crates/anvil/rpc/src/error.rs b/crates/anvil/rpc/src/error.rs
index eb95f8413ecab..427acd384ced4 100644
--- a/crates/anvil/rpc/src/error.rs
+++ b/crates/anvil/rpc/src/error.rs
@@ -69,7 +69,7 @@ impl RpcError {
}
impl fmt::Display for RpcError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.code.message(), self.message)
}
}
diff --git a/crates/anvil/src/config.rs b/crates/anvil/src/config.rs
index 265fbd972650f..151282e417261 100644
--- a/crates/anvil/src/config.rs
+++ b/crates/anvil/src/config.rs
@@ -32,9 +32,9 @@ use foundry_common::{
};
use foundry_config::Config;
use foundry_evm::{
- executor::{
+ executors::{
fork::{BlockchainDb, BlockchainDbMeta, SharedBackend},
- inspector::DEFAULT_CREATE2_DEPLOYER,
+ DEFAULT_CREATE2_DEPLOYER,
},
revm,
revm::primitives::{BlockEnv, CfgEnv, SpecId, TxEnv, U256 as rU256},
diff --git a/crates/anvil/src/eth/api.rs b/crates/anvil/src/eth/api.rs
index 313ecfb4efb9a..35219b7d364ad 100644
--- a/crates/anvil/src/eth/api.rs
+++ b/crates/anvil/src/eth/api.rs
@@ -59,8 +59,9 @@ use ethers::{
};
use foundry_common::ProviderBuilder;
use foundry_evm::{
- executor::{backend::DatabaseError, DatabaseRef},
+ executors::backend::DatabaseError,
revm::{
+ db::DatabaseRef,
interpreter::{return_ok, return_revert, InstructionResult},
primitives::BlockEnv,
},
diff --git a/crates/anvil/src/eth/backend/db.rs b/crates/anvil/src/eth/backend/db.rs
index ff924eff848ca..aa6494f2b03a3 100644
--- a/crates/anvil/src/eth/backend/db.rs
+++ b/crates/anvil/src/eth/backend/db.rs
@@ -10,17 +10,16 @@ use ethers::{
};
use foundry_common::errors::FsPathError;
use foundry_evm::{
- executor::{
- backend::{snapshot::StateSnapshot, DatabaseError, DatabaseResult, MemDb},
+ executors::{
+ backend::{DatabaseError, DatabaseResult, MemDb, StateSnapshot},
fork::BlockchainDb,
- DatabaseRef,
},
+ hashbrown::HashMap,
revm::{
- db::{CacheDB, DbAccount},
+ db::{CacheDB, DatabaseRef, DbAccount},
primitives::{Bytecode, KECCAK_EMPTY},
Database, DatabaseCommit,
},
- HashMap,
};
use foundry_utils::types::ToAlloy;
use hash_db::HashDB;
diff --git a/crates/anvil/src/eth/backend/executor.rs b/crates/anvil/src/eth/backend/executor.rs
index 8cbf6381163df..fc9cff994a57f 100644
--- a/crates/anvil/src/eth/backend/executor.rs
+++ b/crates/anvil/src/eth/backend/executor.rs
@@ -18,13 +18,13 @@ use ethers::{
utils::rlp,
};
use foundry_evm::{
- executor::backend::DatabaseError,
+ executors::backend::DatabaseError,
revm,
revm::{
interpreter::InstructionResult,
primitives::{BlockEnv, CfgEnv, EVMError, Env, ExecutionResult, Output, SpecId},
},
- trace::{node::CallTraceNode, CallTraceArena},
+ traces::{node::CallTraceNode, CallTraceArena},
utils::{eval_to_instruction_result, halt_to_instruction_result},
};
use foundry_utils::types::{ToAlloy, ToEthers};
diff --git a/crates/anvil/src/eth/backend/genesis.rs b/crates/anvil/src/eth/backend/genesis.rs
index ade5ac6f5c79e..e1a4a2ceca24b 100644
--- a/crates/anvil/src/eth/backend/genesis.rs
+++ b/crates/anvil/src/eth/backend/genesis.rs
@@ -10,11 +10,11 @@ use ethers::{
types::{Address, H256},
};
use foundry_evm::{
- executor::{
- backend::{snapshot::StateSnapshot, DatabaseError, DatabaseResult},
- DatabaseRef,
+ executors::backend::{DatabaseError, DatabaseResult, StateSnapshot},
+ revm::{
+ db::DatabaseRef,
+ primitives::{AccountInfo, Bytecode, KECCAK_EMPTY},
},
- revm::primitives::{AccountInfo, Bytecode, KECCAK_EMPTY},
};
use foundry_utils::types::{ToAlloy, ToEthers};
use parking_lot::Mutex;
diff --git a/crates/anvil/src/eth/backend/mem/cache.rs b/crates/anvil/src/eth/backend/mem/cache.rs
index 0703cb78fb5ec..649f1c4ba6377 100644
--- a/crates/anvil/src/eth/backend/mem/cache.rs
+++ b/crates/anvil/src/eth/backend/mem/cache.rs
@@ -1,6 +1,6 @@
use crate::config::anvil_tmp_dir;
use ethers::prelude::H256;
-use foundry_evm::executor::backend::snapshot::StateSnapshot;
+use foundry_evm::executors::backend::StateSnapshot;
use std::{
io,
path::{Path, PathBuf},
diff --git a/crates/anvil/src/eth/backend/mem/fork_db.rs b/crates/anvil/src/eth/backend/mem/fork_db.rs
index 8039442a4286b..bba62fc4a1095 100644
--- a/crates/anvil/src/eth/backend/mem/fork_db.rs
+++ b/crates/anvil/src/eth/backend/mem/fork_db.rs
@@ -7,16 +7,17 @@ use crate::{
Address, U256,
};
use ethers::{prelude::H256, types::BlockId};
-pub use foundry_evm::executor::fork::database::ForkedDatabase;
use foundry_evm::{
- executor::{
- backend::{snapshot::StateSnapshot, DatabaseResult},
+ executors::{
+ backend::{DatabaseResult, StateSnapshot},
fork::{database::ForkDbSnapshot, BlockchainDb},
},
revm::Database,
};
use foundry_utils::types::{ToAlloy, ToEthers};
+pub use foundry_evm::executors::fork::database::ForkedDatabase;
+
/// Implement the helper for the fork database
impl Db for ForkedDatabase {
fn insert_account(&mut self, address: Address, account: AccountInfo) {
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 ebba405fc806c..62cf70ff222dd 100644
--- a/crates/anvil/src/eth/backend/mem/in_memory_db.rs
+++ b/crates/anvil/src/eth/backend/mem/in_memory_db.rs
@@ -5,21 +5,20 @@ use crate::{
AsHashDB, Db, MaybeForkedDatabase, MaybeHashDatabase, SerializableAccountRecord,
SerializableState, StateDb,
},
- mem::state::{state_merkle_trie_root, trie_hash_db},
+ mem::state::{state_merkle_trie_root, storage_trie_db, trie_hash_db},
revm::primitives::AccountInfo,
Address, U256,
};
use ethers::{prelude::H256, types::BlockId};
+use foundry_evm::executors::{
+ backend::{DatabaseResult, StateSnapshot},
+ fork::BlockchainDb,
+};
use foundry_utils::types::{ToAlloy, ToEthers};
use tracing::{trace, warn};
// reexport for convenience
-use crate::mem::state::storage_trie_db;
-pub use foundry_evm::executor::{backend::MemDb, DatabaseRef};
-use foundry_evm::executor::{
- backend::{snapshot::StateSnapshot, DatabaseResult},
- fork::BlockchainDb,
-};
+pub use foundry_evm::{executors::backend::MemDb, revm::db::DatabaseRef};
impl Db for MemDb {
fn insert_account(&mut self, address: Address, account: AccountInfo) {
@@ -135,6 +134,7 @@ impl MaybeForkedDatabase for MemDb {
#[cfg(test)]
mod tests {
+ use super::*;
use crate::{
eth::backend::db::{Db, SerializableAccountRecord, SerializableState},
revm::primitives::AccountInfo,
@@ -143,7 +143,7 @@ mod tests {
use alloy_primitives::{Bytes, U256 as rU256};
use ethers::types::U256;
use foundry_evm::{
- executor::{backend::MemDb, DatabaseRef},
+ executors::backend::MemDb,
revm::primitives::{Bytecode, KECCAK_EMPTY},
};
use foundry_utils::types::ToAlloy;
diff --git a/crates/anvil/src/eth/backend/mem/inspector.rs b/crates/anvil/src/eth/backend/mem/inspector.rs
index ee46ea101d14c..a4e2d0d94f4db 100644
--- a/crates/anvil/src/eth/backend/mem/inspector.rs
+++ b/crates/anvil/src/eth/backend/mem/inspector.rs
@@ -5,7 +5,7 @@ use ethers::types::Log;
use foundry_evm::{
call_inspectors,
decode::decode_console_logs,
- executor::inspector::{LogCollector, Tracer},
+ inspectors::{LogCollector, Tracer},
revm,
revm::{
interpreter::{CallInputs, CreateInputs, Gas, InstructionResult, Interpreter},
diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs
index a8cd2b9e5a7c1..456d874c5b1fc 100644
--- a/crates/anvil/src/eth/backend/mem/mod.rs
+++ b/crates/anvil/src/eth/backend/mem/mod.rs
@@ -59,11 +59,11 @@ use flate2::{read::GzDecoder, write::GzEncoder, Compression};
use foundry_common::abi::format_token;
use foundry_evm::{
decode::{decode_custom_error_args, decode_revert},
- executor::{
+ executors::{
backend::{DatabaseError, DatabaseResult},
- inspector::AccessListTracer,
DEFAULT_CREATE2_DEPLOYER_RUNTIME_CODE,
},
+ inspectors::AccessListTracer,
revm::{
self,
db::CacheDB,
@@ -103,7 +103,8 @@ pub const MIN_TRANSACTION_GAS: U256 = U256([21_000, 0, 0, 0]);
// Gas per transaction creating a contract.
pub const MIN_CREATE_GAS: U256 = U256([53_000, 0, 0, 0]);
-pub type State = foundry_evm::HashMap
;
+// TODO: This is the same as foundry_evm::executors::StateChangeset but with ethers H160
+pub type State = foundry_evm::hashbrown::HashMap;
/// A block request, which includes the Pool Transactions if it's Pending
#[derive(Debug)]
diff --git a/crates/anvil/src/eth/backend/mem/state.rs b/crates/anvil/src/eth/backend/mem/state.rs
index c0d5271ab85bd..8e3c23a2d5124 100644
--- a/crates/anvil/src/eth/backend/mem/state.rs
+++ b/crates/anvil/src/eth/backend/mem/state.rs
@@ -8,12 +8,12 @@ use ethers::{
utils::{rlp, rlp::RlpStream},
};
use foundry_evm::{
- executor::{backend::DatabaseError, DatabaseRef},
+ executors::backend::DatabaseError,
+ hashbrown::HashMap as Map,
revm::{
- db::{CacheDB, DbAccount},
+ db::{CacheDB, DatabaseRef, DbAccount},
primitives::{AccountInfo, Bytecode, Log},
},
- HashMap as Map,
};
use foundry_utils::types::{ToAlloy, ToEthers};
use memory_db::HashKey;
diff --git a/crates/anvil/src/eth/backend/mem/storage.rs b/crates/anvil/src/eth/backend/mem/storage.rs
index 4d693ed060119..d973fbf27ab72 100644
--- a/crates/anvil/src/eth/backend/mem/storage.rs
+++ b/crates/anvil/src/eth/backend/mem/storage.rs
@@ -425,7 +425,7 @@ mod tests {
use crate::eth::backend::db::Db;
use ethers::{abi::ethereum_types::BigEndianHash, types::Address};
use foundry_evm::{
- executor::backend::MemDb,
+ executors::backend::MemDb,
revm::{
db::DatabaseRef,
primitives::{AccountInfo, U256 as rU256},
diff --git a/crates/anvil/src/eth/error.rs b/crates/anvil/src/eth/error.rs
index 3fa9e6c732d35..8e48511b02ab7 100644
--- a/crates/anvil/src/eth/error.rs
+++ b/crates/anvil/src/eth/error.rs
@@ -13,7 +13,7 @@ use ethers::{
};
use foundry_common::SELECTOR_LEN;
use foundry_evm::{
- executor::backend::DatabaseError,
+ executors::backend::DatabaseError,
revm::{
self,
interpreter::InstructionResult,
diff --git a/crates/anvil/src/eth/fees.rs b/crates/anvil/src/eth/fees.rs
index 5b1e54679a4fc..97acabb1df36a 100644
--- a/crates/anvil/src/eth/fees.rs
+++ b/crates/anvil/src/eth/fees.rs
@@ -405,7 +405,7 @@ impl FeeDetails {
}
impl fmt::Debug for FeeDetails {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "Fees {{ ")?;
write!(fmt, "gaPrice: {:?}, ", self.gas_price)?;
write!(fmt, "max_fee_per_gas: {:?}, ", self.max_fee_per_gas)?;
diff --git a/crates/anvil/src/eth/otterscan/types.rs b/crates/anvil/src/eth/otterscan/types.rs
index bd2567d749a56..3f49d0df1ce87 100644
--- a/crates/anvil/src/eth/otterscan/types.rs
+++ b/crates/anvil/src/eth/otterscan/types.rs
@@ -2,7 +2,7 @@ use alloy_primitives::U256 as rU256;
use ethers::types::{
Action, Address, Block, Bytes, CallType, Trace, Transaction, TransactionReceipt, H256, U256,
};
-use foundry_evm::{executor::InstructionResult, CallKind};
+use foundry_evm::{revm::interpreter::InstructionResult, utils::CallKind};
use foundry_utils::types::ToEthers;
use futures::future::join_all;
use serde::{de::DeserializeOwned, Serialize};
diff --git a/crates/anvil/src/eth/pool/mod.rs b/crates/anvil/src/eth/pool/mod.rs
index ee43d8556eda8..842015837d71e 100644
--- a/crates/anvil/src/eth/pool/mod.rs
+++ b/crates/anvil/src/eth/pool/mod.rs
@@ -358,7 +358,7 @@ pub struct PruneResult {
}
impl fmt::Debug for PruneResult {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "PruneResult {{ ")?;
write!(
fmt,
diff --git a/crates/anvil/src/eth/pool/transactions.rs b/crates/anvil/src/eth/pool/transactions.rs
index 39b0d1cc1fe13..d0c0337c6b0f2 100644
--- a/crates/anvil/src/eth/pool/transactions.rs
+++ b/crates/anvil/src/eth/pool/transactions.rs
@@ -99,7 +99,7 @@ impl PoolTransaction {
}
impl fmt::Debug for PoolTransaction {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "Transaction {{ ")?;
write!(fmt, "hash: {:?}, ", &self.pending_transaction.hash())?;
write!(fmt, "requires: [{}], ", hex_fmt_many(self.requires.iter()))?;
@@ -283,7 +283,7 @@ impl PendingPoolTransaction {
}
impl fmt::Debug for PendingPoolTransaction {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "PendingTransaction {{ ")?;
write!(fmt, "added_at: {:?}, ", self.added_at)?;
write!(fmt, "tx: {:?}, ", self.transaction)?;
diff --git a/crates/anvil/src/eth/util.rs b/crates/anvil/src/eth/util.rs
index 078971c577884..5fdf3dc6ae1c4 100644
--- a/crates/anvil/src/eth/util.rs
+++ b/crates/anvil/src/eth/util.rs
@@ -31,7 +31,7 @@ impl<'a> HexDisplay<'a> {
}
impl<'a> fmt::Display for HexDisplay<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.0.len() < 1027 {
for byte in self.0 {
f.write_fmt(format_args!("{byte:02x}"))?;
@@ -50,7 +50,7 @@ impl<'a> fmt::Display for HexDisplay<'a> {
}
impl<'a> fmt::Debug for HexDisplay<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.0 {
f.write_fmt(format_args!("{byte:02x}"))?;
}
diff --git a/crates/cast/bin/cmd/call.rs b/crates/cast/bin/cmd/call.rs
index 30c8fa4c20f88..9c1b2b58d6830 100644
--- a/crates/cast/bin/cmd/call.rs
+++ b/crates/cast/bin/cmd/call.rs
@@ -10,7 +10,7 @@ use foundry_cli::{
use foundry_common::runtime_client::RuntimeClient;
use foundry_compilers::EvmVersion;
use foundry_config::{find_project_root_path, Config};
-use foundry_evm::{executor::opts::EvmOpts, trace::TracingExecutor};
+use foundry_evm::executors::{opts::EvmOpts, TracingExecutor};
use foundry_utils::types::{ToAlloy, ToEthers};
use std::str::FromStr;
@@ -151,7 +151,7 @@ impl CallArgs {
TracingExecutor::get_fork_material(&config, evm_opts).await?;
let mut executor =
- foundry_evm::trace::TracingExecutor::new(env, fork, evm_version, debug)
+ foundry_evm::executors::TracingExecutor::new(env, fork, evm_version, debug)
.await;
let trace = match executor.deploy(
@@ -186,7 +186,7 @@ impl CallArgs {
TracingExecutor::get_fork_material(&config, evm_opts).await?;
let mut executor =
- foundry_evm::trace::TracingExecutor::new(env, fork, evm_version, debug)
+ foundry_evm::executors::TracingExecutor::new(env, fork, evm_version, debug)
.await;
let (tx, _) = builder.build();
diff --git a/crates/cast/bin/cmd/run.rs b/crates/cast/bin/cmd/run.rs
index 2ba8016ff1250..d628d1ea379e0 100644
--- a/crates/cast/bin/cmd/run.rs
+++ b/crates/cast/bin/cmd/run.rs
@@ -1,3 +1,4 @@
+use alloy_primitives::U256;
use clap::Parser;
use ethers::prelude::Middleware;
use eyre::{Result, WrapErr};
@@ -11,9 +12,8 @@ use foundry_common::{is_known_system_sender, SYSTEM_TRANSACTION_TYPE};
use foundry_compilers::EvmVersion;
use foundry_config::{find_project_root_path, Config};
use foundry_evm::{
- executor::{inspector::cheatcodes::util::configure_tx_env, opts::EvmOpts, EvmError},
- revm::primitives::U256 as rU256,
- trace::TracingExecutor,
+ executors::{opts::EvmOpts, EvmError, TracingExecutor},
+ utils::configure_tx_env,
};
use foundry_utils::types::ToAlloy;
use tracing::trace;
@@ -121,7 +121,7 @@ impl RunArgs {
let mut executor =
TracingExecutor::new(env.clone(), fork, self.evm_version, self.debug).await;
- env.block.number = rU256::from(tx_block_number);
+ env.block.number = U256::from(tx_block_number);
let block = provider.get_block_with_txs(tx_block_number).await?;
if let Some(ref block) = block {
diff --git a/crates/chisel/Cargo.toml b/crates/chisel/Cargo.toml
index 51f9930786e78..21314dafd8496 100644
--- a/crates/chisel/Cargo.toml
+++ b/crates/chisel/Cargo.toml
@@ -26,7 +26,7 @@ foundry-common.workspace = true
foundry-utils.workspace = true
forge-fmt.workspace = true
-foundry-compilers = { workspace = true, default-features = false, features = ["project-util", "full"]}
+foundry-compilers = { workspace = true, features = ["project-util", "full"] }
# ethers
ethers.workspace = true
diff --git a/crates/chisel/benches/session_source.rs b/crates/chisel/benches/session_source.rs
index 784de2c4b03df..38f0c04b75140 100644
--- a/crates/chisel/benches/session_source.rs
+++ b/crates/chisel/benches/session_source.rs
@@ -2,7 +2,7 @@ use chisel::session_source::{SessionSource, SessionSourceConfig};
use criterion::{criterion_group, Criterion};
use foundry_compilers::Solc;
use foundry_config::Config;
-use foundry_evm::executor::opts::EvmOpts;
+use foundry_evm::executors::opts::EvmOpts;
use once_cell::sync::Lazy;
use std::hint::black_box;
use tokio::runtime::Runtime;
diff --git a/crates/chisel/src/dispatcher.rs b/crates/chisel/src/dispatcher.rs
index db8950ca1323d..927cc2e2f6089 100644
--- a/crates/chisel/src/dispatcher.rs
+++ b/crates/chisel/src/dispatcher.rs
@@ -13,7 +13,7 @@ use forge_fmt::FormatterConfig;
use foundry_config::{Config, RpcEndpoint};
use foundry_evm::{
decode::decode_console_logs,
- trace::{
+ traces::{
identifier::{EtherscanIdentifier, SignaturesIdentifier},
CallTraceDecoder, CallTraceDecoderBuilder, TraceKind,
},
diff --git a/crates/chisel/src/executor.rs b/crates/chisel/src/executor.rs
index 5979743bcbc50..af0ead61d48b2 100644
--- a/crates/chisel/src/executor.rs
+++ b/crates/chisel/src/executor.rs
@@ -13,7 +13,8 @@ use eyre::{Result, WrapErr};
use foundry_compilers::Artifact;
use foundry_evm::{
decode::decode_console_logs,
- executor::{inspector::CheatsConfig, Backend, ExecutorBuilder},
+ executors::{Backend, ExecutorBuilder},
+ inspectors::CheatsConfig,
};
use foundry_utils::types::ToEthers;
use solang_parser::pt::{self, CodeLocation};
diff --git a/crates/chisel/src/runner.rs b/crates/chisel/src/runner.rs
index 043cde85c7bc3..cb0ed68452512 100644
--- a/crates/chisel/src/runner.rs
+++ b/crates/chisel/src/runner.rs
@@ -7,8 +7,8 @@ use alloy_primitives::{Address, Bytes, U256};
use ethers::types::Log;
use eyre::Result;
use foundry_evm::{
- executor::{DeployResult, Executor, RawCallResult},
- trace::{CallTraceArena, TraceKind},
+ executors::{DeployResult, Executor, RawCallResult},
+ traces::{CallTraceArena, TraceKind},
};
use revm::interpreter::{return_ok, InstructionResult};
use std::collections::BTreeMap;
diff --git a/crates/chisel/src/session_source.rs b/crates/chisel/src/session_source.rs
index 5fbb0a1e104a8..08ab4cd8f0a65 100644
--- a/crates/chisel/src/session_source.rs
+++ b/crates/chisel/src/session_source.rs
@@ -11,7 +11,7 @@ use foundry_compilers::{
CompilerInput, CompilerOutput, EvmVersion, Solc,
};
use foundry_config::{Config, SolcReq};
-use foundry_evm::executor::{opts::EvmOpts, Backend};
+use foundry_evm::executors::{opts::EvmOpts, Backend};
use semver::Version;
use serde::{Deserialize, Serialize};
use solang_parser::pt;
diff --git a/crates/chisel/tests/cache.rs b/crates/chisel/tests/cache.rs
index 7ea13c64de986..d51a4fd32600d 100644
--- a/crates/chisel/tests/cache.rs
+++ b/crates/chisel/tests/cache.rs
@@ -1,7 +1,7 @@
use chisel::session::ChiselSession;
use foundry_compilers::EvmVersion;
use foundry_config::Config;
-use foundry_evm::executor::opts::EvmOpts;
+use foundry_evm::executors::opts::EvmOpts;
use serial_test::serial;
use std::path::Path;
diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml
index d0b253499d9fc..f0f314edd3f2c 100644
--- a/crates/cli/Cargo.toml
+++ b/crates/cli/Cargo.toml
@@ -17,7 +17,7 @@ foundry-evm.workspace = true
foundry-debugger.workspace = true
foundry-utils.workspace = true
-foundry-compilers = { workspace = true, default-features = false, features = ["full"] }
+foundry-compilers = { workspace = true, features = ["full"] }
# aws
rusoto_core = { version = "0.48", default-features = false }
diff --git a/crates/cli/src/utils/cmd.rs b/crates/cli/src/utils/cmd.rs
index e43c0e2968608..890d0dd3c8f90 100644
--- a/crates/cli/src/utils/cmd.rs
+++ b/crates/cli/src/utils/cmd.rs
@@ -14,8 +14,8 @@ use foundry_config::{error::ExtractConfigError, figment::Figment, Chain as Confi
use foundry_debugger::DebuggerArgs;
use foundry_evm::{
debug::DebugArena,
- executor::{opts::EvmOpts, DeployResult, EvmError, ExecutionErr, RawCallResult},
- trace::{
+ executors::{opts::EvmOpts, DeployResult, EvmError, ExecutionErr, RawCallResult},
+ traces::{
identifier::{EtherscanIdentifier, SignaturesIdentifier},
CallTraceDecoder, CallTraceDecoderBuilder, TraceKind, Traces,
},
diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml
index e2ab1df43f31c..f12289aaa459b 100644
--- a/crates/common/Cargo.toml
+++ b/crates/common/Cargo.toml
@@ -24,7 +24,8 @@ foundry-block-explorers = { workspace = true, features = ["foundry-compilers"] }
alloy-primitives = { workspace = true, features = ["serde", "getrandom", "arbitrary", "rlp"] }
alloy-dyn-abi = { workspace = true, features = ["arbitrary", "eip712"] }
alloy-json-abi.workspace = true
-foundry-compilers = { workspace = true, default-features = false }
+foundry-compilers.workspace = true
+
# io
reqwest = { version = "0.11", default-features = false }
diff --git a/crates/common/src/compile.rs b/crates/common/src/compile.rs
index a08287beac1d2..a990035244d33 100644
--- a/crates/common/src/compile.rs
+++ b/crates/common/src/compile.rs
@@ -203,7 +203,7 @@ impl SizeReport {
}
impl Display for SizeReport {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let mut table = Table::new();
table.load_preset(ASCII_MARKDOWN);
table.set_header(vec![
diff --git a/crates/debugger/src/debugger.rs b/crates/debugger/src/debugger.rs
index eb59780194b0f..e65556bd5f24a 100644
--- a/crates/debugger/src/debugger.rs
+++ b/crates/debugger/src/debugger.rs
@@ -1,6 +1,6 @@
use crate::{TUIExitReason, Tui, Ui};
use foundry_common::{compile::ContractSources, evm::Breakpoints, get_contract_name};
-use foundry_evm::{debug::DebugArena, trace::CallTraceDecoder};
+use foundry_evm::{debug::DebugArena, traces::CallTraceDecoder};
use tracing::{error, trace};
/// Standardized way of firing up the debugger
diff --git a/crates/debugger/src/lib.rs b/crates/debugger/src/lib.rs
index 7fc74325dcb7f..c6f645e8a2c07 100644
--- a/crates/debugger/src/lib.rs
+++ b/crates/debugger/src/lib.rs
@@ -13,8 +13,7 @@ use eyre::Result;
use foundry_common::{compile::ContractSources, evm::Breakpoints};
use foundry_evm::{
debug::{DebugStep, Instruction},
- utils::{build_pc_ic_map, PCICMap},
- CallKind,
+ utils::{build_pc_ic_map, CallKind, PCICMap},
};
use ratatui::{
backend::{Backend, CrosstermBackend},
diff --git a/crates/doc/Cargo.toml b/crates/doc/Cargo.toml
index fb5f8dcc14f1b..cb0db0d18bfdc 100644
--- a/crates/doc/Cargo.toml
+++ b/crates/doc/Cargo.toml
@@ -16,11 +16,11 @@ forge-fmt.workspace = true
foundry-config.workspace = true
foundry-utils.workspace = true
+foundry-compilers = { workspace = true, features = ["async"] }
+
# ethers
ethers-core.workspace = true
-foundry-compilers = { workspace = true, features = ["async"] }
-
# tracing
tracing.workspace = true
diff --git a/crates/evm-coverage/Cargo.toml b/crates/evm-coverage/Cargo.toml
new file mode 100644
index 0000000000000..4e9404873996d
--- /dev/null
+++ b/crates/evm-coverage/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "foundry-evm-coverage"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+foundry-common.workspace = true
+foundry-compilers.workspace = true
+foundry-evm-executors.workspace = true
+
+alloy-primitives.workspace = true
+eyre = "0.6"
+revm.workspace = true
+semver = "1"
+tracing = "0.1"
diff --git a/crates/evm/src/coverage/analysis.rs b/crates/evm-coverage/src/analysis.rs
similarity index 100%
rename from crates/evm/src/coverage/analysis.rs
rename to crates/evm-coverage/src/analysis.rs
diff --git a/crates/evm/src/coverage/anchors.rs b/crates/evm-coverage/src/anchors.rs
similarity index 99%
rename from crates/evm/src/coverage/anchors.rs
rename to crates/evm-coverage/src/anchors.rs
index bbba9544286ce..ae4453f638d5c 100644
--- a/crates/evm/src/coverage/anchors.rs
+++ b/crates/evm-coverage/src/anchors.rs
@@ -1,7 +1,7 @@
use super::{CoverageItem, CoverageItemKind, ItemAnchor, SourceLocation};
-use crate::utils::ICPCMap;
use alloy_primitives::Bytes;
use foundry_compilers::sourcemap::{SourceElement, SourceMap};
+use foundry_evm_executors::utils::ICPCMap;
use revm::{
interpreter::opcode::{self, spec_opcode_gas},
primitives::SpecId,
diff --git a/crates/evm/src/executor/inspector/coverage.rs b/crates/evm-coverage/src/inspector.rs
similarity index 94%
rename from crates/evm/src/executor/inspector/coverage.rs
rename to crates/evm-coverage/src/inspector.rs
index 3f06c490e4160..3ee7ec98cce9b 100644
--- a/crates/evm/src/executor/inspector/coverage.rs
+++ b/crates/evm-coverage/src/inspector.rs
@@ -1,5 +1,5 @@
-use crate::coverage::{HitMap, HitMaps};
-use bytes::Bytes;
+use crate::{HitMap, HitMaps};
+use alloy_primitives::Bytes;
use revm::{
interpreter::{InstructionResult, Interpreter},
Database, EVMData, Inspector,
diff --git a/crates/evm/src/coverage/mod.rs b/crates/evm-coverage/src/lib.rs
similarity index 97%
rename from crates/evm/src/coverage/mod.rs
rename to crates/evm-coverage/src/lib.rs
index 7d78e9b519478..0ae3d6ea4ae73 100644
--- a/crates/evm/src/coverage/mod.rs
+++ b/crates/evm-coverage/src/lib.rs
@@ -1,8 +1,13 @@
-pub mod analysis;
-pub mod anchors;
+//! # foundry-evm-coverage
+//!
+//! EVM bytecode coverage analysis.
+
+#![warn(unreachable_pub, unused_crate_dependencies, rust_2018_idioms)]
+
+#[macro_use]
+extern crate tracing;
-use alloy_primitives::B256;
-use bytes::Bytes;
+use alloy_primitives::{Bytes, B256};
use semver::Version;
use std::{
collections::{BTreeMap, HashMap},
@@ -10,6 +15,12 @@ use std::{
ops::{AddAssign, Deref, DerefMut},
};
+pub mod analysis;
+pub mod anchors;
+
+mod inspector;
+pub use inspector::CoverageCollector;
+
/// A coverage report.
///
/// A coverage report contains coverage items and opcodes corresponding to those items (called
diff --git a/crates/evm-executors/Cargo.toml b/crates/evm-executors/Cargo.toml
new file mode 100644
index 0000000000000..ad5983f513a2e
--- /dev/null
+++ b/crates/evm-executors/Cargo.toml
@@ -0,0 +1,56 @@
+[package]
+name = "foundry-evm-executors"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+foundry-abi.workspace = true
+foundry-common.workspace = true
+foundry-compilers.workspace = true
+foundry-config.workspace = true
+foundry-utils.workspace = true
+
+# EVM
+revm = { workspace = true, default-features = false, features = [
+ "std",
+ "serde",
+ "memory_limit",
+ "optional_eip3607",
+ "optional_block_gas_limit",
+ "optional_no_base_fee",
+ "arbitrary",
+] }
+alloy-primitives = { workspace = true, features = ["serde", "getrandom", "arbitrary", "rlp"] }
+alloy-dyn-abi = { workspace = true, features = ["arbitrary", "eip712"] }
+alloy-json-abi = { workspace = true }
+alloy-sol-types.workspace = true
+ethers = { workspace = true, features = ["ethers-solc"] }
+
+# Encoding/decoding
+serde_json = "1"
+serde = "1"
+hex.workspace = true
+
+# Error handling
+eyre = "0.6"
+thiserror = "1"
+
+# Logging
+tracing = "0.1"
+
+# Threading/futures
+tokio = { version = "1", features = ["time", "macros"] }
+parking_lot = "0.12"
+futures = "0.3"
+once_cell = "1"
+
+# Misc
+url = "2"
+auto_impl = "1"
+itertools.workspace = true
diff --git a/crates/evm-executors/src/abi/mod.rs b/crates/evm-executors/src/abi/mod.rs
new file mode 100644
index 0000000000000..b3620e50e5062
--- /dev/null
+++ b/crates/evm-executors/src/abi/mod.rs
@@ -0,0 +1,573 @@
+//! Several ABI-related utilities for executors.
+
+use alloy_primitives::Address;
+pub use foundry_abi::{
+ console::{self, ConsoleEvents, CONSOLE_ABI},
+ hardhat_console::{self, HardhatConsoleCalls, HARDHATCONSOLE_ABI as HARDHAT_CONSOLE_ABI},
+ hevm::{self, HEVMCalls, HEVM_ABI},
+};
+use once_cell::sync::Lazy;
+use std::collections::HashMap;
+
+/// The cheatcode handler address (0x7109709ECfa91a80626fF3989D68f67F5b1DD12D).
+///
+/// This is the same address as the one used in DappTools's HEVM.
+/// `address(bytes20(uint160(uint256(keccak256('hevm cheat code')))))`
+pub const CHEATCODE_ADDRESS: Address = Address::new([
+ 0x71, 0x09, 0x70, 0x9E, 0xcf, 0xa9, 0x1a, 0x80, 0x62, 0x6f, 0xf3, 0x98, 0x9d, 0x68, 0xf6, 0x7f,
+ 0x5b, 0x1d, 0xd1, 0x2d,
+]);
+
+/// The Hardhat console address (0x000000000000000000636F6e736F6c652e6c6f67).
+///
+/// See: https://github.com/nomiclabs/hardhat/blob/master/packages/hardhat-core/console.sol
+pub const HARDHAT_CONSOLE_ADDRESS: Address = Address::new([
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65,
+ 0x2e, 0x6c, 0x6f, 0x67,
+]);
+
+/// If the input starts with a known `hardhat/console.log` `uint` selector, then this will replace
+/// it with the selector `abigen!` bindings expect.
+pub fn patch_hardhat_console_selector(input: &mut Vec) {
+ if input.len() < 4 {
+ return
+ }
+ let selector = unsafe { &mut *(input.get_unchecked_mut(..4) as *mut [u8] as *mut [u8; 4]) };
+ if let Some(abigen_selector) = HARDHAT_CONSOLE_SELECTOR_PATCHES.get(selector) {
+ *selector = *abigen_selector;
+ }
+}
+
+/// This contains a map with all the `hardhat/console.log` log selectors that use `uint` or `int`
+/// as key and the selector of the call with `uint256`,
+///
+/// This is a bit terrible but a workaround for the differing selectors used by hardhat and the call
+/// bindings which `abigen!` creates. `hardhat/console.log` logs its events in functions that accept
+/// `uint` manually as `abi.encodeWithSignature("log(int)", p0)`, but `abigen!` uses `uint256` for
+/// its call bindings (`HardhatConsoleCalls`) as generated by solc.
+pub static HARDHAT_CONSOLE_SELECTOR_PATCHES: Lazy> = Lazy::new(|| {
+ HashMap::from([
+ // log(bool,uint256,uint256,address)
+ ([241, 97, 178, 33], [0, 221, 135, 185]),
+ // log(uint256,address,address,string)
+ ([121, 67, 220, 102], [3, 28, 111, 115]),
+ // log(uint256,bool,address,uint256)
+ ([65, 181, 239, 59], [7, 130, 135, 245]),
+ // log(bool,address,bool,uint256)
+ ([76, 182, 15, 209], [7, 131, 21, 2]),
+ // log(bool,uint256,address)
+ ([196, 210, 53, 7], [8, 142, 249, 210]),
+ // log(uint256,address,address,bool)
+ ([1, 85, 11, 4], [9, 31, 250, 245]),
+ // log(address,bool,uint256,string)
+ ([155, 88, 142, 204], [10, 166, 207, 173]),
+ // log(bool,bool,uint256,uint256)
+ ([70, 103, 222, 142], [11, 176, 14, 171]),
+ // log(bool,address,address,uint256)
+ ([82, 132, 189, 108], [12, 102, 209, 190]),
+ // log(uint256,address,uint256,uint256)
+ ([202, 154, 62, 180], [12, 156, 217, 193]),
+ // log(string,address,uint256)
+ ([7, 200, 18, 23], [13, 38, 185, 37]),
+ // log(address,string,uint256,bool)
+ ([126, 37, 13, 91], [14, 247, 224, 80]),
+ // log(address,uint256,address,uint256)
+ ([165, 217, 135, 104], [16, 15, 101, 14]),
+ // log(string,string,uint256,address)
+ ([93, 79, 70, 128], [16, 35, 247, 178]),
+ // log(bool,string,uint256)
+ ([192, 56, 42, 172], [16, 147, 238, 17]),
+ // log(bool,bool,uint256)
+ ([176, 19, 101, 187], [18, 242, 22, 2]),
+ // log(bool,address,uint256,address)
+ ([104, 241, 88, 181], [19, 107, 5, 221]),
+ // log(bool,uint256,address,uint256)
+ ([202, 165, 35, 106], [21, 55, 220, 135]),
+ // log(bool,string,uint256,address)
+ ([91, 34, 185, 56], [21, 150, 161, 206]),
+ // log(address,string,string,uint256)
+ ([161, 79, 208, 57], [21, 159, 137, 39]),
+ // log(uint256,address,uint256,address)
+ ([253, 178, 236, 212], [21, 193, 39, 181]),
+ // log(uint256,uint256,address,bool)
+ ([168, 232, 32, 174], [21, 202, 196, 118]),
+ // log(bool,string,bool,uint256)
+ ([141, 111, 156, 165], [22, 6, 163, 147]),
+ // log(address,address,uint256)
+ ([108, 54, 109, 114], [23, 254, 97, 133]),
+ // log(uint256,uint256,uint256,uint256)
+ ([92, 160, 173, 62], [25, 63, 184, 0]),
+ // log(bool,string,uint256,string)
+ ([119, 161, 171, 237], [26, 217, 109, 230]),
+ // log(bool,uint256,address,string)
+ ([24, 9, 19, 65], [27, 179, 176, 154]),
+ // log(string,uint256,address)
+ ([227, 132, 159, 121], [28, 126, 196, 72]),
+ // log(uint256,bool)
+ ([30, 109, 212, 236], [28, 157, 126, 179]),
+ // log(address,uint256,address,string)
+ ([93, 113, 243, 158], [29, 169, 134, 234]),
+ // log(address,string,uint256,uint256)
+ ([164, 201, 42, 96], [29, 200, 225, 184]),
+ // log(uint256,bool,uint256)
+ ([90, 77, 153, 34], [32, 9, 128, 20]),
+ // log(uint256,bool,bool)
+ ([213, 206, 172, 224], [32, 113, 134, 80]),
+ // log(address,uint256,uint256,address)
+ ([30, 246, 52, 52], [32, 227, 152, 77]),
+ // log(uint256,string,string,string)
+ ([87, 221, 10, 17], [33, 173, 6, 131]),
+ // log(address,uint256,bool,uint256)
+ ([105, 143, 67, 146], [34, 246, 185, 153]),
+ // log(uint256,address,address,address)
+ ([85, 71, 69, 249], [36, 136, 180, 20]),
+ // log(string,bool,string,uint256)
+ ([52, 203, 48, 141], [36, 249, 20, 101]),
+ // log(bool,uint256,address,address)
+ ([138, 47, 144, 170], [38, 245, 96, 168]),
+ // log(uint256,uint256,string,string)
+ ([124, 3, 42, 50], [39, 216, 175, 210]),
+ // log(bool,string,uint256,uint256)
+ ([142, 74, 232, 110], [40, 134, 63, 203]),
+ // log(uint256,bool,string,uint256)
+ ([145, 95, 219, 40], [44, 29, 7, 70]),
+ // log(address,uint256,uint256,uint256)
+ ([61, 14, 157, 228], [52, 240, 230, 54]),
+ // log(uint256,bool,address)
+ ([66, 78, 255, 191], [53, 8, 95, 123]),
+ // log(string,uint256,bool,bool)
+ ([227, 127, 243, 208], [53, 76, 54, 214]),
+ // log(bool,uint256,uint256)
+ ([59, 92, 3, 224], [55, 16, 51, 103]),
+ // log(bool,uint256,uint256,uint256)
+ ([50, 223, 165, 36], [55, 75, 180, 178]),
+ // log(uint256,string,uint256)
+ ([91, 109, 232, 63], [55, 170, 125, 76]),
+ // log(address,bool,uint256,uint256)
+ ([194, 16, 160, 30], [56, 111, 245, 244]),
+ // log(address,address,bool,uint256)
+ ([149, 214, 95, 17], [57, 113, 231, 140]),
+ // log(bool,uint256)
+ ([54, 75, 106, 146], [57, 145, 116, 211]),
+ // log(uint256,string,uint256,address)
+ ([171, 123, 217, 253], [59, 34, 121, 180]),
+ // log(address,uint256,bool,bool)
+ ([254, 161, 213, 90], [59, 245, 229, 55]),
+ // log(uint256,address,string,string)
+ ([141, 119, 134, 36], [62, 18, 140, 163]),
+ // log(string,address,bool,uint256)
+ ([197, 209, 187, 139], [62, 159, 134, 106]),
+ // log(uint256,uint256,string,address)
+ ([67, 50, 133, 162], [66, 210, 29, 183]),
+ // log(address,string,uint256,string)
+ ([93, 19, 101, 201], [68, 136, 48, 168]),
+ // log(uint256,bool,address,bool)
+ ([145, 251, 18, 66], [69, 77, 84, 165]),
+ // log(address,string,address,uint256)
+ ([140, 25, 51, 169], [69, 127, 227, 207]),
+ // log(uint256,address,string,uint256)
+ ([160, 196, 20, 232], [70, 130, 107, 93]),
+ // log(uint256,uint256,bool)
+ ([103, 87, 15, 247], [71, 102, 218, 114]),
+ // log(address,uint256,address,address)
+ ([236, 36, 132, 111], [71, 141, 28, 98]),
+ // log(address,uint256,uint256,string)
+ ([137, 52, 13, 171], [74, 40, 192, 23]),
+ // log(bool,bool,address,uint256)
+ ([96, 147, 134, 231], [76, 18, 61, 87]),
+ // log(uint256,string,bool)
+ ([70, 167, 208, 206], [76, 237, 167, 90]),
+ // log(string,uint256,address,uint256)
+ ([88, 73, 122, 254], [79, 4, 253, 198]),
+ // log(address,string,bool,uint256)
+ ([231, 32, 82, 28], [81, 94, 56, 182]),
+ // log(bool,address,uint256,string)
+ ([160, 104, 88, 51], [81, 240, 159, 248]),
+ // log(bool,bool,uint256,address)
+ ([11, 255, 149, 13], [84, 167, 169, 160]),
+ // log(uint256,uint256,address,address)
+ ([202, 147, 155, 32], [86, 165, 209, 177]),
+ // log(string,string,uint256)
+ ([243, 98, 202, 89], [88, 33, 239, 161]),
+ // log(string,uint256,string)
+ ([163, 245, 199, 57], [89, 112, 224, 137]),
+ // log(uint256,uint256,uint256,string)
+ ([120, 173, 122, 12], [89, 207, 203, 227]),
+ // log(string,address,uint256,string)
+ ([76, 85, 242, 52], [90, 71, 118, 50]),
+ // log(uint256,address,uint256)
+ ([136, 67, 67, 170], [90, 155, 94, 213]),
+ // log(string,uint256,string,string)
+ ([108, 152, 218, 226], [90, 184, 78, 31]),
+ // log(uint256,address,bool,uint256)
+ ([123, 8, 232, 235], [90, 189, 153, 42]),
+ // log(address,uint256,string,address)
+ ([220, 121, 38, 4], [92, 67, 13, 71]),
+ // log(uint256,uint256,address)
+ ([190, 51, 73, 27], [92, 150, 179, 49]),
+ // log(string,bool,address,uint256)
+ ([40, 223, 78, 150], [93, 8, 187, 5]),
+ // log(string,string,uint256,string)
+ ([141, 20, 44, 221], [93, 26, 151, 26]),
+ // log(uint256,uint256,string,uint256)
+ ([56, 148, 22, 61], [93, 162, 151, 235]),
+ // log(string,uint256,address,address)
+ ([234, 200, 146, 129], [94, 162, 183, 174]),
+ // log(uint256,address,uint256,bool)
+ ([25, 246, 115, 105], [95, 116, 58, 124]),
+ // log(bool,address,uint256)
+ ([235, 112, 75, 175], [95, 123, 154, 251]),
+ // log(uint256,string,address,address)
+ ([127, 165, 69, 139], [97, 104, 237, 97]),
+ // log(bool,bool,uint256,bool)
+ ([171, 92, 193, 196], [97, 158, 77, 14]),
+ // log(address,string,uint256,address)
+ ([223, 215, 216, 11], [99, 24, 54, 120]),
+ // log(uint256,address,string)
+ ([206, 131, 4, 123], [99, 203, 65, 249]),
+ // log(string,address,uint256,address)
+ ([163, 102, 236, 128], [99, 251, 139, 197]),
+ // log(uint256,string)
+ ([15, 163, 243, 69], [100, 63, 208, 223]),
+ // log(string,bool,uint256,uint256)
+ ([93, 191, 240, 56], [100, 181, 187, 103]),
+ // log(address,uint256,uint256,bool)
+ ([236, 75, 168, 162], [102, 241, 188, 103]),
+ // log(address,uint256,bool)
+ ([229, 74, 225, 68], [103, 130, 9, 168]),
+ // log(address,string,uint256)
+ ([28, 218, 242, 138], [103, 221, 111, 241]),
+ // log(uint256,bool,string,string)
+ ([164, 51, 252, 253], [104, 200, 184, 189]),
+ // log(uint256,string,uint256,bool)
+ ([135, 90, 110, 46], [105, 26, 143, 116]),
+ // log(uint256,address)
+ ([88, 235, 134, 12], [105, 39, 108, 134]),
+ // log(uint256,bool,bool,address)
+ ([83, 6, 34, 93], [105, 100, 11, 89]),
+ // log(bool,uint256,string,uint256)
+ ([65, 128, 1, 27], [106, 17, 153, 226]),
+ // log(bool,string,uint256,bool)
+ ([32, 187, 201, 175], [107, 14, 93, 83]),
+ // log(uint256,uint256,address,string)
+ ([214, 162, 209, 222], [108, 222, 64, 184]),
+ // log(bool,bool,bool,uint256)
+ ([194, 72, 131, 77], [109, 112, 69, 193]),
+ // log(uint256,uint256,string)
+ ([125, 105, 14, 230], [113, 208, 74, 242]),
+ // log(uint256,address,address,uint256)
+ ([154, 60, 191, 150], [115, 110, 251, 182]),
+ // log(string,bool,uint256,string)
+ ([66, 185, 162, 39], [116, 45, 110, 231]),
+ // log(uint256,bool,bool,uint256)
+ ([189, 37, 173, 89], [116, 100, 206, 35]),
+ // log(string,uint256,uint256,bool)
+ ([247, 60, 126, 61], [118, 38, 219, 146]),
+ // log(uint256,uint256,string,bool)
+ ([178, 46, 175, 6], [122, 246, 171, 37]),
+ // log(uint256,string,address)
+ ([31, 144, 242, 74], [122, 250, 201, 89]),
+ // log(address,uint256,address)
+ ([151, 236, 163, 148], [123, 192, 216, 72]),
+ // log(bool,string,string,uint256)
+ ([93, 219, 37, 146], [123, 224, 195, 235]),
+ // log(bool,address,uint256,uint256)
+ ([155, 254, 114, 188], [123, 241, 129, 161]),
+ // log(string,uint256,string,address)
+ ([187, 114, 53, 233], [124, 70, 50, 164]),
+ // log(string,string,address,uint256)
+ ([74, 129, 165, 106], [124, 195, 198, 7]),
+ // log(string,uint256,string,bool)
+ ([233, 159, 130, 207], [125, 36, 73, 29]),
+ // log(bool,bool,uint256,string)
+ ([80, 97, 137, 55], [125, 212, 208, 224]),
+ // log(bool,uint256,bool,uint256)
+ ([211, 222, 85, 147], [127, 155, 188, 162]),
+ // log(address,bool,string,uint256)
+ ([158, 18, 123, 110], [128, 230, 162, 11]),
+ // log(string,uint256,address,bool)
+ ([17, 6, 168, 247], [130, 17, 42, 66]),
+ // log(uint256,string,uint256,uint256)
+ ([192, 4, 56, 7], [130, 194, 91, 116]),
+ // log(address,uint256)
+ ([34, 67, 207, 163], [131, 9, 232, 168]),
+ // log(string,uint256,uint256,string)
+ ([165, 78, 212, 189], [133, 75, 52, 150]),
+ // log(uint256,bool,string)
+ ([139, 14, 20, 254], [133, 119, 80, 33]),
+ // log(address,uint256,string,string)
+ ([126, 86, 198, 147], [136, 168, 196, 6]),
+ // log(uint256,bool,uint256,address)
+ ([79, 64, 5, 142], [136, 203, 96, 65]),
+ // log(uint256,uint256,address,uint256)
+ ([97, 11, 168, 192], [136, 246, 228, 178]),
+ // log(string,bool,uint256,bool)
+ ([60, 197, 181, 211], [138, 247, 207, 138]),
+ // log(address,bool,bool,uint256)
+ ([207, 181, 135, 86], [140, 78, 93, 230]),
+ // log(address,address,uint256,address)
+ ([214, 198, 82, 118], [141, 166, 222, 245]),
+ // log(string,bool,bool,uint256)
+ ([128, 117, 49, 232], [142, 63, 120, 169]),
+ // log(bool,uint256,uint256,string)
+ ([218, 6, 102, 200], [142, 105, 251, 93]),
+ // log(string,string,string,uint256)
+ ([159, 208, 9, 245], [142, 175, 176, 43]),
+ // log(string,address,address,uint256)
+ ([110, 183, 148, 61], [142, 243, 243, 153]),
+ // log(uint256,string,address,bool)
+ ([249, 63, 255, 55], [144, 195, 10, 86]),
+ // log(uint256,address,bool,string)
+ ([99, 240, 226, 66], [144, 251, 6, 170]),
+ // log(bool,uint256,bool,string)
+ ([182, 213, 105, 212], [145, 67, 219, 177]),
+ // log(uint256,bool,uint256,bool)
+ ([210, 171, 196, 253], [145, 160, 46, 42]),
+ // log(string,address,string,uint256)
+ ([143, 98, 75, 233], [145, 209, 17, 46]),
+ // log(string,bool,uint256,address)
+ ([113, 211, 133, 13], [147, 94, 9, 191]),
+ // log(address,address,address,uint256)
+ ([237, 94, 172, 135], [148, 37, 13, 119]),
+ // log(uint256,uint256,bool,address)
+ ([225, 23, 116, 79], [154, 129, 106, 131]),
+ // log(bool,uint256,bool,address)
+ ([66, 103, 199, 248], [154, 205, 54, 22]),
+ // log(address,address,uint256,bool)
+ ([194, 246, 136, 236], [155, 66, 84, 226]),
+ // log(uint256,address,bool)
+ ([122, 208, 18, 142], [155, 110, 192, 66]),
+ // log(uint256,string,address,string)
+ ([248, 152, 87, 127], [156, 58, 223, 161]),
+ // log(address,bool,uint256)
+ ([44, 70, 141, 21], [156, 79, 153, 251]),
+ // log(uint256,address,string,address)
+ ([203, 229, 142, 253], [156, 186, 143, 255]),
+ // log(string,uint256,address,string)
+ ([50, 84, 194, 232], [159, 251, 47, 147]),
+ // log(address,uint256,address,bool)
+ ([241, 129, 161, 233], [161, 188, 201, 179]),
+ // log(uint256,bool,address,address)
+ ([134, 237, 193, 12], [161, 239, 76, 187]),
+ // log(address,uint256,string)
+ ([186, 249, 104, 73], [161, 242, 232, 170]),
+ // log(address,uint256,bool,address)
+ ([35, 229, 73, 114], [163, 27, 253, 204]),
+ // log(uint256,uint256,bool,string)
+ ([239, 217, 203, 238], [165, 180, 252, 153]),
+ // log(bool,string,address,uint256)
+ ([27, 11, 149, 91], [165, 202, 218, 148]),
+ // log(address,bool,address,uint256)
+ ([220, 113, 22, 210], [167, 92, 89, 222]),
+ // log(string,uint256,uint256,uint256)
+ ([8, 238, 86, 102], [167, 168, 120, 83]),
+ // log(uint256,uint256,bool,bool)
+ ([148, 190, 59, 177], [171, 8, 90, 230]),
+ // log(string,uint256,bool,string)
+ ([118, 204, 96, 100], [171, 247, 58, 152]),
+ // log(uint256,bool,address,string)
+ ([162, 48, 118, 30], [173, 224, 82, 199]),
+ // log(uint256,string,bool,address)
+ ([121, 111, 40, 160], [174, 46, 197, 129]),
+ // log(uint256,string,string,uint256)
+ ([118, 236, 99, 94], [176, 40, 201, 189]),
+ // log(uint256,string,string)
+ ([63, 87, 194, 149], [177, 21, 97, 31]),
+ // log(uint256,string,string,bool)
+ ([18, 134, 43, 152], [179, 166, 182, 189]),
+ // log(bool,uint256,address,bool)
+ ([101, 173, 244, 8], [180, 195, 20, 255]),
+ // log(string,uint256)
+ ([151, 16, 169, 208], [182, 14, 114, 204]),
+ // log(address,uint256,uint256)
+ ([135, 134, 19, 94], [182, 155, 202, 246]),
+ // log(uint256,bool,bool,bool)
+ ([78, 108, 83, 21], [182, 245, 119, 161]),
+ // log(uint256,string,uint256,string)
+ ([162, 188, 12, 153], [183, 185, 20, 202]),
+ // log(uint256,string,bool,bool)
+ ([81, 188, 43, 193], [186, 83, 93, 156]),
+ // log(uint256,address,address)
+ ([125, 119, 166, 27], [188, 253, 155, 224]),
+ // log(address,address,uint256,uint256)
+ ([84, 253, 243, 228], [190, 85, 52, 129]),
+ // log(bool,uint256,uint256,bool)
+ ([164, 29, 129, 222], [190, 152, 67, 83]),
+ // log(address,uint256,string,uint256)
+ ([245, 18, 207, 155], [191, 1, 248, 145]),
+ // log(bool,address,string,uint256)
+ ([11, 153, 252, 34], [194, 31, 100, 199]),
+ // log(string,string,uint256,bool)
+ ([230, 86, 88, 202], [195, 168, 166, 84]),
+ // log(bool,uint256,string)
+ ([200, 57, 126, 176], [195, 252, 57, 112]),
+ // log(address,bool,uint256,bool)
+ ([133, 205, 197, 175], [196, 100, 62, 32]),
+ // log(uint256,uint256,uint256,bool)
+ ([100, 82, 185, 203], [197, 152, 209, 133]),
+ // log(address,uint256,bool,string)
+ ([142, 142, 78, 117], [197, 173, 133, 249]),
+ // log(string,uint256,string,uint256)
+ ([160, 196, 178, 37], [198, 126, 169, 209]),
+ // log(uint256,bool,uint256,uint256)
+ ([86, 130, 141, 164], [198, 172, 199, 168]),
+ // log(string,bool,uint256)
+ ([41, 27, 185, 208], [201, 89, 88, 214]),
+ // log(string,uint256,uint256)
+ ([150, 156, 221, 3], [202, 71, 196, 235]),
+ // log(string,uint256,bool)
+ ([241, 2, 238, 5], [202, 119, 51, 177]),
+ // log(uint256,address,string,bool)
+ ([34, 164, 121, 166], [204, 50, 171, 7]),
+ // log(address,bool,uint256,address)
+ ([13, 140, 230, 30], [204, 247, 144, 161]),
+ // log(bool,uint256,bool,bool)
+ ([158, 1, 247, 65], [206, 181, 244, 215]),
+ // log(uint256,string,bool,uint256)
+ ([164, 180, 138, 127], [207, 0, 152, 128]),
+ // log(address,uint256,string,bool)
+ ([164, 2, 79, 17], [207, 24, 16, 92]),
+ // log(uint256,uint256,uint256)
+ ([231, 130, 10, 116], [209, 237, 122, 60]),
+ // log(uint256,string,bool,string)
+ ([141, 72, 156, 160], [210, 212, 35, 205]),
+ // log(uint256,string,string,address)
+ ([204, 152, 138, 160], [213, 131, 198, 2]),
+ // log(bool,address,uint256,bool)
+ ([238, 141, 134, 114], [214, 1, 159, 28]),
+ // log(string,string,bool,uint256)
+ ([134, 129, 138, 122], [214, 174, 250, 210]),
+ // log(uint256,address,uint256,string)
+ ([62, 211, 189, 40], [221, 176, 101, 33]),
+ // log(uint256,bool,bool,string)
+ ([49, 138, 229, 155], [221, 219, 149, 97]),
+ // log(uint256,bool,uint256,string)
+ ([232, 221, 188, 86], [222, 3, 231, 116]),
+ // log(string,uint256,bool,address)
+ ([229, 84, 157, 145], [224, 233, 91, 152]),
+ // log(string,uint256,uint256,address)
+ ([190, 215, 40, 191], [226, 29, 226, 120]),
+ // log(uint256,address,bool,bool)
+ ([126, 39, 65, 13], [227, 81, 20, 15]),
+ // log(bool,bool,string,uint256)
+ ([23, 139, 70, 133], [227, 169, 202, 47]),
+ // log(string,uint256,bool,uint256)
+ ([85, 14, 110, 245], [228, 27, 111, 111]),
+ // log(bool,uint256,string,bool)
+ ([145, 210, 248, 19], [229, 231, 11, 43]),
+ // log(uint256,string,address,uint256)
+ ([152, 231, 243, 243], [232, 211, 1, 141]),
+ // log(bool,uint256,bool)
+ ([27, 173, 201, 235], [232, 222, 251, 169]),
+ // log(uint256,uint256,bool,uint256)
+ ([108, 100, 124, 140], [235, 127, 111, 210]),
+ // log(uint256,bool,string,bool)
+ ([52, 110, 184, 199], [235, 146, 141, 127]),
+ // log(address,address,string,uint256)
+ ([4, 40, 147, 0], [239, 28, 239, 231]),
+ // log(uint256,bool,string,address)
+ ([73, 110, 43, 180], [239, 82, 144, 24]),
+ // log(uint256,address,bool,address)
+ ([182, 49, 48, 148], [239, 114, 197, 19]),
+ // log(string,string,uint256,uint256)
+ ([213, 207, 23, 208], [244, 93, 125, 44]),
+ // log(bool,uint256,string,string)
+ ([211, 42, 101, 72], [245, 188, 34, 73]),
+ // log(uint256,uint256)
+ ([108, 15, 105, 128], [246, 102, 113, 90]),
+ // log(uint256) and logUint(uint256)
+ ([245, 177, 187, 169], [248, 44, 80, 241]),
+ // log(string,address,uint256,uint256)
+ ([218, 163, 148, 189], [248, 245, 27, 30]),
+ // log(uint256,uint256,uint256,address)
+ ([224, 133, 63, 105], [250, 129, 133, 175]),
+ // log(string,address,uint256,bool)
+ ([90, 193, 193, 60], [252, 72, 69, 240]),
+ // log(address,address,uint256,string)
+ ([157, 209, 46, 173], [253, 180, 249, 144]),
+ // log(bool,uint256,string,address)
+ ([165, 199, 13, 41], [254, 221, 31, 255]),
+ // logInt(int256)
+ ([78, 12, 29, 29], [101, 37, 181, 245]),
+ // logBytes(bytes)
+ ([11, 231, 127, 86], [225, 123, 249, 86]),
+ // logBytes1(bytes1)
+ ([110, 24, 161, 40], [111, 65, 113, 201]),
+ // logBytes2(bytes2)
+ ([233, 182, 34, 150], [155, 94, 148, 62]),
+ // logBytes3(bytes3)
+ ([45, 131, 73, 38], [119, 130, 250, 45]),
+ // logBytes4(bytes4)
+ ([224, 95, 72, 209], [251, 163, 173, 57]),
+ // logBytes5(bytes5)
+ ([166, 132, 128, 141], [85, 131, 190, 46]),
+ // logBytes6(bytes6)
+ ([174, 132, 165, 145], [73, 66, 173, 198]),
+ // logBytes7(bytes7)
+ ([78, 213, 126, 40], [69, 116, 175, 171]),
+ // logBytes8(bytes8)
+ ([79, 132, 37, 46], [153, 2, 228, 127]),
+ // logBytes9(bytes9)
+ ([144, 189, 140, 208], [80, 161, 56, 223]),
+ // logBytes10(bytes10)
+ ([1, 61, 23, 139], [157, 194, 168, 151]),
+ // logBytes11(bytes11)
+ ([4, 0, 74, 46], [220, 8, 182, 167]),
+ // logBytes12(bytes12)
+ ([134, 160, 106, 189], [118, 86, 214, 199]),
+ // logBytes13(bytes13)
+ ([148, 82, 158, 52], [52, 193, 216, 27]),
+ // logBytes14(bytes14)
+ ([146, 102, 240, 127], [60, 234, 186, 101]),
+ // logBytes15(bytes15)
+ ([218, 149, 116, 224], [89, 26, 61, 162]),
+ // logBytes16(bytes16)
+ ([102, 92, 97, 4], [31, 141, 115, 18]),
+ // logBytes17(bytes17)
+ ([51, 159, 103, 58], [248, 154, 83, 47]),
+ // logBytes18(bytes18)
+ ([196, 210, 61, 154], [216, 101, 38, 66]),
+ // logBytes19(bytes19)
+ ([94, 107, 90, 51], [0, 245, 107, 201]),
+ // logBytes20(bytes20)
+ ([81, 136, 227, 233], [236, 184, 86, 126]),
+ // logBytes21(bytes21)
+ ([233, 218, 53, 96], [48, 82, 192, 143]),
+ // logBytes22(bytes22)
+ ([213, 250, 232, 156], [128, 122, 180, 52]),
+ // logBytes23(bytes23)
+ ([171, 161, 207, 13], [73, 121, 176, 55]),
+ // logBytes24(bytes24)
+ ([241, 179, 91, 52], [9, 119, 174, 252]),
+ // logBytes25(bytes25)
+ ([11, 132, 188, 88], [174, 169, 150, 63]),
+ // logBytes26(bytes26)
+ ([248, 177, 73, 241], [211, 99, 86, 40]),
+ // logBytes27(bytes27)
+ ([58, 55, 87, 221], [252, 55, 47, 159]),
+ // logBytes28(bytes28)
+ ([200, 42, 234, 238], [56, 47, 154, 52]),
+ // logBytes29(bytes29)
+ ([75, 105, 195, 213], [122, 24, 118, 65]),
+ // logBytes30(bytes30)
+ ([238, 18, 196, 237], [196, 52, 14, 246]),
+ // logBytes31(bytes31)
+ ([194, 133, 77, 146], [129, 252, 134, 72]),
+ // logBytes32(bytes32)
+ ([39, 183, 207, 133], [45, 33, 214, 247]),
+ ])
+});
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn hardhat_console_path_works() {
+ for (hh, abigen) in HARDHAT_CONSOLE_SELECTOR_PATCHES.iter() {
+ let mut hh = (*hh).to_vec();
+ patch_hardhat_console_selector(&mut hh);
+ assert_eq!((*abigen).to_vec(), hh);
+ }
+ }
+}
diff --git a/crates/evm/src/executor/backend/diagnostic.rs b/crates/evm-executors/src/backend/diagnostic.rs
similarity index 80%
rename from crates/evm/src/executor/backend/diagnostic.rs
rename to crates/evm-executors/src/backend/diagnostic.rs
index ff179460e3008..1e2b0b0d26672 100644
--- a/crates/evm/src/executor/backend/diagnostic.rs
+++ b/crates/evm-executors/src/backend/diagnostic.rs
@@ -1,9 +1,7 @@
-use crate::executor::{backend::LocalForkId, inspector::Cheatcodes};
+use crate::backend::LocalForkId;
use alloy_primitives::Address;
-use foundry_common::fmt::UIfmt;
-
-use foundry_utils::types::ToEthers;
use itertools::Itertools;
+use std::collections::BTreeMap;
/// Represents possible diagnostic cases on revert
#[derive(Debug, Clone)]
@@ -21,14 +19,11 @@ pub enum RevertDiagnostic {
},
}
-// === impl RevertDiagnostic ===
-
impl RevertDiagnostic {
/// Converts the diagnostic to a readable error message
- pub fn to_error_msg(&self, cheats: &Cheatcodes) -> String {
- let get_label = |addr: &Address| {
- cheats.labels.get(addr).cloned().unwrap_or_else(|| addr.to_ethers().pretty())
- };
+ pub fn to_error_msg(&self, labels: &BTreeMap) -> String {
+ let get_label =
+ |addr: &Address| labels.get(addr).cloned().unwrap_or_else(|| addr.to_string());
match self {
RevertDiagnostic::ContractExistsOnOtherForks { contract, active, available_on } => {
diff --git a/crates/evm/src/executor/backend/error.rs b/crates/evm-executors/src/backend/error.rs
similarity index 98%
rename from crates/evm/src/executor/backend/error.rs
rename to crates/evm-executors/src/backend/error.rs
index a23a16c3828cd..209ecf4b01ef0 100644
--- a/crates/evm/src/executor/backend/error.rs
+++ b/crates/evm-executors/src/backend/error.rs
@@ -99,7 +99,7 @@ impl From for DatabaseError {
/// Error thrown when the address is not allowed to execute cheatcodes
///
-/// See also [`DatabaseExt`](crate::executor::DatabaseExt)
+/// See also [`DatabaseExt`](crate::DatabaseExt)
#[derive(Debug, Clone, Copy)]
pub struct NoCheatcodeAccessError(pub Address);
diff --git a/crates/evm/src/executor/backend/fuzz.rs b/crates/evm-executors/src/backend/fuzz.rs
similarity index 97%
rename from crates/evm/src/executor/backend/fuzz.rs
rename to crates/evm-executors/src/backend/fuzz.rs
index 738fa8a34c2a7..12d0f6ce781ed 100644
--- a/crates/evm/src/executor/backend/fuzz.rs
+++ b/crates/evm-executors/src/backend/fuzz.rs
@@ -1,11 +1,10 @@
//! A wrapper around `Backend` that is clone-on-write used for fuzzing.
-use crate::executor::{
+use crate::{
backend::{
diagnostic::RevertDiagnostic, error::DatabaseError, Backend, DatabaseExt, LocalForkId,
},
fork::{CreateFork, ForkId},
- inspector::cheatcodes::Cheatcodes,
};
use alloy_primitives::{Address, B256, U256};
use revm::{
@@ -46,8 +45,6 @@ pub struct FuzzBackendWrapper<'a> {
has_snapshot_failure: bool,
}
-// === impl FuzzBackendWrapper ===
-
impl<'a> FuzzBackendWrapper<'a> {
pub fn new(backend: &'a Backend) -> Self {
Self { backend: Cow::Borrowed(backend), is_initialized: false, has_snapshot_failure: false }
@@ -165,16 +162,16 @@ impl<'a> DatabaseExt for FuzzBackendWrapper<'a> {
self.backend_mut(env).roll_fork_to_transaction(id, transaction, env, journaled_state)
}
- fn transact(
+ fn transact>(
&mut self,
id: Option,
transaction: B256,
env: &mut Env,
journaled_state: &mut JournaledState,
- cheatcodes_inspector: Option<&mut Cheatcodes>,
+ inspector: I,
) -> eyre::Result<()> {
trace!(?id, ?transaction, "fuzz: execute transaction");
- self.backend_mut(env).transact(id, transaction, env, journaled_state, cheatcodes_inspector)
+ self.backend_mut(env).transact(id, transaction, env, journaled_state, inspector)
}
fn active_fork_id(&self) -> Option {
diff --git a/crates/evm/src/executor/backend/in_memory_db.rs b/crates/evm-executors/src/backend/in_memory_db.rs
similarity index 98%
rename from crates/evm/src/executor/backend/in_memory_db.rs
rename to crates/evm-executors/src/backend/in_memory_db.rs
index 4687db7804e95..9041258593455 100644
--- a/crates/evm/src/executor/backend/in_memory_db.rs
+++ b/crates/evm-executors/src/backend/in_memory_db.rs
@@ -1,5 +1,5 @@
//! The in memory DB
-use crate::executor::backend::error::DatabaseError;
+use crate::{backend::error::DatabaseError, snapshot::Snapshots};
use alloy_primitives::{Address, B256, U256};
use revm::{
db::{CacheDB, DatabaseRef, EmptyDB},
@@ -7,8 +7,6 @@ use revm::{
Database, DatabaseCommit,
};
-use crate::executor::snapshot::Snapshots;
-
/// Type alias for an in memory database
///
/// See `EmptyDBWrapper`
diff --git a/crates/evm/src/executor/backend/mod.rs b/crates/evm-executors/src/backend/mod.rs
similarity index 98%
rename from crates/evm/src/executor/backend/mod.rs
rename to crates/evm-executors/src/backend/mod.rs
index f159ef82c6dbe..49d464e4e2d46 100644
--- a/crates/evm/src/executor/backend/mod.rs
+++ b/crates/evm-executors/src/backend/mod.rs
@@ -1,20 +1,10 @@
//! Foundry's main executor backend abstraction and implementation.
use crate::{
- abi::CHEATCODE_ADDRESS,
- executor::{
- backend::{
- error::NoCheatcodeAccessError, in_memory_db::FoundryEvmInMemoryDB,
- snapshot::BackendSnapshot,
- },
- fork::{CreateFork, ForkId, MultiFork, SharedBackend},
- inspector::{
- cheatcodes::{util::configure_tx_env, Cheatcodes},
- DEFAULT_CREATE2_DEPLOYER,
- },
- snapshot::Snapshots,
- },
- CALLER, TEST_CONTRACT_ADDRESS,
+ fork::{CreateFork, ForkId, MultiFork, SharedBackend},
+ snapshot::Snapshots,
+ utils::configure_tx_env,
+ CALLER, CHEATCODE_ADDRESS, DEFAULT_CREATE2_DEPLOYER, TEST_CONTRACT_ADDRESS,
};
use alloy_primitives::{b256, keccak256, Address, B256, U256, U64};
use ethers::{
@@ -23,9 +13,9 @@ use ethers::{
};
use foundry_common::{is_known_system_sender, SYSTEM_TRANSACTION_TYPE};
use foundry_utils::types::{ToAlloy, ToEthers};
-pub use in_memory_db::MemDb;
use revm::{
db::{CacheDB, DatabaseRef},
+ inspectors::NoOpInspector,
precompile::{Precompiles, SpecId},
primitives::{
Account, AccountInfo, Bytecode, CreateScheme, Env, HashMap as Map, Log, ResultAndState,
@@ -41,17 +31,20 @@ use std::{
},
};
-mod fuzz;
-pub mod snapshot;
-pub use fuzz::FuzzBackendWrapper;
mod diagnostic;
-
pub use diagnostic::RevertDiagnostic;
-pub mod error;
-pub use error::{DatabaseError, DatabaseResult};
+mod error;
+pub use error::{DatabaseError, DatabaseResult, NoCheatcodeAccessError};
+
+mod fuzz;
+pub use fuzz::FuzzBackendWrapper;
mod in_memory_db;
+pub use in_memory_db::{EmptyDBWrapper, FoundryEvmInMemoryDB, MemDb};
+
+mod snapshot;
+pub use snapshot::{BackendSnapshot, StateSnapshot};
// A `revm::Database` that is used in forking mode
type ForkDB = CacheDB;
@@ -83,6 +76,7 @@ pub trait DatabaseExt: Database {
/// Snapshots can be reverted: [DatabaseExt::revert], however a snapshot can only be reverted
/// once. After a successful revert, the same snapshot id cannot be used again.
fn snapshot(&mut self, journaled_state: &JournaledState, env: &Env) -> U256;
+
/// Reverts the snapshot if it exists
///
/// Returns `true` if the snapshot was successfully reverted, `false` if no snapshot for that id
@@ -187,13 +181,13 @@ pub trait DatabaseExt: Database {
) -> eyre::Result<()>;
/// Fetches the given transaction for the fork and executes it, committing the state in the DB
- fn transact(
+ fn transact>(
&mut self,
id: Option,
transaction: B256,
env: &mut Env,
journaled_state: &mut JournaledState,
- cheatcodes_inspector: Option<&mut Cheatcodes>,
+ inspector: I,
) -> eyre::Result<()>;
/// Returns the `ForkId` that's currently used in the database, if fork mode is on
@@ -877,7 +871,7 @@ impl Backend {
}
trace!(tx=?tx.hash, "committing transaction");
- commit_transaction(tx, env.clone(), journaled_state, fork, &fork_id, None)?;
+ commit_transaction(tx, env.clone(), journaled_state, fork, &fork_id, NoOpInspector)?;
}
Ok(None)
@@ -1176,13 +1170,13 @@ impl DatabaseExt for Backend {
Ok(())
}
- fn transact(
+ fn transact>(
&mut self,
maybe_id: Option,
transaction: B256,
env: &mut Env,
journaled_state: &mut JournaledState,
- cheatcodes_inspector: Option<&mut Cheatcodes>,
+ inspector: I,
) -> eyre::Result<()> {
trace!(?maybe_id, ?transaction, "execute transaction");
let id = self.ensure_fork(maybe_id)?;
@@ -1199,9 +1193,7 @@ impl DatabaseExt for Backend {
let fork = self.inner.get_fork_by_id_mut(id)?;
let tx = fork.db.db.get_transaction(transaction)?;
- commit_transaction(tx, env, journaled_state, fork, &fork_id, cheatcodes_inspector)?;
-
- Ok(())
+ commit_transaction(tx, env, journaled_state, fork, &fork_id, inspector)
}
fn active_fork_id(&self) -> Option {
@@ -1803,13 +1795,13 @@ fn is_contract_in_state(journaled_state: &JournaledState, acc: Address) -> bool
/// Executes the given transaction and commits state changes to the database _and_ the journaled
/// state, with an optional inspector
-fn commit_transaction(
+fn commit_transaction>(
tx: Transaction,
mut env: Env,
journaled_state: &mut JournaledState,
fork: &mut Fork,
fork_id: &ForkId,
- cheatcodes_inspector: Option<&mut Cheatcodes>,
+ inspector: I,
) -> eyre::Result<()> {
configure_tx_env(&mut env, &tx);
@@ -1823,16 +1815,9 @@ fn commit_transaction(
.block_on(async move { Backend::new_with_fork(fork_id, fork, journaled_state).await });
evm.database(db);
- if let Some(inspector) = cheatcodes_inspector {
- match evm.inspect(inspector) {
- Ok(res) => res.state,
- Err(e) => eyre::bail!("backend: failed committing transaction: {:?}", e),
- }
- } else {
- match evm.transact() {
- Ok(res) => res.state,
- Err(e) => eyre::bail!("backend: failed committing transaction: {:?}", e),
- }
+ match evm.inspect(inspector) {
+ Ok(res) => res.state,
+ Err(e) => eyre::bail!("backend: failed committing transaction: {:?}", e),
}
};
diff --git a/crates/evm/src/executor/backend/snapshot.rs b/crates/evm-executors/src/backend/snapshot.rs
similarity index 100%
rename from crates/evm/src/executor/backend/snapshot.rs
rename to crates/evm-executors/src/backend/snapshot.rs
diff --git a/crates/evm-executors/src/constants.rs b/crates/evm-executors/src/constants.rs
new file mode 100644
index 0000000000000..55a0458ed0649
--- /dev/null
+++ b/crates/evm-executors/src/constants.rs
@@ -0,0 +1,37 @@
+use alloy_primitives::{address, hex, Address};
+
+/// The cheatcode handler address.
+///
+/// This is the same address as the one used in DappTools's HEVM.
+/// It is calculated as:
+/// `address(bytes20(uint160(uint256(keccak256('hevm cheat code')))))`
+pub const CHEATCODE_ADDRESS: Address = address!("7109709ECfa91a80626fF3989D68f67F5b1DD12D");
+
+/// The Hardhat console address.
+///
+/// See:
+pub const HARDHAT_CONSOLE_ADDRESS: Address = address!("000000000000000000636F6e736F6c652e6c6f67");
+
+/// Stores the caller address to be used as *sender* account for:
+/// - deploying Test contracts
+/// - deploying Script contracts
+///
+/// Derived from `address(uint160(uint256(keccak256("foundry default caller"))))`,
+/// which is equal to `0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38`.
+pub const CALLER: Address = address!("1804c8AB1F12E6bbf3894d4083f33e07309d1f38");
+
+/// The default test contract address.
+pub const TEST_CONTRACT_ADDRESS: Address = address!("b4c79daB8f259C7Aee6E5b2Aa729821864227e84");
+
+/// Magic return value returned by the `assume` cheatcode.
+pub const ASSUME_MAGIC_RETURN_CODE: &[u8] = b"FOUNDRY::ASSUME";
+
+/// Magic return value returned by the `skip` cheatcode.
+pub const MAGIC_SKIP_BYTES: &[u8] = b"FOUNDRY::SKIP";
+
+/// The default CREATE2 deployer.
+pub const DEFAULT_CREATE2_DEPLOYER: Address = address!("4e59b44847b379578588920ca78fbf26c0b4956c");
+/// The initcode of the default CREATE2 deployer.
+pub const DEFAULT_CREATE2_DEPLOYER_CODE: &[u8] = &hex!("604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3");
+/// The runtime code of the default CREATE2 deployer.
+pub const DEFAULT_CREATE2_DEPLOYER_RUNTIME_CODE: &[u8] = &hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3");
diff --git a/crates/evm/src/debug.rs b/crates/evm-executors/src/debug.rs
similarity index 98%
rename from crates/evm/src/debug.rs
rename to crates/evm-executors/src/debug.rs
index d4c97fedf95be..be6252109e72c 100644
--- a/crates/evm/src/debug.rs
+++ b/crates/evm-executors/src/debug.rs
@@ -180,7 +180,7 @@ impl Display for Instruction {
"VM_{}",
&*HEVM_ABI
.functions()
- .find(|func| func.selector() == *cheat)
+ .find(|func| func.short_signature() == *cheat)
.expect("unknown cheatcode found in debugger")
.name
.to_uppercase()
diff --git a/crates/evm/src/decode.rs b/crates/evm-executors/src/decode.rs
similarity index 99%
rename from crates/evm/src/decode.rs
rename to crates/evm-executors/src/decode.rs
index 9386c098548f2..943e3144778e8 100644
--- a/crates/evm/src/decode.rs
+++ b/crates/evm-executors/src/decode.rs
@@ -1,5 +1,6 @@
-//! Various utilities to decode test results
-use crate::executor::inspector::cheatcodes::util::MAGIC_SKIP_BYTES;
+//! Various utilities to decode test results.
+
+use crate::MAGIC_SKIP_BYTES;
use alloy_dyn_abi::{DynSolType, DynSolValue, JsonAbiExt};
use alloy_json_abi::JsonAbi;
use alloy_primitives::{B256, U256};
diff --git a/crates/evm/src/executor/fork/backend.rs b/crates/evm-executors/src/fork/backend.rs
similarity index 98%
rename from crates/evm/src/executor/fork/backend.rs
rename to crates/evm-executors/src/fork/backend.rs
index f296796b7097f..e781601560e3b 100644
--- a/crates/evm/src/executor/fork/backend.rs
+++ b/crates/evm-executors/src/fork/backend.rs
@@ -1,6 +1,6 @@
//! Smart caching and deduplication of requests when using a forking provider
-use crate::executor::{
- backend::error::{DatabaseError, DatabaseResult},
+use crate::{
+ backend::{DatabaseError, DatabaseResult},
fork::{cache::FlushJsonBlockCacheDB, BlockchainDb},
};
use alloy_primitives::{keccak256, Address, Bytes, B256, U256};
@@ -346,19 +346,17 @@ where
};
// convert it to revm-style types
- let (code, code_hash) = if !code.0.is_empty() {
- (Some(code.0.clone()), keccak256(&code))
+ let (code, code_hash) = if !code.is_empty() {
+ (code.clone(), keccak256(&code))
} else {
- (Some(bytes::Bytes::default()), KECCAK_EMPTY)
+ (Bytes::default(), KECCAK_EMPTY)
};
// update the cache
let acc = AccountInfo {
nonce: nonce.to(),
balance,
- code: code.map(|bytes| {
- Bytecode::new_raw(alloy_primitives::Bytes(bytes)).to_checked()
- }),
+ code: Some(Bytecode::new_raw(code).to_checked()),
code_hash,
};
pin.db.accounts().write().insert(addr, acc.clone());
@@ -696,7 +694,7 @@ impl DatabaseRef for SharedBackend {
#[cfg(test)]
mod tests {
use super::*;
- use crate::executor::{
+ use crate::{
fork::{BlockchainDbMeta, CreateFork, JsonBlockCacheDB},
opts::EvmOpts,
Backend,
diff --git a/crates/evm/src/executor/fork/cache.rs b/crates/evm-executors/src/fork/cache.rs
similarity index 99%
rename from crates/evm/src/executor/fork/cache.rs
rename to crates/evm-executors/src/fork/cache.rs
index f9a96772ce34d..f2203fc5de9c4 100644
--- a/crates/evm/src/executor/fork/cache.rs
+++ b/crates/evm-executors/src/fork/cache.rs
@@ -1,5 +1,5 @@
//! Cache related abstraction
-use crate::executor::backend::snapshot::StateSnapshot;
+use crate::backend::StateSnapshot;
use alloy_primitives::{Address, B256, U256};
use parking_lot::RwLock;
use revm::{
diff --git a/crates/evm/src/executor/fork/database.rs b/crates/evm-executors/src/fork/database.rs
similarity index 96%
rename from crates/evm/src/executor/fork/database.rs
rename to crates/evm-executors/src/fork/database.rs
index 8da324b24cf29..13596fee4796f 100644
--- a/crates/evm/src/executor/fork/database.rs
+++ b/crates/evm-executors/src/fork/database.rs
@@ -1,18 +1,15 @@
//! A revm database that forks off a remote client
use crate::{
- executor::{
- backend::{error::DatabaseError, snapshot::StateSnapshot},
- fork::{BlockchainDb, SharedBackend},
- snapshot::Snapshots,
- },
- revm::db::CacheDB,
+ backend::{DatabaseError, StateSnapshot},
+ fork::{BlockchainDb, SharedBackend},
+ snapshot::Snapshots,
};
use alloy_primitives::{Address, B256, U256};
use ethers::types::BlockId;
use parking_lot::Mutex;
use revm::{
- db::DatabaseRef,
+ db::{CacheDB, DatabaseRef},
primitives::{Account, AccountInfo, Bytecode, HashMap as Map},
Database, DatabaseCommit,
};
@@ -155,7 +152,7 @@ impl Database for ForkedDatabase {
fn basic(&mut self, address: Address) -> Result