What actually happens on-chain
A new transaction type (0x04) carries signed authorization tuples. After a valid authorization, the account code becomes exactly:
0xef0100 || <20-byte implementation address> // 23 bytes total
0xef is a banned opcode, so clients treat this as a pointer, not executable code. When anything calls the EOA, the EVM runs the pointed-to implementation in the EOA’s own context — same address, balance, storage, nonce space. Delegating to the zero address clears the designation. Anyone may submit the transaction carrying a signed authorization, so a sponsor can pay gas — that is how gasless delegation works, and why an agent wallet can stay USDC-only.
Detection recipe (what our indexer runs)
code = eth_getCode(address)
if code starts with 0xef0100 and len == 23 bytes:
implementation = code[3:23] → DELEGATED
elif code is empty: → vanilla EOA
else: → classic contract / 4337 account
Plus: trace type-0x04 transactions and decode the authorization_list (the sender may be a sponsor — store both), map implementations against the audited allowlist, and watch for rotation (new designator) and revocation (zero address). A chain_id = 0 authorization is valid on every chain — the graph fans that edge out.
The session-key policy surface
Once delegated, the implementation issues session keys with scoped rights. The controls seen in production wallet APIs:
| Control | Example policy for an agent |
|---|---|
| Time | expires in 24h / 7d |
| Spend cap | $500 per tx · $5,000 per session |
| Function allowlist | only swap on Uniswap, deposit on a named vault |
| Asset allowlist | USDC + ETH only |
| Rate limit | ≤ 10 txs / hour |
| Target allowlist | named routers / vaults only |
| Gas cap | max gas the key may burn |
If the agent is prompt-injected, the attacker gets the valet key, not the trunk key. Coinbase CDP upgrades the existing EOA in place with sponsored delegation on Base, Arbitrum, Ethereum, Optimism, and Polygon; Alchemy’s pattern is delegate → wallet_createSession → one EIP-712 signature → the agent signs with the session key only; MetaMask’s agent wallet adds allowlists, simulation, and batch swaps via ERC-7821.
The critical security fact
Delegation is not custody transfer. The master key can always replace or clear the code, and a malicious implementation runs with the account’s full balance. Policy is only as strong as the delegate contract plus operational discipline: if the raw key lives in the same runtime as the agent, the policy is theater. Wallets are expected to whitelist audited implementations — everything else carries implementation_risk = unknown in our graph. Known-audited examples we seed from public documentation: Uniswap/calibur, Alchemy modular-account, Ambire, and MetaMask’s delegation framework (verified live before labeling).
How this appears in the graph
DELEGATES_CODE_TOedges from wallet to implementation, with rotation and revocation history.- Session-key and policy objects where visible on-chain or shared by partners — with the enforcement location labeled: chain module vs TEE vs API gateway vs “prompt says please don’t.”
- Funded, labeled agent wallets with no delegation and no signer isolation get the god-key flag — a first-class incident precursor, not a style choice.
Questions the graph answers: how many labeled agent wallets are 7702-delegated vs raw EOA vs 4337? Which implementations dominate? After an incident — was the leak a session key or the master key? See the graph model →