ERC-4337 Overview

0xMorph
10 min readNov 24, 2023

Self-custodial wallets or EOAs have been only method transactions could be initiated independently, as contracts require an EOA to initiate the transaction. This makes EOAs rigid and risky for users prone to error as it’s a single point of failure for all the user’s assets.

Aside from that, transactions have certain limitations that worsen user experience. A example would be having a new wallet where someone transfers tokens to you on mainnet, but you would have to deposit ETH within to pay any gas fees, increasing another step in the process.

ERC-4337 seeks to solve these issues by introducing account abstraction using the alt-mempool and other features. It’s complexity can be determined through the flexibility it provides the ecosystem like:

  • Programmable transactions
  • Alternative payment methods both on-chain and off-chain
  • Sponsored transactions
  • Alternative signature verification methods

and many more.

When it comes to ERC-4337, some developers might find it confusing and hard to understand due to the amount of features it bring to the ecosystem, along with not requiring a hard fork to implement this ERC. This article aid in understanding how this is done by unpacking how ERC-4337’s transaction flow works and detail the basic commonly called functions in the transaction process. It’s recommended to understand how the a common transaction flow works, a detailed article on this can be found from TinCho’s article “What happens when you send one DAI“ .

For aid in understanding the more technical details, it’s recommended to briefly go through the ERC-4337 draft.

Let’s dive in…

Account Abstraction

Account abstraction allows a user to create non-custodial wallets as programmable smart contracts, which allows a wallet to have arbitrary execution logic.

The concept and introduction of account abstraction has been around multiple times even before ERC-4337, notably EIP-86. However the edge of ERC-4337 is that it introduces account abstraction without requiring consensus-level changes to the Ethereum ecosystem, no hard-fork required. This makes this ERC much more convenient for integration within the existing ecosystem.

Generally the term “Account Abstraction” in context of Web3 would be allowing user’s to use smart contracts as their accounts. But to be specific ERC-4337 does this by introducing several new actors, mainly:

  • User Operations, abi-encoded structure that contains the transaction data
  • Bundlers, nodes that send User Operations on-chain from the alt-mempool to the Entry Point contract
  • Paymasters, contract that can sponsor transactions, allow alternative methods and many more
  • Entry Point, a singleton contract that handles the execution and validation of User Operations

We will go through these actors within this article, along with what specific functions are invoked throughout a typical ERC-4337 transaction.

Smart Accounts

Due to the amount of features added in the ERC, ERC-4337 compatible wallets are introduced. For convenience, we’ll just refer to them as smart accounts.

There are 2 main functions required to be present in smart accounts, those being:

  • validateUserOp function
  • execute function

validateUserOp takes in the UserOp as input and verifies the signature and nonce on it. This function performs most of the verification needed for the wallet to be certain that the transaction is valid.

The execute function interprets calldata for the wallet to perform actions. This calldata would include the target address, function and values needed for the transaction.

Users can create a smart account by simply deploying it on-chain, as authentication can be done through multi-sig, access control limitation or off-chain authentication methods by implementing the respective logic properly. As long as certain functions exists like the mentioned ones above, the wallet will be ERC-4337 compliant.

User Operations

User Operations, or UserOps are an abi-encoded structure containing several fields to contain transaction information and data.

UserOp struct

These field parameters have everything a normal transaction has and some added field, notably the paymasterAndData field and different gas limits like verificationGasLimit and preVerificationGas. It’s not important to understand these for now as the main point is to showcase the differences a UserOp and a normal transaction struct.

UserOps are sent by the user through a smart account to the alt-mempool.

Alt-Mempool

The alt-mempool is, like the public mempool, a waiting room for storing information on unconfirmed transactions. However it’s known to be “higher-level”, as in it’s specifically just for UserOps.

The term “alt-mempool” can be misunderstood as there could be an arbitrary amount of alt-mempools that exist at the same time. An educated assumption is made that UserOps with similar parameters are encouraged to be placed within the same alt-mempool while other UserOps that differ greatly would round up in another alt-mempool.

For any centralization concerns, the alt-mempool is P2P (Peer-to-peer), thus making centralization likely a non-issue here.

Bundlers

Bundlers are nodes that monitor the alt-mempool. Anyone from mev searchers or user could potentially act as a bundler. There are even some centralized entities that provide bundlers part of their service like Blocknative.

The main responsibility for bundlers are bundling UserOps together, forming a bundled transaction. Here’s a simple diagram showcasing the flow from UserOps to the bundlers:

Bundler flow

They control inclusion, exclusion and ordering for the bundled transactions, thus are a likely source of MEV.

Bundlers pay the gas forward for the UserOps, which raises a lot of questions, like:

  • Why are bundlers incentivized to bundle transactions?

The gas is paid back by either the user or the Paymaster, alongside additional funds for further incentivisation.

  • How does bundlers make sure they are being paid back properly, not resulting in their own loss?

The bundlers make several calls to the EntryPoint contract, which without getting into too much detail yet, simulates the transaction to notify the bundler whether they will get compensated properly for the gas spent. But to explain more on this, we have to talk about the EntryPoint contract.

EntryPoint Contract

EntryPoint is a singleton smart contract that is called by the bundler and interacts with the smart accounts. This means that there is only one main EntryPoint contract for each chain and it’s called based on the similar “fee-prioritization” logic used by block builders on mainnet today.

Each smart account must trust and approve this contract in order to perform ERC-4337 transactions with UserOps.

As previously mentioned, this contract is responsible for simulating the transaction for the bundler to be confident to start perform the bundling process. It also verifies the UserOp to be valid through the simulation and after that, executes the UserOp by sending the calldata to the smart account for execution.

Interaction map of the entrypoint contract

In essence, the EntryPoint contract can be simplified into 2 parts, a verification loop and an execution loop.

The verification loop:

  • Simulates each UserOp for the bundler to make sure they won’t result in losses paying the gas forward temporarily.
  • Verfies the UserOp to be valid and following ERC-4337 specifications.

The execution loop:

  • sends calldata in each UserOp to the smart account for execution.

These 2 loops correspond to the same functions within the smart account, as they are invoked by it as well.

Bundler & EntryPoint Contract verification loop

Here we will look in detail on the functions being called for an example ERC-4337 transaction.

Once a UserOp is sent to the alt-mempool and before it isbundled together by a bundler, the bundler runs a series of checks to ensure said UserOp adhere’s by

First we have the bundler call simulateValidation() on EntryPoint.

simulateValidation checks for usage of banned opcodes and makes sure the UserOp does not reference storage outside of account data.

This function always reverts, while giving a ValidationResult error if validation is successful, any other error message will mean that validation failed.

Assuming success, the EntryPoint contract once received the ValidationResult error, calls validateUserOp() on the smart account.

This is where the UserOp’s signature and nonce is checked.

Now with all prechecks validation done, the bundler does a final full simulation of handling the UserOps through simulateHandleOp() on the EntryPoint contract.

This function, like the previous functions, reverts and gives a specific error on success. Bundlers can identify how much they’ll earn from these functions along with verifying the received UserOp to be valid.

Now the bundler would add the UserOp to the dedicated mempool, where it is eligible to be bundled and included within a block.

Execution Loop

Once everything is verified, and the UserOp is ready to be sent to the dedicated mempool, the bundler has to submit a set of UserOperations as calldata to the EntryPoint contract by invoking it’s handleOps() function.

handleOps() executes a batch of UserOperations after the bundler has bundled them together. These UserOps are received as calldata and the beneficiary address would be the bundler’s address, where they would get compensated for their work.

From this function, it calls _executeUserOp , which is an internal function on EntryPoint, which in turn calls the smart account for execution on the designated dAPP.

Paymasters

Paymasters is where most of the logic of the featured benefits of ERC-4337 are written. We mentioned paymasters a few times previously as the potential party to compensate the bundlers for the gas fees instead of the msg.sender. “Potential” being that paymasters is optional in the process, but still brings a lot of features to the table, most notable ones being sponsoring transactions, allowing alternate gas payment methods and abstract payment logic.

Paymasters are first to know when a UserOp is sent, even before bundlers. They access whether to accept a UserOp during the verification stage and implements the required fee logic during execution.

In terms of sponsoring transaction or providing alternate payment methods, a paymaster is required to implement the proper logic and math to exchange the whitelisted token/payment method allowed as payment, and swap that with staked ETH within the paymaster itself.

There is a reputation system that is implemented so that paymasters would adhere by the ERC standards, examples of changes to the reputation system would be too many unsuccessful validations, execution revert etc. Typically there is a cronjob that updates each hour for it to prevent abuse.

Paymaster Example

To aid in a better understanding of paymasters, we can look at a simple example paymaster from Visa to showcase how a user is allowed to pay for gas fees using an ERC-20 token.

In this function within the paymaster, it calculates and sets the logic of how the swap would occur between the user supplied ERC-20 token and then charges the user for the ETH used for the gas fees of the UserOp. After that it transfers the gas fees in ETH to the bundler for compensation.

This oversimplified example is taken from here, where the full logic and calculations are shown. Paymasters are quite versatile as it’s up to the developers on how to implement a proper exchange rate, how users can be sponsored etc while having the reputation system keeping them in check.

Signature Aggregators

Like Paymasters, signature aggregators are also extensions part of ERC-4337. Instead of featuring new payment and fee logic, signature aggregators improve efficiency of the verification process by being able to validate an aggregated signature for multiple transactions.

As per the usual validation process, they ensure submitted UserOps are valid and attempts to prevent malicious transactions from being executed. However what makes them special is that signature aggregators could offer alternate signature validation schemes, most notably BLS signatures.

Signature aggregators manages to save gas to a small degree (as this ERC introduces a higher gas cost in total, thus this reduces it a little) with UserOps being able to be validated at one go instead of one by one, improving scalability within the ecosystem.

Here’s an example on how it’s used in practice within the validation loop that we went through previously:

The rest of the contract can be found here.

Ending Thoughts

In this article we went through a very surface-level technical view of ERC-4337. Due to this ERC bringing in lot’s of new functionality though additional logic like Paymasters and smart wallets, there are still many technical details left out there to discover.

In essence, ERC-4337’s main goal is to improve user experience. Despite the drawbacks of the increased gas fees, it brings alternate methods of payment and off-chain authentication methods that “crypto muggles“ would be more familiarized with.

With an open window of different logic possible for the implementation of ERC-4337, it is safe to assume that there would be plenty of edge cases in the future that we could see.

If you have any questions concerning the topic you may dm me on Twitter.

--

--

0xMorph

Rustacean 🦀 that finds bugs in the Web3 space