// inside head tag

EIP-7702 Attack Surfaces: What Developers Should Know

Security

April 8, 2025

EIP-7702 Security Risks Developers Shouldn’t Ignore

Ethereum continues to evolve, introducing proposals like EIP 7702, that reshape how accounts work. This proposal opens new possibilities, but also introduces new risks developers must understand before integrating. In this article, we’ll explore what EIP 7702 brings to the table, why it matters, and what security risks developers must watch for when implementing smart accounts.

Introduction

Ethereum distinguishes between two types of accounts:

  • Externally Owned Accounts (EOAs): Managed by private keys and without any on-chain code. These are typical wallets such as Metamask.
  • Smart Contract Accounts: These accounts have code that governs their behavior and can execute complex operations.

EIP 7702 proposes to allow EOAs to have code. This change will bring Ethereum a step closer to Account Abstraction by enabling EOAs to batch operations, implementing native multisig, or alternative signature schemes, but also introduces new security risks if the implementation isn’t carefully designed and audited.

What is EIP-7702?

At its core, EIP 7702 introduces a new transaction type that allows accounts to set and delegate code on themselves. Rather than storing the full contract code directly on the account, a delegation designator, which is a specific prefix followed by an address ((0xef0100 || address)), is stored instead. This pointer indicates where the actual smart contract code resides on-chain.

Put simply, the wallet will point to an on-chain smart contract, and that contract's logic governs how the account behaves.

Key components of this new transaction type include:

  • An authorization list: A list of authorization tuples that bundles together the chain ID, the address of the deployed code (i.e. the Delegate contract), a nonce, and a signature. According to the EIP, it looks like this [chain_id, address, nonce, y_parity, r, s]
  • Delegation mechanism: By “attaching” code to an EOA, the account can perform advanced operations, like batching multiple operations in one transaction or sponsoring gas fees for new users.

This mechanism enables EOAs to behave more like smart accounts instead. However, a significant difference between them is that the EOA's private key retains full control over the account. If the private key of the EOA is compromised, the attacker will have full control over the account.

Comparison with EIP-4337

While EIP‑7702 allows EOAs to delegate their behavior via an on-chain code pointer, EIP‑4337 proposes a more holistic account abstraction model using an off-chain bundler and a dedicated EntryPoint contract.

Both approaches enhance account functionality—EIP‑7702 with a leaner integration and EIP‑4337 with more extensive capabilities. Ultimately, EIP‑7702 can serve specific use cases and may coexist with EIP‑4337, each addressing different aspects of the evolving Ethereum account model.

Security Risks and Vulnerabilities

Implementing EIP 7702 is not as straightforward as it seems. Before moving forward, here are some useful things that readers should know:

  1. Multiple wallets can point to the same delegation designator contract at the same time.
  2. It is possible to redelegate from one delegation designator contract to another.
  3. The owner of the EOA can clear the code by delegating to address(0). This will restore your EOA back to normal.

Now, let’s talk about the risks that developers need to consider before integrating this EIP into their protocol.

1. Access controls

1.1 Lack of access control

If the delegate contract lacks proper access controls, attackers can execute arbitrary logic on behalf of the EOA, such as transferring the tokens out of the wallet.

⚠️ Warning: This contract is purposefully insecure and should not be used in production environments.

//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract VulnerableContract{
    function doSomething(bytes memory _data, address _to, uint _value) public payable {
        (bool success, ) = _to.call{value: _value}(_data);
        require(success);
    }
}

The above contract has a doSomething function without any access controls. This means that anyone is able to call this function and execute transactions on behalf of the EOAs that are delegated to this contract.

Here is another dummy contract:

contract A {
    uint public a;

    function increment(uint256 number) public {
        a += number;
    }
}

If you put these two contracts in Remix and deploy them, you can call the doSomething function of the VulnerableContract with the following params:

_data: 0x7cf5dab0000000000000000000000000000000000000000000000000000000000000000a
_to: {the address of your contract A instance in Remix}
_value: 0

After the above call, you’ll see that the value of the variable a in contract A has been incremented by 10.

2. Initialization challenges

2.1 Constructors

Unlike normal smart contracts, when you delegate code to an account, the constructor of the delegation designator contract does not execute in the context of the EOA. This is a very important point to remember because it can lead to wrong assumptions about how the contract will behave.

Take this contract as an example

//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract Random{
    uint a;

    constructor(uint _someNumber) {
        a = _someNumber;
    }
}

Upon deployment, the deployer is able to set the value of a to an arbitrary number. Let’s say that Alice calls the set code transaction and delegates to the above Random contract. If Alice expects to be able to override the value of a, her assumption is wrong. The delegation transaction doesn’t include initcode,  so the constructor logic will not execute.

If developers want to give users the possibility to set some data upon delegating for the first time, it is worth considering using an initialization pattern, similar to how proxy contracts work.

2.2 Front running and (re)initialization

If the contract uses an initialization pattern, users must make sure that the initialize function has proper access controls and that the contract can not be reinitialized by a malicious user. As a user, you’ll need to delegate and call the initialize function in the same transaction.

If users attempt to delegate in one transaction and then call the initialize function in a second transaction, there is a risk of getting frontran by an attacker that can call the initialize function first and get control of the user’s account.

3. Storage collisions

3.1 Persistent state across redelegations and upgrades

Delegating code does not clear existing storage. Again, this is an important point to remember because when migrating from one delegation designator contract to another, users and developers must account for the old storage data to prevent storage collisions and unexpected behaviors.

Below is an example to illustrate what this would look like:

//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract ContractA{
    bool thisIsABool = true;
}

contract ContractB{
    uint thisIsAUint;
}

Assume that Alice initially delegates to ContractA where the storage variable is a bool and later on she delegates to ContractB where the storage variable is a uint . This will cause a storage collision and the uint in the second contract will be interpreted as a bool, potentially causing undefined behavior or security vulnerabilities.

Conclusion

EIP 7702 represents a significant evolution in Ethereum’s account model. By allowing EOAs to incorporate code, it opens up possibilities for richer functionality such as batch transactions, gas sponsorship, and customizable logic. However, this added flexibility comes at the cost of increasing the attack surface with numerous potential vulnerabilities.

For developers, the key takeaway is clear—implementations must be meticulously designed and thoroughly audited. Any EIP-7702 implementation must be designed with these risks in mind. Thorough audits and strong access controls are essential to ensure safe adoption.

Latest articles