diff --git a/Cargo.lock b/Cargo.lock index 112351887f28b..88afde82a8b85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3664,7 +3664,6 @@ dependencies = [ "alloy-provider", "alloy-rpc-types", "async-trait", - "ciborium", "clap", "eyre", "foundry-block-explorers", @@ -3841,6 +3840,7 @@ dependencies = [ "async-trait", "axum", "chrono", + "ciborium", "clap", "comfy-table", "dunce", diff --git a/Cargo.toml b/Cargo.toml index a5e1cfaef6317..ee58e68c7da99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -270,6 +270,7 @@ chrono = { version = "0.4", default-features = false, features = [ "std", ] } axum = "0.7" +ciborium = "0.2" color-eyre = "0.6" comfy-table = "7" dirs = "6" diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 11e67174b65be..08e44948ee1c4 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -72,6 +72,7 @@ path-slash.workspace = true anstream.workspace = true anstyle.workspace = true terminal_size.workspace = true +ciborium.workspace = true [build-dependencies] chrono.workspace = true diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index 8fc612c2d6197..a655d1e3d713f 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -37,3 +37,20 @@ pub fn erc7201(id: &str) -> B256 { let x = U256::from_be_bytes(keccak256(id).0) - U256::from(1); keccak256(x.to_be_bytes::<32>()) & B256::from(!U256::from(0xff)) } + +/// Utility function to ignore metadata hash of the given bytecode. +/// This assumes that the metadata is at the end of the bytecode. +pub fn ignore_metadata_hash(bytecode: &[u8]) -> &[u8] { + // Get the last two bytes of the bytecode to find the length of CBOR metadata. + let Some((rest, metadata_len_bytes)) = bytecode.split_last_chunk() else { return bytecode }; + let metadata_len = u16::from_be_bytes(*metadata_len_bytes) as usize; + if metadata_len > rest.len() { + return bytecode; + } + let (rest, metadata) = rest.split_at(rest.len() - metadata_len); + if ciborium::from_reader::(metadata).is_ok() { + rest + } else { + bytecode + } +} diff --git a/crates/evm/fuzz/src/strategies/state.rs b/crates/evm/fuzz/src/strategies/state.rs index 9bcca6aa16d2e..c598ada0accab 100644 --- a/crates/evm/fuzz/src/strategies/state.rs +++ b/crates/evm/fuzz/src/strategies/state.rs @@ -5,6 +5,7 @@ use alloy_primitives::{ map::{AddressIndexSet, B256IndexSet, HashMap}, Address, Bytes, Log, B256, U256, }; +use foundry_common::ignore_metadata_hash; use foundry_config::FuzzDictionaryConfig; use foundry_evm_core::utils::StateChangeset; use parking_lot::{lock_api::RwLockReadGuard, RawRwLock, RwLock}; @@ -248,7 +249,7 @@ impl FuzzDictionary { // Insert push bytes if let Some(code) = &account_info.code { self.insert_address(*address); - self.collect_push_bytes(code.bytes_slice()); + self.collect_push_bytes(ignore_metadata_hash(code.original_byte_slice())); } } } diff --git a/crates/forge/tests/it/invariant.rs b/crates/forge/tests/it/invariant.rs index 43db084d06df3..5a072cedb7195 100644 --- a/crates/forge/tests/it/invariant.rs +++ b/crates/forge/tests/it/invariant.rs @@ -1114,9 +1114,9 @@ Encountered 1 failing test in test/InvariantSequenceLenTest.t.sol:InvariantSeque [FAIL: invariant increment failure] [Sequence] (original: 4, shrunk: 4) sender=0x00000000000000000000000000000000000018dE addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=setNumber(uint256) args=[1931387396117645594923 [1.931e21]] - sender=0x00000000000000000000000000000000000009d5 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] - sender=0x0000000000000000000000000000000000000105 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] - sender=0x00000000000000000000000000000000000009B2 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=setNumber(uint256) args=[996881781832960761274744263729582347 [9.968e35]] + sender=0x0000000000000000000000000000000000000C37 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] + sender=0x0000000000000000000000000000000000000106 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] + sender=0x0000000000000000000000000000000000001684 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=setNumber(uint256) args=[996881781832960761274744263729582347 [9.968e35]] invariant_increment() (runs: 0, calls: 0, reverts: 0) Encountered a total of 1 failing tests, 0 tests succeeded @@ -1138,11 +1138,11 @@ Encountered 1 failing test in test/InvariantSequenceLenTest.t.sol:InvariantSeque [Sequence] (original: 4, shrunk: 4) vm.prank(0x00000000000000000000000000000000000018dE); Counter(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f).setNumber(1931387396117645594923); - vm.prank(0x00000000000000000000000000000000000009d5); + vm.prank(0x0000000000000000000000000000000000000C37); Counter(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f).increment(); - vm.prank(0x0000000000000000000000000000000000000105); + vm.prank(0x0000000000000000000000000000000000000106); Counter(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f).increment(); - vm.prank(0x00000000000000000000000000000000000009B2); + vm.prank(0x0000000000000000000000000000000000001684); Counter(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f).setNumber(996881781832960761274744263729582347); invariant_increment() (runs: 0, calls: 0, reverts: 0) @@ -1163,9 +1163,9 @@ Encountered 1 failing test in test/InvariantSequenceLenTest.t.sol:InvariantSeque [FAIL: invariant_increment replay failure] [Sequence] (original: 4, shrunk: 4) sender=0x00000000000000000000000000000000000018dE addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=setNumber(uint256) args=[1931387396117645594923 [1.931e21]] - sender=0x00000000000000000000000000000000000009d5 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] - sender=0x0000000000000000000000000000000000000105 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] - sender=0x00000000000000000000000000000000000009B2 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=setNumber(uint256) args=[996881781832960761274744263729582347 [9.968e35]] + sender=0x0000000000000000000000000000000000000C37 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] + sender=0x0000000000000000000000000000000000000106 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=increment() args=[] + sender=0x0000000000000000000000000000000000001684 addr=[src/Counter.sol:Counter]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=setNumber(uint256) args=[996881781832960761274744263729582347 [9.968e35]] invariant_increment() (runs: 1, calls: 1, reverts: 1) Encountered a total of 1 failing tests, 0 tests succeeded diff --git a/crates/verify/Cargo.toml b/crates/verify/Cargo.toml index 443d44cc110a4..8e2ec24f7d4d4 100644 --- a/crates/verify/Cargo.toml +++ b/crates/verify/Cargo.toml @@ -40,8 +40,6 @@ regex = { workspace = true, default-features = false } yansi.workspace = true itertools.workspace = true -ciborium = "0.2" - [dev-dependencies] tokio = { workspace = true, features = ["macros"] } foundry-test-utils.workspace = true diff --git a/crates/verify/src/utils.rs b/crates/verify/src/utils.rs index 714fe4eee0e36..81defa05d0f7b 100644 --- a/crates/verify/src/utils.rs +++ b/crates/verify/src/utils.rs @@ -9,7 +9,10 @@ use foundry_block_explorers::{ contract::{ContractCreationData, ContractMetadata, Metadata}, errors::EtherscanError, }; -use foundry_common::{abi::encode_args, compile::ProjectCompiler, provider::RetryProvider, shell}; +use foundry_common::{ + abi::encode_args, compile::ProjectCompiler, ignore_metadata_hash, provider::RetryProvider, + shell, +}; use foundry_compilers::artifacts::{BytecodeHash, CompactContractBytecode, EvmVersion}; use foundry_config::Config; use foundry_evm::{ @@ -204,22 +207,6 @@ fn try_extract_and_compare_bytecode(mut local_bytecode: &[u8], mut bytecode: &[u local_bytecode == bytecode } -/// This assumes that the metadata is at the end of the bytecode. -fn ignore_metadata_hash(bytecode: &[u8]) -> &[u8] { - // Get the last two bytes of the bytecode to find the length of CBOR metadata. - let Some((rest, metadata_len_bytes)) = bytecode.split_last_chunk() else { return bytecode }; - let metadata_len = u16::from_be_bytes(*metadata_len_bytes) as usize; - if metadata_len > rest.len() { - return bytecode; - } - let (rest, metadata) = rest.split_at(rest.len() - metadata_len); - if ciborium::from_reader::(metadata).is_ok() { - rest - } else { - bytecode - } -} - fn find_mismatch_in_settings( etherscan_settings: &Metadata, local_settings: &Config,