Smashing ERC4337 Wallets For Fun and Profit: The Paymaster

Smashing ERC4337 Wallets For Fun and Profit: The Paymaster

In the previous article, we showed how a userOperation is processed by the EntryPoint contract and ultimately executed to modify the account state.

Such flow uses the funds deposited by the account to the EntryPoint to fund the transaction gas cost. However, there is an extension to that flow that allows users to execute operations without paying for gas at all.

Introducing the paymaster component…

The paymaster covers the transaction cost of a given user. It can either pay through the native token or any ERC20 token as well!

This calls for a slight modification of the flow. It starts with passing an address value for the paymaster field in the userOperation object.

Note that when an address is passed, there is no need for the account itself to have any funds staked to the EntryPoint.This removes further friction from the user experience as well.

The paymaster has the following interface:

First, the EntryPoint calls validateUserOp on the account to make sure the user is allowed to execute the calldata field on the wallet. This is the same flow as if we are not using a paymaster.

Then EntryPoint now calls validatePaymesterUserOp on the paymaster which has one goal:

To make sure the user can use the paymaster’s stake to execute their operation.

Where this function is called is not straightforward to find in the EntryPoint contract, but it is called within _validatePrepayment()

After performing these checks, it returns a context stored in outOpInfo.contextOffset field.

_handleOps() then calls _executeUserOp() while passing outOpInfo.

Note that there is a loop because the EntryPoint executes multiple userOperations at a time.

_executeUserOp then calls innerHandleOp() which finally executes the calldata to modify the account state.

Then, the function _handlePostOp() is called. If the address of the paymaster in the userOp is not the 0 address, the postOp() function is called on the paymaster. This function finally handles the internal paymaster accounting.

What happens inside the Paymaster

Paymaster usually requires certain entities to stake ether or tokens to cover the transaction cost. We can call them sponsors

Sponsors then can whitelist spenders to use their stake. A sponsor can be the account service provider for instance. This is usually the process for paymasters that uses ETH.

For paymaster that uses ERC20 tokens. The process is pretty much the same. Except an oracle is used to get the price for the token used in terms of ETH.

Then, the tokens are removed from the stake of the sponsor. Which means it is implicitly seized by the paymaster.

Note that the paymaster can be developed by a third party other than the service provider. The project developing the wallet does not need to develop its paymaster as well.

It is pretty much like Oracles, you can use UniswapV3 instead of building your own.

In the next article in this series, we will go through a checklist of issues to look for when auditing ERC4337 wallets!

Stay tuned!