50 signatures. 1 applied.
The 2026-10-29 drain, rebuilt from its 4,916 raw bytes. ef0100 decodes EIP-7702 delegations and refuses what it cannot decode before it reaches a key.
4,916 raw bytes. Their keccak256 is the transaction hash.
50 of 50 recover to the wallet, in this tab.
93 of 93 pass, cross-checked against viem.
3, pinned: @noble/curves, @noble/hashes, @scure/base.
Read it from the bytes. Not from a description of them.
- 01Decoded in your browser
This page runs ef0100 on the transaction's 4,916 bytes. Nothing is fetched.
- 02One rule decides
A tuple applies only if its nonce equals the account's nonce at that moment.
- 03The order matters
Listed in descending order, at most one can apply. Reverse the list and every tuple from the live nonce up applies.
tx 0xad99…298b
- Wallet nonce
- Applies
- Nonces used
Drag the slider or use the arrow keys. 18,914,809 is what the wallet's nonce was.
Tuple #15
What the key signed: derived, never in the transaction
Recomputing the 50 tuples from the raw bytes in this tab…
3h49m36s delegated. Every block of it.
- 204 s
from inclusion to the first sweep
- 72 · 60 s
for the two largest top-ups to be swept out again
- 36,800 gas
for the wallet's own clear, which
ef0100 clearrebuilds byte for byte
Every event, in order (UTC)
| UTC | Event |
|---|
The delegation transaction is not among the 11,060 type-4 transactions Flashbots Mempool Dumpster logged that day, while 651 of 651 of the wallet's own transactions between 19:27 and 24:00 UTC are: strong evidence of private order flow, not proof. The earliest public trace of the delegation was its block, 204 s before the first sweep.
No preimage, no signature.
A signer handed 32 bytes cannot tell an EIP-7702 authorization from anything else: the 0x05
that marks one is inside the hash. ef0100's guard sits in front of the signer and decides from the bytes
it is asked to sign.
NO_PREIMAGEA bare digest is refused.
DELEGATE_NOT_ALLOWEDOnly delegates you list can be authorized.
NONCE_NOT_LIVEOnly the key's live nonce. A signed future nonce stays valid until the account reaches it.
OWN_CODE_PRESENTOnce the key's own account has code, only the clear and break-glass transfers pass.
Nothing requested yet.
The raw-digest signer uses anvil's public test key #0, which nobody should fund. Nothing leaves this tab.
import { Guard, profiles } from "ef0100";
const guard = new Guard(profiles.hotWallet);
// KMS DIGEST, Web3Signer, sign(hash):
// send the preimage along with the digest.
const d = guard.checkDigest(digest, preimage, {
signer, nonce, ownCode,
});
if (!d.allow) {
throw new Error(d.reasons.map((r) => r.code).join(", "));
}
| Requests | Verdict | Reasons |
|---|
Regression fixtures, profile hotWallet. It refuses the 50 because it allows no delegate:
deny-by-default working, not proof that a rule told good from bad.
After the sweeps. Where it went.
Every call through the delegation paid one of 2 collector addresses. replay --flows
follows the first hop out of each, from data bundled in the package.
- Decoded
The three large ETH transfers out of R1, each decoded from raw transaction bytes in the package.
- Ledger
What arrived through the delegation: the same ledger the timeline sums, held equal by a test.
- Snapshot
The second wallet's transfers, transaction counts and router names, from an explorer at 2026-10-30 06:41:26 UTC.
- Not claimed
Who controls R1 or R2, or where the value went after the first hop.
One command. No network.
npx ef0100 replay prints this from bytes bundled in the package. It never asks for your keys;
oracle, the one command that signs, uses a public test key. Live commands read public chain data,
or your own endpoint through EF0100_RPC_<CHAIN>.
replayThe 2026-10-29 drain from its own bytes, offline
0 3decode <tx>Any transaction; a type 4 tuple by tuple, against the state it ran on
0 1 2 69<address>Delegated on any of 11 EVM chains? The delegate's code, read
0 1 2 69guard testThe guard against the incident's tuples, digests and clear
0 1 3classify <hex>What a key is being asked to sign, and whether the guard would pass it
0 2recipient <address>Hold a top-up bound for a delegated, contract or blacklisted address
0 2 69clear <address>The unsigned, self-sponsored transaction that clears a delegation
0 69code <address>What a delegate's bytecode does, read statically
0 2 69sol <signature>Solana before signing: durable nonces, Assign, authorities, Squads
0 1 2 69sol nonces <key>Every durable-nonce account a key controls
0 1 69oracleA raw-digest signature, read back as an authorization
0
Exit codes: 0 clean or allowed, 1 a finding, 2 refused or a known-malicious or sweeper-like delegate, 3
bundled data does not match SHA256SUMS, 64 usage, 69 no endpoint answered, 70 internal error.
7 chains traced. EIP-7702 on one.
Every other leg that was traced was an ordinary signed transfer, which needs destination and template rules rather than an authorization guard. Amounts come from explorers and the incident research, not from bytes in the package. Arbitrum, Base and Polygon outflows were not traced transaction by transaction.
Sources: one transaction per leg
| Chain | UTC | Moved | Transaction |
|---|
Refuse what you cannot decode.
Not audited: read the code before you put it in a signing path. A stolen key signs without asking anyone, and ef0100 does not claim it would have stopped this drain; how the 50 signatures were produced is not public.