ERC 4337: Account Abstraction via Entry Point Contract specification

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.

As I understand it, the purpose of the approval model is to be able to submit a single transaction which does multiple actions at once, in an atomic transaction.
While it solves the on-chain problem (atomic transaction) it is still a nuisance for the user (which has to manually approve all operations)

This is a “best practice” when using an EOA, which has no other way to approve transactions.

When working with a wallet contract, the solution is different: A wallet contract can have an “executeBatch” , which trigger a sequence operations from the contract to external entities.
The contract owner approve once this batch, and the contract execute it all.

This way, we solve both the on-chain (single-transaction) and off-chain (single approval).

Yes, it comes with a cost (using contract account).
I don’t think that batching by itself is a reason for using wallet contract, but it comes with all other benefits of account-abstraction (authorization, security, gas abstraction etc)

It seems you and I use the term “approval model” to refer to two different things.

What I mean when using “approval model” I mean that

  • Account Alice wants to approve an action, e.g. transfer 1 units of her ERC20 to Account Charlie
  • Account Bob gets Alice’s approval and go ahead to execute the execution on Alice’s behalf.

The modeling of this process is what I refer to as “Approval Model”.

Currently, without ERC-4337 and ERC-5453, user would probably need to do something like

  • Alice: call ERC20.approve(bob, 1);
  • Bob: then call ERC20.transferFrom(alice, charlie, 1);

The alternative is to use ERC-2612

  • Alice: sign an approval with ERC-2612 and send digital signature off-chain to Bob
  • Bob: call ERC2612.permit(alice, bob, 1, tomorrow, v, r, s)
  • Bob: then call ERC20.transferFrom(alice, charlie, 1);

With ERC-5453

  • Alice: sign an approval with ERC-5453 and send digital signature off-chain to Bob
  • Bob: call ERC20.transferFrom(alice, charlie, 1, endorsement); (ERC20 needs to be extended but ERC721 supports this)

The account approving an action can be different from the account executing an action, is what I am trying to discuss this.

Perhaps related to delegatable from @danfinlay, and this thread with Yoav considering 4337 compatibility.

1 Like

Thank you, that seems quite solving the same problem with two different approach, let me take a look.

Yes. it’s in that space. Took slightly different approach. Will chat with Dan and work out a summary of different and see if we can collaborate to get some solution out.


Looking forward to chatting, it does look like you’ve started designing the same thing, I love that! There are surely lots of ways to improve it.

I recently think I made a breakthrough for how Delegatable-4337 could be simply achieved:

I think you could use this branch of Delegatable that adds support for EIP-1271 signatures from contract accounts, and just normalize that all 4337 accounts also implement EIP-1271.

At that point, you get half the benefit: Even 4337 accounts (and contract accounts) can use any Delegatable contract.

Additionally, if the account contract itself also inherits Delegatable, then it could also delegate its own ability to do anything (and so delegate capabilities from contracts that do not themselves inherit from Delegatable).