Skip to content

Commit

Permalink
Merge branch 'main' into main-with-foundry-commits
Browse files Browse the repository at this point in the history
  • Loading branch information
Romsters authored Aug 15, 2024
2 parents 73765d8 + 5c7b918 commit aae932a
Show file tree
Hide file tree
Showing 14 changed files with 425 additions and 45 deletions.
8 changes: 5 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 2 additions & 7 deletions crates/forge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ opener = "0.7"
soldeer.workspace = true

# zk
zksync-web3-rs = { workspace = true }
zksync_types = { workspace = true }
zksync-web3-rs.workspace = true
zksync_types.workspace = true

[target.'cfg(unix)'.dependencies]
tikv-jemallocator = { workspace = true, optional = true }
Expand All @@ -124,11 +124,6 @@ tikv-jemallocator = { workspace = true, optional = true }
anvil.workspace = true
foundry-test-utils.workspace = true

# zk
era_test_node.workspace = true
jsonrpc-core = { git = "https://github.com/matter-labs/jsonrpc.git", branch = "master" }
jsonrpc-http-server = { git = "https://github.com/matter-labs/jsonrpc.git", branch = "master" }

mockall = "0.12"
criterion = "0.5"
paste = "1.0"
Expand Down
2 changes: 0 additions & 2 deletions crates/forge/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,4 @@ mod svm;
mod test_cmd;
mod verify;

mod zksync_node;

mod ext_integration;
4 changes: 2 additions & 2 deletions crates/forge/tests/cli/script.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Contains various tests related to `forge script`.
use crate::{constants::TEMPLATE_CONTRACT, zksync_node};
use crate::constants::TEMPLATE_CONTRACT;
use alloy_primitives::{hex, Address, Bytes};
use anvil::{spawn, NodeConfig};
use foundry_test_utils::{rpc, util::OutputExt, ScriptOutcome, ScriptTester};
Expand Down Expand Up @@ -1472,7 +1472,7 @@ forgetest_async!(test_zk_can_execute_script_with_arguments, |prj, cmd| {
factory_deps: Vec<Vec<u8>>,
}

let node = zksync_node::ZkSyncNode::start();
let node = foundry_test_utils::ZkSyncNode::start();

cmd.args(["init", "--force"]).arg(prj.root());
cmd.assert_non_empty_stdout();
Expand Down
67 changes: 67 additions & 0 deletions crates/forge/tests/fixtures/zk/Factory.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import "forge-std/Script.sol";
import "../src/Factory.sol";

contract ZkClassicFactoryScript is Script {
function run() external {
vm.startBroadcast();
MyClassicFactory factory = new MyClassicFactory();
factory.create(42);

vm.stopBroadcast();
assert(factory.getNumber() == 42);
}
}

contract ZkConstructorFactoryScript is Script {
function run() external {
vm.startBroadcast();
MyConstructorFactory factory = new MyConstructorFactory(42);

vm.stopBroadcast();
assert(factory.getNumber() == 42);
}
}

contract ZkNestedFactoryScript is Script{
function run() external {
vm.startBroadcast();
MyNestedFactory factory = new MyNestedFactory();
factory.create(42);

vm.stopBroadcast();
assert(factory.getNumber() == 42);
}
}

contract ZkNestedConstructorFactoryScript is Script{
function run() external {
vm.startBroadcast();
MyNestedConstructorFactory factory = new MyNestedConstructorFactory(42);

vm.stopBroadcast();
assert(factory.getNumber() == 42);
}
}

contract ZkUserFactoryScript is Script {
function run() external {
vm.startBroadcast();
MyClassicFactory factory = new MyClassicFactory();
MyUserFactory user = new MyUserFactory();
user.create(address(factory), 42);

vm.stopBroadcast();
assert(user.getNumber(address(factory)) == 42);
}
}

contract ZkUserConstructorFactoryScript is Script{
function run() external {
vm.startBroadcast();
MyConstructorFactory factory = new MyConstructorFactory(42);
MyUserFactory user = new MyUserFactory();

vm.stopBroadcast();
assert(user.getNumber(address(factory)) == 42);
}
}
102 changes: 102 additions & 0 deletions crates/forge/tests/it/zk/factory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//! Forge tests for zksync factory contracts.
use forge::revm::primitives::SpecId;
use foundry_test_utils::{forgetest_async, util, Filter, TestCommand, TestProject, ZkSyncNode};

use crate::{config::TestConfig, test_helpers::TEST_DATA_DEFAULT};

#[tokio::test(flavor = "multi_thread")]
async fn test_zk_can_deploy_in_method() {
let runner = TEST_DATA_DEFAULT.runner_zksync();
{
let filter = Filter::new("testClassicFactory|testNestedFactory", "ZkFactoryTest", ".*");
TestConfig::with_filter(runner, filter).evm_spec(SpecId::SHANGHAI).run().await;
}
}

#[tokio::test(flavor = "multi_thread")]
async fn test_zk_can_deploy_in_constructor() {
let runner = TEST_DATA_DEFAULT.runner_zksync();
{
let filter = Filter::new(
"testConstructorFactory|testNestedConstructorFactory",
"ZkFactoryTest",
".*",
);
TestConfig::with_filter(runner, filter).evm_spec(SpecId::SHANGHAI).run().await;
}
}

#[tokio::test(flavor = "multi_thread")]
async fn test_zk_can_use_predeployed_factory() {
let runner = TEST_DATA_DEFAULT.runner_zksync();
{
let filter = Filter::new("testUser.*", "ZkFactoryTest", ".*");
TestConfig::with_filter(runner, filter).evm_spec(SpecId::SHANGHAI).run().await;
}
}

forgetest_async!(script_zk_can_deploy_in_method, |prj, cmd| {
setup_factory_prj(&mut prj);
run_factory_script_test(prj.root(), &mut cmd, "ZkClassicFactoryScript", 2);
run_factory_script_test(prj.root(), &mut cmd, "ZkNestedFactoryScript", 2);
});

forgetest_async!(script_zk_can_deploy_in_constructor, |prj, cmd| {
setup_factory_prj(&mut prj);
run_factory_script_test(prj.root(), &mut cmd, "ZkConstructorFactoryScript", 1);
run_factory_script_test(prj.root(), &mut cmd, "ZkNestedConstructorFactoryScript", 1);
});

forgetest_async!(script_zk_can_use_predeployed_factory, |prj, cmd| {
setup_factory_prj(&mut prj);
run_factory_script_test(prj.root(), &mut cmd, "ZkUserFactoryScript", 3);
run_factory_script_test(prj.root(), &mut cmd, "ZkUserConstructorFactoryScript", 2);
});

fn setup_factory_prj(prj: &mut TestProject) {
util::initialize(prj.root());
prj.add_source("Factory.sol", include_str!("../../../../../testdata/zk/Factory.sol")).unwrap();
prj.add_script("Factory.s.sol", include_str!("../../fixtures/zk/Factory.s.sol")).unwrap();
}

fn run_factory_script_test(
root: impl AsRef<std::path::Path>,
cmd: &mut TestCommand,
name: &str,
expected_broadcastable_txs: usize,
) {
let node = ZkSyncNode::start();

cmd.arg("script").args([
"--zk-startup",
&format!("./script/Factory.s.sol:{name}"),
"--broadcast",
"--private-key",
"0x3d3cbc973389cb26f657686445bcc75662b415b656078503592ac8c1abb8810e",
"--chain",
"260",
"--gas-estimate-multiplier",
"310",
"--rpc-url",
node.url().as_str(),
"--slow",
"--evm-version",
"shanghai",
]);

assert!(cmd.stdout_lossy().contains("ONCHAIN EXECUTION COMPLETE & SUCCESSFUL"));

let run_latest = foundry_common::fs::json_files(root.as_ref().join("broadcast").as_path())
.find(|file| file.ends_with("run-latest.json"))
.expect("No broadcast artifacts");

let content = foundry_common::fs::read_to_string(run_latest).unwrap();

let json: serde_json::Value = serde_json::from_str(&content).unwrap();
assert_eq!(
json["transactions"].as_array().expect("broadcastable txs").len(),
expected_broadcastable_txs
);
cmd.forge_fuse();
}
2 changes: 2 additions & 0 deletions crates/forge/tests/it/zk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
mod basic;
mod cheats;
mod contracts;
mod factory;
mod fuzz;
mod invariant;
mod logs;
mod ownership;
mod repros;
20 changes: 20 additions & 0 deletions crates/forge/tests/it/zk/ownership.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Forge tests for testing ownership in zksync.
use crate::{config::*, test_helpers::TEST_DATA_DEFAULT};
use forge::revm::primitives::SpecId;
use foundry_test_utils::Filter;

#[tokio::test(flavor = "multi_thread")]
async fn test_zk_ownership() {
let runner = TEST_DATA_DEFAULT.runner_zksync();
let filter = Filter::new("testZkOwnership", "ZkOwnershipTest", ".*");

TestConfig::with_filter(runner, filter).evm_spec(SpecId::SHANGHAI).run().await;
}

#[tokio::test(flavor = "multi_thread")]
async fn test_zk_ownership_delegate_call() {
let runner = TEST_DATA_DEFAULT.runner_zksync();
let filter = Filter::new("testZkOwnershipDelegateCall", "ZkOwnershipTest", ".*");

TestConfig::with_filter(runner, filter).evm_spec(SpecId::SHANGHAI).run().await;
}
7 changes: 7 additions & 0 deletions crates/test-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ tracing-subscriber = { workspace = true, features = ["env-filter"] }
walkdir.workspace = true
rand.workspace = true
snapbox = { version = "0.6.9", features = ["json"] }
tokio.workspace = true

# zk
zksync_types.workspace = true
era_test_node.workspace = true
jsonrpc-core = { git = "https://github.com/matter-labs/jsonrpc.git", branch = "master" }
jsonrpc-http-server = { git = "https://github.com/matter-labs/jsonrpc.git", branch = "master" }

[features]
# feature for integration tests that test external projects
Expand Down
4 changes: 4 additions & 0 deletions crates/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ pub use util::{TestCommand, TestProject};
mod script;
pub use script::{ScriptOutcome, ScriptTester};

// TODO: remove once anvil supports zksync node
mod zksync;
pub use zksync::ZkSyncNode;

// re-exports for convenience
pub use foundry_compilers;

Expand Down
Loading

0 comments on commit aae932a

Please sign in to comment.