Root Cause
Liquid Network's Elements software validates Confidential Transactions using rangeproofs — zero-knowledge commitments proving output values are non-negative without revealing amounts. Because full rangeproof verification is computationally expensive, Elements maintains an in-memory cache.
The bug: the cache key was computed from rangeproof bytes alone, omitting asset identifier and script context. This created an ambiguity where two structurally different validation inputs could produce the same cache entry. An attacker could prime the cache with a legitimately valid proof, then reuse that cached result for a second transaction representing unbacked, inflated L-BTC. The node would return VALID from cache without re-running verification.
# Simplified pseudocode of the flawed cache lookup (Elements before patch):
def verify_rangeproof(proof_bytes, asset_id, script_ctx):
key = sha256(proof_bytes) # BUG: asset_id and script_ctx excluded
if key in cache:
return cache[key] # Stale/colliding result returned
result = full_verify(proof_bytes, asset_id, script_ctx)
cache[key] = result
return result
# After patch:
def verify_rangeproof(proof_bytes, asset_id, script_ctx):
key = sha256(proof_bytes + asset_id + script_ctx) # Fixed: all context included
...
Critically, the fix was committed to the public Elements GitHub repository on September 1, 2026 — five days before the exploit — with a descriptive commit title and diff that identified the exact vulnerable function. No production-tagged release containing the fix had been deployed to any federated node by the time of the attack. Independent technical analysis from CertiK and others concluded the attacker most likely reverse-engineered the exploit by reading the patch.
Attack Steps
| Step | Action |
|---|---|
| 1 | Attacker monitors public Elements GitHub repository; identifies Sept 1 security-relevant commit |
| 2 | Reverse-engineers cache key collision from the diff; constructs exploit transactions |
| 3 | Submits a "primer" transaction to populate the verification cache with a crafted valid rangeproof entry |
| 4 | Submits malicious "inflation" transaction whose proof bytes collide with the cached key, minting ~4,000 unbacked L-BTC |
| 5 | Redeems unbacked L-BTC through SideSwap (an authorized peg-out pathway), withdrawing ~4,000 BTC from the federation wallet |
| 6 | Full drain completes in ~23 minutes; 95% of reserves (3,997 of ~4,200 BTC) removed |
| 7 | Attacker announces intent via Bitcoin OP_RETURN messages claiming white-hat status |
| 8 | Blockstream emergency-patches all federation nodes; attacker returns 3,400 BTC (~$268M) on Sept 7 |
| 9 | 598.5 BTC (~$47M) retained by attacker as informal bounty |
Impact
- Gross exploit value: ~$320M (3,997.5 BTC at ~$80,000/BTC)
- Recovered:
3,400 BTC ($268M) returned September 7, 2026 - Permanent net loss: ~598.5 BTC (~$47M)
- Systemic disruption: Liquid Network peg temporarily suspended; L-BTC traded at a ~28% discount on secondary markets before restoration
- Federation layer not breached: The 11-of-15 multisig and Peg-out Authorisation Keys (PAKs) were not compromised — the exploit bypassed security entirely at the node-validation layer
- Chain: Bitcoin (Liquid sidechain); exploit used an authorized peg-out mechanism (SideSwap) to exit to mainchain BTC
Lessons for Auditors
- Patch disclosure timing is an attack surface. Publishing a security fix before all nodes are upgraded creates a patch-differential window where attackers can reverse-engineer exploits faster than operators deploy mitigations. Critical patches to multi-operator infrastructure should be staged: private coordinated deployment first, then public disclosure after >90% of nodes have upgraded.
- Cache keys must encode ALL semantic context. Any caching of expensive cryptographic checks must key on every input that influences the validity determination — including asset type, script, commitment context, and execution flags. Missing any dimension creates a collision surface.
- Authorized exit pathways are high-value attack complements. The attacker exited through SideSwap, a legitimate peg-out mechanism. Trusted exit pathways must enforce invariants server-side (e.g., verify BTC reserves match L-BTC supply) as an independent check, not rely solely on node-layer validation.
- Confidential Transaction systems need cache-collision regression tests. Add explicit test vectors for rangeproof cache collision scenarios to Elements and any fork; CI should fail if a proof validates under one asset context but the cached result is accepted under a different one.