From eee8b92aa268055003168ace490fff2006e1b21c Mon Sep 17 00:00:00 2001 From: Hubert Ritzdorf Date: Fri, 16 May 2025 01:19:35 +0200 Subject: [PATCH 1/8] Limited Library Support --- README.md | 1 + .../compare_bytecodes.rs | 11 ++++ lib/bytecode_verification/parse_json.rs | 66 ++++++++++++------- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 9af1a35d..7529641c 100644 --- a/README.md +++ b/README.md @@ -526,6 +526,7 @@ This section will be updated soon. ## Known Limitations and Bugs +- Compilation with libraries is currently not supported. The best workaround is to compile using `forge build --libraries --build-info --build-info-path ` and then use `` using the `--buildcache` argument. - Currently only solidity is supported. - Only projects with `solc` version starting from `0.5.13` are supported due to the lack of generated storage layout in older versions (see [solc release 0.5.13](https://github.com/ethereum/solidity/releases/tag/v0.5.13)). - The RPC endpoints automatically parsed in `dv generate-config` are not guaranteed to be compatible. diff --git a/lib/bytecode_verification/compare_bytecodes.rs b/lib/bytecode_verification/compare_bytecodes.rs index 31ea708a..c85a8aa4 100644 --- a/lib/bytecode_verification/compare_bytecodes.rs +++ b/lib/bytecode_verification/compare_bytecodes.rs @@ -145,6 +145,16 @@ impl CompareBytecode { Self::ignore_immutables(&project_info.immutables, &mut relevant_indices); + // Ignore Library Address at the beginning of a Library: PUSH20 address + if project_info.is_library { + debug!("Skipping initial library bytes"); + for i in 1..21 { + relevant_indices[i] = false; + } + // Check for PUSH20 + assert_eq!(compiled_bytecode[0], 0x73); + } + // If no metadata is appended if Some(BytecodeHash::None) == project_info.cbor_metadata { let matched = @@ -260,6 +270,7 @@ impl CompareInitCode { ); } // println!("Relevant Indices: {:?}", relevant_indices.clone()); + // debug!("Initcode comparison: {:?} ?= {:?}", compiled_init_code.clone(), init_bytecode[..init_len].to_vec()); if !compare_relevant( &compiled_init_code, &init_bytecode[..init_len], diff --git a/lib/bytecode_verification/parse_json.rs b/lib/bytecode_verification/parse_json.rs index 5bffed55..b0f4ea35 100644 --- a/lib/bytecode_verification/parse_json.rs +++ b/lib/bytecode_verification/parse_json.rs @@ -6,6 +6,7 @@ use std::path::PathBuf; use alloy::json_abi::Constructor; use clap::ValueEnum; use semver::Version; +use serde_json; use serde_json::Value; use std::path::Path; use std::process::Command; @@ -26,8 +27,8 @@ use alloy::json_abi::Event; use alloy::primitives::U256; use foundry_compilers::artifacts::Error as CompilerError; use foundry_compilers::artifacts::{ - BytecodeHash, BytecodeObject, Contract as ContractArt, DeployedBytecode, Node as EAstNode, - NodeType, SolcInput, SourceFile, + Ast, BytecodeHash, BytecodeObject, Contract as ContractArt, ContractDefinition, ContractKind, + DeployedBytecode, Node as EAstNode, NodeType, SolcInput, SourceFile, }; use foundry_compilers::buildinfo::BuildInfo as BInfo; use foundry_compilers::CompilerOutput; @@ -55,6 +56,7 @@ pub struct ProjectInfo { pub storage: Vec, pub types: HashMap, pub absolute_path: Option, + pub is_library: bool, } impl ProjectInfo { @@ -1317,21 +1319,18 @@ impl ProjectInfo { } } - /// Parses the AST for a contract definition. - fn contains_contract(node: &EAstNode, contract_name: &String) -> bool { - if node.node_type == NodeType::ContractDefinition { - if let Some(name) = node.other.get("name") { - if name == contract_name { - return true; - } - } - } + // Tries to figure out whether this is a library + + // Parses the AST for a contract definition. + // Assumes that it is one of the top nodes + fn find_contract_definition(node: &Ast) -> Result { for subnode in &node.nodes { - if Self::contains_contract(subnode, contract_name) { - return true; + if subnode.node_type == NodeType::ContractDefinition { + let serialized = serde_json::to_value(subnode)?; + return Ok(serde_json::from_value::(serialized)?); } } - false + Err(ValidationError::from("No Contract Definition found")) } // Parses the AST to find all associated contracts (libraries & parent contracts) @@ -1341,10 +1340,10 @@ impl ProjectInfo { exported_ids: &mut Vec, ) { for source in sources.values() { - if let Some(new_ast) = source.ast.clone() { - for node in &new_ast.nodes { - if Self::contains_contract(node, contract_name) { - for (sub_contract, symbols) in new_ast.exported_symbols { + if let Some(new_ast) = &source.ast { + if let Ok(contract_definition) = Self::find_contract_definition(new_ast) { + if contract_definition.name == *contract_name { + for (sub_contract, symbols) in &new_ast.exported_symbols { // TODO: what does it mean if there is more than 1 symbol per contract? if symbols.len() == 1 && !exported_ids.contains(&symbols[0]) { exported_ids.extend(symbols); @@ -1532,11 +1531,16 @@ impl ProjectInfo { let mut types: HashMap = HashMap::new(); let mut exported_ids: Vec = vec![]; let mut absolute_path: Option = None; - for (file, source) in build_info.output.sources.clone() { - if let Some(new_ast) = source.ast.clone() { - for node in &new_ast.nodes { - if Self::contains_contract(node, contract_name) { - absolute_path = Some(new_ast.absolute_path.to_string()); + // TODO: Use relevant_ast instead of repeatedly searching + // let mut relevant_ast: Ast; + let mut contract_definition: Option = None; + for (file, source) in &build_info.output.sources { + if let Some(ast_ref) = &source.ast { + if let Ok(tmp_contract_definition) = Self::find_contract_definition(ast_ref) { + if tmp_contract_definition.name == *contract_name { + // relevant_ast = ast_ref.clone(); + absolute_path = Some(ast_ref.absolute_path.clone()); + contract_definition = Some(tmp_contract_definition); break; } } @@ -1544,6 +1548,15 @@ impl ProjectInfo { debug!("Empty AST found: {}", file.display()); } } + + if contract_definition.is_none() { + return Err(ValidationError::from(format!( + "Could not find the contract definition AST node of {}", + &contract_name + ))); + } + let contract_definition = contract_definition.unwrap(); + // get exported AST IDs of the current contract to prevent parsing storage slots of other contracts // in the project Self::find_exported_ids(&build_info.output.sources, contract_name, &mut exported_ids); @@ -1555,7 +1568,7 @@ impl ProjectInfo { } for source in build_info.output.sources.values() { // TODO: Error handle here, what though? - if let Some(new_ast) = source.ast.clone() { + if let Some(new_ast) = &source.ast { for node in &new_ast.nodes { Self::find_var_defs(node, &mut id_to_ast); } @@ -1584,6 +1597,10 @@ impl ProjectInfo { fs::remove_dir_all(&build_info_path)?; }; + let contract_kind = contract_definition.kind.clone(); + let is_library = contract_kind == ContractKind::Library; + debug!("Contract Kind: {contract_kind:?}, is_library: {is_library:?}"); + let pi = ProjectInfo { compiled_bytecode: compiled_bytecode_str, init_code: init_code_str, @@ -1604,6 +1621,7 @@ impl ProjectInfo { storage, types, absolute_path, + is_library, }; Ok(pi) From fb070a9efc2f619f5032bc53aee2eae07d35883c Mon Sep 17 00:00:00 2001 From: Hubert Ritzdorf Date: Fri, 16 May 2025 01:33:54 +0200 Subject: [PATCH 2/8] Forgot to adjust tests... --- lib/bytecode_verification/compare_bytecodes.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/bytecode_verification/compare_bytecodes.rs b/lib/bytecode_verification/compare_bytecodes.rs index c85a8aa4..f222cd8f 100644 --- a/lib/bytecode_verification/compare_bytecodes.rs +++ b/lib/bytecode_verification/compare_bytecodes.rs @@ -336,6 +336,7 @@ mod tests { types: HashMap::new(), storage: vec![], absolute_path: None, + is_library: false }; let compare_status = CompareBytecode::compare(&mut p, false, &onchain_code); assert!(!compare_status.matched); @@ -360,6 +361,7 @@ mod tests { types: HashMap::new(), storage: vec![], absolute_path: None, + is_library: false }; let compare_status = CompareBytecode::compare(&mut p, false, &onchain_code); assert!(compare_status.matched); @@ -415,6 +417,7 @@ mod tests { types: HashMap::new(), storage: vec![], absolute_path: None, + is_library: false }; let compare_status = CompareInitCode::compare(&mut p, &tx_init_code, false); From 86b2255af7777a68759f61250b32a0ee901d2ba7 Mon Sep 17 00:00:00 2001 From: Stefan Effenberger Date: Fri, 16 May 2025 09:27:31 +0200 Subject: [PATCH 3/8] fmt + clippy --- lib/bytecode_verification/compare_bytecodes.rs | 10 +++++----- lib/bytecode_verification/parse_json.rs | 2 +- lib/state/contract_state.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/bytecode_verification/compare_bytecodes.rs b/lib/bytecode_verification/compare_bytecodes.rs index f222cd8f..23156bf8 100644 --- a/lib/bytecode_verification/compare_bytecodes.rs +++ b/lib/bytecode_verification/compare_bytecodes.rs @@ -148,8 +148,8 @@ impl CompareBytecode { // Ignore Library Address at the beginning of a Library: PUSH20 address if project_info.is_library { debug!("Skipping initial library bytes"); - for i in 1..21 { - relevant_indices[i] = false; + for index in relevant_indices.iter_mut().take(21).skip(1) { + *index = false; } // Check for PUSH20 assert_eq!(compiled_bytecode[0], 0x73); @@ -336,7 +336,7 @@ mod tests { types: HashMap::new(), storage: vec![], absolute_path: None, - is_library: false + is_library: false, }; let compare_status = CompareBytecode::compare(&mut p, false, &onchain_code); assert!(!compare_status.matched); @@ -361,7 +361,7 @@ mod tests { types: HashMap::new(), storage: vec![], absolute_path: None, - is_library: false + is_library: false, }; let compare_status = CompareBytecode::compare(&mut p, false, &onchain_code); assert!(compare_status.matched); @@ -417,7 +417,7 @@ mod tests { types: HashMap::new(), storage: vec![], absolute_path: None, - is_library: false + is_library: false, }; let compare_status = CompareInitCode::compare(&mut p, &tx_init_code, false); diff --git a/lib/bytecode_verification/parse_json.rs b/lib/bytecode_verification/parse_json.rs index b0f4ea35..650c8e17 100644 --- a/lib/bytecode_verification/parse_json.rs +++ b/lib/bytecode_verification/parse_json.rs @@ -1347,7 +1347,7 @@ impl ProjectInfo { // TODO: what does it mean if there is more than 1 symbol per contract? if symbols.len() == 1 && !exported_ids.contains(&symbols[0]) { exported_ids.extend(symbols); - Self::find_exported_ids(sources, &sub_contract, exported_ids); + Self::find_exported_ids(sources, sub_contract, exported_ids); } } break; diff --git a/lib/state/contract_state.rs b/lib/state/contract_state.rs index 749b117e..9e7601ec 100644 --- a/lib/state/contract_state.rs +++ b/lib/state/contract_state.rs @@ -463,7 +463,7 @@ impl<'a> ContractState<'a> { // Check if we need to skip multiple slots if base_num_bytes > 32 { current_slot = - current_slot.add(U256::from((current_offset + base_num_bytes + 31) / 32)); + current_slot.add(U256::from((current_offset + base_num_bytes).div_ceil(32))); current_offset = 0; // Check if we need to skip one slot } else if current_offset + base_num_bytes + base_num_bytes > 32 { From f8b0a0b48b7dce1ef82bf9faadbbaec16cb5f74d Mon Sep 17 00:00:00 2001 From: Stefan Effenberger Date: Fri, 16 May 2025 09:30:20 +0200 Subject: [PATCH 4/8] fmt again --- lib/state/contract_state.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/state/contract_state.rs b/lib/state/contract_state.rs index 9e7601ec..2f274c93 100644 --- a/lib/state/contract_state.rs +++ b/lib/state/contract_state.rs @@ -462,8 +462,8 @@ impl<'a> ContractState<'a> { .extend(self.get_critical_variable(&base, snapshot, table)?); // Check if we need to skip multiple slots if base_num_bytes > 32 { - current_slot = - current_slot.add(U256::from((current_offset + base_num_bytes).div_ceil(32))); + current_slot = current_slot + .add(U256::from((current_offset + base_num_bytes).div_ceil(32))); current_offset = 0; // Check if we need to skip one slot } else if current_offset + base_num_bytes + base_num_bytes > 32 { From e67edc45ff0ee61f037ac3c5059032a7e159c44a Mon Sep 17 00:00:00 2001 From: Stefan Effenberger Date: Fri, 16 May 2025 10:31:28 +0200 Subject: [PATCH 5/8] revert some optimizations due to more complicated ASTs --- lib/bytecode_verification/parse_json.rs | 28 +++++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/bytecode_verification/parse_json.rs b/lib/bytecode_verification/parse_json.rs index 650c8e17..685439d9 100644 --- a/lib/bytecode_verification/parse_json.rs +++ b/lib/bytecode_verification/parse_json.rs @@ -1323,14 +1323,24 @@ impl ProjectInfo { // Parses the AST for a contract definition. // Assumes that it is one of the top nodes - fn find_contract_definition(node: &Ast) -> Result { + fn find_contract_definition(node: &EAstNode, contract_name: &String) -> Result { + if node.node_type == NodeType::ContractDefinition { + if let Some(name) = node.other.get("name") { + if name == contract_name { + let serialized = serde_json::to_value(node)?; + return Ok(serde_json::from_value::(serialized)?); + } + } + } for subnode in &node.nodes { - if subnode.node_type == NodeType::ContractDefinition { - let serialized = serde_json::to_value(subnode)?; - return Ok(serde_json::from_value::(serialized)?); + if let Ok(contract_definition) = Self::find_contract_definition(subnode, contract_name) { + return Ok(contract_definition); } } - Err(ValidationError::from("No Contract Definition found")) + Err(ValidationError::from(format!( + "Could not find contract definition for {}", + contract_name + ))) } // Parses the AST to find all associated contracts (libraries & parent contracts) @@ -1341,8 +1351,8 @@ impl ProjectInfo { ) { for source in sources.values() { if let Some(new_ast) = &source.ast { - if let Ok(contract_definition) = Self::find_contract_definition(new_ast) { - if contract_definition.name == *contract_name { + for node in &new_ast.nodes { + if let Ok(_) = Self::find_contract_definition(node, contract_name) { for (sub_contract, symbols) in &new_ast.exported_symbols { // TODO: what does it mean if there is more than 1 symbol per contract? if symbols.len() == 1 && !exported_ids.contains(&symbols[0]) { @@ -1536,8 +1546,8 @@ impl ProjectInfo { let mut contract_definition: Option = None; for (file, source) in &build_info.output.sources { if let Some(ast_ref) = &source.ast { - if let Ok(tmp_contract_definition) = Self::find_contract_definition(ast_ref) { - if tmp_contract_definition.name == *contract_name { + for node in &ast_ref.nodes { + if let Ok(tmp_contract_definition) = Self::find_contract_definition(node, contract_name) { // relevant_ast = ast_ref.clone(); absolute_path = Some(ast_ref.absolute_path.clone()); contract_definition = Some(tmp_contract_definition); From 82fbaa8f8afe51b1f4d6f362446959c1acdb46d1 Mon Sep 17 00:00:00 2001 From: Stefan Effenberger Date: Fri, 16 May 2025 10:38:59 +0200 Subject: [PATCH 6/8] fmt + clippy --- lib/bytecode_verification/parse_json.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/bytecode_verification/parse_json.rs b/lib/bytecode_verification/parse_json.rs index 685439d9..fad1069e 100644 --- a/lib/bytecode_verification/parse_json.rs +++ b/lib/bytecode_verification/parse_json.rs @@ -27,7 +27,7 @@ use alloy::json_abi::Event; use alloy::primitives::U256; use foundry_compilers::artifacts::Error as CompilerError; use foundry_compilers::artifacts::{ - Ast, BytecodeHash, BytecodeObject, Contract as ContractArt, ContractDefinition, ContractKind, + BytecodeHash, BytecodeObject, Contract as ContractArt, ContractDefinition, ContractKind, DeployedBytecode, Node as EAstNode, NodeType, SolcInput, SourceFile, }; use foundry_compilers::buildinfo::BuildInfo as BInfo; @@ -1323,7 +1323,10 @@ impl ProjectInfo { // Parses the AST for a contract definition. // Assumes that it is one of the top nodes - fn find_contract_definition(node: &EAstNode, contract_name: &String) -> Result { + fn find_contract_definition( + node: &EAstNode, + contract_name: &String, + ) -> Result { if node.node_type == NodeType::ContractDefinition { if let Some(name) = node.other.get("name") { if name == contract_name { @@ -1333,7 +1336,8 @@ impl ProjectInfo { } } for subnode in &node.nodes { - if let Ok(contract_definition) = Self::find_contract_definition(subnode, contract_name) { + if let Ok(contract_definition) = Self::find_contract_definition(subnode, contract_name) + { return Ok(contract_definition); } } @@ -1352,7 +1356,7 @@ impl ProjectInfo { for source in sources.values() { if let Some(new_ast) = &source.ast { for node in &new_ast.nodes { - if let Ok(_) = Self::find_contract_definition(node, contract_name) { + if Self::find_contract_definition(node, contract_name).is_ok() { for (sub_contract, symbols) in &new_ast.exported_symbols { // TODO: what does it mean if there is more than 1 symbol per contract? if symbols.len() == 1 && !exported_ids.contains(&symbols[0]) { @@ -1547,7 +1551,9 @@ impl ProjectInfo { for (file, source) in &build_info.output.sources { if let Some(ast_ref) = &source.ast { for node in &ast_ref.nodes { - if let Ok(tmp_contract_definition) = Self::find_contract_definition(node, contract_name) { + if let Ok(tmp_contract_definition) = + Self::find_contract_definition(node, contract_name) + { // relevant_ast = ast_ref.clone(); absolute_path = Some(ast_ref.absolute_path.clone()); contract_definition = Some(tmp_contract_definition); From 503b620808b6a6db0eda0439a51f3d31dc245618 Mon Sep 17 00:00:00 2001 From: Stefan Effenberger Date: Fri, 16 May 2025 12:06:10 +0200 Subject: [PATCH 7/8] added test case --- tests/Contracts/script/Deploy_Lib.s.sol | 21 +++++++++++++++++++ tests/Contracts/src/Lib.sol | 8 ++++++++ tests/Contracts/src/LibUser.sol | 10 +++++++++ tests/expected_dvfs/Lib.dvf.json | 27 +++++++++++++++++++++++++ tests/test_end_to_end.rs | 17 +++++++++++++++- 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/Contracts/script/Deploy_Lib.s.sol create mode 100644 tests/Contracts/src/Lib.sol create mode 100644 tests/Contracts/src/LibUser.sol create mode 100644 tests/expected_dvfs/Lib.dvf.json diff --git a/tests/Contracts/script/Deploy_Lib.s.sol b/tests/Contracts/script/Deploy_Lib.s.sol new file mode 100644 index 00000000..917ee2c5 --- /dev/null +++ b/tests/Contracts/script/Deploy_Lib.s.sol @@ -0,0 +1,21 @@ +pragma solidity ^0.8.12; + +import "forge-std/Script.sol"; +import "../src/LibUser.sol"; + +contract S is Script { + uint256 x; + uint256 y; + + function run() external { + uint256 anvilDefaultKey = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; + //uint256 ganacheDefaultKey = 0x0cc0c2de7e8c30525b4ca3b9e0b9703fb29569060d403261055481df7014f7fa; + vm.startBroadcast(anvilDefaultKey); + + LibUser libUser = new LibUser(); + for (uint256 i = 0; i < 5; i++) { + libUser.doSomething(); + } + vm.stopBroadcast(); + } +} diff --git a/tests/Contracts/src/Lib.sol b/tests/Contracts/src/Lib.sol new file mode 100644 index 00000000..efdbf3fb --- /dev/null +++ b/tests/Contracts/src/Lib.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +library Lib { + function doSomething(uint a, uint b) external pure returns (uint) { + return a + b; + } +} diff --git a/tests/Contracts/src/LibUser.sol b/tests/Contracts/src/LibUser.sol new file mode 100644 index 00000000..3c5f6ba4 --- /dev/null +++ b/tests/Contracts/src/LibUser.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "../src/Lib.sol"; + +contract LibUser { + function doSomething() external { + Lib.doSomething(1, 2); + } +} \ No newline at end of file diff --git a/tests/expected_dvfs/Lib.dvf.json b/tests/expected_dvfs/Lib.dvf.json new file mode 100644 index 00000000..c41fa165 --- /dev/null +++ b/tests/expected_dvfs/Lib.dvf.json @@ -0,0 +1,27 @@ +{ + "version": "0.9.1", + "id": "0xdb26661b8d95e1e02f9331fc20ac3e28635fa9895083c1366c7918a59963312d", + "contract_name": "Lib", + "address": "0x8627e5da250bd67817177c77ed8432e8528d2bc9", + "chain_id": 31337, + "deployment_block_num": 1, + "init_block_num": 4, + "deployment_tx": "0xc46bb378f0ae75fbf0c0c65d9536df3854c9147ebb0d8adec1cd65355cfe36bc", + "codehash": "0xacdec87e06ce0e6478a315ee1ceccbd69f4b0e9bb3ee92c4ea70b8a757818512", + "insecure": false, + "immutables": [], + "constructor_args": [], + "critical_storage_variables": [], + "critical_events": [], + "unvalidated_metadata": { + "author_name": "Author", + "description": "System Description", + "hardfork": [ + "paris", + "shanghai" + ], + "audit_report": "https://example.org/report.pdf", + "source_url": "https://github.com/source/code", + "security_contact": "security@example.org" + } +} \ No newline at end of file diff --git a/tests/test_end_to_end.rs b/tests/test_end_to_end.rs index ae5a85d8..4e5a196b 100644 --- a/tests/test_end_to_end.rs +++ b/tests/test_end_to_end.rs @@ -786,6 +786,12 @@ mod tests { let mut testcases: Vec = vec![]; + testcases.push(TestCaseE2E { + script: String::from("script/Deploy_Lib.s.sol"), + contract: String::from("Lib"), + expected: String::from("tests/expected_dvfs/Lib.dvf.json"), + }); + testcases.push(TestCaseE2E { script: String::from("script/Deploy_0.s.sol"), contract: String::from("BytesMapping"), @@ -829,9 +835,14 @@ mod tests { contract: String::from("CrazyHiddenStruct"), expected: String::from("tests/expected_dvfs/CrazyHiddenStruct.dvf.json"), }); + for testcase in testcases { let url = format!("http://localhost:{}", port).to_string(); for client_type in LocalClientType::iterator() { + // Don't run this test with Geth as it requires a different setup + if testcase.contract == "Lib" && client_type == LocalClientType::Geth { + continue; + } let local_client = start_local_client(client_type.clone(), port); // forge script script/Deploy_0.s.sol --rpc-url "http://127.0.0.1:8546" --broadcast --slow @@ -861,7 +872,11 @@ mod tests { &config_file.path().to_string_lossy(), "init", "--address", - "0x5fbdb2315678afecb367f032d93f642f64180aa3", + if testcase.contract == "Lib" { + "0x8627e5da250bd67817177c77ed8432e8528d2bc9" + } else { + "0x5fbdb2315678afecb367f032d93f642f64180aa3" + }, "--chainid", &chain_id_str(client_type.clone()), "--project", From 14053a452f9507173831ce2873d52e6dccfeb660 Mon Sep 17 00:00:00 2001 From: Stefan Effenberger Date: Fri, 16 May 2025 12:25:58 +0200 Subject: [PATCH 8/8] forge fmt --- tests/Contracts/src/Lib.sol | 2 +- tests/Contracts/src/LibUser.sol | 2 +- tests/test_end_to_end.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Contracts/src/Lib.sol b/tests/Contracts/src/Lib.sol index efdbf3fb..568c1498 100644 --- a/tests/Contracts/src/Lib.sol +++ b/tests/Contracts/src/Lib.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.13; library Lib { - function doSomething(uint a, uint b) external pure returns (uint) { + function doSomething(uint256 a, uint256 b) external pure returns (uint256) { return a + b; } } diff --git a/tests/Contracts/src/LibUser.sol b/tests/Contracts/src/LibUser.sol index 3c5f6ba4..885fb33a 100644 --- a/tests/Contracts/src/LibUser.sol +++ b/tests/Contracts/src/LibUser.sol @@ -7,4 +7,4 @@ contract LibUser { function doSomething() external { Lib.doSomething(1, 2); } -} \ No newline at end of file +} diff --git a/tests/test_end_to_end.rs b/tests/test_end_to_end.rs index 4e5a196b..974f7d50 100644 --- a/tests/test_end_to_end.rs +++ b/tests/test_end_to_end.rs @@ -791,7 +791,7 @@ mod tests { contract: String::from("Lib"), expected: String::from("tests/expected_dvfs/Lib.dvf.json"), }); - + testcases.push(TestCaseE2E { script: String::from("script/Deploy_0.s.sol"), contract: String::from("BytesMapping"), @@ -835,12 +835,12 @@ mod tests { contract: String::from("CrazyHiddenStruct"), expected: String::from("tests/expected_dvfs/CrazyHiddenStruct.dvf.json"), }); - + for testcase in testcases { let url = format!("http://localhost:{}", port).to_string(); for client_type in LocalClientType::iterator() { // Don't run this test with Geth as it requires a different setup - if testcase.contract == "Lib" && client_type == LocalClientType::Geth { + if testcase.contract == "Lib" && client_type == LocalClientType::Geth { continue; } let local_client = start_local_client(client_type.clone(), port);