From 1047055abf6174c3c220adfb868ac77403611a9d Mon Sep 17 00:00:00 2001 From: Jrigada Date: Thu, 28 Nov 2024 16:45:38 -0300 Subject: [PATCH 1/6] Add missing injection and clear it afterwards --- crates/cheatcodes/src/inspector.rs | 33 ++++++++++++++++--- .../zk/DeployCounterWithBytecodeHash.s.sol | 2 +- crates/forge/tests/fixtures/zk/Factory.sol | 28 ++++++++++++++-- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index 4d4f937b4..0dca907e4 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -1265,7 +1265,25 @@ impl Cheatcodes { constructor_args.to_vec(), ); - let factory_deps = self.dual_compiled_contracts.fetch_all_factory_deps(contract); + let mut factory_deps = self.dual_compiled_contracts.fetch_all_factory_deps(contract); + let injected_factory_deps = self + .zk_use_factory_deps + .iter() + .flat_map(|contract| { + let artifact_code = crate::fs::get_artifact_code(self, contract, false) + .inspect(|_| info!(contract, "pushing factory dep")) + .unwrap_or_else(|_| { + panic!("failed to get bytecode for factory deps contract {contract}") + }) + .to_vec(); + let res = self.dual_compiled_contracts.find_bytecode(&artifact_code).unwrap(); + self.dual_compiled_contracts.fetch_all_factory_deps(res.contract()) + }) + .collect_vec(); + factory_deps.extend(injected_factory_deps); + + // Note(zk): Clear injected factory deps + self.zk_use_factory_deps.clear(); tracing::debug!(contract = contract.name, "using dual compiled contract"); let zk_persist_nonce_update = self.zk_persist_nonce_update.check(); @@ -1740,13 +1758,15 @@ where { ecx_inner.journaled_state.state().get_mut(&broadcast.new_origin).unwrap(); let zk_tx = if self.use_zk_vm { - let injected_factory_deps = self.zk_use_factory_deps.iter().map(|contract| { - crate::fs::get_artifact_code(self, contract, false) + let injected_factory_deps = self.zk_use_factory_deps.iter().flat_map(|contract| { + let artifact_code = crate::fs::get_artifact_code(self, contract, false) .inspect(|_| info!(contract, "pushing factory dep")) .unwrap_or_else(|_| { panic!("failed to get bytecode for factory deps contract {contract}") }) - .to_vec() + .to_vec(); + let res = self.dual_compiled_contracts.find_bytecode(&artifact_code).unwrap(); + self.dual_compiled_contracts.fetch_all_factory_deps(res.contract()) }).collect_vec(); factory_deps.extend(injected_factory_deps.clone()); @@ -1899,6 +1919,11 @@ where { info!("running call in zkEVM {:#?}", call); let zk_persist_nonce_update = self.zk_persist_nonce_update.check(); + + // Note(zk): Clear injected factory deps here even though it's actually used in broadcast. + // To be consistent with where we clear factory deps in try_create_in_zk. + self.zk_use_factory_deps.clear(); + let ccx = foundry_zksync_core::vm::CheatcodeTracerContext { mocked_calls: self.mocked_calls.clone(), expected_calls: Some(&mut self.expected_calls), diff --git a/crates/forge/tests/fixtures/zk/DeployCounterWithBytecodeHash.s.sol b/crates/forge/tests/fixtures/zk/DeployCounterWithBytecodeHash.s.sol index fa2710b0c..2e11a7cb8 100644 --- a/crates/forge/tests/fixtures/zk/DeployCounterWithBytecodeHash.s.sol +++ b/crates/forge/tests/fixtures/zk/DeployCounterWithBytecodeHash.s.sol @@ -17,7 +17,7 @@ contract DeployCounterWithBytecodeHash is Script { Factory factory = new Factory(counterBytecodeHash); (bool _success,) = address(vm).call(abi.encodeWithSignature("zkUseFactoryDep(string)", "Counter")); require(_success, "Cheatcode failed"); - address counter = factory.deployAccount(salt); + address counter = factory.deployContract(salt, abi.encode()); require(counter != address(0), "Counter deployment failed"); vm.stopBroadcast(); } diff --git a/crates/forge/tests/fixtures/zk/Factory.sol b/crates/forge/tests/fixtures/zk/Factory.sol index 15f2f62e0..e981ed042 100644 --- a/crates/forge/tests/fixtures/zk/Factory.sol +++ b/crates/forge/tests/fixtures/zk/Factory.sol @@ -4,21 +4,21 @@ pragma solidity ^0.8.17; import "zksync-contracts/zksync-contracts/l2/system-contracts/Constants.sol"; import "zksync-contracts/zksync-contracts/l2/system-contracts/libraries/SystemContractsCaller.sol"; -contract Factory { +contract AAFactory { bytes32 public aaBytecodeHash; constructor(bytes32 _aaBytecodeHash) { aaBytecodeHash = _aaBytecodeHash; } - function deployAccount(bytes32 salt) external returns (address accountAddress) { + function deployAccount(bytes32 salt, bytes memory constructorArgs) external returns (address accountAddress) { (bool success, bytes memory returnData) = SystemContractsCaller.systemCallWithReturndata( uint32(gasleft()), address(DEPLOYER_SYSTEM_CONTRACT), uint128(0), abi.encodeCall( DEPLOYER_SYSTEM_CONTRACT.create2Account, - (salt, aaBytecodeHash, abi.encode(), IContractDeployer.AccountAbstractionVersion.Version1) + (salt, aaBytecodeHash, constructorArgs, IContractDeployer.AccountAbstractionVersion.Version1) ) ); require(success, "Deployment failed"); @@ -26,3 +26,25 @@ contract Factory { (accountAddress) = abi.decode(returnData, (address)); } } + +contract Factory { + bytes32 public bytecodeHash; + + constructor(bytes32 _bytecodeHash) { + bytecodeHash = _bytecodeHash; + } + + + function deployContract(bytes32 salt, bytes memory constructorArgs) external returns (address contractAddress) { + (bool success, bytes memory returnData) = SystemContractsCaller.systemCallWithReturndata( + uint32(gasleft()), + address(DEPLOYER_SYSTEM_CONTRACT), + uint128(0), + abi.encodeCall(DEPLOYER_SYSTEM_CONTRACT.create2, (salt, bytecodeHash, constructorArgs)) + ); + + require(success, "Deployment failed"); + + (contractAddress) = abi.decode(returnData, (address)); + } +} From e63800cb59bcf6e6f6b8de4a566aa1014f18274f Mon Sep 17 00:00:00 2001 From: Juan Rigada <62958725+Jrigada@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:20:51 -0300 Subject: [PATCH 2/6] Update crates/cheatcodes/src/inspector.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Federico Rodríguez --- crates/cheatcodes/src/inspector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index 0dca907e4..a45b3700c 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -1273,7 +1273,7 @@ impl Cheatcodes { let artifact_code = crate::fs::get_artifact_code(self, contract, false) .inspect(|_| info!(contract, "pushing factory dep")) .unwrap_or_else(|_| { - panic!("failed to get bytecode for factory deps contract {contract}") + panic!("failed to get bytecode for injected factory deps contract {contract}") }) .to_vec(); let res = self.dual_compiled_contracts.find_bytecode(&artifact_code).unwrap(); From cfd818d9a434bed2bc68f88c366eb31624e758ae Mon Sep 17 00:00:00 2001 From: Juan Rigada <62958725+Jrigada@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:21:07 -0300 Subject: [PATCH 3/6] Update crates/cheatcodes/src/inspector.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Federico Rodríguez --- crates/cheatcodes/src/inspector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index a45b3700c..6ade4fe0a 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -1282,7 +1282,7 @@ impl Cheatcodes { .collect_vec(); factory_deps.extend(injected_factory_deps); - // Note(zk): Clear injected factory deps + // NOTE(zk): Clear injected factory deps self.zk_use_factory_deps.clear(); tracing::debug!(contract = contract.name, "using dual compiled contract"); From d715248510f81abd459b2fccafde85a1cc3c7070 Mon Sep 17 00:00:00 2001 From: Juan Rigada <62958725+Jrigada@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:21:14 -0300 Subject: [PATCH 4/6] Update crates/cheatcodes/src/inspector.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Federico Rodríguez --- crates/cheatcodes/src/inspector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index 6ade4fe0a..50cdab542 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -1920,7 +1920,7 @@ where { info!("running call in zkEVM {:#?}", call); let zk_persist_nonce_update = self.zk_persist_nonce_update.check(); - // Note(zk): Clear injected factory deps here even though it's actually used in broadcast. + // NOTE(zk): Clear injected factory deps here even though it's actually used in broadcast. // To be consistent with where we clear factory deps in try_create_in_zk. self.zk_use_factory_deps.clear(); From 4f0bdf0b1287bcaca6ab8025842164e5f3a263eb Mon Sep 17 00:00:00 2001 From: Juan Rigada <62958725+Jrigada@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:24:21 -0300 Subject: [PATCH 5/6] clarify clear message --- crates/cheatcodes/src/inspector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index 50cdab542..3382a6331 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -1282,7 +1282,7 @@ impl Cheatcodes { .collect_vec(); factory_deps.extend(injected_factory_deps); - // NOTE(zk): Clear injected factory deps + // NOTE(zk): Clear injected factory deps so that they are not sent on further transactions self.zk_use_factory_deps.clear(); tracing::debug!(contract = contract.name, "using dual compiled contract"); From c6aec130afa1c36177adc43a68764128ecb3e89c Mon Sep 17 00:00:00 2001 From: Jrigada Date: Mon, 2 Dec 2024 10:46:53 -0300 Subject: [PATCH 6/6] Cargo fmt --- crates/cheatcodes/src/inspector.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index 3382a6331..8d1b715aa 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -1273,7 +1273,9 @@ impl Cheatcodes { let artifact_code = crate::fs::get_artifact_code(self, contract, false) .inspect(|_| info!(contract, "pushing factory dep")) .unwrap_or_else(|_| { - panic!("failed to get bytecode for injected factory deps contract {contract}") + panic!( + "failed to get bytecode for injected factory deps contract {contract}" + ) }) .to_vec(); let res = self.dual_compiled_contracts.find_bytecode(&artifact_code).unwrap();