At 14:06:10 UTC on Sunday, a peg-out was requested on the Liquid Network. Twenty-three minutes later a Bitcoin transaction confirmed in block 965,783 and about 4,000 BTC — roughly $320 million — moved to an address nobody at Blockstream controls.
Nothing was broken at that moment. No key was stolen. No signer was tricked. The federation looked at a withdrawal request, checked that it was properly formed and properly authorised, and signed it, because from where the federation stood it was indistinguishable from every legitimate withdrawal it had ever signed.
The theft had already happened, upstream, in a place with no money in it at all.
Twenty-five hours later most of the bitcoin came back. The reserve is still 602.67 BTC short, the network is still paused, and the mechanism that emptied it in twenty-three minutes has not changed.
The withdrawal that was indistinguishable from a real one
The clearest way to see this is to follow the money across the two ledgers it touches. L-BTC lives on Liquid; the bitcoin backing it lives on Bitcoin, in one wallet the federation signs for together.
01Liquid / tokens
L-BTC is created from nothing
A validation bug lets a transaction that should have been rejected be accepted instead. The result is L-BTC in a wallet with no corresponding bitcoin anywhere.
Block 4,050,336 · 13:53:10 UTC
02Liquid / tokens
The token is redeemed and burned
The tokens are sent to a peg-out service, which does what a peg-out service does: it destroys them and asks the federation to release the bitcoin they represented.
≈3,996 L-BTC burned
03Bitcoin / real BTC
The federation signs a normal payout
The request is well formed and comes from an authorised key. The federation has no way to ask whether the tokens being burned were ever backed — that question was answered upstream, wrongly.
Peg-out requested 14:06:10 UTC
04Bitcoin / real BTC
Real bitcoin leaves the shared reserve
The bitcoin paid out is not the attacker’s. There was none of theirs to pay. It comes out of the single pot that backs every other holder’s tokens.
4,002.67 BTC out · block 965,783 · 14:28:56 UTC
Read stage four again, because it is the whole article. The attacker was not paid from their own deposit. They were paid from everyone else’s.
Why a pooled reserve turns one bad token into everyone’s loss
Here is the part most of the coverage skips. If L-BTC were backed the way a safety deposit box is backed — your bitcoin in your box — a minting bug would be embarrassing and contained. You would hold a token that redeems for nothing, and everyone else would be untouched.
That is not how a peg works. Every L-BTC is a claim on one shared reserve, and claims are settled in the order they arrive. So a fake claim does not dilute the pot proportionally across holders. It is paid in full, first, and the shortfall lands entirely on whoever redeems last.
- Before the peg-out
- 4,200.14 BTC
- After the peg-out
- 197.47 BTC
- After 3,400 came back
- 3,597.47 BTC
Ninety-five per cent of the reserve left in one transaction on Sunday; most of it returned in one transaction on Monday. The balances are the federation wallet's own, read off the Bitcoin chain. The working below is ours.
Now the uncomfortable sum. If the reserve held about 4,200 BTC against about 4,200 legitimately issued L-BTC, and the roughly 3,996 tokens that were burned were the unbacked ones, then the legitimate tokens did not go anywhere. They are all still out there. What changed is what stands behind them:
Sunday 197.47 ÷ 4,200.14 = 4.7% backing each L-BTC
Monday 3,597.47 ÷ 4,200.14 = 85.7% backing each L-BTCStill out 602.67 BTC = 14.3% of the reserve
That second line is the whole difference between a dead peg and a damaged one. At 4.7% backing there is no honest way to reopen: the first holders in the queue take everything and the rest get nothing, so the only defensible move is to stop the queue, which is what happened. At 85.7% there is a reserve worth arguing over. The argument is now about 602.67 BTC — roughly $48 million — and about who eats it.
The 602.67 BTC and the 598.50 BTC sitting at the attacker’s address are not the same number, and the gap is worth a sentence. Of the 4,002.67 BTC that left the reserve, 3,996.00 reached that address; the remaining 6.67 went to the peg-out transaction’s other outputs and to the miner. The reserve’s books show 602.67 missing. Reporting has settled on “15%”, which is the attacker’s side of the ledger, not the federation’s.
The negotiation ran through OP_RETURN
There was no press conference and no intermediary. The entire exchange happened in messages attached to Bitcoin transactions, PGP-signed on Blockstream’s side, starting with the party holding the coins announcing “we are whitehats. contact us on chain”.
Sun 19:31 UTC Blockstream Please contact security@blockstream.com
Mon 02:20 UTC Attacker sending most back to bc1qdlld6…, is that ok
Mon 03:30 UTC Blockstream Yes, thank you
Mon 11:46 UTC Blockstream Bridge nodes are patched, safe to return the funds
Mon 12:16 UTC Attacker confirm again
Mon 16:09 UTC — 3,400.00000000 BTC lands · block 965,950
Read that for what it does not contain. “Most” is never given a number. Blockstream’s “Yes, thank you” answers a question about an address, not about an amount. No message on either side names 598.50 BTC, agrees to it, or calls it a fee, a bounty or a settlement. The 15% is not something that was negotiated. It is simply what did not come back.
The transaction itself is worth looking at too. Moving $269 million back to the federation cost a fee of 1,768 satoshis — about $1.40 — and every input was flagged replaceable, meaning the sender kept the option to pull it back until the moment it confirmed.
The fix that was written five weeks earlier
The most uncomfortable detail is not in the money at all.
On 3 August, a Blockstream engineer authored a one-file change to Elements — the software Liquid
runs on — titled fix: range proof cache bind to asset and scriptpubkey. Elements uses
Confidential Transactions, which hide amounts behind cryptographic range proofs. Verifying those
proofs is expensive, so results are cached. The change altered what the cache is keyed on: before,
the proof and the value commitment; after, the asset commitment and the output script as well.
A cache keyed too loosely will hand back a “valid” answer for a question it was never asked. That is the shape of an inflation bug: a proof verified once in a harmless context, replayed in a context where it should not hold.
That change was merged to the 23.x branch on 3 September. The pull request carrying it was merged on 6 September at 17:21 UTC — three hours after the peg-out confirmed. The most recent tagged release, 23.3.3, is from 13 April and does not contain it.
That is still true a day later, and it sits oddly beside the message Blockstream sent the attacker. The bridge nodes were declared patched at 11:46 UTC on Monday. Whatever they were patched with is not a released version of Elements: no new tag exists, and Blockstream has not said which build the federation will run when Liquid restarts.
There is corroborating evidence that something split consensus. Blockstream’s explorer accepted Liquid block 4,050,336; a node run by mempool.space rejected it and stopped one block earlier. Two nodes disagreeing about a block is the signature of a validation rule one of them applies and the other does not — which is the same thing as saying some nodes accepted a transaction other nodes would not have.
The mint itself cannot be read off the chain. Confidential Transactions hide amounts by design, so the block that created the unbacked L-BTC does not show it. The privacy feature works exactly as specified, and it makes this particular failure invisible to everyone but the people who ran the node that rejected it.
What is actually established, and what is not
This is a live incident, and the section below is current as of 19:30 UTC on Monday 7 September. The following is what the chain and the published statements support.
Established. 4,002.67 BTC left the federation wallet on 6 September, leaving 197.47. On
7 September at 16:09:25 UTC, transaction a6d697a2…a46d returned 3,400.00000000 BTC to the same
wallet, which now holds 3,597.47. The tokens were routed through SideSwap, a federation member
holding a whitelisted Peg-out Authorization Key. That key was used but was not compromised, and
SideSwap’s position is that “the L-BTC came from an Elements bug, not from any SideSwap system”.
The network was paused, bridge nodes were disabled and exchanges were asked to suspend L-BTC
deposits and withdrawals; all of that is still in force. Blockstream attributes the incident to a
software bug in Elements rather than to a key compromise.
Claimed, and consistent with the evidence. That the root cause is a range proof caching bug in Elements which allowed unbacked L-BTC to be minted and accepted by some nodes.
Not established. The exact mechanism of the mint. Whether the 3 August commit addresses it. Which Elements version the functionaries were running, and which one they will run on restart. Whether the remaining 598.50 BTC comes back, and whether anyone with authority agreed it could be kept. When peg-outs reopen. And the question that will outlast the incident: who carries the 602.67 BTC — Blockstream, the functionaries, SideSwap, or the holders.
What a holder can take from this
The lesson is not “sidechains are unsafe”. It is narrower and more useful, and it applies to every wrapped, bridged or pegged asset anyone reading this holds.
A peg is a claim on a pot, not a receipt for your own coins. Your exposure is not to your own token’s validity. It is to the validity of every other token in existence, because they all redeem from the same reserve and yours is not ring-fenced.
The security of a peg is the security of its issuance, not its custody. The federation’s keys were never at risk here. Multisig, hardware, geographic distribution — none of it mattered, because the money left through the front door with correct paperwork. The question worth asking of any wrapped asset is not “who holds the keys” but “what stops a token existing that nothing backs”.
A reserve is only auditable if you can see it. Proof-of-reserves on the Bitcoin side was perfect throughout: anyone could see the 4,200 BTC leave and 3,400 come back. The failure was on the liabilities side, and Confidential Transactions meant the liabilities could not be counted. An unauditable liability makes a verified reserve meaningless.
Whether you are repaid is a negotiation you are not in. The coins came back because the party holding them chose to send them, after an exchange conducted in transaction metadata, on terms nobody published. There was no court, no insurer and no clawback — and the 14.3% that stayed behind is the price of that. Every holder is a creditor in a workout they have no seat at.
Nothing here is advice, and none of it is a prediction about whether the last 598.50 BTC comes back. It is a count of what is actually in the reserve, and a note about which half of a peg is worth watching.
Sources
Every figure above comes from one of these, or from the working shown against them. Balances, amounts, block heights and transaction fees were read directly from the Bitcoin chain. This is a live incident and the reporting is moving; where an account is single-sourced, it is marked as such in the section above rather than here.
- The federation wallet on mempool.space — the balance before, after and now
- The peg-out transaction and the return transaction
- CoinDesk — $320 million exploit hits the Bitcoin network used by exchanges
- The Defiant — attacker broadcasts return of 3,400 BTC, keeps 598 — the on-chain message log
- Crypto Briefing — hacker returns 3,400 bitcoin, keeps 15% of the haul
- Bitcoin.com News — hackers return 3,400 BTC, keep $47M as the network stays frozen
- The Block — attacker says they will return most of 4,000 BTC after a bug fix
- defiprime — peg-out exploit: block heights, timestamps, the commit and the consensus split
- Unchained — Liquid sidechain frozen after a “white hat” drains the reserve