Standard / EIP·EVM
ERC-7779 — Interoperable Delegated Accounts (EIP-7702 Migration)
Draft ERC defining interfaces that let an EIP-7702-delegated EOA migrate between wallet implementations without storage collisions. Adds `accountId()`, `accountStorageBases()`, and the optional `onRedelegation()` hook so the outgoing implementation can clean up before the new one takes over.
- 01EIP-7702 wallet vendors that want users to switch implementations
- 02smart-account SDKs supporting multi-vendor delegation
- 03wallet migration UX (e.g. moving from MetaMask Smart Accounts to Safe 7702 module)
- 04auditing storage layouts across delegated implementations
- 05preventing storage-slot collisions on redelegation
- pnpm add viem
- forge install ethereum/ERCs
Implement the ERC-7779 trio on every EIP-7702 delegate contract you ship: `function accountId() external view returns (string memory)` returning a unique namespace (e.g. `'safe.7702.v1.4.1'`); `function accountStorageBases() external view returns (bytes32[] memory)` returning the ERC-7201 namespaced storage roots the implementation reads/writes; and `function onRedelegation() external returns (bool)` which the new implementation calls (via `delegatecall`) on the outgoing one before authorising a swap, allowing it to wipe owner sets, session keys, or pending nonces. Use ERC-7201 (`keccak256(abi.encode(uint256(keccak256("namespace")) - 1)) & ~bytes32(uint256(0xff))`) for every storage struct — it is mandatory because raw slot 0 layouts WILL collide across implementations on redelegation. Wallet SDKs should call `accountStorageBases()` on both the old and new implementation before signing the SET_CODE auth tuple and refuse the migration if the sets overlap and `onRedelegation` is not implemented.
- ⚑Storage-slot collision is the central hazard: two 7702 implementations both writing to slot 0 will alias each other's owners/nonces after redelegation, leaving the account in an inconsistent or attacker-controlled state. Always namespace via ERC-7201 — every struct, every variable.
- ⚑`onRedelegation()` runs in the OUTGOING implementation's code but in the EOA's storage context — a malicious outgoing implementation can refuse to clean up or even re-write storage. Wallet UIs must warn users when migrating away from an implementation that does not declare ERC-7779 support.
- ⚑ERC-7779 is Draft and depends on EIP-7702 (Pectra) plus ERC-7201; pre-Pectra chains have no delegation primitive, so the standard is inert there. Gate features by chainId.
- ⚑`accountId()` is a string, not a bytes32 hash — case sensitivity and trailing whitespace matter. Pick a canonical lowercase form (`vendor.product.major.minor`) and never change it across an upgrade, or migration tooling will treat the upgrade as a fresh implementation.
- ⚑Redelegation cost: calling `onRedelegation` plus the SET_CODE tx itself is gas-heavy. Batch with the user's first action under the new implementation rather than charging a separate migration tx, and pre-simulate to surface failures (e.g., insufficient cleanup gas) before the user signs.