Skip to content
Top-down isometric bank booth: a hooded figure slides teal banknotes with red-glowing edges through a counter slot to a gloved teller whose counting machine shows a teal approval lamp, while the vault shelves behind stand mostly bare under red light
exploitsOctober 27, 20264 min read

Initia's $2.7M Exploit: A MoveVM Cache Bug Printed Balances the Bridges Paid For

Dmitry Serdyuk
Dmitry SerdyukCo-Founder & CDO

Updated on October 27, 2026

TL;DR

At 14:59 UTC on October 23, 2026, an attacker used a bug in the script cache of Initia's MoveVM to credit themselves unbacked WETH, iUSD and USDC on the Initia L1, according to Initia's own account. They bridged roughly $2.7M of real assets to Ethereum before the L1 and its rollups were halted at 15:41:30 UTC: 105 WETH and about 1.4M AUSD through LayerZero (Initia's statement names the bridged token AUSD0), and about 1.08M USDC through Noble and Circle's CCTP. Every Ethereum-side release we checked was a valid, correctly attested message. The lockboxes paid at par because nothing on Ethereum can tell a burn of a forged balance from a burn of a real one. The stablecoins were swapped to ETH within minutes, and together with the 105 ETH everything sits as 1,135.52 ETH in one wallet. Initia says native INIT supply is unaffected, a patch is being written and audited, and it had published no post-mortem or restart date as of October 27. A bridge lockbox insures the mint logic of every chain it connects to, at par, with no deductible.


What Is Initia, and Why Did a VM Bug Reach Ethereum?

Initia is a Cosmos SDK layer 1 that hosts its own rollups (Minitias), and its smart contracts run on a Move virtual machine, as BlockchainReporter's incident write-up describes. Assets from other chains reach it through bridges. On Ethereum those bridges are lockbox contracts: the real AUSD and ETH sit in an adapter, a representation is minted on Initia, and a burn on Initia releases the original.

Move was built so that money cannot be conjured. A resource type "can only be created or destroyed by procedures inside its declaring module," in the words of the original Move resources paper. If you do not own the token module, you cannot mint the token. That guarantee lives in the VM's checks, and those checks are where Initia says the attacker went through.

Everything downstream behaved correctly. The one bad input was a balance on Initia that no mint ever produced, and once burned and relayed it became real AUSD and ETH on a chain that never ran the buggy code.


How Did the Initia Exploit Work?

Initia's October 24 statement is the only first-party account so far. It says the attacker "exploited a bug in Initia MoveVM's script caching that allowed malicious code to bypass security checks," and "artificially spoofed the MoveVM state, thereby crediting themselves with unbacked WETH, iUSD, and USDC tokens without changing the corresponding token's total supply," as also reported by The Industry Spread. Co-founder Zon had earlier called it "a Day 0 bug related to Initia's MoveVM on CosmosSDK".

Initia has not said which checks were skipped. A Move script is a one-off transaction program, as opposed to a published module. Caching anything about it, the compiled form or the result of checking it, skips work the VM believes it already did. If the cache key leaves out any input the check depended on, unchecked code runs under a result that belonged to different code. That is our reading of "script caching" plus "bypass security checks", not a confirmed mechanism; the post-mortem will settle it.

The on-chain decode came from D2 Finance, summarised with its timestamps by Unchained. One signed transaction at 14:59:26 UTC minted 2,000,000 of the Initia-side AUSD representation. The mint was the attacker's own key calling one Move function for 135,888 gas, with no bridge message involved, and D2 reports the token as an argument of that function (recipient, token, amount), which D2 says is consistent with one wallet printing several assets. Initia has not published the function, so treat that as D2's reading. D2's conclusion is the one that matters for everyone else: an OFT adapter "cannot check whether burned tokens were ever backed."

The "total supply unchanged" detail is the most useful line in Initia's statement. Our inference: the per-token invariant (sum of balances equals recorded supply) broke at 14:59:26 and stayed broken, and that is the one check on Initia that would have seen the theft directly.


The Attack, Step by Step

Times are UTC on October 23, 2026. Ethereum rows are on-chain observations; Initia-side rows rely on Initia and D2 because the halted chain's public API is not serving history.

#TimeStepEvidence
108:26:59Attacker wallet 0xDD92...edFA receives 0.098 ETH from Tornado Cashfunding tx
213:14 onwardSmall transfers through an Axelar contract, per D2on-chain, D2
314:37:350.006 ETH sent into the native-ETH OFT adapter it would empty 29 minutes laterD2, on-chain
414:59:26One Initia transaction credits 2M of the unbacked Initia-side AUSD mirrorD2, Initia
515:00:49Attacker burns 1.4M of the AUSD mirror on Initia; LayerZero carries the message (source tx in the record)LayerZero Scan API record
615:01:591.4M AUSD released from the Ethereum AUSD adapterrelease tx
715:02:35999,999.89 USDC minted to the attacker via CCTPCCTP mint tx
815:03:23AUSD swapped to 581.56 ETH via 1inch, 84 seconds after landingswap tx
915:04:59USDC swapped to 415.70 ETH via 1inchswap tx
1015:06:47105 ETH released from the native-ETH adapterrelease tx
1115:25:11A second 79,999.85 USDC CCTP mint, swapped to 33.18 ETH at 15:26:47mint tx, swap tx
1215:27Researcher Spreek posts "Initia chain hacked"Spreek on X
1315:41:30Initia L1 and rollups haltedInitia
1415:41:351,135.52 ETH moved to a fresh wallet, five seconds after the haltconsolidation tx
1516:31:59Agora calls batchFreeze on 0xDD92...edFAfreeze tx

The path splits after the mint into three bridges and rejoins in one wallet, which is easier to see than to read:

rendering diagram…

Do the Numbers Reconcile?

Yes, exactly, once you use the Ethereum side as the ledger. Early figures ran from Spreek's $2.6M to Zon's "~$2.7m"; crypto.news noted on October 23 that the figures had not been reconciled. The Ethereum receipts add up as follows:

LegAmount receivedSwapped into
AUSD via LayerZero1,400,000 AUSD581.56 ETH
USDC via CCTP, tranche 1999,999.89 USDC415.70 ETH
USDC via CCTP, tranche 279,999.85 USDC33.18 ETH
WETH via LayerZero105 ETH(already ETH)
Total1,135.44 ETH

The destination wallet holds 1,135.52 ETH, the same 1,135.52 ETH figure Initia's statement gives, and D2 prices it at about $2.73M. The other 0.08 ETH is the attacker's own 0.098 ETH Tornado seed, minus the 0.006 ETH test deposit, 0.0086 ETH of Axelar transfers and 0.0012 ETH of gas. Add every inflow and outflow on the attacker wallet and it balances to under 0.00001 ETH. We treat $2.7M as the loss. D2's $2.65M is the first wave, everything that landed by 15:06:47; the second USDC tranche came 18 minutes later, which is why early counts came in lower. As of October 27 the 1,135.52 ETH has not moved.

The token names are disputed too. D2's first post said 2,000,000 "AUSD" was minted. Agora, the issuer, replied that "AUSD does not exist on Initia" and that AUSD is fully backed, and said a third-party product using AUSD was the one affected, as crypto.news also reported. D2 then corrected its post on X: the minted token was a third-party LayerZero mirror of AUSD, and the 1.4M that left Ethereum was real AUSD held in that product's lockbox. Second, Initia's statement lists the credited tokens as WETH, iUSD and USDC, while the bridged assets were WETH, AUSD0 and USDC. The Industry Spread flagged the mismatch and Initia has not explained it.

Nobody has explained why only 1.4M of the 2M left. By D2's figures the AUSD adapter held about 1.98M before the drain (1.4M out, 576K left), so the attacker took 71% and stopped. If the remaining 600K of unbacked representation was never burned, it is still sitting on the halted chain; Initia has not addressed it. That matters at restart: if that balance is still spendable when blocks resume, it is more than enough to empty the 576K left in the AUSD adapter, so the patch has to deal with balances as well as code. That is our inference from D2's figures. The USDC leg has a similar gap: CCTP minted on Ethereum against a burn on Noble, and nobody has said whose USDC on the Noble side backed it.

The adapter damage is lopsided. Per D2, the AUSD release took 71% of that adapter's balance and the ETH release took 96% of the other's, leaving 4.84 ETH. LayerZero Scan records each as one message.


Was Anyone Watching in the 42 Minutes?

Spreek's public alert came 28 minutes after the mint and the halt 14 minutes after that. The first $2.65M was on Ethereum within 7 minutes 21 seconds of the mint, and the last USDC tranche was swapped less than a minute before the alert.

Agora's freeze on 0xDD92...edFA landed at 16:31:59, quick by any normal standard. The AUSD had been swapped to ETH 88 minutes earlier, and that ETH had moved to the fresh wallet at 15:41:35, so the frozen address held none of the proceeds.

One on-chain footnote: within the hour, lookalike addresses ending in CAC8 began sending dust to the attacker's wallet. That is the usual address-poisoning pattern, here aimed at the attacker's own counterparty address.


Why Does This Keep Happening to Bridges?

This is the second time in seven weeks. On September 6, Liquid lost about 4,000 BTC when an Elements bug let an invalid output ride through on a cached "already verified" result, and a valid peg-out paid real BTC for L-BTC that should never have existed. D2 drew the same comparison. The two systems run different codebases and different bridges. Liquid's bug is confirmed as a verification cache; Initia's statement names a script cache that let code bypass security checks, which points the same way pending the post-mortem. Both ended at a bridge that paid at par.

The verifiers attested correctly and Circle's CCTP did what CCTP does. The bug lived in a VM on another chain, and each lockbox was underwriting that VM's correctness to the full value of its balance. An adapter audit covers the release logic, and the release logic was fine.

Move's own builders treat static checks as one layer. A June 2026 paper on the Aptos Move VM calls the bytecode verifier "not immune to bugs" and adds runtime checks as "protection against latent verifier bugs and malicious bytecode." Initia shows that depth has to continue into the bridge, where a VM failure becomes somebody else's money.

D2 put the scale mismatch in one line: Initia's DEX held $3.50M of TVL, and its bridges moved about 8x the DEX's daily volume for one wallet in seven minutes.


What Could Monitoring Have Changed?

It could not have stopped the first release. The 1.4M AUSD left 2 minutes 33 seconds after the mint, through a message that was valid on every check Ethereum can run. What remained after that was a clock, and the clock ran for 42 minutes.

These events were observable, each one a figure already cited above:

  • 14:59:26 on Initia: balances credited with no change in recorded supply. That one is for the chain operator: a per-token check of sum of balances against supply, run by the node, fires on the first block.
  • 15:01:59 on Ethereum: one inbound message takes 71% of the AUSD adapter's balance in a single release, to a wallet funded from Tornado Cash that morning.
  • 15:02:35: the same wallet receives a 999,999.89 USDC CCTP mint 36 seconds later.
  • 15:06:47: the native-ETH adapter releases 96% of its balance to the same wallet.

A rule on the 15:01:59 release fires while two legs are still on Initia. The ETH burn left Initia at 15:05:32, per the LayerZero Scan record for the ETH release, and the second 79,999.85 USDC tranche reached Ethereum at 15:25:11 by way of Noble and CCTP. Only Initia's halt reaches both. A halt inside 3 and a half minutes of the alert keeps the 105 ETH, and the USDC tranche had a longer runway still. The first public alert we can find came at 15:27, from a researcher on X.

Neither Ethereum adapter, as deployed, has a pause for a circuit breaker to pull. The verified contracts behind the AUSD adapter and the native-ETH adapter expose no pause and no rate limit, and each owner's lever is setPeer, which cuts that adapter's Initia route and nothing else. So the honest claim here is notify. Tripwire checks every block and pending transaction against rules that state what must always hold, and for a lockbox the rule is short: its token balance never falls by more than a set share in one transaction. Run by the team that operates the AUSD adapter, that rule trips on the 71% release at 15:01:59, the first moment anything on Ethereum looked wrong, and gives that team and Initia a concrete reason to halt while 105 ETH and the second USDC tranche are still on the Initia side.


What Should Operators Do About This?

  1. Cap releases on the lockbox side. A single message releasing 71% of an adapter's balance should revert. Size a per-message and per-window cap to normal flow and treat anything above it as an incident. LayerZero documents a per-destination rate limiter for OApp sends; the inbound side needs the same discipline.
  2. Give every lockbox a pause and decide who holds it. Both adapters here could only be cut by reconfiguring the peer. Add a pause-only role that a monitor can call on its own, so the balance rule that only alerted here can stop the oversized release while it is still pending.
  3. Pre-authorise the chain halt. The halt came 14 minutes after a public alert and 42 minutes after the mint. Write down the signal that triggers it and who can call it.
  4. Run the supply invariant per token, per block. Initia's own description says balances rose while supply did not. Sum of balances against recorded supply is cheap to check and catches this class directly.
  5. Price bridge exposure to the remote chain's maturity. If you issue an OFT mirror on a young L1, your lockbox underwrites that L1's VM. Size it to what you would lose to a Day 0 bug, not to demand.
  6. Treat a VM's internal caches as a security boundary. For chain teams: any cache that stores a verification result needs a review that the key covers every input the check read. Liquid shipped a bug of that kind, and Initia's statement points at the same family.

Frequently Asked Questions

How much was stolen in the Initia exploit?

About $2.7M. Initia's figure is roughly $2.7M across 105 WETH, about 1.4M AUSD and about 1.08M USDC, and the Ethereum receipts reconcile to 1,135.52 ETH in one wallet. Early reports of $2.6M predate the second USDC tranche.

Was native INIT minted or affected?

No. Initia says no native INIT was minted and total INIT supply is unaffected. The credited tokens were bridged assets, which is why the losses landed in Ethereum-side lockboxes.

Was AUSD hacked?

No. Agora says AUSD is not deployed on Initia and is fully backed. The minted token was a third-party LayerZero mirror, and the 1.4M that left was real AUSD from that product's lockbox.

Could monitoring have stopped the Initia exploit?

No, not the first leg. The AUSD release passed every check Ethereum can run 153 seconds after the mint. An alert on that release would have arrived while the 105 ETH and the second USDC tranche were still on Initia, and Initia's halt was the one lever that reached both.

Has Initia published a post-mortem?

Not yet. As of October 27, 2026, Initia says a fix is being completed and audited, recovery is under way with security partners, and a full post-mortem will follow. The chain remains halted with no restart date.


Sources / References

Dmitry Serdyuk
Dmitry Serdyuk

Co-Founder & CDO

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