Skip to content

Commit

Permalink
Merge pull request #728 from matter-labs/fix-jrigada-simulation-fail-…
Browse files Browse the repository at this point in the history
…zero-balance-with-paymaster

fix: Add Paymaster Params to transact
  • Loading branch information
Jrigada authored Nov 20, 2024
2 parents 0c43026 + 7706b63 commit 420660c
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 19 deletions.
9 changes: 8 additions & 1 deletion crates/evm/core/src/backend/cow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,19 @@ impl<'a> CowBackend<'a> {
env: &mut Env,
persisted_factory_deps: &mut HashMap<foundry_zksync_core::H256, Vec<u8>>,
factory_deps: Option<Vec<Vec<u8>>>,
paymaster_data: Option<foundry_zksync_core::PaymasterParams>,
) -> eyre::Result<ResultAndState> {
// this is a new call to inspect with a new env, so even if we've cloned the backend
// already, we reset the initialized state
self.is_initialized = false;

foundry_zksync_core::vm::transact(Some(persisted_factory_deps), factory_deps, env, self)
foundry_zksync_core::vm::transact(
Some(persisted_factory_deps),
factory_deps,
paymaster_data,
env,
self,
)
}

/// Executes the configured transaction of the `env` without committing state changes
Expand Down
9 changes: 8 additions & 1 deletion crates/evm/core/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,10 +840,17 @@ impl Backend {
env: &mut EnvWithHandlerCfg,
persisted_factory_deps: &mut HashMap<foundry_zksync_core::H256, Vec<u8>>,
factory_deps: Option<Vec<Vec<u8>>>,
paymaster_data: Option<foundry_zksync_core::PaymasterParams>,
) -> eyre::Result<ResultAndState> {
self.initialize(env);

foundry_zksync_core::vm::transact(Some(persisted_factory_deps), factory_deps, env, self)
foundry_zksync_core::vm::transact(
Some(persisted_factory_deps),
factory_deps,
paymaster_data,
env,
self,
)
}

/// Returns true if the address is a precompile
Expand Down
2 changes: 2 additions & 0 deletions crates/evm/evm/src/executors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ impl Executor {
&mut env,
&mut self.zk_persisted_factory_deps.clone(),
Some(zk_tx.factory_deps.clone()),
zk_tx.paymaster_data.clone(),
)?
}
};
Expand All @@ -464,6 +465,7 @@ impl Executor {
// no need to commit them later
&mut self.zk_persisted_factory_deps,
Some(zk_tx.factory_deps),
zk_tx.paymaster_data,
)?
}
};
Expand Down
40 changes: 40 additions & 0 deletions crates/forge/tests/fixtures/zk/Paymaster.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Script, console} from "forge-std/Script.sol";
import {Greeter} from "../src/Greeter.sol";
import {MyPaymaster} from "../src/MyPaymaster.sol";

contract PaymasterScript is Script {
MyPaymaster private paymaster;
bytes private paymaster_encoded_input;
address private alice;

function run() public {
// random private key to get the address of alice with zero balance
alice = vm.rememberKey(0x60d80818010eb4826dc44d7342076a36978544fc89199061f452ea65d67e99e1);
require(address(alice).balance == 0, "Alice balance is not 0");

// We broadcast first to deploy the paymaster and fund it
vm.startBroadcast();
paymaster = new MyPaymaster();
(bool transferSuccess,) = address(paymaster).call{value: 10 ether}("");
require(transferSuccess, "Paymaster funding failed");
vm.stopBroadcast();

// Encode paymaster input
paymaster_encoded_input = abi.encodeWithSelector(bytes4(keccak256("general(bytes)")), bytes("0x"));

// We broadcast the transaction from alice's account to avoid having balance
vm.startBroadcast(alice);

(bool success,) = address(vm).call(
abi.encodeWithSignature("zkUsePaymaster(address,bytes)", address(paymaster), paymaster_encoded_input)
);
require(success, "zkUsePaymaster call failed");

Greeter greeter = new Greeter();

vm.stopBroadcast();
}
}
1 change: 0 additions & 1 deletion crates/forge/tests/it/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,6 @@ pub fn run_zk_script_test(
let mut script_args = vec![
"--zk-startup",
&script_path_contract,
"--broadcast",
"--private-key",
private_key,
"--chain",
Expand Down
2 changes: 1 addition & 1 deletion crates/forge/tests/it/zk/cheats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ forgetest_async!(test_zk_use_factory_dep, |prj, cmd| {
"DeployCounterWithBytecodeHash",
Some("transmissions11/solmate@v7 OpenZeppelin/openzeppelin-contracts cyfrin/zksync-contracts"),
2,
Some(&["-vvvvv", "--via-ir", "--system-mode", "true"]),
Some(&["-vvvvv", "--via-ir", "--system-mode", "true", "--broadcast"]),
);
});

Expand Down
2 changes: 1 addition & 1 deletion crates/forge/tests/it/zk/create2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ forgetest_async!(can_deploy_via_create2, |prj, cmd| {
"Create2Script",
None,
2,
Some(&["-vvvvv"]),
Some(&["-vvvvv", "--broadcast"]),
);
});

Expand Down
4 changes: 2 additions & 2 deletions crates/forge/tests/it/zk/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ forgetest_async!(multiple_deployments_of_the_same_contract, |prj, cmd| {
"DeployScript",
None,
3,
Some(&["-vvvvv"]),
Some(&["-vvvvv", "--broadcast"]),
);
run_zk_script_test(
prj.root(),
Expand All @@ -20,7 +20,7 @@ forgetest_async!(multiple_deployments_of_the_same_contract, |prj, cmd| {
"DeployScript",
None,
3,
Some(&["-vvvvv"]),
Some(&["-vvvvv", "--broadcast"]),
);
});

Expand Down
12 changes: 6 additions & 6 deletions crates/forge/tests/it/zk/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ forgetest_async!(script_zk_can_deploy_in_method, |prj, cmd| {
"ZkClassicFactoryScript",
None,
2,
None,
Some(&["--broadcast"]),
);
run_zk_script_test(
prj.root(),
Expand All @@ -57,7 +57,7 @@ forgetest_async!(script_zk_can_deploy_in_method, |prj, cmd| {
"ZkNestedFactoryScript",
None,
2,
None,
Some(&["--broadcast"]),
);
});

Expand All @@ -70,7 +70,7 @@ forgetest_async!(script_zk_can_deploy_in_constructor, |prj, cmd| {
"ZkConstructorFactoryScript",
None,
1,
None,
Some(&["--broadcast"]),
);
run_zk_script_test(
prj.root(),
Expand All @@ -79,7 +79,7 @@ forgetest_async!(script_zk_can_deploy_in_constructor, |prj, cmd| {
"ZkNestedConstructorFactoryScript",
None,
1,
None,
Some(&["--broadcast"]),
);
});

Expand All @@ -92,7 +92,7 @@ forgetest_async!(script_zk_can_use_predeployed_factory, |prj, cmd| {
"ZkUserFactoryScript",
None,
3,
None,
Some(&["--broadcast"]),
);
run_zk_script_test(
prj.root(),
Expand All @@ -101,7 +101,7 @@ forgetest_async!(script_zk_can_use_predeployed_factory, |prj, cmd| {
"ZkUserConstructorFactoryScript",
None,
2,
None,
Some(&["--broadcast"]),
);
});

Expand Down
2 changes: 1 addition & 1 deletion crates/forge/tests/it/zk/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ forgetest_async!(script_zk_can_deploy_nft, |prj, cmd| {
"MyScript",
Some("transmissions11/solmate@v7 OpenZeppelin/openzeppelin-contracts"),
1,
Some(&["-vvvvv"]),
Some(&["-vvvvv", "--broadcast"]),
);
});

Expand Down
29 changes: 28 additions & 1 deletion crates/forge/tests/it/zk/paymaster.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
//! Forge tests for zksync contracts.

use foundry_test_utils::util::{self, OutputExt};
use foundry_test_utils::{
forgetest_async,
util::{self, OutputExt},
TestProject,
};

use crate::test_helpers::run_zk_script_test;

#[tokio::test(flavor = "multi_thread")]
async fn test_zk_contract_paymaster() {
Expand Down Expand Up @@ -29,3 +35,24 @@ async fn test_zk_contract_paymaster() {
cmd.args(["test", "--zk-startup", "--via-ir", "--match-contract", "TestPaymasterFlow"]);
assert!(cmd.assert_success().get_output().stdout_lossy().contains("Suite result: ok"));
}

forgetest_async!(paymaster_script_test, |prj, cmd| {
setup_deploy_prj(&mut prj);
cmd.forge_fuse();
run_zk_script_test(
prj.root(),
&mut cmd,
"./script/Paymaster.s.sol",
"PaymasterScript",
Some("OpenZeppelin/openzeppelin-contracts cyfrin/zksync-contracts"),
3,
Some(&["-vvvvv", "--via-ir"]),
);
});

fn setup_deploy_prj(prj: &mut TestProject) {
util::initialize(prj.root());
prj.add_script("Paymaster.s.sol", include_str!("../../fixtures/zk/Paymaster.s.sol")).unwrap();
prj.add_source("MyPaymaster.sol", include_str!("../../fixtures/zk/MyPaymaster.sol")).unwrap();
prj.add_source("Greeter.sol", include_str!("../../../../../testdata/zk/Greeter.sol")).unwrap();
}
2 changes: 1 addition & 1 deletion crates/forge/tests/it/zk/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ forgetest_async!(script_zk_can_deploy_proxy, |prj, cmd| {
"ProxyScript",
Some("OpenZeppelin/openzeppelin-contracts"),
4,
None,
Some(&["--broadcast"]),
);
});

Expand Down
2 changes: 1 addition & 1 deletion crates/zksync/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub use zksync_types::{
};
use zksync_types::{utils::storage_key_for_eth_balance, U256};
pub use zksync_utils::bytecode::hash_bytecode;
use zksync_web3_rs::{
pub use zksync_web3_rs::{
eip712::{Eip712Meta, Eip712Transaction, Eip712TransactionRequest, PaymasterParams},
zks_provider::types::Fee,
zks_utils::EIP712_TX_TYPE,
Expand Down
12 changes: 10 additions & 2 deletions crates/zksync/core/src/vm/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::{
pub fn transact<'a, DB>(
persisted_factory_deps: Option<&'a mut HashMap<H256, Vec<u8>>>,
factory_deps: Option<Vec<Vec<u8>>>,
paymaster_data: Option<zksync_web3_rs::eip712::PaymasterParams>,
env: &'a mut Env,
db: &'a mut DB,
) -> eyre::Result<ResultAndState>
Expand All @@ -37,6 +38,13 @@ where
{
info!(calldata = ?env.tx.data, fdeps = factory_deps.as_ref().map(|deps| deps.iter().map(|dep| dep.len()).join(",")).unwrap_or_default(), "zk transact");

let paymaster_params = PaymasterParams {
paymaster: paymaster_data.as_ref().map_or_else(Default::default, |data| data.paymaster),
paymaster_input: paymaster_data
.as_ref()
.map_or_else(Vec::new, |data| data.paymaster_input.to_vec()),
};

let mut ecx = EvmContext::new_with_env(db, Box::new(env.clone()));
let caller = env.tx.caller;
let nonce = ZKVMData::new(&mut ecx).get_tx_nonce(caller);
Expand All @@ -45,7 +53,7 @@ where
TransactTo::Create => (CONTRACT_DEPLOYER_ADDRESS, true),
};

let (gas_limit, max_fee_per_gas) = gas_params(&mut ecx, caller, &PaymasterParams::default());
let (gas_limit, max_fee_per_gas) = gas_params(&mut ecx, caller, &paymaster_params);
debug!(?gas_limit, ?max_fee_per_gas, "tx gas parameters");
let tx = L2Tx::new(
Some(transact_to),
Expand All @@ -60,7 +68,7 @@ where
caller.to_h160(),
env.tx.value.to_u256(),
factory_deps.unwrap_or_default(),
PaymasterParams::default(),
paymaster_params,
);

let call_ctx = CallContext {
Expand Down

0 comments on commit 420660c

Please sign in to comment.