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..be4c07c2b --- /dev/null +++ b/crates/forge/tests/fixtures/zk/Constructor.s.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.18; + +import {Script} from "forge-std/Script.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(); + } +} + +contract Bank { + event Received(address sender, uint256 amount); + + function balance() public view returns (uint256) { + return address(this).balance; + } + + constructor() payable { + } +} diff --git a/crates/forge/tests/it/zk/constructor.rs b/crates/forge/tests/it/zk/constructor.rs new file mode 100644 index 000000000..35da9005e --- /dev/null +++ b/crates/forge/tests/it/zk/constructor.rs @@ -0,0 +1,35 @@ +//! 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(); +} 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/zk/Constructor.t.sol b/testdata/zk/Constructor.t.sol new file mode 100644 index 000000000..5a49f963d --- /dev/null +++ b/testdata/zk/Constructor.t.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.18; + +import "ds-test/test.sol"; +import "../cheats/Vm.sol"; +import "../default/logs/console.sol"; + +contract Bank { + function balance() public view returns (uint256) { + return address(this).balance; + } + + constructor() payable {} + + receive() external payable {} +} + +contract ZkConstructorTest is DSTest { + Vm constant vm = Vm(HEVM_ADDRESS); + + 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); + } +}