Search 73 posts

Fifty Signatures: Reading the Binance Hack on Chain

How 50 signed EIP-7702 authorizations helped empty a Binance hot wallet, traced block by block with public data: the nonces, the sweep and the 3h 49m window.

Karl NyenTechnology7 min read
A grid of 50 tiles labelled with the last three digits of each signed nonce, headed type 0x04, 50 authorizations; the tile for nonce 809 glows gold and carries the Binance logo, above the labels 1 matched and 49 skipped
On this page

At 20:24:23 UTC on 2026-10-29, one Ethereum transaction took 167,464 ETH and 63 tokens, including 1.6 billion USDT, out of a Binance hot wallet. The fee was 0.0004 ETH. It was one part of the largest crypto theft on record: about $6.36 billion across ten blockchains, by TRM Labs’ count.

Binance has not published a root cause. The Ethereum part of the attack happened in public, though, so I pulled the blocks from a public RPC node to see what the record shows on its own. Everything in the table below comes from those blocks, and you can check it with one curl command. Times are UTC. “Binance 14” is Etherscan’s label for the wallet.

Time Block On chain
20:17:47 26300737 Binance 14 reaches nonce 18,914,775, the lowest nonce in the batch signed for the attack
20:20:59 26300753 A type-4 transaction carries 50 signed authorizations; one lands and the wallet gets code
20:24:23 26300770 First sweep: the wallet drops from 167,465 ETH to exactly 1 ETH
20:41:23 26300855 780 million USDC pulled from a Binance smart account the wallet could control
21:44:11 26301167 Another sweep takes 200.4 million USDT that arrived after the first one
00:10:35 26301896 The wallet clears its own delegation

What EIP-7702 changed

An ordinary Ethereum account is a key and a balance. It has no code, and it can only do what its key signs. EIP-7702, which shipped in the Pectra upgrade in May 2025, lets such an account point at a contract and run that contract’s code as its own.

The owner signs a small tuple: chain ID, contract address, nonce. Anyone can then submit it, and the sender pays the gas. The network writes 0xef0100 plus the contract address into the account’s code, and it stays there until the account signs a new delegation. The tuple’s nonce must equal the account’s current nonce. If it doesn’t, the network skips that tuple and moves on to the next one.

That persistence is the part that matters here. What the account can then be made to do depends entirely on the contract, with no further signatures. The spec warns that a poorly written delegate “can allow a malicious actor to take near complete control over a signer’s EOA”. In this case the delegate was the attacker’s own contract, and TRM says it took instructions only from the operator.

Fifty tickets for one busy wallet

The nonce rule creates a problem for an attacker. A hot wallet at an exchange sends transactions constantly. In the 1,200 blocks before the attack, Binance 14 sent 2,678 of them, about 11 a minute. A signature for the current nonce goes stale within seconds.

So the attacker’s operator address sent 50 authorizations in one transaction, all signed by Binance 14, all pointing at the same contract, one for each nonce from 18,914,775 to 18,914,824. Blockaid and TRM both reported the batch. The chain adds the detail of how it landed.

A strip of 50 tiles, one per signed nonce from 18,914,775 to 18,914,824. 34 are already spent, one at 18,914,809 matched at 20:20:59, and 15 were not reached. The wallet reached the lowest nonce at 20:17:47 and had spent the highest by 20:24:23.

The batch, laid out in nonce order. Timings are from my own read of the blocks
Signed nonces Count Result
18,914,775 to 18,914,808 34 Already spent, skipped
18,914,809 1 Matched at 20:20:59
18,914,810 to 18,914,824 15 Not reached, skipped

The list runs from high to low. That ordering means only one can land: once the nonce moves up, every tuple left in the list is below it. In block 26300753, Binance’s own traffic spent nonce 18,914,808 at position 133. The attacker’s transaction landed at position 138, and the tuple for 18,914,809 matched. Forty-nine were skipped and the transaction still succeeded.

The range also works as a clock, though only for when the batch could land. The wallet reached the bottom of it at 20:17:47 and had spent the top of it by 20:24:23, so the signatures were usable for about six and a half minutes. That does not show when they were made or how. TRM suggests a batch like this may point to time-limited access, or to signatures that had to be requested through a system. Someone holding the key could have sent one too.

Seventeen blocks of warning

The delegation was live for 3 minutes 24 seconds before anything moved. Anyone polling the wallet’s code would have seen this:

block      time (UTC)  Binance 14 code
26300752   20:20:47    0x
26300753   20:20:59    0xef0100 63e842b054bd624a465454d533c33f573e9c6fae
26301895   00:10:23    0xef0100 63e842b054bd624a465454d533c33f573e9c6fae
26301896   00:10:35    0x
text

Then the operator called sweep(address pool, address[] depositors) on the wallet itself, using Etherscan’s decoded names for selector 0x8a179be4. The depositors array held 65 addresses, and the receipt shows 63 token transfers to one new address. The balance went from 167,465.25 ETH to exactly 1 ETH.

Three hours and 49 minutes

The delegation outlived the sweep because nothing about it expires. The operator came back twelve times in all.

Timeline from 20:00 to 00:30 UTC. The wallet is delegated from 20:20:59 to 00:10:35. Attacker calls move tokens at 20:24, 20:41, 20:59, 21:04, 21:44 and 22:39, then six calls around 23:37 and 23:55 move none. Freezes come from Tether at 21:01, Circle at 21:04, Ripple at 22:01, World Liberty at 22:10 and Arbitrum at 00:08. Binance suspends withdrawals at 22:15.

Delegation and attacker calls from my own read of the chain; other events from TRM Labs and FinanceFeeds
Time (UTC) Call Tokens moved
20:24:23 Sweep 63 tokens, including 1,615.4M USDT, plus 167,464 ETH
20:41:23 Forward 780M USDC from the Binance smart account
20:59:47 Forward 43M USDC from the same account
21:04:23 Sweep 23 transfers, including 3.9M USDT
21:44:11 Sweep 14 transfers, including 200.4M USDT
22:39:35 Sweep 122 transfers, to a second address
23:36:47 to 23:38:23 4 sweeps None
23:54:59 and 23:56:47 2 sweeps None

The freezes in the chart come from TRM’s timeline: Tether at 21:01, Circle at 21:04, Ripple at 22:01, World Liberty at 22:10 and Arbitrum’s Security Council at 00:08.

Binance suspended withdrawals from about 22:15, and the wallet’s own key kept working throughout. It sent 93 ordinary signed transactions between the delegation and the clearing, 46 of them between 22:45 and 23:15. The chain does not say who asked for them.

The fix was a self-sent type-4 transaction with one tuple pointing at the zero address, which the spec defines as clearing the delegation. The delegation sits on the address, so replacing the signing system would not clear it, and moving to a new address would only leave it behind. It took a new authorization from that same account, 3 hours 46 minutes after the first sweep. Binance has not said what took that long.

Ethereum was only part of it

EIP-7702 does not exist on Bitcoin or the XRP Ledger, and those chains lost money too. TRM’s timeline starts at 20:05, when five XRP wallets sent 233.46 million XRP to one address, a quarter of an hour before the Ethereum delegation. At 20:20, a Bitcoin hot wallet sent 18,270 BTC. A second Ethereum hot wallet sent 28,006 ETH by plain signed transfer, no delegation needed.

Bar chart of value taken per chain: Ethereum $3.79B, Bitcoin $1.47B, Tron $628M, XRP Ledger $296M, Solana $96M, Arbitrum, Optimism and Base $39M, Avalanche $28M, Polygon $10M.

Values at the time of the theft, from TRM Labs
Chain Value taken
Ethereum $3.79B
Bitcoin $1.47B
Tron $628M
XRP Ledger $296M
Solana $96M
Arbitrum, Optimism, Base $39M
Avalanche $28M
Polygon $10M

So EIP-7702 was a tool for one wallet and not the way in. TRM’s assessment is that the attacker could make Binance’s hot wallet signing system sign across chains. Blockaid counted eleven hot wallet keys signing transfers to an address created minutes earlier. Binance says it has found no evidence of a private key leak, which is consistent with that picture: the keys may have stayed put while something told them what to sign.

What the chain can’t tell you

  • How they got in. Binance first pointed to a compromised DevOps engineer’s laptop, then said it had found additional points of breach. It has promised a technical post-mortem. None has been published as of 2026-11-02.
  • Who did it. TRM and Chainalysis named North Korea’s TraderTraitor, and the FBI agreed on 2026-10-31, publishing 608 Ethereum, 19 Bitcoin and 1 Solana addresses. North Korea denies it. Binance has not attributed the attack. The blockchain shows wallets, not people.
  • The exact total. Binance says about $6.3 billion, TRM $6.36 billion across ten chains, Elliptic $6.43 billion across eleven. The differences appear to come from which chains are counted and which prices are used.

Binance says customers will not bear the loss and has replaced about 95% of the assets from its own funds, and Elliptic counts 44% of the money as frozen or seized. The rest of the story is laundering, which Elliptic expects to take months.

Check it yourself

This returns the delegation pointer for block 26300753. Change the block to 0x1915150, one earlier, and you get 0x. It needs a node that serves historical state:

curl -s https://eth.drpc.org -H 'content-type: application/json' -d '{
  "jsonrpc":"2.0","id":1,"method":"eth_getCode",
  "params":["0x28C6c06298d514Db089934071355E5743bf21d60","0x1915151"]}'
bash
Karl Nyen

Writing about virtualization, home lab, cloud, storage and gaming on vSkilled, started in 2014.

Keep exploring