EIP-7702 Account Delegation: Attack Surfaces in Ephemeral Contract Wallets

During an incident triage on a drained Ethereum address, an engineer queried the account using cast code. Standard Externally Owned Accounts (EOAs) return empty bytecode: 0x. Smart contract wallets return their full compiled runtime code. In this incident, the RPC node returned a 23-byte response starting with 0xef0100 followed by a twenty-byte hex sequence. The owner had never deployed a contract, yet the address executed arbitrary bytecode instructions whenever a caller triggered it.

The account had fallen victim to an unauthorized EIP-7702 delegation. Account abstraction has historically required moving balances to dedicated smart contracts like ERC-4337 wallets. EIP-7702 changes this boundary by allowing standard private keys to adopt smart contract code on demand. When abused through phishing or blind signature prompts, this mechanism transforms a standard private key into a persistent proxy under an attacker’s control.

The mechanics of ephemeral code delegation

Ethereum Improvement Proposal 7702 introduces a dedicated transaction envelope: Type 4 (identified by the 0x04 prefix). Inside this transaction, the sender attaches an authorization_list containing signed delegation tuples. Each entry specifies four parameters: the target chain ID, the address of an existing smart contract implementation, a replay-protection nonce, and the account owner’s ECDSA signature.

When the execution client processes the authorization, it writes a delegation designator into the world state for that account:

0xef0100 || target_contract_address

The initial two bytes (0xef01) represent a reserved EVM prefix chosen because existing contracts cannot start with 0xef under EIP-3541 rules. The third byte (0x00) marks the designation format version, and the remaining twenty bytes contain the address of the target smart contract. Subsequent calls to the EOA follow standard delegation rules: the EVM loads bytecode from the target address but executes it within the context, balance, and storage namespace of the EOA.

Storage traps and persistent authorization hazards

Early community discussions frequently described EIP-7702 as ephemeral, implying that delegation code disappears as soon as the transaction finishes. This assumption is incorrect. The delegation designator remains in the world state until another authorization overwrites it. If an attacker convinces a user to sign an authorization tuple pointing to a malicious implementation, that account stays compromised indefinitely.

This persistence changes how wallet drainers operate. Attackers no longer need per-token allowances like approve(max) or setApprovalForAll. A single signed authorization payload grants an external contract complete execution rights over the account state.

EIP-7702 converts any private key into an active smart contract wallet, which means a single malicious signature can bind persistent external execution logic directly to an account.

Once bound, the malicious contract can inspect caller addresses, drain incoming deposits immediately, or alter internal storage slots. If the implementation uses storage layout slots that clash with standard wallet implementations, recovery modules become uncallable.

Verification and immediate revocation steps

Auditing an account for active delegations requires checking its on-chain runtime code. You can verify this directly from the command line using Foundry’s cast utility:

# Query bytecode for the target account
cast code 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --rpc-url https://eth.llamarpc.com

# Standard EOA response:
# 0x

# Delegated EIP-7702 account response (23 bytes):
# 0xef0100a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48

If the account returns a 0xef0100 prefix, an active delegation exists. To revoke the delegation and restore the account to a clean EOA, the account owner must author a new Type 4 authorization targeting the zero address:

# Revocation authorization structure
revocation_payload = {
    "chain_id": 1,
    "address": "0x0000000000000000000000000000000000000000",
    "nonce": current_account_nonce,
}

Submitting this payload in a Type 4 transaction instructs the execution client to clear the delegation designator, resetting the account bytecode to empty. If an off-chain signature was leaked but has not yet been broadcast by an attacker, the user can invalidate the signature immediately by sending any standard transaction, such as a zero-value self-transfer, that increments the account nonce past the signed value.

Operational defensive controls

Wallet providers and security monitoring services must adapt their telemetry to recognize EIP-7702 structures:

  • Refuse off-chain signatures where chain_id is set to zero, preventing cross-chain signature replays.
  • Display the human-readable implementation address and verify contract bytecode before presenting an authorization prompt to users.
  • Include cast code or eth_getCode checks in automated account health monitors to detect silent delegation bindings.

Signing an EIP-7702 tuple is not an ordinary message verification. It is an instruction to execute arbitrary smart contract logic under the account’s identity. Security teams must treat authorization requests with the same scrutiny as deploying unverified bytecode to production.

Press Cmd K to search برای جستجوی سایت از Cmd+K استفاده کنید