EIP-7702: Set EOA account code

Why is the authorization a no-op when the nonce is incorrect?

See the spec:

If any of the above steps fail, immediately stop processing that tuple and continue to the next tuple in the list.

See also geth implementation here.

I asked why. What is the rationale?

I believe it’s so taking an authorization from transaction A in the mempool and “frontrunning it” with a separate EIP-7702 transaction B doesn’t cause the entire tx A to fail.

1 Like

The EOA can still frontrun it, and with different code than the sender was expecting. This griefing vector is going to prevent several “paymaster” designs from working securely. Too bad invalid-nonce’ing the entire transaction is a DoS vector agains the mempool.

I believe this was actually considered and was the motivation for ethereum/EIPs#9248.

The relayer/paymaster is able to assert that the delegation is the one that’s expected.

1 Like

I am a developer working on EIP-7702 smart account implementation. Our prototype is tested and launched on testnet.

Our goal is to allow users to upgrade their EOA account to try out the smart contract functionalities. But I realize currently there is not a good way to help users upgrade their existing EOA wallet to EIP-7702.

What do you feel about a RPC standard for the EIP-7702 sign_authorization? Basically the app developer and propose the wallet to sign the hash keccak(MAGIC || rlp([chain_id, address, nonce]).

I found an existing proposal on Github: eth_signAuthorization.md · GitHub

App developers shouldn’t request user’s to sign specific authorizations. Dapps aren’t trusted like a wallet is. There is basically no way for a user to receive such a request and sign it confidently. There are so many hidden ways this could blow up for the user. Only the user’s wallet should directly have the user sign authorizations.

2 Likes

It is indeed pretty hard to verify a proposed EIP-7702 contract, but there are still several ways to achieve this.

  1. Maintaining a list a verified and audited 7702 contracts. Because each contract only needs to be deployed once, it is possible to maintain a limit list of 7702 contracts and just share them across wallets/dapps. This is similar to the EntryPoint contract in ERC-4337 standard.
  2. Allowing wallet owner to determine which 7702 contract they want to use. Based on the non-custodial principle, wallet apps don’t really have the right to block users’ request if the user wants to delegate to a 7702 contract.

EIP-7702 has the potential to extend all EOA wallets to be a unified interface. Besides initiating transaction from the wallet itself, EIP-7702 will allow other users to proactively interact with the EOA wallet like interacting with a smart contract. For example, an EOA wallet can delegate to an OTC-style smart contract and allow others to swap tokens with it at a fixed rate.

To make it possible for wide adoption, such interface and 7702 contract must be simple and extensible. I have a proposal to turn all EOA wallets into an intent-centric interface, which is stateless, non-custodial, and modular:

Reading EIP-7702’s Transaction propagation section:

Another alternative would be to expand the EIP-7702 transaction with a list of accounts the caller wishes to “hydrate” during the transaction.

This is not currently part of EIP-7702, so a mass invalidation where a single tx sweeps multiple cod-delegated accounts is currently possible?

Hi all, in the process of integrating EIP-7702 into our products, one of the pain points is the inability to efficiently determine the results of both the transaction and the delegation, without going through multiple RPC calls.

We propose a change to the current getTransactionReceipt, to add a list of authorization statuses, so that we are able to determine both results in 1 RPC call.

The hackmd link below shows an expanded discussion, and the corresponding PR to ethereum/execution-apis repository.

Isn’t this already possible with eth_getProof? As soon as the nonce is increased and the codeHash is not empty anymore you know that the code delegation was successful. This should work at least for self-sponsored transactions.

In general I think devs should make sure that 7702 txs cannot fail. If not, you end up in this weird situation where the tx has failed, but the delegation is persisted anyways. Which requires to add at least one special case to your business logic.

GM

EIP-7702’s ability to let EOAs temporarily act as contracts unlocks novel use cases. However, its inverse effect—granting contracts EOA-like transaction signing—is a paradigm shift requiring scrutiny.

While EOAs gaining smart contract-like behavior is transformative, the reverse—smart contracts wielding EOA-like signing authority—carries profound risks. Imagine widely-adopted, high-value contracts (e.g., WETH, vaults, cross-chain bridges) “autonomously initiating” (signing) transactions—what safeguards exist?.


Core Risks:

  1. Accountability Blur: Contracts wielding EOA-like signing keys could lack clear governance, revocation pathways, or ownership transparency.
  2. Risk Amplification: Contract initiated transactions could magnify systemic risks.

Proposed Safeguard: Sandboxed Delegation

  • Mechanism:
    • Restrict delegated EOAs to ONLY sign transactions that modify/revoke their delegation .

      • Preserve EIP-3607 safeguards—preventing delegated EOAs (contracts) from autonomously initiating transactions.
      • While delegated, the EOA can only modify or revoke delegation.
      • To regain initiating ability, the EOA must first revoke delegation, ensuring clear separation.
    • Pros: Adds friction to misuse while retaining flexibility.

    • Trade-offs: Uncharted territory—UX friction, Pandora’s box.


“With great power comes great responsibility” — a mantra worth embedding into EIP-7702’s adoption.

An issue here is that we will still be unable to determine the result of the execution of calldata, since reverted transactions will still consume the nonce.

Although eth_getProof does indicate the success of code delegation, it is tied to chain state at a particular block height, and not towards the transaction itself. As such, we will still need to utilise methods like eth_getTransactionReceipt to detect confirmation, then pull the proofs.

I think its unrealistic to ensure 7702 transactions cannot fail. The attached calldata can be reliant on on-chain state, which does not revert during simulation but fails on-chain.

If the suggestion is to avoid using calldata during 7702 transactions, this would contradict the intent and direction of the EIP itself — which explicitly allows for combining code authorization and execution in one transaction.

Tagging this PR before the “Last Call” deadline triggers and it goes final

This migrates the parameter named MAGIC to SET_CODE_TX_MAGIC, aligning with SET_CODE_TX_TYPE and the EELS reference code. No semantics change.

I noticed that eip-7702 transactions cannot have blobs. I suspect that should be justified in the EIP Rationale.

1 Like

The delegations cannot cause a tx to revert, nor does a tx revert cause the delegations to revert. So there is no need to send 7702 txs without calldata.

This isn’t to say that determining if a delegation was successful is fool proof, because since delegations don’t cause tx reverts, their inclusion in a block isn’t a testament to their validity. That needs to be determined separately or the RPC can return the outcome.

I think doing so at the RPC is reasonable. Clients can compute the result of the delegations on the fly fairly cheaply so it seems fair to lump into some of the other computations we already do.

1 Like

Can someone suggest a reliable route for calling an EIP-7702 account once deployed? I deployed a custom EIP-7702 wallet several days ago, but have been unable to find a way to call it successfully.

Here’s the EIP-7702 transaction on Sepolia: 0xa2cef1760b5b9222e5b9b6453f446054fceb12ff12e0e8dc1f4c9d5671bd2a41

Here’s the “minimal” EIP-7702 wallet address: 0x4fed4cb93b2d7b2773b22a4897febe1e6cc6e0d9#code

Note that it has some helper functions to allow for easier manual testing.

I have tried sending transactions from a custom go-ethereum v1.15.7 program directly to a publicnode[.]com RPC endpoint, but it does not work. eth_getCode returns no code at the address (whereas I would have expected the EIP-7702 “pointer” code there), and calling smart contract functions through the address also does not work.

Any ideas/suggestions?

For Contract as per I understand,

  • The contract code only exists during the processing of the transaction.
  • eth_getCode after the transaction returns 0x because there’s no persistent contract code stored at the address.
  • Think of it like an ephemeral proxy for one transaction.
1 Like

Thanks for the explanation.

So any time you want to execute an EIP-7702 transaction, you:

  • Pass the EIP-7702 transaction information (authorization to perform the action, contract to delegate to)
  • In the “regular” part of the transaction, do whatever it is you were going to do

Does this make sense?

1 Like