Original Title: Securing EIP-7702 Upgrades: A Proxy Pattern for Safe EOA-to-Smart Wallet Transitions
Original Author: Amie Corso Original Compilation: Foresight News
EIP-7702 allows simple Ethereum wallets (EOA) to upgrade to smart contract wallets, providing enhanced security, advanced features, gas sponsorship opportunities, and other benefits. Historically, smart wallets had to be built from scratch, but with the introduction of EIP-7702, traditional wallets can upgrade, retaining all their assets and on-chain history while maintaining the same wallet address. It's like switching from a landline to a smartphone without getting a new number.
EOA upgrades by setting a 'delegation designation,' which is a pointer to the delegate smart contract, and then the logic of the delegate smart contract manages the EOA. Thus, the upgraded EOA can have functions, set storage, emit events, and perform all other actions that a smart contract can perform. The EOA can change or delete this delegation at any time through a new, signed EIP-7702 authorization. While this unlocks many new possibilities, this powerful capability also introduces new security challenges that require careful consideration and innovative solutions.
To enable EOA to act as a smart contract wallet, we developed EIP7702Proxy, a lightweight ERC-1967 proxy contract intended to serve as the EIP-7702 delegation for the EOA. In addition to basic logic forwarding executed by the proxy, EIP7702Proxy also includes other features and design choices to address some challenges specific to EIP-7702 delegated accounts. One goal of designing EIP7702Proxy is to maintain equivalence between the 'standard deployment' of Coinbase smart wallets and the EIP-7702 delegated Coinbase smart wallets as much as possible, which means abstracting the additional complexity required by the EIP-7702 mechanism into a dedicated proxy while continuing to rely on the original implementation of CoinbaseSmartWallet. Solutions to this challenge can be effectively applied to any implementation logic, not just the CoinbaseSmartWallet implementation, while also helping the EOA to remain secure in an environment that enables 7702.
Below we will outline specific challenges and corresponding design solutions that enable us to safely adjust any existing smart contract wallet implementation for EIP-7702 upgrades.
Challenge 1: Enforcing Secure Initialization
The first major obstacle to implementing EIP-7702 comes from its initialization constraints. Traditional smart contract wallets (including CoinbaseSmartWallet) typically handle secure initialization (establishing account ownership) atomically during deployment through separate factory contracts. This atomicity means that many such implementations have unprotected initializer functions that can only be called once. However, the design of EIP-7702 does not allow for the execution of initialization calldata during the delegation process (which is analogous to the 'deployment' step), thus preventing atomic completion of this task.
This separation of steps creates a critical vulnerability window. When the implementation contract is 'deployed' to EOA via EIP-7702, it cannot be guaranteed that this 7702 upgrade and initialization wallet's standard EVM transaction will execute atomically. Technically, even if submitted simultaneously, the code setting authorization can be applied independently of the initialization transaction, potentially allowing an attacker to preemptively execute the initialization transaction and declare ownership of the smart account.
Solution: Require EOA Signature to Atomically Set Implementation and Initialize
Please note that the existing Coinbase Smart Wallet is deployed behind an ERC-1967 proxy with UUPSUpgradeable implementation (the actual logic of CoinbaseSmartWallet). The code in the actual account address is a proxy that uses the standard storage location defined by ERC-1967 to store pointers to its implementation logic. Our solution to the initialization vulnerability in the context of 7702 includes recognizing that any implementation logic only becomes active when the proxy establishes a connection with it (hence becoming dangerous). Therefore, if we cannot enforce atomic deployment and initialization, we can enforce atomic implementation setting and initialization.
EIP-7702 Coinbase Smart Wallet Contract Architecture and Logic Delegation Flow
In the context of EIP-7702, the EOA itself is the initial authority for making any changes to its account and must provide a signature to authorize the initialization and establishment of any new smart account. Our EIP7702Proxy contract implements a setImplementation function that can atomically set the new logical implementation and initialize the account. setImplementation function:
Verifying signatures from EOA, which include critical data such as the address of the new implementation contract, initialization calldata, the address of the validator contract that will assess the security of the final account state, and basic signature replay protections such as nonce and expiration time.
Set the value of the ERC-1967 pointer to the new implementation and execute the provided calldata against the new logic implementation. Call the validateAccountState function, which must be implemented by the validator included in the signature. The validator is a contract specific to the implementation that contains logic to evaluate whether it considers the final account state to be safe. For example, for CoinbaseSmartWallet, the CoinbaseSmartWalletValidator will check that the ownership status of the account is non-empty, thus making it less susceptible to arbitrary initialization.
Challenge 2: Shared Storage Across EIP-7702 Delegations
The most complex challenge of EIP-7702 may relate to storage management. EOAs can freely re-delegate their logic to different contracts at any time or completely remove delegations. All delegates share the same storage space at the EOA address. Over time, multiple contracts sharing access to the same storage may lead to 'storage conflict' issues. Storage conflicts occur when two contracts make different changes or assumptions about the same storage location, potentially leading to unpredictable errors.
Managing storage conflicts has already been a familiar issue in the realm of proxy design, where mutable implementation logic is used to manage shared storage. Even if upgradeable proxies can change implementations, the proxy code itself (for non-7702 addresses) cannot be changed. This brings determinism and guarantees to the upgrade process. The re-delegation of 7702 introduces another layer of complete variability regarding the potential logic that can manage this shared storage. This essentially eliminates any guarantees regarding the impact arbitrary delegation may have on storage. For example, if EOA delegates from Delegate A to B and back to A, the returned delegate cannot make assumptions about its storage state, as Delegate B may have erased or altered it to a state that cannot be achieved solely through Delegate A's logic. This holds true for any 7702 delegation, regardless of the delegation pattern, as previous delegates may have stored or deleted anything in any storage location.
Example of Invalid State of Delegate A Caused by A → B → A Delegation Pattern
Solution: Externalization of Security-Critical Storage Values
EOA delegation can arbitrarily affect account state. If EOA delegates to a malicious or destructive contract, any current delegate cannot prevent this situation. Similar to signing draining transactions, authorizing a malicious 7702 delegate can have catastrophic consequences, and preventing these outcomes is beyond the scope of our design. Our EXIP7702Proxy is designed to be self-defensive against foreseeable problems in a multi-wallet, 7702-enabled ecosystem with well-meaning but potentially chaotic participants. It cannot protect the EOA from authorizing truly malicious or erroneous delegates.
A foreseeable issue involves the signatures of the setImplementation call and the risks brought by mutable account states. EIP7702Proxy relies on EOA signatures to set implementation logic and initialize to a secure state. If these signatures can be replayed, they may become burdensome. For example, if a signature authorized an initial owner who was later compromised and deleted, replayed signatures could recreate the compromised owner or force a downgrade of the implementation.
Common protections against signature replay involve using nonce in the signature information and marking it as used after validation. Risks for 7702 accounts: other delegates may compromise this nonce tracking storage. If the storage tracking nonce usage is deleted, the EOA's setImplementation signature (publicly available in the mempool) can be reapplied when delegating back to EIP7702Proxy.
To ensure that signatures are non-replayable, we have implemented a separate NonceTracker singleton that maintains nonce state at an immutable contract location outside of account storage. Only EOA can affect its nonce (only in an increasing manner), preventing other delegates from manipulating these security-critical values. Regardless of changes to account storage, the NonceTracker ensures that each setImplementation signature only works once.
Challenge 3: Increased Risk of Shared Traditional Storage Locations
Standard storage slots defined by ERC-1967 are particularly vulnerable to potential storage conflicts because they are common locations that multiple delegates may use. The ERC-1967 implementation slot is the only standard storage location used in EIP7702Proxy, which stores the address of the logical implementation pointed to by the proxy. Our design ensures that regardless of the value of this storage location (which determines most of the logic available in the account), EIP7702Proxy can always successfully set its implementation logic to the contract expected by the EOA.
To clarify the issue being addressed, note that when an account transitions between different delegates (A→B→A) where both delegates implement the ERC-1967 proxy pattern, Delegate B will naturally use the same storage slot that Delegate A uses to store its implementation address. During its term, Delegate B may modify or overwrite this slot, either intentionally or as a normal part of its own proxy operations. In the UUPSUpgradeable proxy pattern, the logic for upgrading the implementation is defined on the implementation contract itself. If the implementation placed by Delegate B at this pointer location does not contain the expected upgradeToAndCall interface on the implementation, then the mechanism to change its implementation may not exist in the currently available logic when returning to Delegate A.
Example of New Delegate Overwriting Shared Traditional Storage Location
Solution: Upgrade Mechanism Available on EIP7702Proxy
Our EIP7702Proxy addresses this issue through its setImplementation function, which provides an upgrade mechanism independent of the implementation directly on the proxy itself. This ensures that even if an intermediate delegate points the ERC-1967 implementation to an invalid implementation (or completely removes it), the original EOA retains the ability to reconfigure the ERC-1967 pointer to point to their chosen logical implementation after delegating back to EIP7702Proxy.
Challenge 4: Backward Compatibility with Standard EOA Behavior
One design goal of EIP7702Proxy is to maintain backward compatibility with account EOA functionality in addition to new smart contract features. The existence or absence of code at an address affects the execution flow of protocols interacting with that address, as they distinguish between EOA and smart contracts based on this characteristic. This necessitates consideration of two main behaviors: signature verification and token reception behavior.
Signature Verification
The signature verification standard for smart contracts differs from that of standard EOA. Smart contracts implement the isValidSignature interface defined by ERC-1271 and can freely define arbitrary logic to determine whether the contract considers the signature valid. For standard EOA, signatures are verified through the standard ecrecover check, which ensures that the signer recovers to the expected EOA address.
To ensure that existing or future EOA signatures continue to be recognized on the EOA after the 7702 upgrade, EIP7702Proxy implements a version of isValidSignature that first delegates signature verification to the isValidSignature function that should be defined on the logic implementation, but if verification fails, it performs a final ecrecover check. If this check passes, the signature is considered valid. In this way, EOA using EIP7702Proxy can ensure that regardless of its smart contract wallet's isValidSignature implementation, simple EOA signatures will always be recognized at its address.
Token Reception
Some token standards (particularly ERC-1155 and ERC-721) attempt to prevent token cards from being in smart contracts that may not be able to manage them. These tokens require any smart contract receiving such tokens to declare this capability by implementing a standard token receiver interface, which is called by the token contract during the token transfer. It is equally important that the logic on the upgraded EOA includes standard receive functions or payable fallbacks to be able to receive native tokens. Accounts should not be in a state where they cannot receive ETH or other tokens, even for a short period.
Due to the absence of an initial implementation in our proxy, we included an immutable DefaultReceiver implementation as the preset logic for EIP7702Proxy in the absence of the ERC-1967 pointer. This receiver implements the receive function and the receiver Hooks of these common token standards, ensuring that accounts can accept token transfers before explicitly setting a new implementation.
Conclusion
The design of EIP7702Proxy allows us to stay closely aligned with standard deployments of CoinbaseSmartWallets while continuing to utilize the existing CoinbaseSmartWallet implementation, all while addressing the unique security challenges that arise in the context of EIP-7702. By carefully considering the implications of initialization security, storage temporality, and interference, the need for uninterrupted token handling, and backward compatibility with standard EOA signature verification, we have established a proxy for securely delegating and managing EIP-7702 smart contract wallets. While the design of EIP7702Proxy considers the CoinbaseSmartWallet V1 implementation, this proxy is ultimately independent of the implementation. We encourage developers to evaluate this solution to provide 7702 protection for other smart contract wallet implementations.
Original Link