From fccfdb90d520cff8ff3b49c377960173591a6c73 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Wed, 26 Jul 2023 08:59:34 -0700 Subject: [PATCH 1/6] fix: interface + metadata bugs --- src/bytecode.rs | 10 ++++++++++ src/frameworks.rs | 21 ++++++++++++++------- src/provider.rs | 15 +++++++-------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/bytecode.rs b/src/bytecode.rs index f181095..07f6df9 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -55,6 +55,11 @@ pub fn creation_code_equality_check( found: &FoundCreationBytecode, expected: &ExpectedCreationBytecode, ) -> MatchType { + // If bytecode is empty, we have an interface, and we can't match with an interface. + if found.raw_code.is_empty() { + return MatchType::None + } + // Expected code might contain appended constructor arguments, so if code matches then expected // can only be equal to or longer than found code. if found.raw_code.len() > expected.raw_code.len() { @@ -74,6 +79,11 @@ pub fn deployed_code_equality_check( found: &FoundDeployedBytecode, expected: &ExpectedDeployedBytecode, ) -> MatchType { + // If bytecode is empty, we have an interface, and we can't match with an interface. + if found.raw_code.is_empty() { + return MatchType::None + } + // Expected and found code must have the same length. if found.raw_code.len() != expected.raw_code.len() { return MatchType::None diff --git a/src/frameworks.rs b/src/frameworks.rs index 948daef..54d8118 100644 --- a/src/frameworks.rs +++ b/src/frameworks.rs @@ -372,7 +372,14 @@ impl Framework for Foundry { })? .get("settings") .ok_or_else(|| { - format!("Missing 'settings' field in metadata JSON: {}", artifact.display()) + format!("Missing 'metdata.settings' field in metadata JSON: {}", artifact.display()) + })? + .get("metadata") + .ok_or_else(|| { + format!( + "Missing 'metadata.settings.metadata' field in metadata JSON: {}", + artifact.display() + ) })?; let settings_metadata: SettingsMetadata = serde_json::from_value(settings_value.clone())?; Ok(settings_metadata) @@ -411,7 +418,7 @@ mod tests { TestCase { content: json!({ "bytecode": { "object": "0x1234" }, - "metadata": { "settings": { "bytecodeHash": "none", "appendCBOR": false } }, + "metadata": { "settings":{ "metadata": { "bytecodeHash": "none", "appendCBOR": false } }}, }), expected: FoundCreationBytecode { raw_code: Bytes::from_str("0x1234")?, @@ -423,7 +430,7 @@ mod tests { TestCase { content: json!({ "bytecode": { "object": "0x1234567890abcdef0002" }, - "metadata": { "settings": { "bytecodeHash": "ipfs", "appendCBOR": true } }, + "metadata": { "settings":{ "metadata": { "bytecodeHash": "ipfs", "appendCBOR": true } }}, }), expected: FoundCreationBytecode { raw_code: Bytes::from_str("0x1234567890abcdef0002")?, @@ -706,7 +713,7 @@ mod tests { let test_cases = vec![ // Test case 1: Both `bytecodeHash` and `appendCBOR` fields are present. TestCase { - content: json!({ "metadata": { "settings": { "bytecodeHash": "ipfs", "appendCBOR": true }}}), + content: json!({ "metadata": { "settings":{ "metadata": { "bytecodeHash": "ipfs", "appendCBOR": true }}}}), expected: SettingsMetadata { use_literal_content: None, bytecode_hash: Some(BytecodeHash::Ipfs), @@ -715,7 +722,7 @@ mod tests { }, // Test case 2: both `bytecodeHash` and `appendCBOR` fields are missing TestCase { - content: json!({ "metadata": { "settings": {} } }), + content: json!({ "metadata": { "settings":{ "metadata": {} } }}), expected: SettingsMetadata { use_literal_content: None, bytecode_hash: None, @@ -724,7 +731,7 @@ mod tests { }, // Test case 3: `bytecodeHash` field is present, `appendCBOR` field is missing TestCase { - content: json!({ "metadata": { "settings": { "bytecodeHash": "bzzr1" } } }), + content: json!({ "metadata": { "settings":{ "metadata": { "bytecodeHash": "bzzr1" } } }}), expected: SettingsMetadata { use_literal_content: None, bytecode_hash: Some(BytecodeHash::Bzzr1), @@ -733,7 +740,7 @@ mod tests { }, // Test case 4: `bytecodeHash` field is missing, `appendCBOR` field is present TestCase { - content: json!({ "metadata": { "settings": { "appendCBOR": false } } }), + content: json!({ "metadata": { "settings":{ "metadata": { "appendCBOR": false } } }}), expected: SettingsMetadata { use_literal_content: None, bytecode_hash: None, diff --git a/src/provider.rs b/src/provider.rs index e71ed90..93c7e92 100644 --- a/src/provider.rs +++ b/src/provider.rs @@ -29,26 +29,26 @@ pub fn provider_from_chain(chain: Chain) -> Arc> { match chain { // Mainnet + Testnets. Chain::Mainnet => { - Arc::new(Provider::::try_from(env::var("MAINNET_RPC_URL").unwrap()).unwrap()) + Arc::new(Provider::::try_from(provider_url_from_chain(chain)).unwrap()) } Chain::Goerli => { - Arc::new(Provider::::try_from(env::var("GOERLI_RPC_URL").unwrap()).unwrap()) + Arc::new(Provider::::try_from(provider_url_from_chain(chain)).unwrap()) } Chain::Sepolia => { - Arc::new(Provider::::try_from(env::var("SEPOLIA_RPC_URL").unwrap()).unwrap()) + Arc::new(Provider::::try_from(provider_url_from_chain(chain)).unwrap()) } // Other chains. Chain::Optimism => { - Arc::new(Provider::::try_from(env::var("OPTIMISM_RPC_URL").unwrap()).unwrap()) + Arc::new(Provider::::try_from(provider_url_from_chain(chain)).unwrap()) } Chain::Arbitrum => { - Arc::new(Provider::::try_from(env::var("ARBITRUM_ONE_RPC_URL").unwrap()).unwrap()) + Arc::new(Provider::::try_from(provider_url_from_chain(chain)).unwrap()) } Chain::Polygon => { - Arc::new(Provider::::try_from(env::var("POLYGON_RPC_URL").unwrap()).unwrap()) + Arc::new(Provider::::try_from(provider_url_from_chain(chain)).unwrap()) } Chain::XDai => { - Arc::new(Provider::::try_from(env::var("GNOSIS_CHAIN_RPC_URL").unwrap()).unwrap()) + Arc::new(Provider::::try_from(provider_url_from_chain(chain)).unwrap()) } _ => panic!("Unsupported chain"), } @@ -185,7 +185,6 @@ impl MultiChainProvider { let mut best_artifact_match: Option = None; for artifact in artifacts { - println!("Checking creation artifact: {:?}", artifact.as_path()); let found = match project.structure_found_creation_code(&artifact) { Ok(found) => found, Err(_) => continue, From 8088977766e4274f3ecd9709fecb753d6a3d8b9b Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Wed, 26 Jul 2023 11:54:58 -0700 Subject: [PATCH 2/6] test: add gitcoin governor alpha integration test --- tests/verify.rs | 62 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/tests/verify.rs b/tests/verify.rs index ff34ce0..72ed8c2 100644 --- a/tests/verify.rs +++ b/tests/verify.rs @@ -388,25 +388,53 @@ async fn verify_counters() -> Result<(), Box> { #[tokio::test] async fn verify_seaport() -> Result<(), Box> { + run_integration_test( + "https://github.com/ProjectOpenSea/seaport", + "d58a91d218b0ab557543c8a292710aa36e693973", + "0x00000000000001ad428e4906aE43D8F9852d0dD6", + json!({ + "framework": "foundry", + "buildHint": "optimized" + }), + json!({ + "mainnet": "0x4f5eae3d221fe4a572d722a57c2fbfd252139e7580b7959d93eb2a8b05b666f6", + "polygon": "0x7c0a769c469d24859cbcb978caacd9b6d5eea1f50ae6c1b3c94d4819375e0b09", + "optimism": "0x3a46979922e781895fae9cba54df645b813eb55447703f590d51af1993ad59d4", + "arbitrum": "0xa150f5c8bf8b8a0fc5f4f64594d09d796476974280e566fe3899b56517cd11da", + "gnosis_chain": "0xfc189820c60536e2ce90443ac3d39633583cfed6653d5f7edd7c0e115fd2a18b", + }), + ) + .await +} + +#[tokio::test] +async fn verify_gitcoin_governor_alpha() -> Result<(), Box> { + run_integration_test( + "https://github.com/gitcoinco/Alpha-Governor-Upgrade", + "17f7717eec0604505da2faf3f65516a8619063a0", + "0x1a84384e1f1b12D53E60C8C528178dC87767b488", + json!({ + "framework": "foundry", + "buildHint": "default" + }), + json!({ + "mainnet": "0x61d669c6c0b976637b8f4528b99b170f060227b2bc20892743f22c6a34c84e23" + }), + ) + .await +} + +async fn run_integration_test( + repo_url: &str, + repo_commit: &str, + contract_address: &str, + build_config: serde_json::Value, + creation_tx_hashes: serde_json::Value, +) -> Result<(), Box> { let app = common::spawn_app().await; let client = reqwest::Client::new(); // POST request inputs. - let repo_url = "https://github.com/ProjectOpenSea/seaport"; - let repo_commit = "d58a91d218b0ab557543c8a292710aa36e693973"; - let contract_address = "0x00000000000001ad428e4906aE43D8F9852d0dD6"; - let build_config = json!({ - "framework": "foundry", - "buildHint": "optimized" - }); - let creation_tx_hashes = json!({ - "mainnet": "0x4f5eae3d221fe4a572d722a57c2fbfd252139e7580b7959d93eb2a8b05b666f6", - "polygon": "0x7c0a769c469d24859cbcb978caacd9b6d5eea1f50ae6c1b3c94d4819375e0b09", - "optimism": "0x3a46979922e781895fae9cba54df645b813eb55447703f590d51af1993ad59d4", - "arbitrum": "0xa150f5c8bf8b8a0fc5f4f64594d09d796476974280e566fe3899b56517cd11da", - "gnosis_chain": "0xfc189820c60536e2ce90443ac3d39633583cfed6653d5f7edd7c0e115fd2a18b", - }); - let body = json!({ "repoUrl": repo_url, "repoCommit": repo_commit, @@ -423,13 +451,11 @@ async fn verify_seaport() -> Result<(), Box> { .send() .await?; - // Assertions. assert_eq!(200, response.status().as_u16()); + let response_body = response.text().await?; - println!("response_body {:?}", response_body); let verification_result: SuccessfulVerification = from_str(&response_body).expect("Failed to deserialize SuccessfulVerification"); - assert_eq!(repo_url, verification_result.repo_url); assert_eq!(repo_commit, verification_result.repo_commit); Ok(()) From caf49f67f0be791ad0b46ea5bd5a6c2f72686ad5 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Thu, 27 Jul 2023 10:02:03 -0700 Subject: [PATCH 3/6] fix: metadata indexing improvement --- src/frameworks.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/frameworks.rs b/src/frameworks.rs index 54d8118..ab14a3b 100644 --- a/src/frameworks.rs +++ b/src/frameworks.rs @@ -227,7 +227,14 @@ impl Framework for Foundry { let metadata_hash: Option = if let (Some(start_index), Some(end_index)) = (found.metadata.start_index, found.metadata.end_index) { - Some(expected[start_index..end_index].to_vec().into()) + // There may be cases where the found bytecode has a full metadata hash, but the + // expected bytecode only has CBOR or none. In those cases the `end_index` will be + // longer than the length of the expected bytecode, and this line will panic since + // `end_index` will be out of bounds. To avoid this while still enabling verification + // for different metadata hashes, the end index is `min(end_index, expected.len())`. + // let end_index = std::cmp::min(end_index, expected.len()); + let adjusted_end_index = std::cmp::min(end_index, expected.len()); + Some(expected[start_index..adjusted_end_index].to_vec().into()) } else { None }; @@ -300,7 +307,14 @@ impl Framework for Foundry { let metadata_hash: Option = if let (Some(start_index), Some(end_index)) = (found.metadata.start_index, found.metadata.end_index) { - Some(expected[start_index..end_index].to_vec().into()) + // There may be cases where the found bytecode has a full metadata hash, but the + // expected bytecode only has CBOR or none. In those cases the `end_index` will be + // longer than the length of the expected bytecode, and this line will panic since + // `end_index` will be out of bounds. To avoid this while still enabling verification + // for different metadata hashes, the end index is `min(end_index, expected.len())`. + // let end_index = std::cmp::min(end_index, expected.len()); + let adjusted_end_index = std::cmp::min(end_index, expected.len()); + Some(expected[start_index..adjusted_end_index].to_vec().into()) } else { None }; From e8162f8585199bee36112ec3e62575c11d069c05 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Thu, 27 Jul 2023 10:26:18 -0700 Subject: [PATCH 4/6] build: bump deps to fix nightly clippy errors error was: unknown feature --- Cargo.lock | 287 +++++++++++++++++++++++-------------------- Cargo.toml | 3 +- src/bytecode.rs | 3 +- src/frameworks.rs | 12 +- src/routes/verify.rs | 12 +- 5 files changed, 168 insertions(+), 149 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f33bdb3..34ef119 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" dependencies = [ "proc-macro-error", "proc-macro2", @@ -160,9 +160,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.11" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d8068b6ccb8b34db9de397c7043f91db8b4c66414952c6db944f238c4d3db3" +checksum = "a6a1de45611fdb535bfde7b7de4fd54f4fd2b17b1737c0a59b69bf9b92074b8c" dependencies = [ "async-trait", "axum-core", @@ -192,9 +192,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes", @@ -468,15 +468,15 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.23" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", + "indexmap 1.9.2", "once_cell", "strsim", "termcolor", @@ -495,9 +495,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.18" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck", "proc-macro-error", @@ -650,6 +650,7 @@ dependencies = [ "config", "dotenvy", "ethers", + "ethers-solc", "futures", "headers", "heimdall", @@ -660,7 +661,7 @@ dependencies = [ "serde_json", "tempfile", "tokio", - "toml 0.7.3", + "toml 0.7.6", "tower", "tower-http", "tracing", @@ -748,6 +749,22 @@ dependencies = [ "winapi", ] +[[package]] +name = "crossterm" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +dependencies = [ + "bitflags", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + [[package]] name = "crossterm_winapi" version = "0.9.0" @@ -829,6 +846,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + [[package]] name = "der" version = "0.7.6" @@ -1034,6 +1057,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.1" @@ -1127,9 +1156,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d5486fdc149826f38c388f26a7df72534ee3f20d3a3f72539376fa7b3bbc43d" +checksum = "96b4026b97da8281276744741fac7eb385da905f6093c583331fa2953fdd4253" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1143,9 +1172,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c66a426b824a0f6d1361ad74b6b01adfd26c44ee1e14c3662dcf28406763ec5" +checksum = "edcb6ffefc230d8c42874c51b28dc11dbb8de50b27a8fdf92648439d6baa68dc" dependencies = [ "ethers-core", "once_cell", @@ -1155,14 +1184,15 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa43e2e69632492d7b38e59465d125a0066cf4c477390ece00d3acbd11b338b" +checksum = "0d4719a44c3d37ab07c6dea99ab174068d8c35e441b60b6c20ce4e48357273e8" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", "ethers-core", "ethers-providers", + "ethers-signers", "futures-util", "hex", "once_cell", @@ -1174,16 +1204,15 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2edb8fdbf77459819a443234b461171a024476bfc12f1853b889a62c6e1185ff" +checksum = "155ea1b84d169d231317ed86e307af6f2bed6b40dd17e5e94bc84da21cadb21c" dependencies = [ "Inflector", "dunce", "ethers-core", "ethers-etherscan", "eyre", - "getrandom", "hex", "prettyplease", "proc-macro2", @@ -1193,17 +1222,15 @@ dependencies = [ "serde", "serde_json", "syn 2.0.16", - "tokio", - "toml 0.7.3", - "url", + "toml 0.7.6", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "939b0c37746929f869285ee37d270b7c998d80cc7404c2e20dda8efe93e3b295" +checksum = "8567ff196c4a37c1a8c90ec73bda0ad2062e191e4f0a6dc4d943e2ec4830fc88" dependencies = [ "Inflector", "ethers-contract-abigen", @@ -1217,9 +1244,9 @@ dependencies = [ [[package]] name = "ethers-core" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198ea9efa8480fa69f73d31d41b1601dace13d053c6fe4be6f5878d9dfcf0108" +checksum = "60ca2514feb98918a0a31de7e1983c29f2267ebf61b2dc5d4294f91e5b866623" dependencies = [ "arrayvec", "bytes", @@ -1228,7 +1255,6 @@ dependencies = [ "elliptic-curve", "ethabi", "generic-array", - "getrandom", "hex", "k256", "num_enum", @@ -1248,13 +1274,11 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196a21d6939ab78b7a1e4c45c2b33b0c2dd821a2e1af7c896f06721e1ba2a0c7" +checksum = "22b3a8269d3df0ed6364bc05b4735b95f4bf830ce3aef87d5e760fb0e93e5b91" dependencies = [ "ethers-core", - "ethers-solc", - "getrandom", "reqwest", "semver", "serde", @@ -1265,9 +1289,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75594cc450992fc7de701c9145de612325fd8a18be765b8ae78767ba2b74876f" +checksum = "e0c339aad74ae5c451d27e0e49c7a3c7d22620b119b4f9291d7aa21f72d7f366" dependencies = [ "async-trait", "auto_impl", @@ -1292,9 +1316,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1009041f40476b972b5d79346cc512e97c662b1a0a2f78285eabe9a122909783" +checksum = "b411b119f1cf0efb69e2190883dee731251882bb21270f893ee9513b3a697c48" dependencies = [ "async-trait", "auto_impl", @@ -1305,7 +1329,6 @@ dependencies = [ "futures-core", "futures-timer", "futures-util", - "getrandom", "hashers", "hex", "http", @@ -1329,9 +1352,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bd11ad6929f01f01be74bb00d02bbd6552f22de030865c898b340a3a592db1" +checksum = "4864d387456a9c09a1157fa10e1528b29d90f1d859443acf06a1b23365fb518c" dependencies = [ "async-trait", "coins-bip32", @@ -1348,14 +1371,13 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.4" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2284784306de73d8ad1bc792ecc1b87da0268185683698d60fd096d23d168c99" +checksum = "7a6c2b9625a2c639d46625f88acc2092a3cb35786c37f7c2128b3ca20f639b3c" dependencies = [ "cfg-if", "dunce", "ethers-core", - "getrandom", "glob", "hex", "home", @@ -1401,9 +1423,9 @@ dependencies = [ [[package]] name = "fancy-regex" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0678ab2d46fa5195aaf59ad034c083d351377d4af57f3e073c074d0da3e3c766" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" dependencies = [ "bit-set", "regex", @@ -1701,7 +1723,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.2", "slab", "tokio", "tokio-util", @@ -1717,6 +1739,12 @@ dependencies = [ "ahash 0.7.6", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "hashers" version = "1.0.1" @@ -1759,14 +1787,14 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heimdall" -version = "0.4.5" -source = "git+https://github.com/Jon-Becker/heimdall-rs.git#bd57e95c3d92f62f8932e87b26c54cbe77770b49" +version = "0.4.8" +source = "git+https://github.com/Jon-Becker/heimdall-rs.git#6363d2fe02b68a4b03e0d5f726f605d1360250b7" dependencies = [ "backtrace", "clap", "clap-verbosity-flag", "colored", - "crossterm", + "crossterm 0.26.1", "dot", "ethers", "fancy-regex", @@ -1785,20 +1813,20 @@ dependencies = [ [[package]] name = "heimdall-cache" -version = "0.4.5" -source = "git+https://github.com/Jon-Becker/heimdall-rs.git#bd57e95c3d92f62f8932e87b26c54cbe77770b49" +version = "0.4.8" +source = "git+https://github.com/Jon-Becker/heimdall-rs.git#6363d2fe02b68a4b03e0d5f726f605d1360250b7" dependencies = [ "bincode", "clap", "clap-verbosity-flag", "serde", - "toml 0.5.11", + "toml 0.7.6", ] [[package]] name = "heimdall-common" -version = "0.4.5" -source = "git+https://github.com/Jon-Becker/heimdall-rs.git#bd57e95c3d92f62f8932e87b26c54cbe77770b49" +version = "0.4.8" +source = "git+https://github.com/Jon-Becker/heimdall-rs.git#6363d2fe02b68a4b03e0d5f726f605d1360250b7" dependencies = [ "async-openai", "clap", @@ -1814,19 +1842,20 @@ dependencies = [ "reqwest", "serde", "serde_json", + "strsim", "tokio", ] [[package]] name = "heimdall-config" -version = "0.4.5" -source = "git+https://github.com/Jon-Becker/heimdall-rs.git#bd57e95c3d92f62f8932e87b26c54cbe77770b49" +version = "0.4.8" +source = "git+https://github.com/Jon-Becker/heimdall-rs.git#6363d2fe02b68a4b03e0d5f726f605d1360250b7" dependencies = [ "clap", "clap-verbosity-flag", "heimdall-common", "serde", - "toml 0.5.11", + "toml 0.7.6", ] [[package]] @@ -1949,9 +1978,9 @@ checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" dependencies = [ "http", "hyper", - "rustls 0.21.1", + "rustls", "tokio", - "tokio-rustls 0.24.0", + "tokio-rustls", ] [[package]] @@ -2034,7 +2063,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", ] [[package]] @@ -2164,9 +2203,9 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.19.12" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" dependencies = [ "ascii-canvas", "bit-set", @@ -2177,7 +2216,7 @@ dependencies = [ "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.6.28", + "regex-syntax 0.7.1", "string_cache", "term", "tiny-keccak", @@ -2186,12 +2225,9 @@ dependencies = [ [[package]] name = "lalrpop-util" -version = "0.19.12" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" -dependencies = [ - "regex", -] +checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" [[package]] name = "lazy_static" @@ -2525,7 +2561,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" dependencies = [ "dlv-list", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -2691,7 +2727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 1.9.2", ] [[package]] @@ -2757,22 +2793,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] @@ -2881,9 +2917,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -3048,7 +3084,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.1", + "rustls", "rustls-native-certs", "rustls-pemfile", "serde", @@ -3056,7 +3092,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", - "tokio-rustls 0.24.0", + "tokio-rustls", "tokio-util", "tower-service", "url", @@ -3064,7 +3100,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 0.22.6", "winreg", ] @@ -3196,18 +3232,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "rustls" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" -dependencies = [ - "log", - "ring", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.21.1" @@ -3442,9 +3466,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -3588,9 +3612,9 @@ dependencies = [ [[package]] name = "solang-parser" -version = "0.2.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c5ead679f39243782be98c2689e592fc0fc9489ca2e47c9e027bd30f948df31" +checksum = "9c792fe9fae2a2f716846f214ca10d5a1e21133e0bf36cef34bcc4a852467b21" dependencies = [ "itertools", "lalrpop", @@ -3643,24 +3667,24 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.24.3" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] @@ -3883,24 +3907,13 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls 0.20.8", - "tokio", - "webpki", -] - [[package]] name = "tokio-rustls" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" dependencies = [ - "rustls 0.21.1", + "rustls", "tokio", ] @@ -3917,18 +3930,17 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" +checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" dependencies = [ "futures-util", "log", - "rustls 0.20.8", + "rustls", "tokio", - "tokio-rustls 0.23.4", + "tokio-rustls", "tungstenite", - "webpki", - "webpki-roots", + "webpki-roots 0.23.1", ] [[package]] @@ -3956,9 +3968,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.3" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" dependencies = [ "serde", "serde_spanned", @@ -3968,20 +3980,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.7" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", @@ -4142,25 +4154,25 @@ checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1" dependencies = [ "bitflags", "cassowary", - "crossterm", + "crossterm 0.25.0", "unicode-segmentation", "unicode-width", ] [[package]] name = "tungstenite" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" +checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" dependencies = [ - "base64 0.13.1", "byteorder", "bytes", + "data-encoding", "http", "httparse", "log", "rand", - "rustls 0.20.8", + "rustls", "sha1", "thiserror", "url", @@ -4435,6 +4447,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "webpki-roots" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +dependencies = [ + "rustls-webpki", +] + [[package]] name = "winapi" version = "0.3.9" @@ -4615,9 +4636,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.3.6" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966" +checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index f286f04..751fd73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,8 @@ axum = "0.6.11" config = "0.13.3" dotenvy = "0.15.6" - ethers = "2.0.4" + ethers = "2.0.8" + ethers-solc = "2.0.8" futures = "0.3.27" headers = "0.3.8" heimdall = { git = "https://github.com/Jon-Becker/heimdall-rs.git", version = "0.4.5" } diff --git a/src/bytecode.rs b/src/bytecode.rs index 07f6df9..2eac63c 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -1,4 +1,5 @@ -use ethers::{solc::artifacts::Offsets, types::Bytes}; +use ethers::types::Bytes; +use ethers_solc::artifacts::Offsets; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; diff --git a/src/frameworks.rs b/src/frameworks.rs index ab14a3b..8867c74 100644 --- a/src/frameworks.rs +++ b/src/frameworks.rs @@ -3,12 +3,10 @@ use crate::bytecode::{ parse_metadata, ExpectedCreationBytecode, ExpectedDeployedBytecode, FoundCreationBytecode, FoundDeployedBytecode, ImmutableReferences, MetadataInfo, }; -use ethers::{ - solc::{ - artifacts::{BytecodeHash, BytecodeObject, LosslessAbi, SettingsMetadata}, - ConfigurableContractArtifact, - }, - types::Bytes, +use ethers::types::Bytes; +use ethers_solc::{ + artifacts::{BytecodeHash, BytecodeObject, LosslessAbi, SettingsMetadata}, + ConfigurableContractArtifact, }; use std::{ error::Error, @@ -403,7 +401,7 @@ impl Framework for Foundry { #[cfg(test)] mod tests { use super::*; - use ethers::solc::artifacts::{BytecodeHash, SettingsMetadata}; + use ethers_solc::artifacts::{BytecodeHash, SettingsMetadata}; use serde_json::json; use std::{error::Error, fs::File, io::Write, path::PathBuf, str::FromStr}; use tempfile::NamedTempFile; diff --git a/src/routes/verify.rs b/src/routes/verify.rs index 59c1e1c..230aadf 100644 --- a/src/routes/verify.rs +++ b/src/routes/verify.rs @@ -8,13 +8,11 @@ use axum::{ response::{IntoResponse, Response}, Json, }; -use ethers::{ - solc::{ - artifacts::{Ast, CompactBytecode, CompactDeployedBytecode, LosslessAbi, MetadataSettings}, - buildinfo::BuildInfo, - ConfigurableContractArtifact, - }, - types::{Address, Bytes, Chain, TxHash}, +use ethers::types::{Address, Bytes, Chain, TxHash}; +use ethers_solc::{ + artifacts::{Ast, CompactBytecode, CompactDeployedBytecode, LosslessAbi, MetadataSettings}, + buildinfo::BuildInfo, + ConfigurableContractArtifact, }; use serde::{Deserialize, Serialize}; use std::{ From 805c2035f81fa5ed06c012a27be74b01d732110b Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Thu, 27 Jul 2023 10:39:42 -0700 Subject: [PATCH 5/6] test: ignore seaport test for now --- tests/verify.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/verify.rs b/tests/verify.rs index 72ed8c2..87b7b0c 100644 --- a/tests/verify.rs +++ b/tests/verify.rs @@ -387,6 +387,7 @@ async fn verify_counters() -> Result<(), Box> { } #[tokio::test] +#[ignore = "This fails because leading bytecode differs in two places. This did not used to happen, TBD what broke here. It's worth noting that Seaport actually uses Hardhat for the production build, which may be related (it used to be the same bytecode aside from the metadata hash, though)"] async fn verify_seaport() -> Result<(), Box> { run_integration_test( "https://github.com/ProjectOpenSea/seaport", From 232f5b009286edc16575996ce34a2d288f991d98 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Wed, 2 Aug 2023 15:01:51 -0700 Subject: [PATCH 6/6] fix: simpler and better deployed bytecode comparison --- src/bytecode.rs | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/bytecode.rs b/src/bytecode.rs index 2eac63c..397a10c 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -90,6 +90,7 @@ pub fn deployed_code_equality_check( return MatchType::None } + // Simple check for exact match. if found.raw_code == expected.raw_code { return MatchType::Full } @@ -97,35 +98,38 @@ pub fn deployed_code_equality_check( // Compare the leading code, but skip all chunks that contain immutables. if found.immutable_references == expected.immutable_references { // Flatten the map to just a vec of the references. Since we know found and expected have - // equal immutable references, we can just use the found ones. + // equal immutable references due to how the structs were constructed, we can just use the + // found ones. let mut offsets: Vec = Vec::new(); for new_offsets in found.immutable_references.values() { offsets.extend(new_offsets.iter().cloned()); } - let mut start: usize = 0; - let mut matches = true; - + // The expected bytecode is deployed and therefore has real values for the immutables. The + // found bytecode uses zeroes as placeholders for the immutables (this is how solc works). + // Therefore for each immutable reference in the expected bytecode, we can replace the + // bytecode with zeroes, then compare the found bytecode with the expected bytecode. + // It's likely the metadata hashes won't match, so we adjust both the raw and leading code + // so we only have to loop through the offsets once. + let mut adjusted_expected_raw_code = expected.raw_code.to_vec(); + let mut adjusted_expected_leading_code = expected.leading_code.to_vec(); for offset in offsets { - // Slice the bytecode from the `start` index until the immutable's start index. let immutable_start: usize = offset.start.try_into().unwrap(); - let found_chunk = &found.leading_code[start..immutable_start]; - let expected_chunk = &expected.leading_code[start..immutable_start]; - - // If the chunks don't match, code does not match. - if found_chunk != expected_chunk { - matches = false; - break + let immutable_length: usize = offset.length.try_into().unwrap(); + let immutable_end = immutable_start + immutable_length; + for i in immutable_start..immutable_end { + adjusted_expected_raw_code[i] = 0; + adjusted_expected_leading_code[i] = 0; } + } - // If the chunks do match, update `start` to be after the immutable and keep looping - // through the offsets. - let immutable_length: usize = offset.length.try_into().unwrap(); - start += immutable_length; + // This matched with the metadata hash, so it's a full match. + if adjusted_expected_raw_code == found.raw_code { + return MatchType::Full } - // Now we check the final chunk of the bytecode after the last immutable. - if matches && found.leading_code[start..] == expected.leading_code[start..] { + // Had to remove the metadata hash, so it's a partial match. + if adjusted_expected_leading_code == found.leading_code { return MatchType::Partial } }