The dotUSD XCM bug that cost the Polkadot Treasury about $1.38 million last month had already been fixed in code for four months. It just never made it into the runtime that was running on Asset Hub.
That is the central admission in the incident review Parity Technologies published on the Polkadot forum late on Monday. The report covers the attack on dotUSD, the network’s native stablecoin, between 24 and 26 October, and it is unusually direct about where the process broke down.
What the attacker actually did
XCM, the messaging format Polkadot chains use to move assets, is supposed to be all or nothing. If a program fails, none of its changes should stick. Parity said a bug in the XCM executor on Asset Hub broke that rule in certain cases.
The attacker built programs around the WithdrawAsset instruction that failed on purpose. The account debits were correctly reversed, but the matching cut to dotUSD’s recorded total supply was not. Run that loop enough times and the chain believed far fewer dotUSD existed than were actually sitting in wallets. Parity’s first notice on 26 October put the gap at roughly 4.06 million dotUSD.
On its own, that is a bookkeeping error. It became a money problem because of how the Hub’s built-in exchange priced the DOT/dotUSD pool. The exchange treated the pool’s dotUSD reserve as the smaller of two numbers: what the pool held, or the asset’s total recorded supply. Normally the second number is always bigger, so the cap never matters. Once the recorded supply fell below the pool’s real balance, the pool started quoting a distorted rate, and traders swapped dotUSD for DOT at prices that should not have existed.
The only liquidity provider in that pool was the Polkadot Treasury. Parity estimates the loss at about $1.381 million in DOT and says no user funds were lost. It also says on-chain evidence has not shown that whoever triggered the bug was the same party that profited from the arbitrage.
The stablecoin itself held up. dotUSD stayed fully backed, and its Peg Stability Module kept minting and redeeming at 1:1 against USDT throughout. The understated supply did restrict redemption capacity until it was corrected.
A fix that sat on the shelf
The part of the review that will draw the most attention is the timeline. Parity said the flaw was reported through its bug bounty programme in June 2026 and fixed in pull request #11910, which GitHub shows was merged on 25 June. It was rated medium severity at the time, because dotUSD had not launched and nobody had mapped how the bug would interact with it. It has since been reclassified as critical.
The fix missed the cut-off for the stable-2606 release of the Polkadot SDK, was folded into stable-2609 instead, and was not included in the production runtimes that were hit.
Then came the disclosure dispute. On 20 October, Parity said, the same researcher who had filed the bounty report posted a public forum comment pointing to PR #11910 as a vulnerability fix. Parity said that broke the programme’s terms, and that the comment was deleted a few hours after it raised the issue with the reporter. Parity believes the comment may have handed attackers enough context to find the bug and reach it through other routes in the days that followed. Parity did not name the researcher.
Four days, two runtimes
Ecosystem partners flagged suspicious activity on 24 October, and Parity said it reproduced the issue within hours. The attack messages had come from Ethereum over Snowbridge, though Parity stressed the bug sat in the XCM executor and was reproduced without the bridge. Snowfork halted its own consensus relayers, which stopped the attack for a while, and Runtime 2.5.1 with the fix went to OpenGov the same day.
On 26 October the attacker ran its own consensus relayer and resumed, about six hours before the upgrade was applied on-chain. Parity then moved what was left in the pool to safety. Referendum #1961 followed on 27 October, and Runtime 2.5.2 was enacted on 30 October. That upgrade rebuilt dotUSD’s recorded supply from actual account balances, without touching any holdings, and fixed a Snowbridge weight problem the first patch had caused. The recovered dotUSD went back to the Treasury.
For a sense of how cross-chain plumbing keeps failing in new ways, our earlier look at the $35 million wave of bridge hacks covers similar ground.
What Parity says will change
The review lists three areas of work:
- Detection: reassessing bug reports as new features ship, more testing of XCM failure cases, and an automated agentic framework that scans pull requests and existing code.
- Speed: simpler release and backport processes, and checks that a merged fix has actually reached deployed runtimes.
- Monitoring: alerts for unusual changes in asset issuance, plus clearer incident response steps.
Parity is also reviewing existing security reports to see whether any should be upgraded now that dotUSD is live, and it cited the risk of increasingly sophisticated AI-assisted attacks.
The lesson travels beyond Polkadot. A medium-severity bug became a critical one because a new product was built on an assumption the bug could break, and a DEX trusted a supply figure that turned out to be writable by an attacker.
FAQ
Did dotUSD holders lose money?
Parity says no. Account balances were never changed, dotUSD stayed fully backed, and the Peg Stability Module kept 1:1 USDT redemptions running. The loss fell on the Treasury’s liquidity position.
How much was lost?
About $1.381 million in DOT, according to Parity’s review. The first notice on 26 October estimated $1.3 million.
Is the bug fixed on-chain now?
Yes. Runtime 2.5.1 carried the XCM fix, and Runtime 2.5.2, enacted on 30 October, corrected dotUSD’s recorded supply.
Disclaimer: This article is for informational purposes only and does not constitute financial advice.


















