From 77198c605dfb771f526dd74927750d27d5de33f4 Mon Sep 17 00:00:00 2001 From: Juan Rigada <62958725+Jrigada@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:04:15 -0300 Subject: [PATCH 1/2] fix: Display name of zksync verifier (#758) Fix display name of zksync verifier --- crates/verify/src/provider.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/verify/src/provider.rs b/crates/verify/src/provider.rs index 0e6afe53f..69c85f9ee 100644 --- a/crates/verify/src/provider.rs +++ b/crates/verify/src/provider.rs @@ -166,7 +166,7 @@ pub enum VerificationProviderType { Sourcify, Blockscout, Oklink, - #[value(alias = "zksync")] + #[clap(name = "zksync")] ZKsync, } From 15b47588df3a9a2d6934927189e387277e43e3b2 Mon Sep 17 00:00:00 2001 From: Juan Rigada <62958725+Jrigada@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:09:14 -0300 Subject: [PATCH 2/2] test: Test constructor function with and without values (#749) * Add test for constructor * Create bank contract to reuse and remove extra event * Forge fmt --- .../forge/tests/fixtures/zk/Constructor.s.sol | 25 +++ crates/forge/tests/it/zk/constructor.rs | 36 ++++ crates/forge/tests/it/zk/mod.rs | 1 + testdata/cheats/Vm.sol | 201 +++++++++++++++--- testdata/zk/Bank.sol | 12 ++ testdata/zk/Constructor.t.sol | 19 ++ 6 files changed, 269 insertions(+), 25 deletions(-) create mode 100644 crates/forge/tests/fixtures/zk/Constructor.s.sol create mode 100644 crates/forge/tests/it/zk/constructor.rs create mode 100644 testdata/zk/Bank.sol create mode 100644 testdata/zk/Constructor.t.sol diff --git a/crates/forge/tests/fixtures/zk/Constructor.s.sol b/crates/forge/tests/fixtures/zk/Constructor.s.sol new file mode 100644 index 000000000..fbc669850 --- /dev/null +++ b/crates/forge/tests/fixtures/zk/Constructor.s.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.18; + +import {Script} from "forge-std/Script.sol"; +import {Bank} from "../src/Bank.sol"; + +contract ConstructorScript is Script { + function run() external { + vm.startBroadcast(); + + // Test constructor without value + Bank bankNoValue = new Bank(); + assert(bankNoValue.balance() == 0); + + // Test constructor with 1 ether + Bank bankWithEther = new Bank{value: 1 ether}(); + assert(bankWithEther.balance() == 1 ether); + + // Test constructor with smaller value + Bank bankSmallValue = new Bank{value: 0.1 ether}(); + assert(bankSmallValue.balance() == 0.1 ether); + + vm.stopBroadcast(); + } +} \ No newline at end of file diff --git a/crates/forge/tests/it/zk/constructor.rs b/crates/forge/tests/it/zk/constructor.rs new file mode 100644 index 000000000..508e6f8bf --- /dev/null +++ b/crates/forge/tests/it/zk/constructor.rs @@ -0,0 +1,36 @@ +//! Forge tests for constructor functionality with and without value. + +use crate::{config::*, test_helpers::TEST_DATA_DEFAULT}; +use foundry_test_utils::{forgetest_async, util, TestProject}; + +use crate::test_helpers::run_zk_script_test; +use forge::revm::primitives::SpecId; +use foundry_test_utils::Filter; + +#[tokio::test(flavor = "multi_thread")] +async fn test_zk_constructor_works() { + let runner = TEST_DATA_DEFAULT.runner_zksync(); + let filter = Filter::new("testZkConstructor", "ZkConstructorTest", ".*"); + + TestConfig::with_filter(runner, filter).evm_spec(SpecId::SHANGHAI).run().await; +} + +forgetest_async!(test_zk_constructor_works_in_script, |prj, cmd| { + setup_deploy_prj(&mut prj); + run_zk_script_test( + prj.root(), + &mut cmd, + "./script/Constructor.s.sol", + "ConstructorScript", + None, + 3, + Some(&["-vvvvv", "--broadcast"]), + ); +}); + +fn setup_deploy_prj(prj: &mut TestProject) { + util::initialize(prj.root()); + prj.add_script("Constructor.s.sol", include_str!("../../fixtures/zk/Constructor.s.sol")) + .unwrap(); + prj.add_source("Bank.sol", include_str!("../../../../../testdata/zk/Bank.sol")).unwrap(); +} diff --git a/crates/forge/tests/it/zk/mod.rs b/crates/forge/tests/it/zk/mod.rs index c25efef4c..0a0500422 100644 --- a/crates/forge/tests/it/zk/mod.rs +++ b/crates/forge/tests/it/zk/mod.rs @@ -1,6 +1,7 @@ //! Forge tests for zkysnc functionality. mod basic; mod cheats; +mod constructor; mod contracts; mod create; mod create2; diff --git a/testdata/cheats/Vm.sol b/testdata/cheats/Vm.sol index 2f6ba7dac..c8e4ec346 100644 --- a/testdata/cheats/Vm.sol +++ b/testdata/cheats/Vm.sol @@ -6,23 +6,152 @@ pragma solidity >=0.6.2 <0.9.0; pragma experimental ABIEncoderV2; interface Vm { - enum CallerMode { None, Broadcast, RecurrentBroadcast, Prank, RecurrentPrank } - enum AccountAccessKind { Call, DelegateCall, CallCode, StaticCall, Create, SelfDestruct, Resume, Balance, Extcodesize, Extcodehash, Extcodecopy } - enum ForgeContext { TestGroup, Test, Coverage, Snapshot, ScriptGroup, ScriptDryRun, ScriptBroadcast, ScriptResume, Unknown } - enum BroadcastTxType { Call, Create, Create2 } - struct Log { bytes32[] topics; bytes data; address emitter; } - struct Rpc { string key; string url; } - struct EthGetLogs { address emitter; bytes32[] topics; bytes data; bytes32 blockHash; uint64 blockNumber; bytes32 transactionHash; uint64 transactionIndex; uint256 logIndex; bool removed; } - struct DirEntry { string errorMessage; string path; uint64 depth; bool isDir; bool isSymlink; } - struct FsMetadata { bool isDir; bool isSymlink; uint256 length; bool readOnly; uint256 modified; uint256 accessed; uint256 created; } - struct Wallet { address addr; uint256 publicKeyX; uint256 publicKeyY; uint256 privateKey; } - struct FfiResult { int32 exitCode; bytes stdout; bytes stderr; } - struct ChainInfo { uint256 forkId; uint256 chainId; } - struct AccountAccess { ChainInfo chainInfo; AccountAccessKind kind; address account; address accessor; bool initialized; uint256 oldBalance; uint256 newBalance; bytes deployedCode; uint256 value; bytes data; bool reverted; StorageAccess[] storageAccesses; uint64 depth; } - struct StorageAccess { address account; bytes32 slot; bool isWrite; bytes32 previousValue; bytes32 newValue; bool reverted; } - struct Gas { uint64 gasLimit; uint64 gasTotalUsed; uint64 gasMemoryUsed; int64 gasRefunded; uint64 gasRemaining; } - struct DebugStep { uint256[] stack; bytes memoryInput; uint8 opcode; uint64 depth; bool isOutOfGas; address contractAddr; } - struct BroadcastTxSummary { bytes32 txHash; BroadcastTxType txType; address contractAddress; uint64 blockNumber; bool success; } + enum CallerMode { + None, + Broadcast, + RecurrentBroadcast, + Prank, + RecurrentPrank + } + enum AccountAccessKind { + Call, + DelegateCall, + CallCode, + StaticCall, + Create, + SelfDestruct, + Resume, + Balance, + Extcodesize, + Extcodehash, + Extcodecopy + } + enum ForgeContext { + TestGroup, + Test, + Coverage, + Snapshot, + ScriptGroup, + ScriptDryRun, + ScriptBroadcast, + ScriptResume, + Unknown + } + enum BroadcastTxType { + Call, + Create, + Create2 + } + + struct Log { + bytes32[] topics; + bytes data; + address emitter; + } + + struct Rpc { + string key; + string url; + } + + struct EthGetLogs { + address emitter; + bytes32[] topics; + bytes data; + bytes32 blockHash; + uint64 blockNumber; + bytes32 transactionHash; + uint64 transactionIndex; + uint256 logIndex; + bool removed; + } + + struct DirEntry { + string errorMessage; + string path; + uint64 depth; + bool isDir; + bool isSymlink; + } + + struct FsMetadata { + bool isDir; + bool isSymlink; + uint256 length; + bool readOnly; + uint256 modified; + uint256 accessed; + uint256 created; + } + + struct Wallet { + address addr; + uint256 publicKeyX; + uint256 publicKeyY; + uint256 privateKey; + } + + struct FfiResult { + int32 exitCode; + bytes stdout; + bytes stderr; + } + + struct ChainInfo { + uint256 forkId; + uint256 chainId; + } + + struct AccountAccess { + ChainInfo chainInfo; + AccountAccessKind kind; + address account; + address accessor; + bool initialized; + uint256 oldBalance; + uint256 newBalance; + bytes deployedCode; + uint256 value; + bytes data; + bool reverted; + StorageAccess[] storageAccesses; + uint64 depth; + } + + struct StorageAccess { + address account; + bytes32 slot; + bool isWrite; + bytes32 previousValue; + bytes32 newValue; + bool reverted; + } + + struct Gas { + uint64 gasLimit; + uint64 gasTotalUsed; + uint64 gasMemoryUsed; + int64 gasRefunded; + uint64 gasRemaining; + } + + struct DebugStep { + uint256[] stack; + bytes memoryInput; + uint8 opcode; + uint64 depth; + bool isOutOfGas; + address contractAddr; + } + + struct BroadcastTxSummary { + bytes32 txHash; + BroadcastTxType txType; + address contractAddress; + uint64 blockNumber; + bool success; + } + function _expectCheatcodeRevert() external; function _expectCheatcodeRevert(bytes4 revertData) external; function _expectCheatcodeRevert(bytes calldata revertData) external; @@ -338,14 +467,20 @@ interface Vm { function getBlobhashes() external view returns (bytes32[] memory hashes); function getBlockNumber() external view returns (uint256 height); function getBlockTimestamp() external view returns (uint256 timestamp); - function getBroadcast(string memory contractName, uint64 chainId, BroadcastTxType txType) external returns (BroadcastTxSummary memory); - function getBroadcasts(string memory contractName, uint64 chainId, BroadcastTxType txType) external returns (BroadcastTxSummary[] memory); + function getBroadcast(string memory contractName, uint64 chainId, BroadcastTxType txType) + external + returns (BroadcastTxSummary memory); + function getBroadcasts(string memory contractName, uint64 chainId, BroadcastTxType txType) + external + returns (BroadcastTxSummary[] memory); function getBroadcasts(string memory contractName, uint64 chainId) external returns (BroadcastTxSummary[] memory); function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); function getDeployment(string memory contractName) external returns (address deployedAddress); function getDeployment(string memory contractName, uint64 chainId) external returns (address deployedAddress); - function getDeployments(string memory contractName, uint64 chainId) external returns (address[] memory deployedAddresses); + function getDeployments(string memory contractName, uint64 chainId) + external + returns (address[] memory deployedAddresses); function getFoundryVersion() external view returns (string memory version); function getLabel(address account) external view returns (string memory currentLabel); function getMappingKeyAndParentOf(address target, bytes32 elementSlot) @@ -440,9 +575,18 @@ interface Vm { function parseTomlKeys(string calldata toml, string calldata key) external pure returns (string[] memory keys); function parseTomlString(string calldata toml, string calldata key) external pure returns (string memory); function parseTomlStringArray(string calldata toml, string calldata key) external pure returns (string[] memory); - function parseTomlTypeArray(string calldata toml, string calldata key, string calldata typeDescription) external pure returns (bytes memory); - function parseTomlType(string calldata toml, string calldata typeDescription) external pure returns (bytes memory); - function parseTomlType(string calldata toml, string calldata key, string calldata typeDescription) external pure returns (bytes memory); + function parseTomlTypeArray(string calldata toml, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + function parseTomlType(string calldata toml, string calldata typeDescription) + external + pure + returns (bytes memory); + function parseTomlType(string calldata toml, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); function parseTomlUint(string calldata toml, string calldata key) external pure returns (uint256); function parseTomlUintArray(string calldata toml, string calldata key) external pure returns (uint256[] memory); function parseToml(string calldata toml) external pure returns (bytes memory abiEncodedData); @@ -485,8 +629,15 @@ interface Vm { function record() external; function recordLogs() external; function rememberKey(uint256 privateKey) external returns (address keyAddr); - function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count) external returns (address[] memory keyAddrs); - function rememberKeys(string calldata mnemonic, string calldata derivationPath, string calldata language, uint32 count) external returns (address[] memory keyAddrs); + function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count) + external + returns (address[] memory keyAddrs); + function rememberKeys( + string calldata mnemonic, + string calldata derivationPath, + string calldata language, + uint32 count + ) external returns (address[] memory keyAddrs); function removeDir(string calldata path, bool recursive) external; function removeFile(string calldata path) external; function replace(string calldata input, string calldata from, string calldata to) diff --git a/testdata/zk/Bank.sol b/testdata/zk/Bank.sol new file mode 100644 index 000000000..e59183469 --- /dev/null +++ b/testdata/zk/Bank.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.18; + +contract Bank { + function balance() public view returns (uint256) { + return address(this).balance; + } + + constructor() payable {} + + receive() external payable {} +} diff --git a/testdata/zk/Constructor.t.sol b/testdata/zk/Constructor.t.sol new file mode 100644 index 000000000..c42dd2b05 --- /dev/null +++ b/testdata/zk/Constructor.t.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.18; + +import "ds-test/test.sol"; +import "../cheats/Vm.sol"; +import "../default/logs/console.sol"; +import "./Bank.sol"; + +contract ZkConstructorTest is DSTest { + function testZkConstructorWorksWithValue() public { + Bank bank = new Bank{value: 1 ether}(); + assertEq(bank.balance(), 1 ether); + } + + function testZkConstructorWorksWithoutValue() public { + Bank bank = new Bank(); + assertEq(bank.balance(), 0); + } +}