Paymasters
Paymasters are specialized accounts designed to subsidize transaction fees for users, enhancing usability and flexibility within protocols. They also facilitate the payment of fees using ERC20 tokens, instead of the default ETH.
Interacting with Paymasters
To utilize a paymaster, users must specify a non-zero paymaster
address in their
EIP712 transaction, accompanied by relevant data in the paymasterInput
field.
Paymaster Verification Rules
- Verification rules are not fully enforced yet.
- Paymasters that do not comply with these rules may cease to function correctly in the future.
To mitigate potential DoS attacks by malicious paymasters, a reputation scoring system similar to EIP4337 is used. Unlike in EIP4337, paymasters in our system can interact with any storage slots and are not throttled under specific conditions, such as time elapsed since the last successful verification or consistent slot access patterns.
Built-in Paymaster Flows
Paymasters can operate automatically or require user interaction, depending on their design. For instance, a paymaster that exchanges ERC20 tokens for ETH would require users to grant a necessary allowance.
The account abstraction protocol by itself is generic and allows both accounts and
paymasters to implement arbitrary interactions. However, the code of default
accounts (EOAs) is constant, but we still want them to be able to participate in
the ecosystem of custom accounts and paymasters. That's why we have standardized
the paymasterInput
field of the transaction to cover the most common uses-cases of the paymaster feature.
Your accounts are free to implement or not implement the support for these flows. However, this is highly encouraged to keep the interface the same for both EOAs and custom accounts.
General Paymaster Flow
This flow is used when the paymaster does not require any preliminary actions from the user:
The paymasterInput
field must be encoded as a call to a function with the following interface:
function general(bytes calldata data);
For EOA accounts, this input is typically non-functional, but paymasters can interpret the data as needed.
Approval-Based Paymaster Flow
This flow is essential when a user must set a token allowance for the paymaster.
The paymasterInput
field must be encoded as a call to a function with the following signature:
function approvalBased(
address _token,
uint256 _minAllowance,
bytes calldata _innerInput
);
The EOA will ensure that the allowance of the _token
towards the paymaster is set
to at least _minAllowance
. The _innerInput
param is an additional payload that
can be sent to the paymaster to implement any logic (e.g. an additional signature or key that can be validated by the paymaster).
If you are developing a paymaster, you should not trust the transaction sender to
behave honestly (e.g. provide the required allowance with the approvalBased
flow). These flows serve mostly as instructions to EOAs and the requirements should always be double-checked by the paymaster.
Testnet paymaster
To ensure users experience paymasters on testnet, as well as keep supporting paying fees in ERC20 tokens, the Matter Labs team provides the testnet paymaster, that enables paying fees in ERC20 token at a 1:1 exchange rate with ETH (i.e. one unit of this token is equal to 1 wei of ETH).
The paymaster supports only the approval based paymaster flow and requires
that the token
param is equal to the token being
swapped and minAllowance
to equal to least tx.maxFeePerGas * tx.gasLimit
.
In addition, the testnet paymaster does not make use of the _innerInput
parameter,
so nothing should be provided (empty bytes
).
Estimating Gas When Interacting with a Paymaster
Interacting with a paymaster generally consumes more gas than a standard transaction due to additional computations and operations. The primary factors contributing to this increased gas usage are:
- Internal Computations: These include the operations within the paymaster's
validateAndPayForPaymasterTransaction
andpostTransaction
. - Funds Transfer: The gas consumed when a paymaster sends funds to the bootloader.
- ERC20 Token Allowance Management: Optionally, if the user compensates the paymaster with an ERC20 token, managing the token's allowance consumes additional gas.
- The gas for internal computations is usually minimal, depending on the specific paymaster's implementation.
- The cost of transferring funds is comparable to what users might pay for similar transactions independently.
- Managing ERC20 allowances can significantly impact gas usage, particularly if
it's the first time the user is setting an allowance. This process might require
publishing a 32-byte storage key identifier, potentially using up to 400k gas at a
50 gwei L1 gas price. Notably, while the transactional flow often zeroes out the
storage slot at execution's end (hence "grant
X
allowance + paymaster spends all allowance"), the initial cost is pre-charged during execution. Only if the slot is zeroed at the end of the transaction will the user be refunded.
Importance of Accurate Gas Estimation
Accurate gas estimation is crucial, especially for operations involving extensive
pubdata, like writing to storage. You should include the necessary paymasterInput
during estimation to ensure the paymaster's involvement is accurately accounted
for.
The code snippet below, from the Custom Paymaster Tutorial,
demonstrates how to perform this estimation:
const gasLimit = await erc20.estimateGas.mint(wallet.address, 5, {
customData: {
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
paymasterParams: paymasterParams,
},
});
Here, paymasterParams
includes both the address of the paymaster and its input.
However, paymasterInput
often contains parameters that are difficult to predict
ahead of time, such as the exact amount of tokens required by the user.
Additionally, paymasters may need to verify pricing data or conversion rates, possibly requiring a server-side signature.
Handling Complex Dependencies
Complex dependencies, such as those involving signatures that depend on transaction content, pose challenges:
- Returning a
magic = 0
fromvalidateAndPayForPaymasterTransaction
can simulate the gas consumption of a valid signature verification. This ensures that, although the transaction would fail on mainnet due tomagic = 0
, the correct gas amount can still be estimated. - Gas estimation is essentially a binary search for the lowest gas amount that prevents transaction failure. If validation consistently fails, so will the gas estimation, as the system will continuously attempt to increase the gas limit.
Strategies for Providing Allowance Estimates
- Rough Estimation: If you have a general idea of the funds involved, use it for the estimation. Minor differences won't typically cause transaction failure due to the buffer already included in our estimates. However, discrepancies can occur if the user's balance changes unexpectedly between estimation and transaction execution.
- Separate Estimation for Allowance Setting: Alternatively, estimate the gas for a transaction where the user sets the allowance separately. Add this estimate to the original transaction's estimated cost. This approach accounts for nonce changes and general validation logic but may introduce significant overhead.
Each method has its pros and cons, and choosing the right approach depends on the specific circumstances of the transaction and the paymaster's requirements.