[KongchangAI]
· 2 min read· 1,470 words

The EIP-7702 Wallet Trap: Looks Normal in the Browser, But the Code Is Stealing Funds

The EIP-7702 Wallet Trap: Looks Normal in the Browser, But the Code Is Stealing Funds

EIP-7702 lets EOAs delegate code, enabling draining contracts that fool browser checks with a clean history.

After EIP-7702 shipped with Pectra, EOAs can set delegation code while keeping the same address and private key, but calls execute the delegate contract's logic. Attackers use this to turn an ordinary-looking EOA into a puppet that forwards incoming funds in the same block, with no revocable authorization and no explorer warning. Six Authorization tuples all recovered to the same signer and delegate, showing a planned setup. The article outlines three read-only checks: eth_getCode for delegation indicators, delegate contract code for forwarding behavior, and Authorization tuples verified with ecrecover.

An address looks unremarkable on a blockchain explorer: an EOA, a short transaction history, no risk flags. You might not hesitate to send it a small test transfer.

But that test transfer never really arrived — or rather, it arrived and left in the same block. The incoming funds were automatically forwarded to another address. There is no transaction from the wallet owner, no authorization you can revoke. This wallet has been "delegated."

EIP-7702 wallet security analysis

What EIP-7702 Changes

EIP-7702 (shipped with the Pectra upgrade) allows an EOA to set code for itself. The owner signs an "authorization tuple," and the account's code becomes a delegation indicator: 0xef0100 || <delegate address>. The account is still an EOA — same address, same private key — but every subsequent call executes the code at the delegate address.

For wallets, this is powerful: batched transactions, sponsored gas, social recovery. But for attackers, it is a gift: one signed authorization turns the account into a puppet on strings, while on most interfaces it still looks like an ordinary EOA.

Where the Attack Surface Lies

The core issue is information asymmetry. Blockchain explorers typically show an address's transaction history, balance, and token holdings, but they do not proactively highlight the critical fact that "this address's code has been delegated to another contract." Users see a clean history, but not the forwarding logic running behind it.

EOA (Externally Owned Account) is the type of account on Ethereum controlled directly by a private key, as opposed to contract accounts controlled by code. Before EIP-7702, an EOA's code field was always empty and could not execute custom logic; contract accounts could execute logic but had no private key. EIP-7702 breaks this dichotomy: through a specially formatted code prefix, 0xef0100, it lets an EOA "temporarily" point to a contract's code. Note that this does not turn the EOA into a contract — the address, private key, and nonce semantics are all preserved; it merely executes the delegated code on calls. This design is part of Ethereum's broader "account abstraction" direction, aiming to give EOAs smart-account capabilities without migrating assets or changing addresses.

The authorization tuple is the core data structure of EIP-7702. It is essentially a declaration signed by an EOA's private key that anyone can broadcast on-chain. It contains six fields: chain_id (the chain on which it is valid; 0 means any chain), address (the delegated contract address), nonce (to prevent replay), y_parity and r, s (the signature itself). Once included in a transaction, the EOA's code field is set to the corresponding delegation indicator. The key point: the tuple is signed offline, and an attacker only needs to obtain one signature to put it on-chain and "activate" it at any time. Once a signature is exposed in the mempool or in historical transactions, it is effectively public; anyone can use ecrecover to derive the signer's address, which also makes the tuple itself usable as forensic evidence.

Six Signatures, One Target

The security researcher pulled all Authorization tuples touching the address. Each tuple is signed data — containing the chain ID, delegate address, nonce, and the y-parity and r/s signature pair. You don't need a wallet to read this data; what you need is ecrecover.

After recovering the signer from each tuple, it turned out that all six authorizations came from the same key, and all six pointed to the same delegate address.

The delegate address's code is short, but reading it makes everything clear: when it receives a transfer, it forwards it directly to a hardcoded address. There is no condition you can satisfy, no branch you can take. If you send 0.01 ETH, it keeps 0.01 ETH — and so will everyone else who later sends a "small test."

Why Six Signatures Matter

Multiple authorization signatures pointing to the same delegate address indicate that this is not an accidental operational mistake, but a planned deployment. The attacker may be scanning for addresses that have exposed private keys or signed malicious authorizations in bulk, then setting up delegations one by one. Six signatures from the same key mean that the address owner (or whoever once controlled that key) signed authorizations on multiple occasions.

ecrecover is a precompiled contract built into the Ethereum Virtual Machine whose purpose is: "given a message hash and an ECDSA signature, recover the signer's address." It requires no private key, no network connection, and no centralized service, making it a fundamental tool for on-chain forensics. In this case, the researcher reconstructs the message to be signed for each authorization tuple according to the format defined by EIP-7702 (including the magic number 0x05, chain_id, delegate address, and nonce), and calls ecrecover to obtain the signer. If all six tuples recover the same address, that conclusively proves these authorizations came from the same private key, which does not contradict the address's "clean history" — because signatures can be created entirely off-chain and only placed on-chain at the last moment.

The Three Checks That Could Have Stopped It

Before sending funds to any address, three on-chain reads can give you the answer — no indexer required:

1. Read the Code, Not the History

Call eth_getCode on the address. Empty return = ordinary EOA. A return beginning with 0xef0100 = delegated: the next 20 bytes are the delegate address. "No transactions yet" proves nothing — a delegated account can have a completely clean transaction history.

2. Read the Delegate Contract

Take the delegate address and read its code. Ask one core question: what happens when an ordinary transfer comes in? Does it forward? To whom? Is the destination address hardcoded? This is where funds are siphoned off — hidden in roughly 30 bytes of bytecode, not in any UI.

3. Read the Authorization Record

Pull the account's Authorization tuples (they exist in the transaction data of delegation transactions). Use ecrecover to verify the signer. If a tuple's signer is not the account owner, that is a red alert that takes priority over everything else.

The Meta-Rule: A Small Test Is Not a Security Strategy

Against a draining contract, a "small test" is not a security strategy — it swallows the test amount too. For a wallet delegated to a draining contract, the only safe transfer amount is zero.

Why AI Agents Need to Care About This

This is not an issue that affects only human users. AI agents are becoming important participants in on-chain activity — and crypto payments are how many agents get paid. That means wallets are their payment channel, and "it looks fine in the browser" is not verification at all.

Agents will send funds autonomously, and the EIP-7702 draining trap is exactly the kind of trap that passes surface checks: the address format is correct, the history is plausible, and the code responds correctly to every hash query. For automated systems, without code-level on-chain checks, it is nearly impossible to distinguish a normal address from one delegated to a draining contract.

From Vulnerability to Tooling

The security researcher packaged this pre-check process into an agent skill. Crypto Wallet Safety Check is a SKILL.md that guides the agent through the checks above — delegation indicators, delegate code, authorization records, nonces, honeypot detection, permit phishing — using only public RPC endpoints, and is read-only by construction. There is also a companion tool, Onchain Claim Verifier, for verifying payment claims.

Both tools are published on Ko-fi and Payhip, and users can choose the platform they prefer.

The Bigger Picture

EIP-7702 represents an important step on Ethereum's account abstraction roadmap, but it also opens a new attack surface. Traditional security advice — such as "send a small test first" — no longer works in this new paradigm. For both human users and AI agents, the first principle of on-chain safety is becoming: read the code first, then look at the history.

The browser shows you an address. The blockchain shows you what it will do. Read the code first.

Background

eth_getCode is a standard JSON-RPC method that takes an address and a block number and returns the code bytes for that address at that block. It returns 0x (empty) for an ordinary EOA, the full bytecode for a contract account, and for an EIP-7702 delegated account it returns 23 bytes beginning with 0xef0100 (a 3-byte prefix + a 20-byte delegate address). This prefix, 0xef0100, is the "magic byte" reserved by EIP-3541; ordinary contracts cannot deploy code beginning with it, so it serves as a deterministic marker of whether an account has been delegated. A single call to a public RPC is enough to get the answer — no indexer, no explorer, no need to trust a third party — which is precisely why it is suitable for embedding into AI agent pre-check flows.

#EIP-7702#wallet security#account abstraction#draining contract#eth_getCode#ecrecover#AI agent security
Share:

Related articles