EIPs Explained: EIP-4337

AfterDark Labs
8 min readJul 27, 2023
Connect with us at afterdarklabs.xyz or @afterdark_labs

Background

EIP-4337, also referred to as account abstraction, came from the idea of separating the verification mechanism from the transaction inclusion mechanism on Ethereum. Separating or abstracting these two mechanisms allows for several key improvements in user experience including: sponsoring of gas costs, gas payments in ERC20 tokens, and support for alternative verification mechanisms beyond ECDSA to name a few. Before we go over the use cases, let’s discuss how EIP-4337 came to be.

Ethereum at launch decided there would be two types of accounts:

  1. Externally Owned Accounts (EOAs)
  2. Smart Contract Accounts (contract accounts)
Image from Ethereum developer docs

EOAs can be thought of as common user accounts. They are controlled by private keys and importantly can send messages by creating and signing transactions. These are the type of accounts most wallets use to initiate transactions. If you’ve ever used metamask or coinbase wallet to interact with a dApp, you’ve used an EOA.

In contrast to the EOA, a contract account is reactive in nature. Contract account code can read and write to internal storage and even send other messages but only upon receipt of an initial message. This is an important distinction and we will see why later. For now, remember that EOAs are essentially the only account type that can actually create and send a transaction without first receiving a message.

In addition to this two type account architecture, the creators of the Ethereum Virtual Machine decided not to include logic for transaction verification within the EVM itself. Why did they make this decision? Well, for one there was concern over how to manage gas and compute costs if a transaction proved to be invalid. For example, if a miner were to have to process a transaction before it could determine if it was valid, then this computational overhead could serve as a denial of service vector.

Previous EIPs

The potential benefits of account abstraction were seen very early on in Ethereum’s development. In fact, there are proposals from as early as 2016 suggesting a form of abstraction. The below timeline covers some of the key precursors to EIP-4337:

  • EIP-86 and EIP-208 (2016–2017) — EIP-86 suggested the creation of a forwarding contract. Under EIP86, if the signature of a transaction was v=r=s=0, then the transaction was considered valid and the sending address was set to a specific entry point. Transactions could then start from this entry point and then make a call to a contract account which would hold the logic for sending other messages. Problematically, these EIPs did not preserve transaction hash uniqueness and they also created a denial of service vector where a single transaction could invalidate a whole stack of transactions in the mempool.
  • Informal proposals from 2017 — There were several ideas floating around for implementing account abstraction in 2017, some of which began to resemble EIP-4337 (Panic + PAYGAS). Still, none of these addressed the denial of service vector that could be caused by a single invalid transaction.
  • Informal proposal from 2018 — An idea from 2018 surfaced that mostly solved for the denial service vector by modifying the EVM to check during the verification portion of transaction execution if an account reads or writes the state of things outside of its own account. If it did, then this transaction would be thrown out. This would make it so that the only way a valid transaction in the mempool could become invalid would be if the transaction itself caused that invalid state.
  • EIP-2938 (2020) — EIP-2938 took the previous ideas on account abstraction and bundled them up into a formal EIP. It proposed a new transaction type and entrypoint as described in EIP-86, leveraged the Panic + PAYGAS ideas from 2017, and suggested preventing accounts from reading from or writing to the state of other accounts during the verification portion of transaction execution (as proposed in 2018). While this was really beginning to look like EIP-4337, the key difference here is that EIP-2938 was a protocol layer change. In the end, the decision was made to favor a higher layer implementation of account abstraction.

EIP Summary

The core idea of EIP-4337 was to actually achieve the same outcome as EIP-2938 but to do this without making any base protocol changes to consensus. It achieved this by allowing accounts to package up the actions they wanted to take into a UserOperation struct instead of creating a new type of transaction at the protocol layer. The UserOperation object can then be sent to a dedicated mempool where bundlers can grab them and put them all into a bundled transaction that makes a single call to a global entry point contract. The process is outlined below:

Diagram from official proposal for EIP-4337

What you have here is a system based on a global entry point contract and an open, MEV-like market that arranges multiple operations into a single wrapper transaction, verifies all of those transactions, and then executes them.

Note that the entry point contract is placed on-chain. Wallets must individually choose to trust this entry point contract in order to interact with it on behalf of their users.

Let’s further explore the process step by step:

1. UserOperation Object Creation

Users who wish to leverage EIP-4337 first create a UserOperation object from a regular EOA that will interact with their account contract. This object’s goal is to take the place of a regular transaction and as a result the fields will pertain to the account contract as opposed to the EOA. The UserOperation object and its fields can be seen below:

Note that the sender is set to the contract account which itself will verify the signature in addition to receiving and executing the calldata.

2. Bundling and Execution of UserOperations

UserOperation objects are sent to a dedicated mempool where a set of bundlers are responsible for handling these objects and including them in a single transaction to the entry point contract.

Before a UserOperation is eligible for transaction inclusion, a bundler must first run a set of sanity checks to verify the UserOperation was formed appropriately using valid inputs for its fields. If these checks are passed, then the bundler runs a simulation to determine if the UserOperation is indeed valid and capable of paying for its execution. This is done by making a call to EntryPoint.simulateValidation():

simulateValidation function from the global entry point contract

This in turn calls sender.validateUserOp() as part of the verification. The validateUserOp() function also checks if the signature itself is valid. A base implementation of this function can be seen below:

validateUserOp function from a base account contract

If all of these checks pass, then the function will revert with the expected error, the UserOperation will be considered valid, and the bundler will add it to the dedicated mempool. This UserOperation would now be eligible for bundling and transaction inclusion. This is where the Bundlers work their magic by submitting (as calldata) a set of UserOperations to the EntryPoint.handleOps() function:

handleOps function from the global entry point contract

This will in turn call into the UserOperation.sender with the UserOperation.calldata. It up to the contract account to implement a workflow for handling and reacting to this calldata. Typically, the account will implement an execute() function that parses the calldata as a series of one or more calls for the contract account to make.

Armed with an understanding of the process for creating and including a standard EIP-4337 transaction, let’s discuss some extra functionality that can be included in an EIP-4337 transaction.

Extensions

There are two extensions within EIP-4337 worth mentioning: Paymasters and Signature Aggregation. Paymasters are contract accounts that can pay on behalf of other users. This is used for sponsoring or otherwise offering users gasless transactions. The slightly modified workflow looks like this:

Diagram from official proposal for EIP-4337

Signature aggregators are also helper contract accounts but instead of paying on behalf of other users, they validate an aggregated signature for multiple transactions improving efficiency of the verification process. For example, BLS signatures generated by multiple unique keys can be aggregated into a single signature which can then be verified in a single step. A base implementation of such an aggregator can be found here.

Use Cases

EIP-4337 brings many advantages to users and protocols alike:

  • Gas payments can be sponsored by protocols to give users a gasless experience
  • Gas payments can be made in ERC20 tokens so users no longer need to have or use native ETH directly
  • Alternative verification mechanisms can be supported beyond ECDSA. This is beneficial for future proofing Ethereum if quantum computing renders ECDSA broken
  • User experience is improved for implementing more granular account permissions such as role based account access
  • Multisignature accounts can be first class citizens and may see wider adoption as a result

Broadly speaking, account abstraction is widely viewed as an important stepping stone in Ethereum’s path to massive user adoption.

Security Considerations

Entry Point Contract

The way EIP-4337 is structured, the bulk of the security risk lies in the entry point contract. This serves as a central trust point for every single EIP-4337 compliant account.

Contract Accounts

For smart wallet developers, there are a few things to consider when implementing EIP-4337 accounts. These accounts will have to implement their own verification functions that should accurately check signatures (or equivalent authentication mechanism), increment nonces, and pay fees. Also special care should be taken to ensure that functions on the account follow the principles of least privilege. Adding a modifier that requires the msg.sender to be the entry point contract is a good idea to ensure that sensitive interactions can only be called by the entry point itself.

Closing Thoughts

EIP-4337’s high-level account abstraction implementation offers several advantages for users and protocols. Protocols can offer their users an improved experience by sponsoring transaction fees and users can even take advantage of EIP-4337 to pay directly in ERC-20 tokens. Importantly, EIP-4337 is one of the first steps towards creating quantum computer resistant transactions on Ethereum. While a bulk of the security responsibility lies on the entry point contract, account developers should also be aware that they must implement some of the functionality themselves. We recommend minimizing the threat surface by restricting as much of the sensitive operations as possible to the entry point contract.

If you’re interested in a smart contract audit or other security services, get the process started by visiting afterdarklabs.xyz or reaching out to info@afterdarklabs.xyz directly.

--

--

AfterDark Labs

https://afterdarklabs.xyz. Shining a light on the darkest corners of Web3. We offer collaborative and client-centric blockchain security solutions.