// inside head tag
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.
Ethereum distinguishes between two types of accounts:
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.
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:
[chain_id, address, nonce, y_parity, r, s]
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.
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.
Implementing EIP 7702 is not as straightforward as it seems. Before moving forward, here are some useful things that readers should know:
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.
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.
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.
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.
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.
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.