The Dev Machine Is the Trust Boundary: Inside Binance's Record $6.3B Hack
Binance lost roughly $6.3 billion on 29 October and says it did not lose a private key. The money left the exchange’s own hot wallets, authorized by the same withdrawal service that pays out every customer request, and it kept moving for about twenty minutes across ten blockchains. By the next morning it was, by TRM Labs’ count, the largest crypto theft on record, almost four times the $1.5 billion taken from Bybit in February 2025.
Six hours later, Binance posted what it believed was the entry point. A compromised DevOps engineer’s laptop gave an attacker access to a service container, and from there the ability to submit unauthorized withdrawal transactions.
Nothing in that sentence is a wallet. A laptop, a service container, a withdrawal transaction: each step is an identity. The chain it describes starts on a developer workstation and ends inside the signing path, and that chain is not specific to crypto exchanges.
TL;DR
- Binance estimates the impact at about $6.3 billion. TRM Labs puts the theft at $6.36 billion and calls it the largest crypto theft on record. The previous record was the $1.5 billion taken from Bybit in February 2025.
- Binance named a compromised DevOps engineer’s laptop as the likely entry point: access to a service container, then unauthorized withdrawal transactions. The exchange reported no evidence of a wallet private key leak.
- On Ethereum, Blockaid reported 50 EIP-7702 authorization entries bundled into one transaction against the Binance 14 hot wallet. One entry matched the account nonce and was accepted, which delegated execution to an unverified sweeper contract. On the other nine chains, funds left through ordinary signed transfers. EIP-7702 was a vector on one chain, not the root cause.
- TRM Labs reports that outflows started at 20:05 UTC and that most of the money moved in about 20 minutes across ten blockchains, with a second wave at 23:05 UTC on Avalanche and Polygon. Preparation began at least 36 hours earlier and was funded through Tornado Cash.
- About $3 billion was frozen onchain by issuers and networks. TRM says the attacker still holds more than 420,000 ETH and 18,270 BTC, roughly $2.4 billion that no issuer can freeze.
- TRM attributes the theft to TraderTraitor, a North Korean unit, with high confidence. Binance has not named a culprit and says law enforcement is still working to identify the attackers.
What Binance said
Binance posted the finding to X at 02:25 UTC on 30 October, six hours after the outflows began.
Binance’s initial investigation suggests that the security incident may involve a compromised DevOps engineer’s laptop, which allowed an attacker to gain access to a service container and submit unauthorized withdrawal transactions. We have found no evidence of any wallet private key leak. We will share a detailed technical post-mortem once the investigation is complete and the facts are fully verified.
The estimated total impact sits at around $6.3B. We have worked with blockchain partners to freeze affected assets, with ~$3 billion frozen on-chain so far.
Binance will cover all losses from the SAFU fund and the company’s funds.

Binance’s update on X, posted at 02:25 UTC on 30 October 2026 and later edited. The announcement link in the post points to the exchange’s own incident notice.
Binance suspended withdrawals while it rebuilt the withdrawal service, kept deposits open, and said it would publish a root-cause report and an updated proof of reserves. In a follow-up on 30 October, it described a “complex attack” that went beyond the laptop, with additional points of breach, and said it had set aside more than $6.34 billion of company funds to cover the incident. Binance.US, a separate company, said it was not affected.
How the money moved
Two independent analyses describe an attack that never needed to forge a signature. Every transfer carried a valid signature from a Binance key. The question is how the attacker got those signatures, and the answer is the signing infrastructure, not the chain.
TRM Labs’ timeline sets the frame. Funds started leaving at 20:05 UTC, first from five Binance wallets on the XRP Ledger. Solana and Optimism followed after 20:10. At 20:20 a Bitcoin hot wallet sent 18,270 BTC. Within two minutes a Tron wallet sent 612.7 million USDT. Most of the value moved in about 20 minutes across ten blockchains. A second wave hit wallets on Avalanche and Polygon around 23:05 UTC. On nine of the ten chains, the funds left through ordinary signed transfers. Nothing exotic happened. The wallets signed, and the money moved.
Ethereum was the exception, and it is where the EIP-7702 detail comes from. Blockaid reported that at 20:20:59 UTC the attacker sent a single type-4 transaction carrying 50 EIP-7702 authorizations, every one signed by the Binance 14 hot wallet. EIP-7702 lets an ordinary account delegate its execution to contract code. An authorization is only valid if its nonce matches the account’s current nonce when the transaction executes. Binance 14 was paying out withdrawals every few seconds, so the attacker could not know which nonce it would land on. They signed a window of 50 consecutive nonces, 18,914,775 through 18,914,824, and submitted all of them. Nonce 18,914,809 matched. The other 49 were discarded. That one entry pointed Binance 14 at an unverified sweeper contract at 0x63e842B054Bd624a465454D533C33F573e9c6fAe.
Three minutes and 24 seconds later, at 20:24:23 UTC, the attacker called the sweeper through Binance 14. One transaction moved 167,464 ETH and 63 other tokens, including 1.615 billion USDT, about $2.5 billion at the time. The delegation stayed in place for almost four hours. At 20:41 and 20:59 the attacker used Binance 14’s borrowed code to drive a separate Binance smart account, Hot Wallet 34, and pulled 823 million USDC from it. Binance’s systems kept routing customer deposits into Binance 14, and the attacker swept them out again at 21:04, 21:44 and 22:39 UTC. Binance cleared the delegation at 00:10:35 UTC on 30 October by signing a fresh authorization that pointed the account at the zero address.
Ethereum also shows that 7702 was a choice, not a requirement. Twenty-four seconds after the sweep, a second hot wallet, Binance 16, signed nine ordinary transfers straight to the attacker: 28,005 ETH, 55.7 million USDT and seven other tokens, about $174 million. Same chain, same window, no delegation. The signer produced plain transfers when the attacker asked for them.
Blockaid chief executive Ido Ben-Natan, speaking to Cointelegraph on the evening of the attack, described the mechanism as key misuse rather than key theft: the attacker tricked or compromised a signing system into authorizing transactions the operators never intended. He called the assessment preliminary.
It seems to be … a compromise of signing infrastructure. We don’t think a key was leaked.
Asked whether it resembled the February 2025 Bybit attack, he called the two incidents “very, very similar.”
TRM reached the same conclusion from the other direction. The 50 authorizations were produced in advance as a batch, and the outflows on all ten chains ran as one coordinated burst. In TRM’s assessment, that points to a compromise of Binance’s hot wallet signing infrastructure rather than a flaw in any one chain.
Inside the sweeper contract
The sweeper was never verified on Etherscan. banteg decompiled it and published a bytecode-matching Solidity reconstruction. The reconstruction compiles byte-for-byte to the on-chain runtime with solc 0.8.28, viaIR, optimizer at 200 runs, and the cancun EVM target. The executable portion is 1,621 bytes, and its keccak256 matches the deployed code exactly. Function, error and event names were confirmed by selector hashing. Internal names and the contract name are inferred.
The contract is short enough to read in full. The parts that matter are below.
contract DelegatedSweeper {
// The only address allowed to call anything. This is the operator wallet
// that was funded through Tornado Cash on 28 October.
address public constant authorizedCaller = 0x7C8601d4645b93cea45F71e118A729332e6B5CA0;
modifier onlyAuthorized() {
if (msg.sender != authorizedCaller) revert NotAuthorized();
_;
}
// Move every listed token, plus ETH, to a recipient.
// address(0) in the list means "sweep ETH, but leave 1 ETH behind".
// A failed token does not revert the whole sweep. It emits an event and moves on.
function sweep(address payable to, address[] calldata tokens) external onlyAuthorized {
for (uint256 i = 0; i < tokens.length; i++) {
address token = tokens[i];
if (token == address(0)) {
uint256 balance = address(this).balance;
if (balance > 1 ether) {
(bool ok,) = payable(to).call{value: balance - 1 ether}("");
if (!ok) emit SweepItemFailed(token, 3);
}
} else {
(bool ok, bytes memory ret) =
token.staticcall(abi.encodeWithSignature("balanceOf(address)", address(this)));
if (!ok || ret.length < 32) { emit SweepItemFailed(token, 1); continue; }
uint256 balance = abi.decode(ret, (uint256));
if (balance > 0) {
(bool success,) =
token.call(abi.encodeWithSignature("transfer(address,uint256)", address(to), balance));
if (!success) emit SweepItemFailed(token, 2);
}
}
}
}
// Forward a call to another smart account's execute(address,uint256,bytes).
// 0xb61d27f6 is that selector. This is how Binance 14, running this code,
// gave orders to Hot Wallet 34.
function callExecute(address account, address to, uint256 value, bytes calldata data)
external payable onlyAuthorized returns (bytes memory)
{
if (account.code.length == 0) revert NoCodeAtExecutor(account);
(bool ok, bytes memory result) =
account.call{value: msg.value}(abi.encodeWithSelector(bytes4(0xb61d27f6), to, value, data));
if (!ok) revert ExecuteCallFailed(account, result);
return result;
}
}
Three details stand out.
The 1 ether floor in sweep explains why Binance 14 was left with exactly 1 ETH after the first drain. The attacker wanted the wallet to keep working so that fresh deposits would keep arriving, and so that Binance’s own withdrawal traffic would not stall and draw attention.
The continue on a failed token explains how 63 tokens moved in one transaction. Any token that reverted, paused transfers, or had already been frozen was skipped instead of breaking the batch. SweepItemFailed events give the operator a list of what to retry.
callExecute is the piece that reached beyond Binance 14. Because the sweeper’s code was running as Binance 14, any contract that trusted Binance 14 as an executor now trusted the attacker. Hot Wallet 34 did, and 823 million USDC left through it.
None of this is an exploit. There is no reentrancy, no overflow, no bug in EIP-7702, and no flaw in any Binance contract. The sweeper is the kind of utility contract a wallet team might write for itself. It does nothing unless the operator calls it, and it has no power over an account unless that account’s key signs an authorization pointing at it. Binance 14’s key did sign fifty of them.
That is the point to hold onto. EIP-7702 did not cause this breach. It was the delivery vector the attacker chose on one chain, most likely because it was the cleanest way to turn a batch of pre-obtained signatures into standing control: one transaction, 63 assets, repeated sweeps of new deposits, and a lever on Hot Wallet 34, with no need to go back to the compromised signer for each transfer. On the other nine chains the attacker did not bother with anything comparable. The signing infrastructure produced ordinary transfers, and that was enough. The compromise that matters happened wherever those signatures were made.
Where the money went
Dickson Wu of CertiK traced the full flow on-chain and published every transaction and freeze receipt. His accounting at 23:50 UTC covers $6.28 billion across eight chains. TRM’s later count adds smaller amounts and the second wave, and reaches $6.36 billion across ten. The two agree on every major figure. What follows is drawn from his trace unless noted.
Preparation
The operator wallet, 0x7c8601d4645b93cea45f71e118a729332e6b5ca0, took its first 0.1 ETH out of Tornado Cash at 07:39 UTC on 28 October. Two more 0.1 ETH withdrawals followed. A second wallet pulled 1 ETH from Tornado and forwarded it to the operator at 18:20 on 29 October.
The sweeper came in two versions. Version one was deployed at 02:28 UTC on 29 October. From 13:51 to 16:47 the attacker rehearsed on wallets they controlled: delegate with EIP-7702, sweep a few dollars of test USDT and USDC, withdraw. At 15:59 they deployed version two with the generic callExecute function. That is the contract banteg reconstructed, and callExecute is the function that later pulled 823 million USDC out of Hot Wallet 34. The attacker added it about four hours before the attack, which suggests they already knew about the smart account and its trust in Binance 14.
The drain, by chain
| Chain | Time (UTC) | What moved | Value at 20:24 UTC |
|---|---|---|---|
| XRP Ledger | 20:05 to 20:09 | 233.5M XRP from five wallets | $296.5M |
| Solana | 20:10 | 965,455 SOL in one transaction | $96.1M |
| Optimism | 20:18 | 44.2M OP | $4.8M |
| Bitcoin | 20:20 | 18,270.2 BTC in 11 transactions, split into 1,000 BTC chunks in the same block | $1.47B |
| Tron | 20:20 to 20:22 | 612.7M USDT and 46.4M TRX | $627.5M |
| Ethereum | 20:24 to 22:39 | Binance 14 sweep, Binance 16 transfers, Hot Wallet 34 USDC, re-sweeps | $3.74B |
| Arbitrum | 20:30 | 8,426 ETH and 74.6M ARB | $31.8M |
| Avalanche | 20:33 to 20:35 | 1.81M AVAX and 8.41M USDt | $24.3M |
The very first move failed. At 20:04:52 a Binance XRP wallet sent 42.75 million RLUSD to the attacker’s XRP address, but that address did not exist yet, so the ledger bounced it. Eight seconds later 185 million XRP went through and created the account. Four more XRP wallets were emptied by 20:09. The bounce is a small tell. The RLUSD payment was queued before the account that would receive it existed, which points to a sequence scripted in advance rather than an operator improvising at a console.
The Bitcoin wallet is the clearest case of pre-planning. All 11 transactions landed in the same block, 973,732, and the funds were already split into 1,000 BTC pieces inside it. That is a peel chain set up before the first transaction confirmed. The BTC now sits in 19 wallets, 17 of them holding exactly 1,000 BTC, and has not moved since.
Ethereum’s $3.74 billion came out in five pieces: the 20:24:23 sweep of Binance 14 ($2.53B), nine plain transfers from Binance 16 at 20:24:47 ($174M), two USDC pulls from Hot Wallet 34 at 20:41 and 20:59 ($823M), two re-sweeps of Binance 14 at 21:04 and 21:44 ($210M), and one last sweep of 128 ETH and 122 small tokens to a fresh wallet at 22:39. By asset, the Ethereum haul was 1.87 billion USDT, 823 million USDC, 197,668 ETH, and about 60 other tokens.
The race against the freezes
The attacker knew the stablecoins would be frozen and moved to convert them before that happened. At 20:30, seven minutes after the sweep, 500 million USDT went to a fresh wallet. By 20:59 that wallet had sold 325 million to RFQ market makers for ETH, at a discount above 10 percent, and passed the remaining 175 million on. At 20:33 another 200 million USDT went to a second wallet, which sold about 10 million on DEXs and forwarded 190 million to a third, which deposited 60 million into Aave and borrowed ETH against it.
Tether’s first blacklists landed at 21:01:35, 37 minutes after the sweep. They caught the main receiving wallet with 971 million USDT still inside, and the first splitting wallet, already empty. Circle froze the 823 million USDC at 21:04:59. From there it became a chase measured in seconds:
- 21:01:59, a wallet sends 130 million USDT onward. Tether freezes it 48 seconds later.
- 21:04 to 21:11, two more hops sell about 100 million USDT on DEXs and pass the rest on. Tether freezes each one after it has emptied.
- 21:16:11, 30 million USDT is forwarded. Tether freezes the sender 36 seconds later and catches the 30 million at the next hop at 21:18:59.
- 21:14:59, the 175 million from the first split is frozen where it sat.
About 435 million of the 1.875 billion USDT on Ethereum was sold before the blacklists caught up. 1.38 billion is frozen and 60 million is stuck as Aave collateral.
The other issuers followed in order. World Liberty blacklisted 48.5 million WLFI at 20:57. Tether froze 8.41 million USDt on Avalanche at 21:07; the attacker tried to move it at 21:40 and the transaction reverted. Tether froze 378.7 million USDT on Tron between 21:09 and 21:21, but 234 million had already gone through SunSwap into TRX. Tether blocked 12,574 XAUt at 21:11. Ripple froze RLUSD at 22:00:59; the attacker had sold 48 million of it for ETH, with the last sale landing in the same block as the freeze, and 40.5 million was caught. World Liberty froze 27.8 million USD1 at 22:10. Paxos froze 1,907 PAXG at 22:30. Binance blacklisted 29,934 wBETH at 22:48. First Digital’s 3.45 million FDUSD was still unfrozen at the time of the trace.
The tug of war over Binance 14
Binance 14 stayed delegated to the attacker’s contract for most of the evening, and both sides kept acting on it.
- 21:04 and 21:44, the attacker re-sweeps new deposits: 1,700 ETH, then 370 ETH and 200.4 million USDT. The USDT lands in the main receiving wallet, which Tether had already frozen.
- 22:06:23, Tether blacklists Binance 14 itself. Binance’s own USDT sends from the wallet fail at 22:15 and 23:01.
- 22:39, the attacker sweeps again, this time to a fresh wallet: 128.5 ETH and 122 small tokens.
- 22:55 to 23:07, Binance empties Binance 14 itself, 46 token transfers to Binance 8, one every twelve seconds or so.
- 23:36 to 23:38, the attacker calls
sweep()four more times. All four come back empty. - 00:10:35 on 30 October, Binance revokes the delegation.
Off Ethereum, the Arbitrum funds moved at 21:35 to a fresh 7702 wallet, which approved the ARB for trading at 21:41. The Arbitrum Security Council later froze them. On Avalanche, 1.81 million AVAX moved at 21:45, and part of it was bridged to Ethereum as 1.56 million USDC through Circle’s CCTP at 23:27. Circle blacklisted the receiving address four minutes later.
What a DevOps laptop holds
The privileges on that workstation are the reason the chain works. A working DevOps laptop carries a specific set of them:
- Cloud IAM sessions and role assumption chains for production accounts.
kubectlcontexts and service account tokens for clusters that run customer-facing services.- CI runner registration tokens and pipeline trigger rights.
- Deploy keys, package registry tokens, and SSH agents for internal repositories.
- Container registry credentials with push rights.
- Browser sessions to admin consoles, with MFA already satisfied.
This is not a list of secrets that a password manager protects. It is a live authorization path. An attacker who controls the laptop does not need to crack anything. They inherit the engineer’s reachable internal surface, including the internal tools that accept an authenticated request and act on it.
The word “container” in Binance’s statement points at the same conclusion. A service container is a running workload with a network identity and a service account. Access to it is access to whatever that workload is allowed to do. If the workload can submit withdrawal transactions, then so can the attacker, and the transaction will carry valid authorization because the service is doing the authorizing.
The pattern is not crypto-specific
The large incidents of the last two years that reached a signing or publishing path share a starting point: a machine that a developer used every day.
| Incident | Date | Entry point | What the attacker reached |
|---|---|---|---|
| Bybit, $1.5B | Feb 2025 | A Safe developer’s machine | Malicious JavaScript in the signing interface; signers approved a payload the interface had altered |
| tj-actions/changed-files | Mar 2025 | A compromised token on a widely used GitHub Action | CI secrets printed into workflow logs across dependent repositories |
| Nx npm packages (“s1ngularity”) | Aug 2025 | Malicious package releases plus a local AI CLI | Developer home directories searched for keys, results published to public repositories |
| Shai-Hulud npm worm | Sep 2025 | Install-time worm in the npm ecosystem | Maintainer tokens, then further infected publishes from trusted packages |
| Binance, $6.3B | Oct 2026 | A DevOps engineer’s laptop | A service container, then the withdrawal service and hot wallet signing path |
The Bybit case was the warning shot. Attackers compromised credentials belonging to a Safe developer, used that access to alter the wallet provider’s interface, and waited for signers to approve what looked like a routine transaction. No key was extracted there either. The signing ceremony was real. The intent was not.
The extension ecosystem produces the same shape at smaller scale. Extensions run inside the editor with the developer’s own permissions and network access, which is why the campaigns Yeeth Security tracks on Open VSX and the VS Code Marketplace keep landing on developer workstations rather than on production servers. The shared RAT engine work is one example: the payload’s value is the machine it lands on, not the extension itself.
The pipeline signs, so the pipeline is the target
Security architecture has spent a decade moving trust away from people and into automation. That trade was correct. A human clicking “approve” 200 times a day is not a control. The problem is that the approval moved into systems that are configured by the same engineers, from the same laptops, using the same credentials.
The Binance incident shows what that looks like when it fails:
- The attacker obtained a developer-adjacent identity.
- That identity reached an internal service.
- The service produced a valid authorization.
- The chain accepted it, because everything about it was valid.
Signature verification cannot catch this. The signature was correct. The nonce matched. The contract was deployed and callable. Every check that asks “who authorized this” returned the right answer.
The only check that would have helped asks a different question: what does this transaction actually do, and is that within policy for this account, this chain, and this hour? Fifty authorizations signed in a batch against a hot wallet is not a normal payout. A delegation to an unverified contract deployed four hours earlier is not a normal payout. Five XRP wallets emptying to one address inside four minutes is not a normal payout. Those are intent signals, and they exist before the first token moves.
The same logic applies to build pipelines. A pipeline that can publish a package, sign a release, or push a container image is a signing authority. If an attacker can influence the pipeline, provenance attestations and SBOMs still verify, because the compromised pipeline produced them. Attestation is evidence after the fact. It is not a control at the moment of signing.
Outlook
Binance has promised a technical post-mortem and an updated proof of reserves. The post-mortem is the document to read, because it will describe how the laptop was compromised in the first place and which control let a single workstation reach the withdrawal path.
Three things are likely to follow from this incident.
The first is more attention on signer interfaces. Exchanges that depend on multisignature approval flows will review what their signers can actually see. A signer who approves a hash cannot catch a delegated sweep. A signer who sees a decoded intent can.
The second is pressure on hot wallet policy. EIP-7702 was not the cause here, but it showed what an attacker with access to a signer can do with one authorization: standing control over the account, for hours, with no further signatures needed. Expect signing services to refuse type-4 authorizations by default for custody wallets, and expect per-transaction limits, chain allowlists and destination allowlists to become standard for any account that holds customer funds.
The third is scope. Regulatory reporting duties for actively exploited vulnerabilities under the EU Cyber Resilience Act have applied since September 2026, and U.S. attestation requirements put secure-development evidence in scope for federal suppliers. An incident that starts on a developer machine and ends in a published or signed artifact is now a compliance event, not only a security one.
What defenders should change
- Treat developer workstations as production identity. Device-bound credentials, short session lifetimes, and conditional access on the tools that can reach production. A laptop that can deploy is a laptop that must be managed like a server.
- Separate the build identity from the signing identity. The system that compiles code should not be the system that authorizes a transfer, a publish, or a release. Where separation is impossible, require an out-of-band approval for the signing step.
- Scope service access to a single action. A container that submits withdrawals should not also be able to change withdrawal destinations, edit policy, or mint credentials. Blast radius is a design decision, not an incident finding.
- Make every authorization carry an intent. Decode the transaction, compare it to a policy for that account, and refuse batches that exceed the policy. Verify what is being approved, not only who approved it.
- Watch the pipeline’s own behaviour. Alert on new workflow definitions, changed action references, unexpected egress from runners, and publishes that no human triggered. The pipeline is an attack surface with a service account.
- Keep long-lived tokens off laptops. Repository tokens, registry tokens, and cloud keys with no expiry are the most portable thing an attacker can take from a workstation.
- Test the recovery path, not only the detection path. About half the loss was frozen because stablecoin issuers and networks moved within an hour of the first sweep. The other half sits in ETH and BTC that nobody can freeze. Know in advance who you would call, and how fast they can act.
The principle this incident teaches is narrow and uncomfortable: a signature proves who authorized a transaction, not what the transaction does. Any system that treats those as the same question will eventually authorize the wrong thing, and it will do so with valid cryptography and a clean audit trail.