zkUsePaymaster

Signature

function zkUsePaymaster(address paymaster, bytes calldata input) external pure;

Description

This cheatcode enables the use of a paymaster for the next transaction in the contract. The parameters specify the address of the paymaster and the pre-encoded data to be passed to the paymaster. The paymaster should be deployed before using this cheatcode.

Examples

MyPaymaster paymaster = new MyPaymaster(); // Encode paymaster input bytes memory paymaster_encoded_input = abi.encodeWithSelector( bytes4(keccak256("general(bytes)")), bytes("0x") ); vm.zkUsePaymaster(address(paymaster), paymaster_encoded_input);

The paymaster flow depends on the type of paymaster used. Here’s an example of the simplest usage of a ‘general’ paymaster in Foundry:

  1. Write a custom paymaster:
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 {} }
  1. Deploy the paymaster:

You can deploy the paymaster either in a test or script:

MyPaymaster paymaster = new MyPaymaster();

Or using the forge create command:

forge create ./src/MyPaymaster.sol:MyPaymaster --rpc-url {RPC_URL} --private-key {PRIVATE_KEY} --zksync
  1. Use the cheatcode to set the paymaster for the next transaction:
vm.zkUsePaymaster(address(paymaster), abi.encodeWithSelector( bytes4(keccak256("general(bytes)")), bytes("0x") ));

For more examples, see the Foundry ZkSync Paymaster Tests.

Also, see the ZKsync Paymaster Documentation for more information.