-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into nish-vm-error-tracer
- Loading branch information
Showing
10 changed files
with
220 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { | ||
IPaymaster, | ||
ExecutionResult, | ||
PAYMASTER_VALIDATION_SUCCESS_MAGIC | ||
} from "zksync-contracts/zksync-contracts/l2/system-contracts/interfaces/IPaymaster.sol"; | ||
import {IPaymasterFlow} from "zksync-contracts/zksync-contracts/l2/system-contracts/interfaces/IPaymasterFlow.sol"; | ||
import { | ||
TransactionHelper, | ||
Transaction | ||
} from "zksync-contracts/zksync-contracts/l2/system-contracts/libraries/TransactionHelper.sol"; | ||
import "zksync-contracts/zksync-contracts/l2/system-contracts/Constants.sol"; | ||
|
||
contract MyPaymaster is IPaymaster { | ||
modifier onlyBootloader() { | ||
require(msg.sender == BOOTLOADER_FORMAL_ADDRESS, "Only bootloader can call this method"); | ||
_; | ||
} | ||
|
||
constructor() payable {} | ||
|
||
function validateAndPayForPaymasterTransaction(bytes32, bytes32, Transaction calldata _transaction) | ||
external | ||
payable | ||
onlyBootloader | ||
returns (bytes4 magic, bytes memory context) | ||
{ | ||
// Always accept the transaction | ||
magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; | ||
|
||
// Pay for the transaction fee | ||
uint256 requiredETH = _transaction.gasLimit * _transaction.maxFeePerGas; | ||
(bool success,) = payable(BOOTLOADER_FORMAL_ADDRESS).call{value: requiredETH}(""); | ||
require(success, "Failed to transfer tx fee to the bootloader"); | ||
} | ||
|
||
function postTransaction( | ||
bytes calldata _context, | ||
Transaction calldata _transaction, | ||
bytes32, | ||
bytes32, | ||
ExecutionResult _txResult, | ||
uint256 _maxRefundedGas | ||
) external payable override onlyBootloader {} | ||
|
||
receive() external payable {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.13; | ||
|
||
import {Test, console} from "forge-std/Test.sol"; | ||
import "zksync-contracts/zksync-contracts/l2/system-contracts/Constants.sol"; | ||
import {MyPaymaster} from "./MyPaymaster.sol"; | ||
|
||
contract TestPaymasterFlow is Test { | ||
MyPaymaster private paymaster; | ||
DoStuff private do_stuff; | ||
address private alice; | ||
address private bob; | ||
bytes private paymaster_encoded_input; | ||
|
||
function setUp() public { | ||
alice = makeAddr("Alice"); | ||
bob = makeAddr("Bob"); | ||
do_stuff = new DoStuff(); | ||
paymaster = new MyPaymaster(); | ||
|
||
// A small amount is needed for initial tx processing | ||
vm.deal(alice, 1 ether); | ||
vm.deal(address(paymaster), 10 ether); | ||
|
||
// Encode paymaster input | ||
paymaster_encoded_input = abi.encodeWithSelector(bytes4(keccak256("general(bytes)")), bytes("0x")); | ||
} | ||
|
||
function testCallWithPaymaster() public { | ||
vm.deal(address(do_stuff), 1 ether); | ||
require(address(do_stuff).balance == 1 ether, "Balance is not 1 ether"); | ||
|
||
uint256 alice_balance = address(alice).balance; | ||
(bool success,) = address(vm).call( | ||
abi.encodeWithSignature("zkUsePaymaster(address,bytes)", address(paymaster), paymaster_encoded_input) | ||
); | ||
require(success, "zkUsePaymaster call failed"); | ||
|
||
vm.prank(alice, alice); | ||
do_stuff.do_stuff(bob); | ||
|
||
require(address(do_stuff).balance == 0, "Balance is not 0 ether"); | ||
require(address(alice).balance == alice_balance, "Balance is not the same"); | ||
require(address(bob).balance == 1 ether, "Balance is not 1 ether"); | ||
} | ||
|
||
function testCreateWithPaymaster() public { | ||
uint256 alice_balance = address(alice).balance; | ||
(bool success,) = address(vm).call( | ||
abi.encodeWithSignature("zkUsePaymaster(address,bytes)", address(paymaster), paymaster_encoded_input) | ||
); | ||
require(success, "zkUsePaymaster call failed"); | ||
|
||
vm.prank(alice, alice); | ||
DoStuff new_do_stuff = new DoStuff(); | ||
|
||
require(address(alice).balance == alice_balance, "Balance is not the same"); | ||
} | ||
|
||
function testFailPaymasterBalanceDoesNotUpdate() public { | ||
uint256 alice_balance = address(alice).balance; | ||
uint256 paymaster_balance = address(paymaster).balance; | ||
(bool success,) = address(vm).call( | ||
abi.encodeWithSignature("zkUsePaymaster(address,bytes)", address(paymaster), paymaster_encoded_input) | ||
); | ||
require(success, "zkUsePaymaster call failed"); | ||
|
||
vm.prank(alice, alice); | ||
do_stuff.do_stuff(bob); | ||
|
||
require(address(alice).balance == alice_balance, "Balance is not the same"); | ||
require(address(paymaster).balance < paymaster_balance, "Paymaster balance is not less"); | ||
} | ||
} | ||
|
||
contract DoStuff { | ||
function do_stuff(address recipient) public { | ||
uint256 amount = address(this).balance; | ||
(bool success,) = payable(recipient).call{value: amount}(""); | ||
require(success, "Failed to transfer balance to the recipient."); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ mod invariant; | |
mod logs; | ||
mod nft; | ||
mod ownership; | ||
mod paymaster; | ||
mod proxy; | ||
mod repros; | ||
mod traces; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//! Forge tests for zksync contracts. | ||
use foundry_test_utils::util; | ||
|
||
#[tokio::test(flavor = "multi_thread")] | ||
async fn test_zk_contract_paymaster() { | ||
let (prj, mut cmd) = util::setup_forge( | ||
"test_zk_contract_paymaster", | ||
foundry_test_utils::foundry_compilers::PathStyle::Dapptools, | ||
); | ||
util::initialize(prj.root()); | ||
|
||
cmd.args([ | ||
"install", | ||
"OpenZeppelin/openzeppelin-contracts", | ||
"cyfrin/zksync-contracts", | ||
"--no-commit", | ||
"--shallow", | ||
]) | ||
.ensure_execute_success() | ||
.expect("able to install dependencies"); | ||
|
||
cmd.forge_fuse(); | ||
|
||
let config = cmd.config(); | ||
prj.write_config(config); | ||
|
||
prj.add_source("MyPaymaster.sol", include_str!("../../fixtures/zk/MyPaymaster.sol")).unwrap(); | ||
prj.add_source("Paymaster.t.sol", include_str!("../../fixtures/zk/Paymaster.t.sol")).unwrap(); | ||
|
||
cmd.args(["test", "--zk-startup", "--via-ir", "--match-contract", "TestPaymasterFlow"]); | ||
assert!(cmd.stdout_lossy().contains("Suite result: ok")); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters