At 21:42:59 UTC on Oct 29, a wallet Etherscan labels Binance 161 sent Binance's Ethereum hot wallet $200M of USDT, the same top-up it had sent six times since September.
The hot wallet had been running an attacker's code for 82 minutes. The $200M was gone 72 seconds later.
I read the Ethereum side of the theft from the chain and set it next to Binance's incident report. All times are UTC.
The timeline
- 20:20:59 - Takeover. An outside address lands one transaction carrying 50 EIP-7702 authorizations signed by the hot wallet, one per nonce, listed high to low. The wallet was sending about two transactions a block, so 34 were already stale. One matched, and in that order only one can. From here the wallet runs the attacker's contract.
- 20:24:23 - First sweep. One call takes 167,464 ETH and 63 tokens, $1.6B of USDT among them.
- 20:41:23 - The USDC. $780M leaves a smart account that the hot wallet owned. Another $43M follows at 20:59:47.
- 21:42:59 - The top-up. Binance 161's $200M of USDT arrives.
- 21:44:11 - Swept. 72 seconds later it is gone.
- 23:56:47 - Last sweep. 2,962 ETH that had arrived a minute earlier. This was the fifth sweep. The others came at 21:04 and 22:39.
- 00:10:35 (Oct 30) - Cleared. Binance removes the attacker's code, 3 hours 50 minutes after it landed.
Why nothing stopped it
After 20:20:59 the attacker needed nothing from Binance. No signer, no credentials. Their own address calls the wallet and the wallet pays.
Binance's report: "suspending withdrawals and shutting down hot wallet services did not automatically invalidate existing on-chain authorizations." So funds kept arriving and kept leaving.
Ending it took one more authorization from the same wallet, this time to the zero address. Binance says that with MPC there was no single key that could revoke it immediately.
What I take from it, as someone who builds smart accounts
An EOA's key is root. Nothing on-chain limits it, and only that key can undo what it signed. A smart account owned by that key inherits the problem. That is how the USDC left.
So make the hot key a scoped signer on a contract account: a cap that refills, and a pause that a different key can pull. Then the off-switch is on-chain, where the access is.
The cap is not hard to size. In the week before, 99.4% of this wallet's USDT transfers were under $1M, and their busiest hour totaled $5.4M. The rest went to 89 addresses, most of the value to four of Binance's own wallets. The wallet held $1.6B.
The hot wallet had been running an attacker's code for 82 minutes. The $200M was gone 72 seconds later.
I read the Ethereum side of the theft from the chain and set it next to Binance's incident report. All times are UTC.
The timeline
- 20:20:59 - Takeover. An outside address lands one transaction carrying 50 EIP-7702 authorizations signed by the hot wallet, one per nonce, listed high to low. The wallet was sending about two transactions a block, so 34 were already stale. One matched, and in that order only one can. From here the wallet runs the attacker's contract.
- 20:24:23 - First sweep. One call takes 167,464 ETH and 63 tokens, $1.6B of USDT among them.
- 20:41:23 - The USDC. $780M leaves a smart account that the hot wallet owned. Another $43M follows at 20:59:47.
- 21:42:59 - The top-up. Binance 161's $200M of USDT arrives.
- 21:44:11 - Swept. 72 seconds later it is gone.
- 23:56:47 - Last sweep. 2,962 ETH that had arrived a minute earlier. This was the fifth sweep. The others came at 21:04 and 22:39.
- 00:10:35 (Oct 30) - Cleared. Binance removes the attacker's code, 3 hours 50 minutes after it landed.
Why nothing stopped it
After 20:20:59 the attacker needed nothing from Binance. No signer, no credentials. Their own address calls the wallet and the wallet pays.
Binance's report: "suspending withdrawals and shutting down hot wallet services did not automatically invalidate existing on-chain authorizations." So funds kept arriving and kept leaving.
Ending it took one more authorization from the same wallet, this time to the zero address. Binance says that with MPC there was no single key that could revoke it immediately.
What I take from it, as someone who builds smart accounts
An EOA's key is root. Nothing on-chain limits it, and only that key can undo what it signed. A smart account owned by that key inherits the problem. That is how the USDC left.
So make the hot key a scoped signer on a contract account: a cap that refills, and a pause that a different key can pull. Then the off-switch is on-chain, where the access is.
The cap is not hard to size. In the week before, 99.4% of this wallet's USDT transfers were under $1M, and their busiest hour totaled $5.4M. The rest went to 89 addresses, most of the value to four of Binance's own wallets. The wallet held $1.6B.