A deep dive into the main components of ERC-4337: Account Abstraction Using Alt Mempool — Part 4

Antonio Viggiano
Oak Security
Published in
5 min readMar 19, 2024

Welcome back to the fourth and final part of our journey into ERC-4337: Account Abstraction Using Alt Mempool. In this concluding part, we will delve into one of the most configurable pieces of the infrastructure of the ERC: the Paymaster. In this post, we will explain how transactions are funded and how fees are managed. Before diving into Paymaster, let’s recap some key points:

  • Bundler and UserOperations: As discussed in Part 1, The Bundler is the component responsible for listening to UserOperations on an “Alt Mempool,” packaging, and sending them as regular transactions to Ethereum nodes. These bundles encapsulate transaction intentions and verification data, replacing the traditional EOA-based workflow.
  • EntryPoint: This central contract manages UserOperations, ensuring their validity and execution, as seen in Part 2.
  • Smart Accounts: The last mandatory component of ERC-4337, responsible for abstracting away some bottlenecks of traditional EOAs, as seen in Part 3.

The paymaster

Traditionally, users pay for gas directly. Paymasters can change this by covering the transaction costs based on their custom logic, which enables various use cases and better user experience.

Source: ERC-4337: Account Abstraction Using Alt Mempool

Thanks to this flexibility in the specification, innovative models like transaction sponsoring, subscription-based gas payment, or dynamic fees can be implemented. Some samples provided on the Infinitism repository implement paymasters that can charge fees in ERC-20 tokens, while others verify an allowance based on a message signature that an external off-chain service would provide.

The specific features and implementation details of each Paymaster depend on the contract owner, who deploys an instance conforming to the IPaymaster interface.

IPaymaster.sol

Understanding the Paymaster flow

The Paymaster flow can be better explained by its interactions with the other components from ERC-4337:

  • UserOperations: Paymaster details are included within the userOp parameter, allowing the EntryPoint to identify and interact with the correct Paymaster.
  • EntryPoint: The Paymaster interacts with the EntryPoint during various stages of a UserOperation’s lifecycle, providing fee estimations, charging for gas, and potentially executing additional logic.
Source: Intro to Account Abstraction: What are paymasters?

Validation Stage

During the verification loop, if the paymaster parameter is specified on the UserOperation, the validateUserOp function from the EntryPoint confirms the Paymaster contains sufficient deposits in ether for the refund. This value is calculated based on the gas limits specified on the UserOp struct.

It should be noted that the Paymaster must contain at least three times the verificationGasLimit since this value is also used as a limit for the postOp call, which can be called twice: once after the UserOperation was executed, and another one if the Paymaster's own postOp reverted. This is used to inform the Paymaster that their sponsoring failed so that they can act accordingly, while the Entrypoint can still charge for gas costs and send it over to the bundler recipient. This way, the Entrypoint can always be sure that the bundler recipient receives their payment regardless of whether the user operation succeeds.

After that, validatePaymasterUserOp is called on the Paymaster. This is where the Paymaster internal logic checks if it is willing to pay for this user operation. For example, if a service provider is subsidizing fees for a specific set of users, they may validate if the account is on their allowlist. Another example is a permissionless Paymaster that allows users to pay in ERC-20 tokens, which may check the user's balance before the operation is executed, charging tokens and then paying in ether.

Execution Stage

Once the validation is successful, the Paymaster moves to the execution stage, where the actual User Operation occurs. If validatePaymasterUserOp returns a non-empty context, handleOps calls postOp on the paymaster after the operation has been executed, during _handlePostOp.

Post Op

During postOp, the Paymaster should analyze the mode parameter, to understand if the user operation succeeded (opSucceeded), reverted (opReverted), or if it succeeded but caused postOp to revert (postOpReverted).

This last mode can happen, for example, in a scenario where the validatePaymasterUserOp succeeded (meaning, the Paymaster has agreed to pay for the user operation), but when trying to "charge" the user after the user operation happened, they cannot. In this scenario, the EntryPoint still calls the Paymaster after innerHandleOp. Then, during this second execution, the Paymaster can still charge the user. This way, Paymasters can't be "tricked" by user operations who appear to have enough funds but, in reality, don't.

To be more specific, imagine the following scenario, as described during this talk by the Ethereum Foundation:

  1. A Token Paymaster can pay for User Operations if users pay in USDC.
  2. A UserOperation is estimated to cost 10 USDC for that execution, and the account has 15 USDC on its balance. The paymaster withdraws 10 USDC and proceeds with the execution
  3. The User Operation performs a flash loan and imbalances a liquidity pool that the Paymaster relies on to exchange their USDC for Ether. Because of that, although the User Operation succeeded, the Paymaster's postOp will revert.
  4. The EntryPoint calls the Paymaster again and informs it of this postOpReverted mode. The Paymaster can choose to revert the whole bundle, which, in turn, has consequences for the reputation system, as described below.

Reputation and throttling system

Paymasters introduce a new layer of complexity to the network, and security considerations are addressed on the ERC. As it explains:

Maliciously crafted paymasters can DoS the system. To prevent this, we use a reputation system. paymaster must either limit its storage usage, or have a stake. see the reputation, throttling and banning section for details.

Since Paymasters are a global entity, as multiple UserOperations can access them, it can cause problems for the whole network. To prevent this, the throttling system was created.

The EntryPoint holds paymasters accountable for post-reversion failures by emitting FailedOp events and alerting bundlers to execute the throttling or banning algorithm as described on the spec and later in ERC-7562.

Stakes are values locked for at least unstakeDelay by a Paymaster, which bundlers use to block UserOperations with low stake delay or low reputation. This logic can be better understood in Part 1 of this series.

Conclusion

The Paymaster is an optional but extremely important component of Account Abstraction. Its arrival made it possible to create several new features and use cases for applications. Paying for gas with tokens such as USDC, pay-as-you-go services, gasless transactions for specific groups, decentralized gas markets, and many other applications are unlocked.

With this, we conclude our deep dive into ERC-4337: Account Abstraction Using Alt Mempool! We hope this series has provided valuable insights into this exciting new approach to account abstraction on Ethereum.

Remember, the journey of exploration never ends — continue delving deeper into the code, engage with the community, and contribute to the future of this innovative technology. Feel free to reach out if you have any security questions.

--

--

Antonio Viggiano
Oak Security

Helping protocols improve their invariant tests with echidna 🦔, foundry ⚒️, and medusa 🪼