diff --git a/libs/verification-common/src/verifier_alliance/code_artifact_types.rs b/libs/verification-common/src/verifier_alliance/code_artifact_types.rs new file mode 100644 index 000000000..556230ea6 --- /dev/null +++ b/libs/verification-common/src/verifier_alliance/code_artifact_types.rs @@ -0,0 +1,22 @@ +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +#[serde_with::serde_as] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +pub struct CborAuxdataValue { + #[serde_as(as = "blockscout_display_bytes::serde_as::Hex")] + pub value: Vec, + pub offset: u32, +} +pub type CborAuxdata = BTreeMap; + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +pub struct Offset { + pub start: u32, + pub length: u32, +} +pub type Offsets = Vec; + +pub type ImmutableReferences = BTreeMap; + +pub type LinkReferences = BTreeMap>; diff --git a/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs b/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs index 3877a8075..519d064e1 100644 --- a/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs +++ b/libs/verification-common/src/verifier_alliance/creation_code_artifacts.rs @@ -1,11 +1,12 @@ +use super::code_artifact_types::{CborAuxdata, LinkReferences}; use serde::{Deserialize, Serialize}; use serde_json::Value; pub trait ToCreationCodeArtifacts { - fn cbor_auxdata(&self) -> Option { + fn cbor_auxdata(&self) -> Option { None } - fn link_references(&self) -> Option { + fn link_references(&self) -> Option { None } fn source_map(&self) -> Option { @@ -14,10 +15,10 @@ pub trait ToCreationCodeArtifacts { } impl ToCreationCodeArtifacts for &T { - fn cbor_auxdata(&self) -> Option { + fn cbor_auxdata(&self) -> Option { (*self).cbor_auxdata() } - fn link_references(&self) -> Option { + fn link_references(&self) -> Option { (*self).link_references() } fn source_map(&self) -> Option { @@ -29,8 +30,8 @@ impl ToCreationCodeArtifacts for &T { #[serde(rename_all = "camelCase")] pub struct CreationCodeArtifacts { pub source_map: Option, - pub link_references: Option, - pub cbor_auxdata: Option, + pub link_references: Option, + pub cbor_auxdata: Option, } impl From for CreationCodeArtifacts { diff --git a/libs/verification-common/src/verifier_alliance/mod.rs b/libs/verification-common/src/verifier_alliance/mod.rs index 0070d14bb..cced123db 100644 --- a/libs/verification-common/src/verifier_alliance/mod.rs +++ b/libs/verification-common/src/verifier_alliance/mod.rs @@ -1,12 +1,18 @@ +mod code_artifact_types; mod compilation_artifacts; mod creation_code_artifacts; mod runtime_code_artifacts; mod verification_match; - mod verification_match_transformations; mod verification_match_values; +pub use code_artifact_types::{ + CborAuxdata, CborAuxdataValue, ImmutableReferences, LinkReferences, Offset, Offsets, +}; pub use compilation_artifacts::{CompilationArtifacts, SourceId, ToCompilationArtifacts}; pub use creation_code_artifacts::{CreationCodeArtifacts, ToCreationCodeArtifacts}; pub use runtime_code_artifacts::{RuntimeCodeArtifacts, ToRuntimeCodeArtifacts}; -pub use verification_match::{Match, MatchBuilder, MatchTransformation, MatchValues}; +pub use verification_match::{ + verify_creation_code, verify_runtime_code, Match, MatchBuilder, MatchTransformation, + MatchValues, +}; diff --git a/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs b/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs index 75f10085f..d87c4e754 100644 --- a/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs +++ b/libs/verification-common/src/verifier_alliance/runtime_code_artifacts.rs @@ -1,14 +1,15 @@ +use super::code_artifact_types::{CborAuxdata, ImmutableReferences, LinkReferences}; use serde::{Deserialize, Serialize}; use serde_json::Value; pub trait ToRuntimeCodeArtifacts { - fn cbor_auxdata(&self) -> Option { + fn cbor_auxdata(&self) -> Option { None } - fn immutable_references(&self) -> Option { + fn immutable_references(&self) -> Option { None } - fn link_references(&self) -> Option { + fn link_references(&self) -> Option { None } fn source_map(&self) -> Option { @@ -17,13 +18,13 @@ pub trait ToRuntimeCodeArtifacts { } impl ToRuntimeCodeArtifacts for &T { - fn cbor_auxdata(&self) -> Option { + fn cbor_auxdata(&self) -> Option { (*self).cbor_auxdata() } - fn immutable_references(&self) -> Option { + fn immutable_references(&self) -> Option { (*self).immutable_references() } - fn link_references(&self) -> Option { + fn link_references(&self) -> Option { (*self).link_references() } fn source_map(&self) -> Option { @@ -34,9 +35,9 @@ impl ToRuntimeCodeArtifacts for &T { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RuntimeCodeArtifacts { - pub cbor_auxdata: Option, - pub immutable_references: Option, - pub link_references: Option, + pub cbor_auxdata: Option, + pub immutable_references: Option, + pub link_references: Option, pub source_map: Option, } diff --git a/libs/verification-common/src/verifier_alliance/verification_match.rs b/libs/verification-common/src/verifier_alliance/verification_match.rs index ef5a041bf..f8503f08e 100644 --- a/libs/verification-common/src/verifier_alliance/verification_match.rs +++ b/libs/verification-common/src/verifier_alliance/verification_match.rs @@ -1,5 +1,7 @@ use super::{ - compilation_artifacts::CompilationArtifacts, creation_code_artifacts::CreationCodeArtifacts, + code_artifact_types::{CborAuxdata, ImmutableReferences, LinkReferences}, + compilation_artifacts::CompilationArtifacts, + creation_code_artifacts::CreationCodeArtifacts, runtime_code_artifacts::RuntimeCodeArtifacts, }; pub use super::{ @@ -7,7 +9,7 @@ pub use super::{ verification_match_values::Values as MatchValues, }; use alloy_dyn_abi::JsonAbiExt; -use anyhow::Context; +use anyhow::{anyhow, Context}; use bytes::Bytes; use serde::Deserialize; @@ -18,6 +20,35 @@ pub struct Match { pub values: MatchValues, } +pub fn verify_creation_code( + on_chain_code: &[u8], + compiled_code: Vec, + creation_code_artifacts: &CreationCodeArtifacts, + compilation_artifacts: &CompilationArtifacts, +) -> Result, anyhow::Error> { + let builder = MatchBuilder::new(on_chain_code, compiled_code); + if let Some(builder) = builder { + return Ok(builder + .apply_creation_code_transformations(creation_code_artifacts, compilation_artifacts)? + .verify_and_build()); + } + Ok(None) +} + +pub fn verify_runtime_code( + on_chain_code: &[u8], + compiled_code: Vec, + runtime_code_artifacts: &RuntimeCodeArtifacts, +) -> Result, anyhow::Error> { + let builder = MatchBuilder::new(on_chain_code, compiled_code); + if let Some(builder) = builder { + return Ok(builder + .apply_runtime_code_transformations(runtime_code_artifacts)? + .verify_and_build()); + } + Ok(None) +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct MatchBuilder<'a> { deployed_code: &'a [u8], @@ -86,23 +117,117 @@ impl<'a> MatchBuilder<'a> { } fn apply_cbor_auxdata_transformations( - self, - _cbor_auxdata: Option<&serde_json::Value>, + mut self, + cbor_auxdata: Option<&CborAuxdata>, ) -> Result { + let cbor_auxdata = match cbor_auxdata { + Some(cbor_auxdata) => cbor_auxdata, + None => return Ok(self), + }; + + self.has_cbor_auxdata = !cbor_auxdata.is_empty(); + for (id, cbor_auxdata_value) in cbor_auxdata { + let offset = cbor_auxdata_value.offset as usize; + let re_compiled_value = cbor_auxdata_value.value.to_vec(); + + let range = offset..offset + re_compiled_value.len(); + + if self.compiled_code.len() < range.end { + return Err(anyhow!("(reason=cbor_auxdata; id={id}) out of range")); + } + + let on_chain_value = &self.deployed_code[range.clone()]; + if on_chain_value != re_compiled_value { + self.has_cbor_auxdata_transformation = true; + self.compiled_code.as_mut_slice()[range].copy_from_slice(on_chain_value); + + self.transformations + .push(MatchTransformation::auxdata(offset, id)); + self.values.add_cbor_auxdata(id, on_chain_value.to_vec()); + } + } + Ok(self) } fn apply_library_transformations( - self, - _link_references: Option<&serde_json::Value>, + mut self, + link_references: Option<&LinkReferences>, ) -> Result { + let link_references = match link_references { + Some(link_references) => link_references, + None => return Ok(self), + }; + + for (file, file_references) in link_references { + for (contract, offsets) in file_references { + let id = format!("{file}:{contract}"); + let mut on_chain_value = None; + for offset in offsets { + let start = offset.start as usize; + let end = start + offset.length as usize; + let range = start..end; + + let offset_value = &self.deployed_code[range.clone()]; + match on_chain_value { + None => { + on_chain_value = Some(offset_value); + } + Some(on_chain_value) if on_chain_value != offset_value => { + return Err(anyhow!( + "(reason=link_reference; id={id}) offset values are not consistent" + )) + } + _ => {} + } + + self.compiled_code.as_mut_slice()[range].copy_from_slice(offset_value); + self.transformations + .push(MatchTransformation::library(start, &id)); + self.values.add_library(&id, offset_value.to_vec()); + } + } + } + Ok(self) } fn apply_immutable_transformations( - self, - _immutable_references: Option<&serde_json::Value>, + mut self, + immutable_references: Option<&ImmutableReferences>, ) -> Result { + let immutable_references = match immutable_references { + Some(immutable_references) => immutable_references, + None => return Ok(self), + }; + + for (id, offsets) in immutable_references { + let mut on_chain_value = None; + for offset in offsets { + let start = offset.start as usize; + let end = start + offset.length as usize; + let range = start..end; + + let offset_value = &self.deployed_code[range.clone()]; + match on_chain_value { + None => { + on_chain_value = Some(offset_value); + } + Some(on_chain_value) if on_chain_value != offset_value => { + return Err(anyhow!( + "(reason=immutable_reference; id={id}) offset values are not consistent" + )) + } + _ => {} + } + + self.compiled_code.as_mut_slice()[range].copy_from_slice(offset_value); + self.transformations + .push(MatchTransformation::immutable(start, id)); + self.values.add_immutable(id, offset_value.to_vec()); + } + } + Ok(self) } diff --git a/libs/verification-common/src/verifier_alliance/verification_match_values.rs b/libs/verification-common/src/verifier_alliance/verification_match_values.rs index 86f6cc255..383a1239a 100644 --- a/libs/verification-common/src/verifier_alliance/verification_match_values.rs +++ b/libs/verification-common/src/verifier_alliance/verification_match_values.rs @@ -29,19 +29,27 @@ impl From for serde_json::Value { } impl Values { - pub fn add_cbor_auxdata(&mut self, key: impl Into, value: Bytes) { - self.cbor_auxdata.insert(key.into(), value); + pub fn add_cbor_auxdata( + &mut self, + key: impl Into, + value: impl Into, + ) -> &mut Self { + self.cbor_auxdata.insert(key.into(), value.into()); + self } - pub fn add_constructor_arguments(&mut self, value: Bytes) { - self.constructor_arguments = Some(value); + pub fn add_constructor_arguments(&mut self, value: impl Into) -> &mut Self { + self.constructor_arguments = Some(value.into()); + self } - pub fn add_library(&mut self, key: impl Into, value: Bytes) { - self.libraries.insert(key.into(), value); + pub fn add_library(&mut self, key: impl Into, value: impl Into) -> &mut Self { + self.libraries.insert(key.into(), value.into()); + self } - pub fn add_immutable(&mut self, key: impl Into, value: Bytes) { - self.immutables.insert(key.into(), value); + pub fn add_immutable(&mut self, key: impl Into, value: impl Into) -> &mut Self { + self.immutables.insert(key.into(), value.into()); + self } } diff --git a/libs/verification-common/tests/integration/main.rs b/libs/verification-common/tests/integration/main.rs new file mode 100644 index 000000000..18e55bea1 --- /dev/null +++ b/libs/verification-common/tests/integration/main.rs @@ -0,0 +1 @@ +mod verifier_alliance_matches; diff --git a/libs/verification-common/tests/integration/verifier_alliance_matches.rs b/libs/verification-common/tests/integration/verifier_alliance_matches.rs new file mode 100644 index 000000000..844c058f3 --- /dev/null +++ b/libs/verification-common/tests/integration/verifier_alliance_matches.rs @@ -0,0 +1,580 @@ +use serde::de::DeserializeOwned; +use serde_json::json; +use verification_common::verifier_alliance::{ + self, CompilationArtifacts, CreationCodeArtifacts, Match, RuntimeCodeArtifacts, +}; + +fn parse_code(code: &str) -> Vec { + blockscout_display_bytes::decode_hex(code).unwrap() +} + +fn parse_artifacts(value: serde_json::Value) -> T { + serde_json::from_value(value).unwrap() +} + +fn verify_creation_code( + on_chain_creation_code: &str, + re_compiled_creation_code: &str, + creation_code_artifacts: serde_json::Value, + compilation_artifacts: serde_json::Value, +) -> Option { + let on_chain_creation_code = parse_code(on_chain_creation_code); + let re_compiled_creation_code = parse_code(re_compiled_creation_code); + let creation_code_artifacts = parse_artifacts::(creation_code_artifacts); + let compilation_artifacts = parse_artifacts::(compilation_artifacts); + verifier_alliance::verify_creation_code( + &on_chain_creation_code, + re_compiled_creation_code, + &creation_code_artifacts, + &compilation_artifacts, + ) + .expect("(creation_code) error while verifying") +} + +fn verify_runtime_code( + on_chain_runtime_code: &str, + re_compiled_runtime_code: &str, + runtime_code_artifacts: serde_json::Value, +) -> Option { + let on_chain_runtime_code = parse_code(on_chain_runtime_code); + let re_compiled_runtime_code = parse_code(re_compiled_runtime_code); + let runtime_code_artifacts = parse_artifacts::(runtime_code_artifacts); + verifier_alliance::verify_runtime_code( + &on_chain_runtime_code, + re_compiled_runtime_code, + &runtime_code_artifacts, + ) + .expect("(runtime_code) error while verifying") +} + +#[test] +fn full_match() { + let on_chain_creation_code = "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"; + let re_compiled_creation_code = "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{},"sourceMap":"141:202:0:-:0;;;;;;;;;;;;;;;;;;;","cborAuxdata":{"1":{"offset":286,"value":"0xa26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"}}}); + let compilation_artifacts = json!({"abi":[{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ) + .expect("(creation_code) match expected"); + assert!( + creation_match.metadata_match, + "(creation_code) invalid metadata match value" + ); + assert_eq!( + creation_match.transformations.len(), + 0, + "(creation_code) invalid number of transformations" + ); + assert_eq!( + creation_match.values.cbor_auxdata.len(), + 0, + "(creation_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + creation_match.values.immutables.len(), + 0, + "(creation_code) invalid number of immutables transformation values" + ); + assert_eq!( + creation_match.values.libraries.len(), + 0, + "(creation_code) invalid number of libraries transformation values" + ); + assert_eq!( + creation_match.values.constructor_arguments, None, + "(creation_code) invalid constructor_arguments transformation value" + ); + + let on_chain_runtime_code = "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"; + let re_compiled_runtime_code = "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"; + let runtime_code_artifacts = json!({"immutableReferences":{},"linkReferences":{},"sourceMap":"141:202:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;277:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;277:64;331:3;322:6;:12;;;;277:64;:::o;164:21::-;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o","cborAuxdata":{"1":{"offset":254,"value":"0xa26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"}}}); + + let runtime_match = verify_runtime_code( + on_chain_runtime_code, + re_compiled_runtime_code, + runtime_code_artifacts, + ) + .expect("(runtime_code) match expected"); + assert!( + runtime_match.metadata_match, + "(runtime_code) invalid metadata match value" + ); + assert_eq!( + runtime_match.transformations.len(), + 0, + "(runtime_code) invalid number of transformations" + ); + assert_eq!( + runtime_match.values.cbor_auxdata.len(), + 0, + "(runtime_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + runtime_match.values.immutables.len(), + 0, + "(runtime_code) invalid number of immutables transformation values" + ); + assert_eq!( + runtime_match.values.libraries.len(), + 0, + "(runtime_code) invalid number of libraries transformation values" + ); + assert_eq!( + runtime_match.values.constructor_arguments, None, + "(runtime_code) invalid constructor_arguments transformation value" + ); +} + +#[test] +fn partial_match() { + let on_chain_creation_code = "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"; + let re_compiled_creation_code = "0x608060405234801561001057600080fd5b50610133806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{},"sourceMap":"141:229:0:-:0;;;;;;;;;;;;;;;;;;;","cborAuxdata":{"1":{"offset":286,"value":"0xa26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033"}}}); + let compilation_artifacts = json!({"abi":[{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"modified_num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"modified_num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ) + .expect("(creation_code) match expected"); + assert!( + !creation_match.metadata_match, + "(creation_code) invalid metadata match value" + ); + assert_eq!( + creation_match.transformations.len(), + 1, + "(creation_code) invalid number of transformations" + ); + assert_eq!( + creation_match.values.cbor_auxdata.len(), + 1, + "(creation_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + creation_match.values.immutables.len(), + 0, + "(creation_code) invalid number of immutables transformation values" + ); + assert_eq!( + creation_match.values.libraries.len(), + 0, + "(creation_code) invalid number of libraries transformation values" + ); + assert_eq!( + creation_match.values.constructor_arguments, None, + "(creation_code) invalid constructor_arguments transformation value" + ); + + let on_chain_runtime_code = "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212204ac0ce5f82b26331fa3e9ae959291a55624ffaf90fcd509deafcc21a5f1da21e64736f6c63430008120033"; + let re_compiled_runtime_code = "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033"; + let runtime_code_artifacts = json!({"immutableReferences":{},"linkReferences":{},"sourceMap":"141:229:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;286:82;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;286:82;349:12;340:6;:21;;;;286:82;:::o;164:21::-;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o","cborAuxdata":{"1":{"offset":254,"value":"0xa26469706673582212203863ce629eb61798cd34ba5d73d729ef1f86d2529ee1bdfc20e7eda860c4260564736f6c63430008120033"}}}); + + let runtime_match = verify_runtime_code( + on_chain_runtime_code, + re_compiled_runtime_code, + runtime_code_artifacts, + ) + .expect("(runtime_code) match expected"); + assert!( + !runtime_match.metadata_match, + "(runtime_code) invalid metadata match value" + ); + assert_eq!( + runtime_match.transformations.len(), + 1, + "(runtime_code) invalid number of transformations" + ); + assert_eq!( + runtime_match.values.cbor_auxdata.len(), + 1, + "(runtime_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + runtime_match.values.immutables.len(), + 0, + "(runtime_code) invalid number of immutables transformation values" + ); + assert_eq!( + runtime_match.values.libraries.len(), + 0, + "(runtime_code) invalid number of libraries transformation values" + ); + assert_eq!( + runtime_match.values.constructor_arguments, None, + "(runtime_code) invalid constructor_arguments transformation value" + ); +} + +#[test] +fn partial_match_with_double_auxdata_parts() { + let on_chain_creation_code = "0x60806040526040518060200161001490610049565b6020820181038252601f19601f820116604052506001908161003691906102a5565b5034801561004357600080fd5b50610377565b605c8061069c83390190565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806100d657607f821691505b6020821081036100e9576100e861008f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610114565b61015b8683610114565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006101a261019d61019884610173565b61017d565b610173565b9050919050565b6000819050919050565b6101bc83610187565b6101d06101c8826101a9565b848454610121565b825550505050565b600090565b6101e56101d8565b6101f08184846101b3565b505050565b5b81811015610214576102096000826101dd565b6001810190506101f6565b5050565b601f8211156102595761022a816100ef565b61023384610104565b81016020851015610242578190505b61025661024e85610104565b8301826101f5565b50505b505050565b600082821c905092915050565b600061027c6000198460080261025e565b1980831691505092915050565b6000610295838361026b565b9150826002028217905092915050565b6102ae82610055565b67ffffffffffffffff8111156102c7576102c6610060565b5b6102d182546100be565b6102dc828285610218565b600060209050601f83116001811461030f57600084156102fd578287015190505b6103078582610289565b86555061036f565b601f19841661031d866100ef565b60005b8281101561034557848901518255600182019150602085019450602081019050610320565b86831015610362578489015161035e601f89168261026b565b8355505b6001600288020188555050505b505050505050565b610316806103866000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea2646970667358221220bc2c6d72c52842d4077bb24c307576e44a078831aaa16da6611ef342fd052ec764736f6c634300081200336080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220f13d144a826a3f18798a534a4b10029a3284d9f4620ccc79750cdc48442cdaad64736f6c63430008120033"; + let re_compiled_creation_code = "0x60806040526040518060200161001490610049565b6020820181038252601f19601f820116604052506001908161003691906102a5565b5034801561004357600080fd5b50610377565b605c8061069c83390190565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806100d657607f821691505b6020821081036100e9576100e861008f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610114565b61015b8683610114565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006101a261019d61019884610173565b61017d565b610173565b9050919050565b6000819050919050565b6101bc83610187565b6101d06101c8826101a9565b848454610121565b825550505050565b600090565b6101e56101d8565b6101f08184846101b3565b505050565b5b81811015610214576102096000826101dd565b6001810190506101f6565b5050565b601f8211156102595761022a816100ef565b61023384610104565b81016020851015610242578190505b61025661024e85610104565b8301826101f5565b50505b505050565b600082821c905092915050565b600061027c6000198460080261025e565b1980831691505092915050565b6000610295838361026b565b9150826002028217905092915050565b6102ae82610055565b67ffffffffffffffff8111156102c7576102c6610060565b5b6102d182546100be565b6102dc828285610218565b600060209050601f83116001811461030f57600084156102fd578287015190505b6103078582610289565b86555061036f565b601f19841661031d866100ef565b60005b8281101561034557848901518255600182019150602085019450602081019050610320565b86831015610362578489015161035e601f89168261026b565b8355505b6001600288020188555050505b505050505050565b610316806103866000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c634300081200336080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220aebf48746b808da25305449bba6945baacf1c2185dfcc58a94b1506b8b5a6dfa64736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{},"sourceMap":"156:288:0:-:0;;;266:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;246:40;;;;;;;:::i;:::-;;156:288;;;;;;;;;;;;;;;;;;;;:::o;7:98:1:-;58:6;92:5;86:12;76:22;;7:98;;;:::o;111:180::-;159:77;156:1;149:88;256:4;253:1;246:15;280:4;277:1;270:15;297:180;345:77;342:1;335:88;442:4;439:1;432:15;466:4;463:1;456:15;483:320;527:6;564:1;558:4;554:12;544:22;;611:1;605:4;601:12;632:18;622:81;;688:4;680:6;676:17;666:27;;622:81;750:2;742:6;739:14;719:18;716:38;713:84;;769:18;;:::i;:::-;713:84;534:269;483:320;;;:::o;809:140::-;857:4;880:3;872:11;;903:3;900:1;893:14;937:4;934:1;924:18;916:26;;809:140;;;:::o;955:93::-;992:6;1039:2;1034;1027:5;1023:14;1019:23;1009:33;;955:93;;;:::o;1054:107::-;1098:8;1148:5;1142:4;1138:16;1117:37;;1054:107;;;;:::o;1167:393::-;1236:6;1286:1;1274:10;1270:18;1309:97;1339:66;1328:9;1309:97;:::i;:::-;1427:39;1457:8;1446:9;1427:39;:::i;:::-;1415:51;;1499:4;1495:9;1488:5;1484:21;1475:30;;1548:4;1538:8;1534:19;1527:5;1524:30;1514:40;;1243:317;;1167:393;;;;;:::o;1566:77::-;1603:7;1632:5;1621:16;;1566:77;;;:::o;1649:60::-;1677:3;1698:5;1691:12;;1649:60;;;:::o;1715:142::-;1765:9;1798:53;1816:34;1825:24;1843:5;1825:24;:::i;:::-;1816:34;:::i;:::-;1798:53;:::i;:::-;1785:66;;1715:142;;;:::o;1863:75::-;1906:3;1927:5;1920:12;;1863:75;;;:::o;1944:269::-;2054:39;2085:7;2054:39;:::i;:::-;2115:91;2164:41;2188:16;2164:41;:::i;:::-;2156:6;2149:4;2143:11;2115:91;:::i;:::-;2109:4;2102:105;2020:193;1944:269;;;:::o;2219:73::-;2264:3;2219:73;:::o;2298:189::-;2375:32;;:::i;:::-;2416:65;2474:6;2466;2460:4;2416:65;:::i;:::-;2351:136;2298:189;;:::o;2493:186::-;2553:120;2570:3;2563:5;2560:14;2553:120;;;2624:39;2661:1;2654:5;2624:39;:::i;:::-;2597:1;2590:5;2586:13;2577:22;;2553:120;;;2493:186;;:::o;2685:541::-;2785:2;2780:3;2777:11;2774:445;;;2819:37;2850:5;2819:37;:::i;:::-;2902:29;2920:10;2902:29;:::i;:::-;2892:8;2888:44;3085:2;3073:10;3070:18;3067:49;;;3106:8;3091:23;;3067:49;3129:80;3185:22;3203:3;3185:22;:::i;:::-;3175:8;3171:37;3158:11;3129:80;:::i;:::-;2789:430;;2774:445;2685:541;;;:::o;3232:117::-;3286:8;3336:5;3330:4;3326:16;3305:37;;3232:117;;;;:::o;3355:169::-;3399:6;3432:51;3480:1;3476:6;3468:5;3465:1;3461:13;3432:51;:::i;:::-;3428:56;3513:4;3507;3503:15;3493:25;;3406:118;3355:169;;;;:::o;3529:295::-;3605:4;3751:29;3776:3;3770:4;3751:29;:::i;:::-;3743:37;;3813:3;3810:1;3806:11;3800:4;3797:21;3789:29;;3529:295;;;;:::o;3829:1390::-;3944:36;3976:3;3944:36;:::i;:::-;4045:18;4037:6;4034:30;4031:56;;;4067:18;;:::i;:::-;4031:56;4111:38;4143:4;4137:11;4111:38;:::i;:::-;4196:66;4255:6;4247;4241:4;4196:66;:::i;:::-;4289:1;4313:4;4300:17;;4345:2;4337:6;4334:14;4362:1;4357:617;;;;5018:1;5035:6;5032:77;;;5084:9;5079:3;5075:19;5069:26;5060:35;;5032:77;5135:67;5195:6;5188:5;5135:67;:::i;:::-;5129:4;5122:81;4991:222;4327:886;;4357:617;4409:4;4405:9;4397:6;4393:22;4443:36;4474:4;4443:36;:::i;:::-;4501:1;4515:208;4529:7;4526:1;4523:14;4515:208;;;4608:9;4603:3;4599:19;4593:26;4585:6;4578:42;4659:1;4651:6;4647:14;4637:24;;4706:2;4695:9;4691:18;4678:31;;4552:4;4549:1;4545:12;4540:17;;4515:208;;;4751:6;4742:7;4739:19;4736:179;;;4809:9;4804:3;4800:19;4794:26;4852:48;4894:4;4886:6;4882:17;4871:9;4852:48;:::i;:::-;4844:6;4837:64;4759:156;4736:179;4961:1;4957;4949:6;4945:14;4941:22;4935:4;4928:36;4364:610;;;4327:886;;3919:1300;;;3829:1390;;:::o;156:288:0:-;;;;;;;","cborAuxdata":{"1":{"offset":1639,"value":"0xa264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c63430008120033"},"2":{"offset":1731,"value":"0xa2646970667358221220aebf48746b808da25305449bba6945baacf1c2185dfcc58a94b1506b8b5a6dfa64736f6c63430008120033"}}}); + let compilation_artifacts = json!({"abi":[{"inputs":[],"name":"code","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":5,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"},{"astId":11,"contract":"contracts/1_Storage.sol:Storage","label":"code","offset":0,"slot":"1","type":"t_bytes_storage"}],"types":{"t_bytes_storage":{"encoding":"bytes","label":"bytes","numberOfBytes":"32"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ) + .expect("(creation_code) match expected"); + assert!( + !creation_match.metadata_match, + "(creation_code) invalid metadata match value" + ); + assert_eq!( + creation_match.transformations.len(), + 2, + "(creation_code) invalid number of transformations" + ); + assert_eq!( + creation_match.values.cbor_auxdata.len(), + 2, + "(creation_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + creation_match.values.immutables.len(), + 0, + "(creation_code) invalid number of immutables transformation values" + ); + assert_eq!( + creation_match.values.libraries.len(), + 0, + "(creation_code) invalid number of libraries transformation values" + ); + assert_eq!( + creation_match.values.constructor_arguments, None, + "(creation_code) invalid constructor_arguments transformation value" + ); + + let on_chain_runtime_code = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea2646970667358221220bc2c6d72c52842d4077bb24c307576e44a078831aaa16da6611ef342fd052ec764736f6c63430008120033"; + let re_compiled_runtime_code = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806324c12bf6146100465780636057361d146100645780638381f58a14610080575b600080fd5b61004e61009e565b60405161005b91906101cc565b60405180910390f35b61007e60048036038101906100799190610229565b61012c565b005b610088610136565b6040516100959190610265565b60405180910390f35b600180546100ab906102af565b80601f01602080910402602001604051908101604052809291908181526020018280546100d7906102af565b80156101245780601f106100f957610100808354040283529160200191610124565b820191906000526020600020905b81548152906001019060200180831161010757829003601f168201915b505050505081565b8060008190555050565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b8381101561017657808201518184015260208101905061015b565b60008484015250505050565b6000601f19601f8301169050919050565b600061019e8261013c565b6101a88185610147565b93506101b8818560208601610158565b6101c181610182565b840191505092915050565b600060208201905081810360008301526101e68184610193565b905092915050565b600080fd5b6000819050919050565b610206816101f3565b811461021157600080fd5b50565b600081359050610223816101fd565b92915050565b60006020828403121561023f5761023e6101ee565b5b600061024d84828501610214565b91505092915050565b61025f816101f3565b82525050565b600060208201905061027a6000830184610256565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102c757607f821691505b6020821081036102da576102d9610280565b5b5091905056fea264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c63430008120033"; + let runtime_code_artifacts = json!({"immutableReferences":{},"linkReferences":{},"sourceMap":"156:288:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;246:40;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;378:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;179:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;246:40;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;378:64::-;432:3;423:6;:12;;;;378:64;:::o;179:21::-;;;;:::o;7:98:1:-;58:6;92:5;86:12;76:22;;7:98;;;:::o;111:168::-;194:11;228:6;223:3;216:19;268:4;263:3;259:14;244:29;;111:168;;;;:::o;285:246::-;366:1;376:113;390:6;387:1;384:13;376:113;;;475:1;470:3;466:11;460:18;456:1;451:3;447:11;440:39;412:2;409:1;405:10;400:15;;376:113;;;523:1;514:6;509:3;505:16;498:27;347:184;285:246;;;:::o;537:102::-;578:6;629:2;625:7;620:2;613:5;609:14;605:28;595:38;;537:102;;;:::o;645:373::-;731:3;759:38;791:5;759:38;:::i;:::-;813:70;876:6;871:3;813:70;:::i;:::-;806:77;;892:65;950:6;945:3;938:4;931:5;927:16;892:65;:::i;:::-;982:29;1004:6;982:29;:::i;:::-;977:3;973:39;966:46;;735:283;645:373;;;;:::o;1024:309::-;1135:4;1173:2;1162:9;1158:18;1150:26;;1222:9;1216:4;1212:20;1208:1;1197:9;1193:17;1186:47;1250:76;1321:4;1312:6;1250:76;:::i;:::-;1242:84;;1024:309;;;;:::o;1420:117::-;1529:1;1526;1519:12;1666:77;1703:7;1732:5;1721:16;;1666:77;;;:::o;1749:122::-;1822:24;1840:5;1822:24;:::i;:::-;1815:5;1812:35;1802:63;;1861:1;1858;1851:12;1802:63;1749:122;:::o;1877:139::-;1923:5;1961:6;1948:20;1939:29;;1977:33;2004:5;1977:33;:::i;:::-;1877:139;;;;:::o;2022:329::-;2081:6;2130:2;2118:9;2109:7;2105:23;2101:32;2098:119;;;2136:79;;:::i;:::-;2098:119;2256:1;2281:53;2326:7;2317:6;2306:9;2302:22;2281:53;:::i;:::-;2271:63;;2227:117;2022:329;;;;:::o;2357:118::-;2444:24;2462:5;2444:24;:::i;:::-;2439:3;2432:37;2357:118;;:::o;2481:222::-;2574:4;2612:2;2601:9;2597:18;2589:26;;2625:71;2693:1;2682:9;2678:17;2669:6;2625:71;:::i;:::-;2481:222;;;;:::o;2709:180::-;2757:77;2754:1;2747:88;2854:4;2851:1;2844:15;2878:4;2875:1;2868:15;2895:320;2939:6;2976:1;2970:4;2966:12;2956:22;;3023:1;3017:4;3013:12;3044:18;3034:81;;3100:4;3092:6;3088:17;3078:27;;3034:81;3162:2;3154:6;3151:14;3131:18;3128:38;3125:84;;3181:18;;:::i;:::-;3125:84;2946:269;2895:320;;;:::o","cborAuxdata":{"1":{"offset":737,"value":"0xa264697066735822122005d1b64ca59de3c6d96eee72b6fef65fc503bfbf8d9719fb047fafce2ebdc29764736f6c63430008120033"}}}); + + let runtime_match = verify_runtime_code( + on_chain_runtime_code, + re_compiled_runtime_code, + runtime_code_artifacts, + ) + .expect("(runtime_code) match expected"); + assert!( + !runtime_match.metadata_match, + "(runtime_code) invalid metadata match value" + ); + assert_eq!( + runtime_match.transformations.len(), + 1, + "(runtime_code) invalid number of transformations" + ); + assert_eq!( + runtime_match.values.cbor_auxdata.len(), + 1, + "(runtime_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + runtime_match.values.immutables.len(), + 0, + "(runtime_code) invalid number of immutables transformation values" + ); + assert_eq!( + runtime_match.values.libraries.len(), + 0, + "(runtime_code) invalid number of libraries transformation values" + ); + assert_eq!( + runtime_match.values.constructor_arguments, None, + "(runtime_code) invalid constructor_arguments transformation value" + ); +} + +#[test] +fn immutables() { + let on_chain_creation_code = "0x60a0604052606460809081525034801561001857600080fd5b5060805161019a610033600039600060b0015261019a6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033"; + let re_compiled_creation_code = "0x60a0604052606460809081525034801561001857600080fd5b5060805161019a610033600039600060b0015261019a6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{},"sourceMap":"141:250:0:-:0;;;230:3;192:41;;;;;141:250;;;;;;;;;;;;;;;;;;;;;;","cborAuxdata":{"1":{"offset":408,"value":"0xa26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033"}}}); + let compilation_artifacts = json!({"abi":[{"inputs":[],"name":"imm_number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ) + .expect("(creation_code) match expected"); + assert!( + creation_match.metadata_match, + "(creation_code) invalid metadata match value" + ); + assert_eq!( + creation_match.transformations.len(), + 0, + "(creation_code) invalid number of transformations" + ); + assert_eq!( + creation_match.values.cbor_auxdata.len(), + 0, + "(creation_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + creation_match.values.immutables.len(), + 0, + "(creation_code) invalid number of immutables transformation values" + ); + assert_eq!( + creation_match.values.libraries.len(), + 0, + "(creation_code) invalid number of libraries transformation values" + ); + assert_eq!( + creation_match.values.constructor_arguments, None, + "(creation_code) invalid constructor_arguments transformation value" + ); + + let on_chain_runtime_code = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000006481565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033"; + let re_compiled_runtime_code = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a146100625780639fe44c4a14610080575b600080fd5b610060600480360381019061005b919061010d565b61009e565b005b61006a6100a8565b6040516100779190610149565b60405180910390f35b6100886100ae565b6040516100959190610149565b60405180910390f35b8060008190555050565b60005481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080fd5b6000819050919050565b6100ea816100d7565b81146100f557600080fd5b50565b600081359050610107816100e1565b92915050565b600060208284031215610123576101226100d2565b5b6000610131848285016100f8565b91505092915050565b610143816100d7565b82525050565b600060208201905061015e600083018461013a565b9291505056fea26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033"; + let runtime_code_artifacts = json!({"immutableReferences":{"7":[{"length":32,"start":176}]},"linkReferences":{},"sourceMap":"141:250:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;325:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;192:41;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;325:64;379:3;370:6;:12;;;;325:64;:::o;164:21::-;;;;:::o;192:41::-;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o","cborAuxdata":{"1":{"offset":357,"value":"0xa26469706673582212205fff17b2676425e48225435ac15579ccae1af038ff8ffb334fc372526b94722664736f6c63430008120033"}}}); + + let runtime_match = verify_runtime_code( + on_chain_runtime_code, + re_compiled_runtime_code, + runtime_code_artifacts, + ) + .expect("(runtime_code) match expected"); + assert!( + runtime_match.metadata_match, + "(runtime_code) invalid metadata match value" + ); + assert_eq!( + runtime_match.transformations.len(), + 1, + "(runtime_code) invalid number of transformations" + ); + assert_eq!( + runtime_match.values.cbor_auxdata.len(), + 0, + "(runtime_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + runtime_match.values.immutables.len(), + 1, + "(runtime_code) invalid number of immutables transformation values" + ); + assert_eq!( + runtime_match.values.libraries.len(), + 0, + "(runtime_code) invalid number of libraries transformation values" + ); + assert_eq!( + runtime_match.values.constructor_arguments, None, + "(runtime_code) invalid constructor_arguments transformation value" + ); +} + +#[test] +fn manually_linked_libraries() { + let on_chain_creation_code = "0x608060405234801561001057600080fd5b50610249806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033"; + let re_compiled_creation_code = "0x608060405234801561001057600080fd5b50610249806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550730000000000000000000000000000000000000000632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{"contracts/1_Storage.sol":{"Journal":[{"length":20,"start":217}]}},"sourceMap":"292:289:0:-:0;;;;;;;;;;;;;;;;;;;","cborAuxdata":{"1":{"offset":564,"value":"0xa26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033"}}}); + let compilation_artifacts = json!({"abi":[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"journal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":22,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"},{"astId":26,"contract":"contracts/1_Storage.sol:Storage","label":"journal","offset":0,"slot":"1","type":"t_mapping(t_uint256,t_uint256)"}],"types":{"t_mapping(t_uint256,t_uint256)":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => uint256)","numberOfBytes":"32","value":"t_uint256"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ) + .expect("(creation_code) match expected"); + assert!( + creation_match.metadata_match, + "(creation_code) invalid metadata match value" + ); + assert_eq!( + creation_match.transformations.len(), + 1, + "(creation_code) invalid number of transformations" + ); + assert_eq!( + creation_match.values.cbor_auxdata.len(), + 0, + "(creation_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + creation_match.values.immutables.len(), + 0, + "(creation_code) invalid number of immutables transformation values" + ); + assert_eq!( + creation_match.values.libraries.len(), + 1, + "(creation_code) invalid number of libraries transformation values" + ); + assert_eq!( + creation_match.values.constructor_arguments, None, + "(creation_code) invalid constructor_arguments transformation value" + ); + + let on_chain_runtime_code = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550737d53f102f4d4aa014db4e10d6deec2009b3cda6b632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033"; + let re_compiled_runtime_code = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636057361d146100465780638381f58a14610062578063e2e2a85a14610080575b600080fd5b610060600480360381019061005b919061017d565b6100b0565b005b61006a610124565b60405161007791906101b9565b60405180910390f35b61009a6004803603810190610095919061017d565b61012a565b6040516100a791906101b9565b60405180910390f35b80600081905550730000000000000000000000000000000000000000632be59dd56001836040518363ffffffff1660e01b81526004016100f19291906101ea565b60006040518083038186803b15801561010957600080fd5b505af415801561011d573d6000803e3d6000fd5b5050505050565b60005481565b60016020528060005260406000206000915090505481565b600080fd5b6000819050919050565b61015a81610147565b811461016557600080fd5b50565b60008135905061017781610151565b92915050565b60006020828403121561019357610192610142565b5b60006101a184828501610168565b91505092915050565b6101b381610147565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b8082525050565b6101e481610147565b82525050565b60006040820190506101ff60008301856101d4565b61020c60208301846101db565b939250505056fea26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033"; + let runtime_code_artifacts = json!({"immutableReferences":{},"linkReferences":{"contracts/1_Storage.sol":{"Journal":[{"length":20,"start":185}]}},"sourceMap":"292:289:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;477:102;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;315:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;343:42;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;477:102;531:3;522:6;:12;;;;544:7;:14;559:7;568:3;544:28;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;477:102;:::o;315:21::-;;;;:::o;343:42::-;;;;;;;;;;;;;;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o;1377:132::-;1497:5;1492:3;1485:18;1377:132;;:::o;1515:126::-;1610:24;1628:5;1610:24;:::i;:::-;1605:3;1598:37;1515:126;;:::o;1647:406::-;1801:4;1839:2;1828:9;1824:18;1816:26;;1852:104;1953:1;1942:9;1938:17;1929:6;1852:104;:::i;:::-;1966:80;2042:2;2031:9;2027:18;2018:6;1966:80;:::i;:::-;1647:406;;;;;:::o","cborAuxdata":{"1":{"offset":532,"value":"0xa26469706673582212205d40d1517b560d915e1b7c005887b93fcce9ec65c0a38a80ee147739551bdd7264736f6c63430008120033"}}}); + + let runtime_match = verify_runtime_code( + on_chain_runtime_code, + re_compiled_runtime_code, + runtime_code_artifacts, + ) + .expect("(runtime_code) match expected"); + assert!( + runtime_match.metadata_match, + "(runtime_code) invalid metadata match value" + ); + assert_eq!( + runtime_match.transformations.len(), + 1, + "(runtime_code) invalid number of transformations" + ); + assert_eq!( + runtime_match.values.cbor_auxdata.len(), + 0, + "(runtime_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + runtime_match.values.immutables.len(), + 0, + "(runtime_code) invalid number of immutables transformation values" + ); + assert_eq!( + runtime_match.values.libraries.len(), + 1, + "(runtime_code) invalid number of libraries transformation values" + ); + assert_eq!( + runtime_match.values.constructor_arguments, None, + "(runtime_code) invalid constructor_arguments transformation value" + ); +} + +#[test] +fn constructor_arguments() { + let on_chain_creation_code = "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c634300081200330000000000000000000000000000000000000000000000000000000000003039"; + let re_compiled_creation_code = "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{},"sourceMap":"141:262:0:-:0;;;192:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;236:3;227:6;:12;;;;192:54;141:262;;88:117:1;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:143::-;602:5;633:6;627:13;618:22;;649:33;676:5;649:33;:::i;:::-;545:143;;;;:::o;694:351::-;764:6;813:2;801:9;792:7;788:23;784:32;781:119;;;819:79;;:::i;:::-;781:119;939:1;964:64;1020:7;1011:6;1000:9;996:22;964:64;:::i;:::-;954:74;;910:128;694:351;;;;:::o;141:262:0:-;;;;;;;","cborAuxdata":{"1":{"offset":436,"value":"0xa2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"}}}); + let compilation_artifacts = json!({"abi":[{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ) + .expect("(creation_code) match expected"); + assert!( + creation_match.metadata_match, + "(creation_code) invalid metadata match value" + ); + assert_eq!( + creation_match.transformations.len(), + 1, + "(creation_code) invalid number of transformations" + ); + assert_eq!( + creation_match.values.cbor_auxdata.len(), + 0, + "(creation_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + creation_match.values.immutables.len(), + 0, + "(creation_code) invalid number of immutables transformation values" + ); + assert_eq!( + creation_match.values.libraries.len(), + 0, + "(creation_code) invalid number of libraries transformation values" + ); + assert!( + creation_match.values.constructor_arguments.is_some(), + "(creation_code) expected constructor_arguments transformation value" + ); + + let on_chain_runtime_code = "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"; + let re_compiled_runtime_code = "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"; + let runtime_code_artifacts = json!({"immutableReferences":{},"linkReferences":{},"sourceMap":"141:262:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;337:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;164:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;337:64;391:3;382:6;:12;;;;337:64;:::o;164:21::-;;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o","cborAuxdata":{"1":{"offset":254,"value":"0xa2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"}}}); + + let runtime_match = verify_runtime_code( + on_chain_runtime_code, + re_compiled_runtime_code, + runtime_code_artifacts, + ) + .expect("(runtime_code) match expected"); + assert!( + runtime_match.metadata_match, + "(runtime_code) invalid metadata match value" + ); + assert_eq!( + runtime_match.transformations.len(), + 0, + "(runtime_code) invalid number of transformations" + ); + assert_eq!( + runtime_match.values.cbor_auxdata.len(), + 0, + "(runtime_code) invalid number of cbor_auxdata transformation values" + ); + assert_eq!( + runtime_match.values.immutables.len(), + 0, + "(runtime_code) invalid number of immutables transformation values" + ); + assert_eq!( + runtime_match.values.libraries.len(), + 0, + "(runtime_code) invalid number of libraries transformation values" + ); + assert_eq!( + runtime_match.values.constructor_arguments, None, + "(runtime_code) invalid constructor_arguments transformation value" + ); +} + +#[test] +fn invalid_constructor_arguments() { + let on_chain_creation_code = "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c634300081200330000000000000000000000000000000000000000000000000000000000003039"; + let re_compiled_creation_code = "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{},"sourceMap":"141:262:0:-:0;;;192:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;236:3;227:6;:12;;;;192:54;141:262;;88:117:1;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:143::-;602:5;633:6;627:13;618:22;;649:33;676:5;649:33;:::i;:::-;545:143;;;;:::o;694:351::-;764:6;813:2;801:9;792:7;788:23;784:32;781:119;;;819:79;;:::i;:::-;781:119;939:1;964:64;1020:7;1011:6;1000:9;996:22;964:64;:::i;:::-;954:74;;910:128;694:351;;;;:::o;141:262:0:-;;;;;;;","cborAuxdata":{"1":{"offset":436,"value":"0xa2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"}}}); + // one more `uint256` argument ('not_actual_num') was added + let compilation_artifacts = json!({"abi":[{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}, {"internalType":"uint256","name":"not_actual_num","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ); + assert_eq!(creation_match, None, "(creation_code) no match expected") +} + +#[test] +fn non_existent_constructor_argument() { + let on_chain_creation_code = "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c634300081200330000000000000000000000000000000000000000000000000000000000003039"; + let re_compiled_creation_code = "0x608060405234801561001057600080fd5b506040516101e93803806101e98339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610133806100b66000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d1460375780638381f58a14604f575b600080fd5b604d60048036038101906049919060af565b6069565b005b60556073565b6040516060919060e4565b60405180910390f35b8060008190555050565b60005481565b600080fd5b6000819050919050565b608f81607e565b8114609957600080fd5b50565b60008135905060a9816088565b92915050565b60006020828403121560c25760c16079565b5b600060ce84828501609c565b91505092915050565b60de81607e565b82525050565b600060208201905060f7600083018460d7565b9291505056fea2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"; + let creation_code_artifacts = json!({"linkReferences":{},"sourceMap":"141:262:0:-:0;;;192:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;236:3;227:6;:12;;;;192:54;141:262;;88:117:1;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:143::-;602:5;633:6;627:13;618:22;;649:33;676:5;649:33;:::i;:::-;545:143;;;;:::o;694:351::-;764:6;813:2;801:9;792:7;788:23;784:32;781:119;;;819:79;;:::i;:::-;781:119;939:1;964:64;1020:7;1011:6;1000:9;996:22;964:64;:::i;:::-;954:74;;910:128;694:351;;;;:::o;141:262:0:-;;;;;;;","cborAuxdata":{"1":{"offset":436,"value":"0xa2646970667358221220dd712ec4cb31d63cd32d3152e52e890b087769e9e4d6746844608039b5015d6a64736f6c63430008120033"}}}); + // constructor was removed from abi + let compilation_artifacts = json!({"abi":[{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Store & retrieve value in a variable","kind":"dev","methods":{"store(uint256)":{"details":"Store value in variable","params":{"num":"value to store"}}},"title":"Storage","version":1},"userdoc":{"kind":"user","methods":{},"version":1},"storageLayout":{"storage":[{"astId":4,"contract":"contracts/1_Storage.sol:Storage","label":"number","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"sources":{"contracts/1_Storage.sol":{"id":0}}}); + + let creation_match = verify_creation_code( + on_chain_creation_code, + re_compiled_creation_code, + creation_code_artifacts, + compilation_artifacts, + ); + assert_eq!(creation_match, None, "(creation_code) no match expected") +}