Liquid Network lost 3,998 BTC to a bug already fixed on GitHub
A cache bug minted 3,998.5 L-BTC that no bitcoin backed. The fix was committed to the Elements repo on 3 August, and no tagged release carries it.
The Editors · 9 min read ·
Someone minted 3,998.5 L-BTC out of nothing on 6 September 2026 and redeemed it for real bitcoin. About $318.7 million left the Liquid federation wallet in roughly fourteen minutes, around 95% of everything backing the sidechain. Blockstream paused the network the next morning. It is still paused.
No key was stolen. Blockstream's incident notice says SideSwap's peg-out authorization key was not compromised, and neither were any others. The 11-of-15 hardware-secured federation multisig did the job it was built for. It signed a withdrawal that looked valid, because on the network's own books it was valid.
The bug sat in Elements, the software Liquid runs on. The fix for that bug was committed to the public Elements repository on 3 August, merged to master on 1 September, and cherry-picked onto the release branches on 2 and 3 September. The exploit ran on 6 September. Every tagged Elements release, including the newest one, predates the fix.
That is the part worth reading twice.
Fourteen minutes on 6 September
CertiK's forensic reconstruction puts a setup transaction at 13:52:10 UTC and the inflation transaction one minute later, at 13:53:10. Two peg-outs followed: a 2.65 L-BTC probe at 14:01:10, then 3,996.02 L-BTC at 14:06:10. Together, 3,998.5 L-BTC, worth about $318.7 million at the time.
The reserve fell from about 4,205 BTC to about 202. Other counts put the residue at 197. Nobody has published a reconciled figure, so read the leftover as roughly 200 BTC. The timings differ across accounts too: crypto.news places the main peg-out at 14:28:56, twenty-three minutes after the mint, against CertiK's 14:06:10. Both agree it was over inside half an hour.
At 18:30 UTC the attacker wrote to Blockstream on the Bitcoin chain itself, in an OP_RETURN output: we are whitehats, contact us on chain. Blockstream halted block production at 04:49 UTC on 7 September and disabled the public bridge nodes, so no new transactions could reach the network at all.
The bug: a hash with nothing separating the fields
Liquid runs confidential transactions. Amounts are hidden, and every output carries a range proof that shows the hidden amount sits inside a legal range. Verifying a range proof is expensive, so Elements caches the answers: check once, remember the result, skip the maths when the same proof turns up again.
The cache key was built by hashing four things end to end. The range proof, the commitment, the asset generator, the script. One SHA-256 over the concatenation, with no field lengths and no separators.
Concatenation without delimiters is ambiguous. Shift a few bytes across a field boundary and you get a different set of four values that flatten into an identical byte stream, and so into an identical key. CertiK publishes the exact pair the attacker used. Both reduce to the same 4,301-byte stream.
So the sequence is short. Send a legitimate transaction to park a "verified" answer in the cache under that key. Send a second transaction whose range proof is garbage but whose cache key collides with the first. The lookup runs before the commitment is parsed and before the real verification function is called. Cache hit, returns true, no maths. The range proof is the one thing standing between a hidden amount and an arbitrary one, and it got answered from memory.
That is how you mint 3,998.5 coins that no bitcoin backs, on a network whose reserve is public and auditable, without touching a key.
The fix was thirty-four days old
The commit that closes this hole is titled "Fix caching bug in rangeproof caching". It was authored on 3 August 2026, merged into Elements master on 1 September, and cherry-picked onto the elements-23.x and elements-23.3.x branches on 2 and 3 September.
The exploit ran on 6 September.
Now look at the releases page. The newest tagged Elements release is elements-23.3.3, dated 13 April 2026, and there is nothing after it. Whatever the functionaries were running, no tagged release available to them carried the fix, because no tag has been cut since four months before the fix was written.
CertiK is careful here, and so should anyone else be: the exact binaries deployed on each functionary have not been published, so nobody outside the federation can say which build was live. Both readings are uncomfortable. If the functionaries ran the April tag, they sat 34 days behind a public fix. If they ran master, they had the patch on 1 September and were five days late applying it.
A security fix pushed to a public repository ahead of production is a countdown. The commit tells anyone reading the repo where the bug is and roughly how to reach it. Elements being open source is a feature right up to the moment the disclosure order runs backwards, and here it ran backwards for at least four days on a branch and 34 on master.
Two ways a peg fails. One of them gets audited.
A pegged asset has two failure surfaces. Someone can take the keys to the reserve. Or the issuer can create more claims than the reserve covers.
Liquid's published security model, and the reserve-watching people do on top of it, speaks to the first. The federation address is public. Anyone can check the balance. That verifiability held for the entire drain and changed nothing, because the withdrawal came through the front door as a peg-out the network considered legitimate. The balance you were watching went down for a reason the chain called valid.
This generalises well past Liquid. Any wrapped bitcoin, any bridged asset, any tokenized claim on something held somewhere else, has an issuance side and a custody side. An attestation reading "we hold 4,205 BTC" answers a custody question. It says nothing about how many claims the software has issued against those coins. Two different systems produce the two numbers, and one of them gets far more attention than the other.
It is also the second bitcoin security story this year to land somewhere other than where the product's threat model pointed. Coldcard's $130 million incident came out of a bug in the device software, with the cold storage design working as advertised.
What an L-BTC is backed by right now
At 18:09:25 UTC on 7 September the attacker returned 3,400 BTC to the federation address and kept 598.5 BTC, about $47 million, sent as change on the return transaction.
L-BTC in circulation did not fall. The unbacked coins were destroyed on peg-out, so supply is roughly where it started, near 4,205, against roughly 3,602 BTC now held. That works out to about 86 cents of bitcoin behind each L-BTC, which is the figure crypto.news reports independently and which matches the arithmetic.
Nobody can act on that number today. The network is paused, the bridge nodes are down, exchanges have suspended L-BTC deposits and withdrawals, and Blockstream's status page still reads Active. Whether an L-BTC holder ends up absorbing a 14% shortfall depends on two decisions that have not been made public: whether the remaining 598.5 BTC comes back, and whether Blockstream or the federation members cover the gap if it does not. No public commitment exists either way.
The 598.5 BTC that stayed
The attacker set their own fee. 598.5 out of 3,998.5 is a shade under 15%. There was no bounty agreement, no published cap, no negotiation with a stated ceiling. The message said whitehats. The funds moved once Blockstream confirmed its bridge nodes were patched and safe for a return. The 15% left with them.
The arithmetic names it: an unpriced fee, collected in a situation where refusing to pay was worse for the counterparty than paying. That is a norm forming in public, and every federation and bridge operator now has a reference point for what a drain costs when the person holding the funds chooses to give most of them back.
The other side is true as well. Blockstream closed about 85% of a $318 million hole inside 36 hours, which beats most bridge incidents on record. Both things sit in the same story.
What to watch
An Elements release. The repository has not cut a tag since 13 April. A 23.3.4 carrying the range-proof cache fix, plus a note on which builds the functionaries run, would answer the question CertiK could not.
A post-mortem naming deployed versions. The status page is an operational notice. It says the keys held and the bridge is down. It does not say what was running when the cache returned true.
The 598.5 BTC. It sits at an address anyone can watch. If it moves back, L-BTC is whole and this becomes a story about patch discipline. If it stays put, somebody has to decide who absorbs roughly $47 million, and L-BTC holders find out whether a federated peg comes with anyone standing behind it.
If you hold a wrapped bitcoin of any kind, ask its issuer what stops the software from issuing a coin the reserve does not cover, and who checks that answer. The key custody question already has a published answer on most of these products. The issuance question usually does not.
Sources
- CertiK, Liquid Network Incident Analysis, retrieved 9 September 2026
- Blockstream, Liquid Security Incident status page, incident opened 7 September 2026, still marked Active
- ElementsProject/elements releases, GitHub, elements-23.3.3 dated 13 April 2026, retrieved 9 September 2026
- crypto.news, Liquid Network drained of $320M in cache bug exploit, 8 September 2026
- The Hacker News, Liquid hackers return 3,400 bitcoin taken via Elements bug, 8 September 2026
- Crypto Briefing, Blockstream confirms bridge nodes patched, funds safe to return, 7 September 2026
This is not financial advice.