ERC 4337: Account Abstraction via Entry Point Contract specification

We’d rather avoid per-wallet reputation. We only have that for paymasters. But this attack does have a cost to the attacker, probably higher than the damage it causes. In order to propagate through the mempool, the op must be valid at the time of propagation. The attacker has to invalidate it after it has been propagated, by deploying a contract. The attacker also has to deploy a large number of wallets in order to fill the mempool, because each wallet can have only one op in the mempool at any given time.

So the attacker has a one-time setup cost of O(concurrent_ops) for setting up the wallets, and then O(iterations) for deploying a new contract on each iteration. And the damage is a single off-chain simulation for each iteration of the attack, since the 2nd simulation never happens due to rule 9.

I agree it would be better to mitigate it entirely, rather than relying on the cost and unprofitability of the attack. But how would you block it without breaking too much functionality? Preventing calls to accounts without code is a good idea and shouldn’t break anything, but doesn’t block the attack due to selfdestruct and recreate.

It’ll be deactivated, but I don’t know about “soon enough”. We did consider having a rule where contracts touched during validation must not have the selfdestruct opcode, but it wasn’t good enough because the contract could delegatecall to an unknown address (specified in the op rather than in the code), and that address could selfdestruct. Preventing delegatecall to unknown addresses seems too harsh.

1 Like

Thanks :slight_smile:

Cautiously optimistic.

How would this EIP in your mind fit into the context of MEV-boost and current builder market dynamics? Could this also potentially be used to implement/augment some form of “re-staking”?

Can the graph in the EIP be simplified to this?

It can, but then you’d miss the fact these are separate calls to separate wallets


Is there any room for adding the transaction types in this proposal? For instance, each transaction will be described as a blob of bytes, where the first byte denotes the type of the transaction. This way it will be easier to keep backward compatibility in case some new types will be added. The question is risen mostly because L2s have different fee model: the price for L1 pubdata is dynamic.

Thus, for instance, zkSync has a separate field ergs_price_per_pubdata.
Arbitrum has similar plans as well.

And the base L1 itself is far from being fully finalized. Thus, new transaction types/execution variables may still be introduced. This way it would make the protocol more future-proof.

1 Like

Hello there!
I’m trying to understand the motivation of the bundler to do his job.
An I correct in assuming the preVerificationGas is always paid entirely so it can be arbitrarily large and used as a tip for the bundler?

The motivation is equivalent for a block builder to include any transactions: gas fees premiums.
The builder pays the “outer transaction” fee (probably to itself, if it is the build), and receives from each UserOp a fee based on userOp.priorityFee (and userOp.maxFeePerGas)
preVerificationGas can be used to tip the bundler a fixed amount, but its original purpose was to cover the gas cost that can’t be computed on-chain - the calldata cost, the fixed overhead (21000) and some EntryPoint contract overhead.

1 Like

The whole idea of the protocol is to check as much as possible from the UserOp in the EntryPoint contract, including the actual gas calculation.
Introducing a byte blobs defeats that purpose.
There is one “placeholder” for external gas calculation per network, namely preVerificationGas. It is assumed to be a function on the data in the UserOp and some network-specific parameters (like the 21000 stipend and the zero/nonzero byte costs)

Thanks you for the answer. It turns out that in order to benefit from the execution of UserOp, the value of UserOpGasPrice must exceed the gas price was used when sending the transaction (except of expenses that can’t be computed on-chain), am I understanding correctly?

Is there any calculations of the potential benefits of bundlers?

Hello friends.

Can you tell me what is my proof of ownership of this or that abstraction account? Isn’t my EOA private key?

I suggest using EIP-2535 Diamonds to implement the smart contract wallet for EIP-4337.

EIP-2535 is a proxy contract standard that can use more than one implementation contract (facet). This makes it relatively easy for uses to add additional contract functionality.

For example you could have a smart contract wallet implemented as an EIP-2535 Diamond that implements all the basic functionality needed and required by ERC-4337. Now if a user wants their smart contract wallet to have additional functionality the user can approve an upgrade on their diamond to add functions from another facet or facets to their diamond that has the functionality they want. Developers can develop different facets with different functionality for smart contract wallets. Users can then pick and choose and approve which facets and functionality they want to add to their smart contract wallet.

The facets of diamonds can be deployed one time and and then reused on-chain. So for example it is possible to create a registry of safe and compatible ERC 4337 account abstraction smart contract wallet facets that are deployed once. Each user can then deploy a diamond that uses a facet that provides the standard/required smart contract wallet functionality. From there each user can then choose what other functionality he or she wants their smart contract wallet to have and add the appropriate facets from the registry to their smart contract wallet diamond. The facets are reused-on chain, not deployed over and over again.

A diamond provides unlimited smart contract functionality at a single Ethereum address. Smart contract wallets can leverage this to provide functionality needed/desired by users without hitting the max contract size limit. EIP-2535 provides other benefits such as tooling, interoperability, multi-contract transparency, gas-efficiency, and code organization, which can be utilized.

What I am describing here is not just theory. Diamonds are being used by more than 70 projects.

A user interface that uses the standard to show deployed diamonds is here:

An introduction to EIP-2535 is here: Introduction to the Diamond Standard, EIP-2535 Diamonds

More resources and information about EIP-2535 are here: Awesome Diamonds.


There is no EOA involved. Your proof of ownership is whatever you set up in the account’s validateUserOp() function. If you implement this function to ecrecover the signature (from UserOp.signature), then it works similarly to an EOA (except that you can rotate the key without changing your address. If you use a different signature scheme, then your proof of ownership is the key of whatever signature scheme you used. If you implement a multisig or any other complex “signature”, then your proof of ownership is whatever the logic requires.

1 Like

Yes. ERC-4337 wallets could greatly benefit from using DiamodStorage and I hope to see wallet developers use it.

The benefit goes beyond just adding functionality via new facets. It also keeps accounts safe when switching them to a new implementation. Wallets are likely to use proxies, and the users may want to switch implementations. For example, a user might start with a simple wallet, and later decide to switch it to a multisig or a wallet with social recovery. There’s a risk that the previous implementation’s storage will break the security of the new implementation by leaving unexpected storage behind. I demonstrated it by leaving shadow signers in Gnosis Safe.

If both implementations were EIP-2535 facets that use DiamondStorage with different base positions, switching between implementations becomes safe.


The main concern I have is that facets used as extensions should use their own storage slot, and if using the common functionality’s slot, that it not modify the slot’s storage structure, even in a way that should be safe. It could play badly with another available facet that makes its own ‘safe’ changes to the structure.

Yes, I agree. As @yoavw said, it makes sense for different facets to use their own Diamond Storage with their own separate slot positions.

I wrote a new post about the ERC-4337 unified mempool: Unified ERC-4337 mempool - HackMD


Was late to the conversation but here is a EIP i like to bring to awareness at this community of EIP-4337 contributors:

EIP-5453 Endorsement which takes a slightly different approach for solving signature / approval functionality than the current version of UserOps but might be interopreable with UserOps. Feedback are greatly appreciated at ERC-5453 Endorsement Standard

1 Like

This 5453 solves a different problem. Namely, approval of specific method calls.
This saves round trips for separate transactions so it close to batching.
But batching is only one feature of 4337 .
With 5453, You must sign with your account, so it “enshrines” eoa accounts.
EIP 4337 is about accounts, and about abstracting them, so that any account can have it’s own execution model, signing model, recovery model, replay mechanism and also different gas model.
In addition, we define the rpc and protocol used by users and nodes to communicate, and make sure UserOperations are as decentralized as normal Ethereum transactions.

1 Like

Yeah, I totally understand that ERC-4337 took a systemic approach that covers a lot of other aspects thank just about signing. That’s why I was asking about feedback for using ERC-5453 in the context of ERC-4337 in one of its aspect: the approval model.