Skip to content
Cutaway of a machined reserve vessel packed with teal ingots, one band of which is a hollow facade behind flush faces, while a gloved hand widens the red end-stop on its gauge
exploitsSeptember 15, 20264 min read

Nomic's 40.65 BTC nBTC Mint: An Escrow Self-Transfer Left Osmosis allBTC 36% Unbacked

Dmitry Serdyuk
Dmitry SerdyukCo-Founder & CDO

Updated on September 15, 2026

TL;DR

On June 25, 2026, a single Nomic transaction emitted 25 identical ICS-20 transfer packets and minted 40.650602 BTC of nBTC on Osmosis with no Bitcoin behind any of it, all of it reconstructed in the incident's forensic report. Two small bugs had to combine: Nomic's ibc_deliver never checked that the transaction signer matched the packet sender, and its escrow accounting aliased when sender and escrow were the same key, so the escrow could pay itself, net to zero, and still commit the packet. The counterfeit went into the Osmosis allBTC transmuter and counted as collateral for 74 days. It went unexamined until Nomic's chain halted on September 7 for an unrelated reason. The static rate limit capping nBTC at 35% of the alloy trapped 56.9% of the money in place, and ten days after it bound, governance moved to raise it.


How Did One Nomic Block Mint 40 BTC of Counterfeit nBTC?

The mint was one transaction. Nomic block 33137470 carried BEE54496B351A018D092779FE6C833238E1CDF965FE9761A572934F37932E028, 25 identical MsgTransfer messages on a fee-exempt path with no gas metering. The packets took sequences 9286 through 9310 on channel-1 to channel-6897, all proving against a single Nomic block at 21:50:03.614 UTC, and Osmosis credited every one of them 4.4 seconds later at block 64910685.

Every packet carried the same amount: 1.626024 BTC, exactly 98% of the 1.659208 BTC that existed on that channel beforehand. The forensic report records the sender field on all 25 as nomic1kq2rzz6fq2q7fsu75a9g7cpzjeanmk685ak9g7, the channel's own escrow address.

That is the whole trick. The escrow account sent Bitcoin to itself, 25 times, in one block, and each send moved 98% of a balance that never actually changed.

The report puts no dollar figure on the full mint. It does price the frozen tranche: 22.650608 BTC at $1,792,773. At that price the whole 40.650602 BTC is about $3.2M, and the portion that got away is about $1.4M. We quote Bitcoin throughout for that reason.


What Are nBTC and Alloyed BTC?

nBTC is Nomic's bridged Bitcoin. Nomic's validators act as signatories on a Bitcoin multisig reserve, and more than 90% of that set by voting power must sign before reserve funds move. The protocol's own documentation states the guarantee plainly: "nBTC is always backed exactly 1:1 by BTC held in the decentralized custody reserves." The Bitcoin side of that promise held: Nomic's checkpoint ledger from December 31, 2025 through September 6, 2026 reconciles to a discrepancy of 0.000000 BTC. The counterfeit was created on Nomic's own ledger, then exported.

Alloyed BTC is a transmuter. allBTC unifies Bitcoin liquidity from several bridges behind one Osmosis token, and converting a constituent into the alloy is a 1:1 swap with no slippage, fee or price impact. Each constituent carries a static rate limit capping its share of the alloy. As Osmosis Proposal 1031 puts it, the caps exist "so that Osmosis's exposure to any one bridge is bounded even if that bridge is compromised."

An alloy that accepts a fake constituent at par converts counterfeit into real Bitcoin exposure in one transaction. The counterfeit never has to be sold into a market that might price it. It only has to be accepted as collateral.


The Root Cause: Two Bugs That Only Work Together

Neither bug is exploitable alone. Both sit in public source.

Bug A is a missing authorization check. ibc_deliver in src/app.rs accepts a raw IBC transaction and passes it straight to the IBC handler without verifying that the account that signed the transaction is the account named as the ICS-20 packet sender. Anyone could submit a packet claiming to be from any sender, and that includes the channel's escrow account. This is CWE-862, Missing Authorization.

Bug B is an aliased read-modify-write. escrow_coins_execute in the orga framework opens two separate entry handles into the same balance map, one for the sender and one for the escrow address, then debits the first and credits the second:

let mut from_balance = denom_balances.entry(*from_account)?.or_default()?;
*from_balance = (*from_balance - amount).result()?;
 
let mut escrow_balance = denom_balances.entry(escrow_address)?.or_default()?;
*escrow_balance = (*escrow_balance + amount).result()?;

When from_account and escrow_address are the same key, those are two live handles to one entry. The debit and the credit land on the same balance and cancel. Net change: zero. The escrow's balance check passes because nothing left it, and the IBC packet commits regardless.

ICS-20 treats the escrow account as a distinct module-owned counterparty that holds the source-chain asset while the voucher circulates. The moment the escrow can also be the sender, escrow stops being a transfer of custody and becomes a formality. Bug A made the escrow a permitted sender. Bug B made that self-transfer free. Twenty-five times in one block, 98% of supply each time, and Osmosis credited every packet.


The Attack, Step by Step

#When (UTC)ActionDetail
1Jun 23, 02:56Dry runAddress created two days earlier tests the path with 0.06 BTC
2Jun 25, 21:50The mintOne Nomic tx, 25 identical MsgTransfer packets, escrow as sender
3Jun 25, 21:50Credit on Osmosis40.650602 BTC of nBTC credited at block 64910685
4Jun 25, 21:59Extraction beginsAround 18 BTC pushed into the allBTC transmuter within 22 minutes
5Jun 25 to Jun 28Laundering671.1 ETH into Tornado Cash across 33 deposits, two sessions
6Jul 15, 11:16Rate limits addedOsmosis adds an IBC quota once nBTC appeared to have real usage
7Jul 17, 22:44Final conversion22.650608 BTC converted to allBTC, then never moves again
8Sep 7, 07:02Nomic haltsCheckpoint solvency panic, tracked as PR #340
9Sep 7, 17:24Shortfall foundOsmosis audits Bitcoin backing, finds the 74-day hole
10Sep 7, 21:55Emergency upgradev31.1.0 released to freeze the attacker's 22.650608 allBTC
11Sep 8, morningFreeze bindingTwo-thirds of voting power activates the freeze

Where Did the Money Go?

The exit was two routes meeting at one address. Counterfeit nBTC went into the allBTC transmuter at pool 1868, and the allBTC that came out left Osmosis by Axelar GMP through a Squid executor and by Noble CCTP to Ethereum domain 0 under nonces 349050 and 349052, where $112,509 of USDC was sold for ETH. Both paths converged on 0x8f36fd9ffc0a8ca373aa7a4787292536a489d2b5.

From there it went into Tornado Cash in two sittings, 439.1 ETH on June 25 and 232.0 ETH on June 28, across 33 deposits split among the 100, 10, 1 and 0.1 ETH pools. Protos valued that 671.1 ETH at roughly $1 million at the time. It was all of what was extracted, and none of it is recoverable.

rendering diagram…

Why Did It Take 74 Days to Notice?

Because nothing in the system was watching the one number that mattered: nBTC in circulation against Bitcoin in the reserve.

Osmosis is accurate about its own scope. The asset-list warning its team merged on September 14 is the protocol's own one-sentence account: "A double-spend in the Nomic bridge's forwarding logic minted nBTC on Osmosis without Bitcoin backing." Osmosis has also said that neither its chain nor IBC was compromised, as CryptoSlate reported, and that reading holds. IBC delivered exactly what Nomic told it to deliver. The packets were well-formed and correctly proven. There was no replay, no light-client forgery, no signature problem. The lie was upstream of the transport, and every downstream check was checking the transport.

Those tooltips are their own small timeline: on September 7 and 8 they said only that the chain had halted, cause under investigation. The exploit was not named until September 14.

Two things did fire in July, and both were read as traffic rather than as alarms. Somebody noticed activity. Nobody asked what was generating it.

The thing that eventually surfaced the hole was unrelated to the attack. Nomic halted on September 7 at 07:02 UTC because a building checkpoint could not cover its own outputs and miner fees, an accounting failure the team tracks in pull request #340 and which remains open. The halt prompted Osmosis to check the Bitcoin backing behind nBTC. That check is what found it, ten hours later.


Did the Cap Save the Money, or Did Luck?

The 35% static cap on nBTC bounded the transmuter route. The forensic report's timeline is blunt about the effect: on July 17 the attacker "over-fills past the 35% cap and traps their own exit." That is why 22.650608 allBTC, 56.9% of the shortfall, was still in an attacker-controlled account on September 7 where a chain upgrade could reach it.

The report is equally blunt that the cap does not get all the credit. A pool sale was open the whole time and the attacker never took it, and when Proposal 1031 reopened the transmuter route on August 1 they did not act on that either. The position never moved again, its account sequence number still 15 when the freeze landed. The report's verdict on the preservation is "more by fortune than design," and we will not upgrade that into a win for the control.

What the cap did reliably is generate a signal. Ten days after the attacker pinned nBTC against it, Proposal 1031 went on-chain on July 27 and passed on August 1, lifting nBTC from 35% to 60%. Its rationale is a fair summary of what the data looked like from outside: "nBTC's static limit has been raised steadily as the Nomic bridge has demonstrated reliability and demand has grown." The proposal noted that nBTC "now sits at roughly 33% of the alloy, effectively at its cap," and that deposits through Nomic were being rejected as a result, "adding friction for users bridging via that route."

Nothing available to voters indicated the position was fabricated, and nobody connected the pin to an exploit. But the arithmetic is not ambiguous. The Osmosis recovery proposal lays out the alloy's composition: 110.570944 shares outstanding, 70.731198 BTC of real collateral in WBTC and cbBTC, and 39.839746 BTC of unbacked nBTC. Every nBTC in the alloy was counterfeit. The demand that filled the nBTC leg to its cap was one attacker's forged vouchers pressing against the only control that was stopping them.

The rate limits inverted the same way. Osmosis added an IBC quota on July 15 once nBTC looked like a used asset, and as the report puts it, "by then the supply that justified them was itself the counterfeit."

A rate limit that binds is telling you something. The one on nBTC said it plainly on July 17, and it was read as a growth metric.


Who Pays for the Hole?

Osmosis paused allBTC minting, redemptions and Nomic deposits on September 9, leaving trading pools live. The recovery proposal posted to the forum on September 10 asks governance for four things: cancel a pending USDC liquidity redeployment to free roughly 7.75 BTC of community-pool Bitcoin, spend community-pool allBTC against the 17.189137 BTC shortfall, approve an upgrade transferring the frozen 22.650608 allBTC at osmo1wq76r2mhqsa9yaygghuwyq4wy6dcsgf8vtzltn to the Liquidity subDAO, then mark nBTC corrupted inside the transmuter, withdraw it and burn it.

The proposal does not dress up what step three is: "This is a major decision: it reassigns a user's balance by state change." A validator-coordinated freeze of one account is a power most Cosmos chains hold and almost never use, and the proposal argues for it on the forensic record, not on urgency.

As of September 15, 2026, that resolution is still a forum thread with no on-chain vote. allBTC holders are 63.97% backed.

Nomic has said nothing publicly. Its account has not posted since November 2024, when it announced the completion of a security audit; nothing in the public record establishes whether the forwarding path that failed here was in that audit's scope. Of the 40.650602 BTC minted, 39.839746 landed in the alloy and roughly 0.8 remains loose on Osmosis, against a Nomic reserve of 0.746 BTC. The chain is halted, so none of it is redeemable.


What This Generalizes To

Every voucher-issuing branch is a mint authority. A bridge's security review concentrates on what looks like custody: the multisig, the signatory threshold, the checkpoint logic. Nomic's custody was fine. What failed was a transport path that could emit a packet, and a packet that can be emitted is a coin that can be minted on the other chain. Every function that can produce an outbound transfer message deserves the same access-control review as a mint().

An aggregator inherits the worst of its constituents at par. allBTC did what it was designed to do and accepted a constituent at 1:1 with no price impact. That is what makes alloys useful, and what turns one upstream bug into a frictionless conversion of counterfeit into real collateral. The static caps were the right answer to that risk. They were also treated as a growth parameter, raised steadily as the bridge "demonstrated reliability" and then lifted again to 60% once the cap bound.

When two chains disagree about a supply, one of them is wrong, and the check is cheap. nBTC on Osmosis versus BTC in Nomic's reserve is a subtraction. It was wrong by 40 BTC for 74 days. Nobody ran it.

This is the second Bitcoin-peg inflation of the month. Liquid Network lost 3,998.5 L-BTC to a rangeproof cache-key bug disclosed three days before this one, and the shape rhymes: a verification shortcut in the layer that decides whether an asset exists, and a supply invariant that nobody was differencing in real time.


What Operators Should Do

  1. Difference your supply against the reserve on every block, not on incident. For any bridged asset, destination-chain supply minus verifiable source-chain reserve is a number you can compute continuously. This one broke in a single block on June 25 and stayed broken until September 7.
  2. Treat a rate limit that binds as a page, not a ticket. A constituent pinning against its cap is either genuine demand or an attack, and the two look identical from the cap alone. Alert on the pin, then go find out which. Raising the limit answers the question in the attacker's favor.
  3. Access-control every path that can emit a cross-chain message. Assert that the transaction signer is the packet sender. Assert that an escrow account cannot appear as a sender on its own channel. Both are one-line invariants and both were absent.
  4. Test the self-referential case in balance accounting. The aliasing bug needs from == to to trigger, which is the case almost nobody writes a test for. Fuzzing the ICS-20 handlers with sender equal to escrow would have produced it in minutes.
  5. Audit the forwarding path with the same weight as the custody path. Nomic's custody was sound and its reserve accounting exact. The money was invented one layer above, in code that looked like plumbing.

An audit would have had a real chance at both bugs. They are code, they sit in a public repository, and they are the kind of finding a focused review of an ICS-20 escrow implementation is built to produce. That is the honest read, and it points at Full Audits rather than at monitoring.

The 74 days is a different failure, and it is the one monitoring owns. Four events here were alarmable, each already a figure above. A single transaction emitting 25 identical ICS-20 packets on a fee-exempt path. Each packet moving 1.626024 BTC, 98% of the 1.659208 BTC that existed on the channel. An nBTC supply on Osmosis stepping to 40.650602 BTC against a Nomic reserve that never carried anything close to it. And around 18 BTC hitting the transmuter nine minutes later, inside a 22-minute window. Any one of those fires at 21:50 UTC on June 25. Alerting would not have stopped that first block, which was atomic. It would have collapsed 74 days into minutes, and the laundering did not finish until June 28. That is a three-day response window against a freeze power Osmosis demonstrably has and used, just 74 days late and 43.1% of the shortfall too late.


Frequently Asked Questions

Was Bitcoin itself or IBC compromised? No. Nomic's reserve accounting reconciles to a 0.000000 BTC discrepancy from December 31, 2025 to September 6, 2026, and IBC delivered well-formed, correctly proven packets. The counterfeit was created in Nomic's own ledger, then legitimately transported.

How much was actually lost, and how much is recoverable? 40.650602 BTC of nBTC was minted, roughly $3.2M at the price the forensic report uses for the frozen tranche, and 39.839746 BTC of it ended up inside allBTC. Of that, 22.650608 BTC is frozen in the attacker's Osmosis account and recoverable if governance approves the seizure, which is 56.9%, leaving a 17.189137 BTC shortfall in the alloy. What the attacker actually carried off Osmosis came out the other end as 671.1 ETH, and all of it went through Tornado Cash.

Is allBTC safe to hold right now? allBTC is 63.97% backed as of the recovery proposal. Minting, redemptions and Nomic deposits are paused, trading pools remain open, and the Osmosis frontend now flags frozen or corrupted assets. The proposal to restore full backing had not reached an on-chain vote as of September 15, 2026.


Sources / References

Dmitry Serdyuk
Dmitry Serdyuk

Co-Founder & CDO

Full-Stack Operator | Building across security, AI, and digital infrastructure.