diff --git a/Cargo.lock b/Cargo.lock index b3e979f4f068a..3878dd32a20f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3135,10 +3135,11 @@ dependencies = [ [[package]] name = "evmole" -version = "0.3.8" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffb1f458e6901be6a6aaa485ce3a5d81478644edde1ffbe95da114ad9c94467" +checksum = "d55794094e85dd9d2a4a44de6554015c7d0d7193a28756f2ee3432bb763003a7" dependencies = [ + "alloy-dyn-abi", "ruint", ] diff --git a/crates/cast/Cargo.toml b/crates/cast/Cargo.toml index edc3fbe8d6089..386c523b467f5 100644 --- a/crates/cast/Cargo.toml +++ b/crates/cast/Cargo.toml @@ -79,7 +79,7 @@ tempfile.workspace = true tokio = { workspace = true, features = ["macros", "signal"] } tracing.workspace = true yansi.workspace = true -evmole = "0.3.1" +evmole = "0.4.1" [target.'cfg(unix)'.dependencies] tikv-jemallocator = { workspace = true, optional = true } diff --git a/crates/cast/bin/main.rs b/crates/cast/bin/main.rs index 501955827fce7..8eaa201d6f5b2 100644 --- a/crates/cast/bin/main.rs +++ b/crates/cast/bin/main.rs @@ -305,25 +305,24 @@ async fn main() -> Result<()> { println!("{}", SimpleCast::disassemble(&bytecode)?); } CastSubcommand::Selectors { bytecode, resolve } => { - let selectors_and_args = SimpleCast::extract_selectors(&bytecode)?; - if resolve { - let selectors_it = selectors_and_args.iter().map(|r| &r.0); - let resolve_results = - decode_selectors(SelectorType::Function, selectors_it).await?; + let functions = SimpleCast::extract_functions(&bytecode)?; + let max_args_len = functions.iter().map(|r| r.1.len()).max().unwrap_or(0); + let max_mutability_len = functions.iter().map(|r| r.2.len()).max().unwrap_or(0); - let max_args_len = selectors_and_args.iter().map(|r| r.1.len()).max().unwrap_or(0); - for ((selector, arguments), func_names) in - selectors_and_args.into_iter().zip(resolve_results.into_iter()) - { - let resolved = match func_names { - Some(v) => v.join("|"), - None => String::new(), - }; - println!("{selector}\t{arguments:max_args_len$}\t{resolved}"); - } + let resolve_results = if resolve { + let selectors_it = functions.iter().map(|r| &r.0); + let ds = decode_selectors(SelectorType::Function, selectors_it).await?; + ds.into_iter().map(|v| v.unwrap_or_default().join("|")).collect() } else { - for (selector, arguments) in selectors_and_args { - println!("{selector}\t{arguments}"); + vec![] + }; + for (pos, (selector, arguments, state_mutability)) in functions.into_iter().enumerate() + { + if resolve { + let resolved = &resolve_results[pos]; + println!("{selector}\t{arguments:max_args_len$}\t{state_mutability:max_mutability_len$}\t{resolved}"); + } else { + println!("{selector}\t{arguments:max_args_len$}\t{state_mutability}"); } } } diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index 12d42c2c95389..c4d756ad72240 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -1103,7 +1103,7 @@ impl SimpleCast { pub fn to_ascii(hex: &str) -> Result { let bytes = hex::decode(hex)?; if !bytes.iter().all(u8::is_ascii) { - return Err(eyre::eyre!("Invalid ASCII bytes")) + return Err(eyre::eyre!("Invalid ASCII bytes")); } Ok(String::from_utf8(bytes).unwrap()) } @@ -1405,7 +1405,7 @@ impl SimpleCast { let base_in = Base::unwrap_or_detect(base_in, value)?; let base_out: Base = base_out.parse()?; if base_in == base_out { - return Ok(value.to_string()) + return Ok(value.to_string()); } let mut n = NumberWithBase::parse_int(value, Some(&base_in.to_string()))?; @@ -1469,7 +1469,7 @@ impl SimpleCast { let s = if let Some(stripped) = s.strip_prefix("000000000000000000000000") { stripped } else { - return Err(eyre::eyre!("Not convertible to address, there are non-zero bytes")) + return Err(eyre::eyre!("Not convertible to address, there are non-zero bytes")); }; let lowercase_address_string = format!("0x{s}"); @@ -1925,7 +1925,7 @@ impl SimpleCast { } if optimize == 0 { let selector = get_func(signature)?.selector(); - return Ok((selector.to_string(), String::from(signature))) + return Ok((selector.to_string(), String::from(signature))); } let Some((name, params)) = signature.split_once('(') else { eyre::bail!("invalid function signature"); @@ -1947,7 +1947,7 @@ impl SimpleCast { if selector.iter().take_while(|&&byte| byte == 0).count() == optimize { found.store(true, Ordering::Relaxed); - return Some((nonce, hex::encode_prefixed(selector), input)) + return Some((nonce, hex::encode_prefixed(selector), input)); } nonce += nonce_step; @@ -1961,7 +1961,7 @@ impl SimpleCast { } } - /// Extracts function selectors and arguments from bytecode + /// Extracts function selectors, arguments and state mutability from bytecode /// /// # Example /// @@ -1969,16 +1969,21 @@ impl SimpleCast { /// use cast::SimpleCast as Cast; /// /// let bytecode = "6080604052348015600e575f80fd5b50600436106026575f3560e01c80632125b65b14602a575b5f80fd5b603a6035366004603c565b505050565b005b5f805f60608486031215604d575f80fd5b833563ffffffff81168114605f575f80fd5b925060208401356001600160a01b03811681146079575f80fd5b915060408401356001600160e01b03811681146093575f80fd5b80915050925092509256"; - /// let selectors = Cast::extract_selectors(bytecode)?; - /// assert_eq!(selectors, vec![("0x2125b65b".to_string(), "uint32,address,uint224".to_string())]); + /// let functions = Cast::extract_functions(bytecode)?; + /// assert_eq!(functions, vec![("0x2125b65b".to_string(), "uint32,address,uint224".to_string(), "pure")]); /// # Ok::<(), eyre::Report>(()) /// ``` - pub fn extract_selectors(bytecode: &str) -> Result> { + pub fn extract_functions(bytecode: &str) -> Result> { let code = hex::decode(strip_0x(bytecode))?; - let s = evmole::function_selectors(&code, 0); - - Ok(s.iter() - .map(|s| (hex::encode_prefixed(s), evmole::function_arguments(&code, s, 0))) + Ok(evmole::function_selectors(&code, 0) + .into_iter() + .map(|s| { + ( + hex::encode_prefixed(s), + evmole::function_arguments(&code, &s, 0), + evmole::function_state_mutability(&code, &s, 0), + ) + }) .collect()) } diff --git a/crates/cheatcodes/tests/assume.rs b/crates/cheatcodes/tests/assume.rs index d60102562abcf..158d5f4b64a9f 100644 --- a/crates/cheatcodes/tests/assume.rs +++ b/crates/cheatcodes/tests/assume.rs @@ -1,5 +1,7 @@ //! Contains various tests for `assume*` cheatcodes. +use alloy_primitives::U256; +use foundry_config::{Config, FuzzConfig}; use foundry_test_utils::{forgetest_init, str}; forgetest_init!(test_assume_no_revert, |prj, cmd| { @@ -8,6 +10,12 @@ forgetest_init!(test_assume_no_revert, |prj, cmd| { prj.insert_vm(); prj.clear(); + let config = Config { + fuzz: { FuzzConfig { runs: 100, seed: Some(U256::from(100)), ..Default::default() } }, + ..Default::default() + }; + prj.write_config(config); + prj.add_source( "Counter.t.sol", r#"pragma solidity 0.8.24; @@ -76,7 +84,7 @@ contract CounterRevertTest is DSTest { [FAIL. Reason: assertion failed; counterexample: [..]] test_assume_no_revert_fail_assert(uint256) [..] [FAIL. Reason: CheckError(); counterexample: [..]] test_assume_no_revert_fail_in_2nd_call(uint256) [..] [FAIL. Reason: CheckError(); counterexample: [..]] test_assume_no_revert_fail_in_3rd_call(uint256) [..] -[PASS] test_assume_no_revert_pass(uint256) (runs: 256, [..]) +[PASS] test_assume_no_revert_pass(uint256) [..] ... "#]]); }); diff --git a/crates/forge/bin/cmd/bind.rs b/crates/forge/bin/cmd/bind.rs index f9e9a22a42e11..d5d23633243f4 100644 --- a/crates/forge/bin/cmd/bind.rs +++ b/crates/forge/bin/cmd/bind.rs @@ -104,10 +104,10 @@ impl BindArgs { let _ = ProjectCompiler::new().compile(&project)?; } - if !self.alloy { + if self.ethers { eprintln!( - "Warning: `--ethers` (default) bindings are deprecated and will be removed in the future. \ - Consider using `--alloy` instead." + "Warning: `--ethers` bindings are deprecated and will be removed in the future. \ + Consider using `--alloy` (default) instead." ); } @@ -191,7 +191,7 @@ impl BindArgs { fn get_json_files(&self, artifacts: &Path) -> Result> { let filter = self.get_filter()?; let alloy_filter = self.get_alloy_filter()?; - let is_alloy = self.alloy; + let is_alloy = !self.ethers; Ok(json_files(artifacts) .filter_map(|path| { // Ignore the build info JSON. @@ -264,7 +264,7 @@ impl BindArgs { /// Check that the existing bindings match the expected abigen output fn check_existing_bindings(&self, artifacts: &Path, bindings_root: &Path) -> Result<()> { - if !self.alloy { + if self.ethers { return self.check_ethers(artifacts, bindings_root); } @@ -316,7 +316,7 @@ impl BindArgs { /// Generate the bindings fn generate_bindings(&self, artifacts: &Path, bindings_root: &Path) -> Result<()> { - if !self.alloy { + if self.ethers { return self.generate_ethers(artifacts, bindings_root); }