A deep dive into the main components of ERC-4337: Account Abstraction Using Alt Mempool — Part 2
Welcome back to our exploration of ERC-4337: Account Abstraction Using Alt Mempool. In our previous post, we analyzed the Bundler, highlighting its role in receiving and executing UserOperations as bundled transactions, introducing the concept of the “Alt Mempool”.
This part will focus on another integral component of ERC-4337: the EntryPoint. For newcomers, we recommend starting with Part 1 for a comprehensive understanding.
The EntryPoint contract is one of the main components of ERC-4337, serving as a trusted singleton by bundlers, wallets, and paymasters, being responsible for validating and handling UserOperations.
One of EntryPoint’s main responsibilities is ensuring that once validation is successful, the operation will be executed, the wallet or the paymaster will be charged, and the Bundler will be reimbursed regardless of the operation’s outcome.
The structure also includes a reputation system that holds paymasters accountable for post-reversion failures, subject to throttling or banning.
Handling User Operations
EntryPoint implements many functionalities defined in the ERC draft. Two main functions,
handleAggregatedOps, are responsible for executing batches of user operations. The first function is used when no signature aggregation is required, while the second is used when a signature aggregator is needed for the operations.
This function handles a batch of user operations and compensates for the
beneficiary account with the collected gas fees.
Inside the first loop, it calls
_validatePrepayment, which validates the account and paymaster (if defined) and makes sure the total validation doesn’t exceed the UserOperation's
verificationGasLimit. This function internally calls
_validateAccountPrepayment, which is responsible for creating the wallet contract through
_createSenderIfNeeded. Interestingly, this allows for ERC-4337 wallets to receive assets at a pre-determined counterfactual address even before they are deployed.
A second verification function is called,
_validateAccountAndPaymasterValidationData, which reverts if either the account or paymaster
validationData is expired.
In the second loop,
_executeUserOp is called for each operation, which calls
this.innerHandleOps , which executes the UserOperation
calldata on the wallet contract.
The post-operation is called just after the
calldata is executed. If a paymaster is defined and its validation returns a non-empty context, its
postOp is called. The excess amount is refunded to the account (or paymaster — if it was used in the request).
handleAggregatedOps function is used to handle a batch of aggregated UserOperations, and compensates the
beneficiary with the collected gas fees.
This function is very similar to
handleOps, with the main difference being that it attempts to validate the signatures using the aggregator’s
validateSignatures function before proceeding with
Managing Deposits and Stakes
In order to guarantee that the
handleAggregatedOps will be reimbursed, the
EntryPoint needs to manage entities' deposits and stakes. For such, it extends from the
Deposits are just a balance used to pay for UserOperations (either by a paymaster or an account), and Stakes are values that are locked for at least
unstakeDelay by a paymaster, which is necessary for the reputation system.
This can be counter-intuitive at first since one of the main ideas of ERC-4337 was to abstract away the requirement of accounts having ether in order to pay for transactions. In fact, all UserOperations must have an ETH deposit on the EntryPoint for them to be executed. The gotcha is that this can either be done through
depositTo on behalf of the counterfactual wallet, or by a paymaster. One can imagine an improved user experience where the user pays for the deposit with fiat in order to have their smart contract wallet deployed, for example.
The initial release v0.4 of ERC-4337 left the nonce to be calculated and checked by the wallet, as it would give the most flexibility to the smart contract account, allowing it to include different nonce schemes. It was encouraged to use a nonce for replay checking, but this was not enforced anywhere. An account could ignore the nonce field, send multiple UserOperations with the same value, and use a different mechanism to protect itself from replay attacks, which would make the
userOpHash a non-unique value.
This could create a side effect for block explorers, as they would no longer have a unique identifier to look for and mark specific operations. It might also confuse applications waiting for a transaction response, which could adversely affect the manner in which applications and wallets operate, as discussed in this GitHub issue.
This also highlights an important aspect of ERC-4337: the EntryPoint is expected to be updated over time. Bundlers are already equipped with this expectation by supporting the
eth_supportedEntryPoints RPC method, which lists the supported EntryPoint versions.
Being a central trust point of all ERC-4337, the
EntryPoint contract needs to be very heavily audited and formally verified. Nevertheless, it is expected that this architecture reduces auditing and formal verification load for the rest of the ecosystem.
The amount of work that individual accounts have to do becomes much smaller, as they only need to verify the
validateUserOp function and its “check signature, increment nonce, and pay fees” logic, and check that other functions are
msg.sender == ENTRY_POINT gated.
Finally, the EntryPoint must also ensure that it only calls an account if
validateUserOp has passed, and that if it calls
validateUserOp and passes, it also must make the generic call with
calldata equal to
op.calldata. This is to ensure safety against arbitrary hijacking and safety against fee draining.
In the second part of our series into ERC-4337: Account Abstraction Using Alt Mempool, we delved deeper into the intricacies of the EntryPoint contract — a cornerstone of the entire system. Serving as the central point for handling UserOperations, the EntryPoint ensures the effective execution of bundled transactions. Additionally, with the ongoing evolution of the EntryPoint, evident from the shift from version v0.4 to v0.6, it now emphasizes a more rigid validation system, while still retaining flexibility for custom account implementations.
Stay tuned for Part 3 of this series where we’ll dive deeper into the remaining components of ERC-4337 and their workflows. If you have any questions regarding secure use of the account abstraction, don’t hesitate to contact us.