Nomad Bridge Hack Explained: How $186M Was Drained
What happened, in two sentences: On August 1, 2022, a June 2022 upgrade to Nomad's Replica contract left unproven messages counting as already "proven." Within about two hours, hundreds of wallets copied the first attacker's transaction, swapped in their own address, and drained roughly $186 million from the bridge.
That's the short version of the Nomad bridge hack. The longer version is more useful. Nomad's verification design was reasonable on paper, and the sources point to a contract logic flaw rather than stolen keys. The bridge broke because Solidity's default value for an unset mapping entry, bytes32(0), was accidentally marked as a trusted Merkle root. Below we go through the contract logic, rebuild the attack pattern, account for who lost what, and finish with a checklist for judging any bridge before you trust it with funds.
Key Takeaways:The Nomad bridge exploit began on August 1, 2022, and took the bridge's balance from $190.3M to $11,815, according to Fortune via Yahoo Finance.The root cause was a Replica contract upgrade that, as commonly described in public post-mortems, set confirmAt[0x00] = 1, so the Solidity default value for any unproven message passed the "proven" check.Nomad's optimistic fraud window couldn't catch the attack because no fraudulent root was ever submitted, which left watchers with nothing to challenge.Nomad had to rely on an engineer on a plane relaying code snippets over chat and could not pause the bridge until it was empty, according to the FTC complaint reported by Decrypt.The cheapest defenses Nomad lacked were operational: a fast pause, per-asset withdrawal rate limits, and invariant tests asserting that unproven messages always revert.Table of Contents
- How Was the Nomad Bridge Supposed to Work?
- What Was the Bug Behind the Nomad Bridge $186 Million Exploit?
- How Did the Attack Unfold, Step by Step?
- Who Lost What and What Happened Next?
- Why Didn't the Optimistic Security Model Catch It?
- How Do Bridge Hacks Happen? Nomad vs. Other Major Exploits
- Which Bridge Verification Models Fail Least Catastrophically?
- Bridge Security Best Practices: What Should You Do?
- Frequently Asked Questions
- Conclusion
How Was the Nomad Bridge Supposed to Work?
Nomad was an optimistic cross-chain messaging protocol, and a lock-and-mint token bridge ran on top of it. "Optimistic" means the system accepts state updates as valid by default unless someone challenges them within a fixed fraud window. Rather than having a committee co-sign each transfer, Nomad needed only one honest watcher to spot a bad update within that window.
Three components did the work, per a University of Athens security lecture that reproduces the contract code:
- Home contract (origin chain): every outbound message is stored as a leaf in a Merkle tree. A Merkle tree hashes pairs of leaves upward until one 32-byte root commits to every message in it.
- Replica contract (one per destination chain): accepts roots and records when each becomes valid in a mapping,
confirmAt[root]. A message is processed only if its root is acceptable. - Updaters and watchers: bonded parties sign new roots, and watchers can flag fraudulent roots during the optimistic window.
Delivering a message on the destination chain took two calls:
prove(leaf, proof, index)rebuilds the Merkle root from the leaf and its sibling hashes. If that root is acceptable, it storesmessages[leaf] = root.process(message)hashes the message, looks up the root stored for it, checks that the root is acceptable, marks the message as processed, and calls the recipient (here, the BridgeRouter, which releases the locked tokens).
The model's security rests on one assumption. A message can only be processed if it was first proven against a root that the Updater signed and the fraud window has cleared. In Nomad's case, a single initialization value broke that assumption.
What Was the Bug Behind the Nomad Bridge $186 Million Exploit?
Here are the two functions involved, simplified from the Replica contract as reproduced in the lecture slides:

function process(bytes memory _message) public returns (bool _success) {
bytes32 _messageHash = keccak256(_message);
// ...
require(acceptableRoot(messages[_messageHash]), "!proven");
messages[_messageHash] = LEGACY_STATUS_PROCESSED;
// ... dispatch to recipient (BridgeRouter releases tokens)
}
function acceptableRoot(bytes32 _root) public view returns (bool) {
uint256 _time = confirmAt[_root];
if (_time == 0) {
return false;
}
return block.timestamp >= _time;
}Taken on its own, this code is correct. A root nobody has submitted has confirmAt[root] == 0 and is rejected. A root still inside its fraud window has a future timestamp and is also rejected.
The bug was in how the contract was initialized.
When a Replica is deployed after its Home contract already holds messages, the deployer can start it at a _committedRoot and set confirmAt[_committedRoot] = 1. That skips the need to replay old updates, and the value 1 is a Unix timestamp from 1970, so the root is valid immediately. The trouble is the case where Home and Replica start fresh. An empty tree has a root of bytes32(0), so initializing with the "current root" stored confirmAt[0x00] = 1.
The FTC says a June 2022 code update "introduced a critical vulnerability" into the Replica, and public post-mortems describe it as this zero-root initialization. The exact commit and code diff are not confirmed in our sources. Now combine it with how Solidity handles mappings:
- In Solidity, every unset mapping key returns zero. For a message that was never proven,
messages[_messageHash]returns0x00. process()passes that0x00intoacceptableRoot().confirmAt[0x00]now returns1, which is not zero, so the first guard passes.block.timestamp >= 1is always true, so the function returnstrue.- The
"!proven"requirement is satisfied for every message that had never been proven.
In practice, the "has this message been proven?" check turned into "has this message not been processed yet?" Merkle proofs no longer mattered. Anyone could write a message and have the bridge execute it.
The general lesson: In any language where storage defaults to zero, the zero value must never mean "authorized." If a sentinel, default, or uninitialized value can pass an authorization check, the check is broken regardless of how strong the cryptography behind it is.
How Did the Attack Unfold, Step by Step?
The attack took no cryptography and no stolen keys. It needed calldata. Ledger's on-chain reconstruction found that the first attackers planned at least a day ahead and tested the bug with small amounts before draining larger ones.
The original exploit transaction
- Craft a message. The attacker builds a Nomad-formatted message addressed to the Ethereum BridgeRouter, with a body that says "transfer N units of token T to address A."
- Skip
prove()entirely. No Merkle proof is submitted. The message hash has never been stored, somessages[hash] == 0x00. - Call
process(message)directly.acceptableRoot(0x00)returns true, the message is marked processed, and the BridgeRouter sends real tokens from Nomad's escrow to the attacker. - Repeat with a new hash. A processed message can't be replayed, but changing the amount, recipient, or nonce produces a fresh hash that again maps to
0x00.
The copycat phase
This is the part that set Nomad apart from other bridge hacks. Once the first exploit transactions landed on Ethereum, anyone reading Etherscan could open the input data, replace the recipient address with their own, and send it again. The class action complaint calls the technique "spoofing," and public on-chain visibility made it easy to replicate. A lecture deck claims more than 300 attackers across about 960 transactions, though we could not independently verify those counts.
It moved fast. The Defiant reported $45M drained by 7:15 PM ET on August 1, and Fortune reported that the bridge emptied "in a matter of two hours on Monday evening." The class action says the drain finished by the end of August 2. That fits an initial exploit on August 1 followed by a copycat tail into the next day.
Who Lost What and What Happened Next?
The losses fell on users and protocols whose assets were held in the Nomad bridge. Per the FTC, the assets taken included Ethereum, USDC, DAI, and WBTC.

| Metric | Figure | Source |
|---|---|---|
| Headline loss | ~$186M | Ledger |
| Bridge balance before drain | $190.3M | Fortune/Yahoo |
| Bridge balance after drain | $11,815 | Fortune/Yahoo |
| Assets taken | Ethereum, USDC, DAI, WBTC | FTC via Decrypt |
| Recovered in following days | ~$22M | FTC via Decrypt |
| Consumer losses cited by FTC | >$100M | FTC via Decrypt |
| Seed round disclosed days earlier | $22M | The Defiant/Yahoo |
Ethereum was the only chain where funds were drained. Connected chains included Avalanche, Evmos, Milkomeda C1, and Moonbeam, and Moonbeam was paused during the investigation.
The legal fallout followed. The FTC compelled Nomad's operator, Illusory Systems, to repay users. It alleged the company marketed itself as "security-first" while failing to adequately test its contracts or keep an incident-response process, as Decrypt reported. A private class action alleges negligence and "knowingly false promises of security." Israeli authorities reportedly arrested Alexander Gurevich, who is accused of initiating the exploit, at an airport as he tried to flee to Moscow. The allegations are unproven in court according to the sources, and we could not confirm the charges or case status.
Copying an exploit transaction does not make you a "white hat." Treat funds that aren't yours as off limits.
Why Didn't the Optimistic Security Model Catch It?
The optimistic model was never tested, because the attack never touched what it guarded. Nomad's watchers were built to catch a fraudulent root. In this attack, no new root was needed: the messages relied on the root 0x00, which the contract already treated as valid, so watchers had nothing to challenge.
This shows up across the industry. A bridge's stated trust model (multisig, optimistic, light client, ZK) describes how it validates new state. Many big losses come from the plumbing around that model: initialization, upgrades, proof parsing, and message decoding. The Halborn post-mortem of the June 2026 Syscoin bridge exploit makes the same point. An SPV proof parsing error let an attacker mint about 5 billion SYS (around $10M at the time), and the post-mortem says it was not a cryptographic break.
The response gap made it worse. According to the FTC complaint, Nomad "had to rely on an engineer, who was on a plane, to relay code snippets in a chat back and forth with the incident manager on duty," and could not pause the bridge until it had been emptied. An optimistic design is only as good as the people and automation watching it.
How Do Bridge Hacks Happen? Nomad vs. Other Major Exploits
Bridges are attractive targets because a single verification mistake turns into direct withdrawals from a large shared escrow. Ledger notes that bridge hacks account for four of the five largest crypto hacks. For more history, see our biggest crypto bridge hacks breakdown. Here are well-documented incidents grouped by failure category:
| Bridge | Year | Loss | Failure category | Control that would have limited it |
|---|---|---|---|---|
| Ronin | 2022 | ~$625M | Key compromise (validator keys) | Independent signers, outflow alerts |
| Poly Network | 2021 | ~$610M | Verification/access-control flaw | Privileged-function isolation |
| Wormhole | 2022 | ~$320M | Verification logic flaw | Invariant tests on the signature-check path |
| Nomad | 2022 | ~$186M | Initialization / default value | Rate limits, fast pause, zero-value tests |
| Horizon | 2022 | ~$100M | Key compromise (validator keys) | Higher thresholds, HSMs |
| Syscoin | Jun 2026 | ~$10M (reported) | SPV proof parsing error | Fuzzing of proof decoders |
Loss figures for Ronin, Poly, Wormhole, and Horizon come from the University of Athens bridge-security lecture. Syscoin's figure is from Halborn. A reported ~$11.6M exploit of the Verus–Ethereum bridge through a fake cross-chain message, according to 1inch, resembles the Nomad pattern, but details were still developing.
Key compromises produce some of the largest losses. Logic and parsing bugs affect every verification model, including the "trustless" ones.
Which Bridge Verification Models Fail Least Catastrophically?
No verification model makes a bridge safe by itself. What differs is who you trust and how the bridge fails when that trust breaks.
| Model | What you trust | Typical failure mode | Blast radius |
|---|---|---|---|
| Multisig / MPC committee | An honest threshold of signers | Key theft (Ronin, Horizon) | Entire escrow |
| Optimistic (Nomad) | At least one live, honest watcher | Bugs outside the fraud-proof path | Entire escrow if no rate limit |
| Light client / SPV | Source chain's consensus (e.g., Bitcoin proof-of-work) | Proof-parsing or header-relay bugs (Syscoin) | Depends on collateral and caps |
| ZK light client | Proof system and circuit correctness | Circuit bugs | Entire escrow if no rate limit |
For Bitcoin, the light-client approach removes the signer committee. An SPV (Simplified Payment Verification) proof shows that a transaction belongs to a Bitcoin block by checking a Merkle branch against a block header. TeleSwap uses this model: SPV light clients verify Bitcoin transactions, and TeleBTC is minted 1:1 only after a verified Bitcoin transaction, with custody backed by slashable collateral rather than a multisig. TeleSwap has bridged $539.6M across 571,518 bridge transactions on 13 supported networks, according to TeleSwap network stats. A route such as BTC → WBTC on Ethereum works this way.
The Syscoin incident shows that SPV code can still fail. Removing trusted signers takes away a major category of loss, but you still need to fuzz the proof decoder, test that zero and default values are rejected, and cap how much value any single bug can reach. For more on this, read Bitcoin bridge security in 2026.
Bridge Security Best Practices: What Should You Do?
If you build or audit bridges
- Treat zero as hostile. Write invariant tests asserting that
process()reverts for any message hash that was never proven, and run them after every upgrade. - Test the deployed state, not just the code. Explicitly test that zero or default values cannot authorize messages, and replay adversarial messages against the live configuration after each upgrade.
- Rate-limit outflows per asset per epoch. A cap on hourly outflows limits how much a single bug can drain.
- Pre-authorize a fast pause. Give automated monitors and several on-call keyholders a pause role that doesn't depend on any one person being reachable.
- Monitor accounting invariants. Alert on any
process()call with no matchingprove(), and on released tokens exceeding locked deposits. - Stage upgrades. Use independent audits of initialization diffs and canary deployments with low caps before full liquidity moves over.
- Publish a disclosure channel and bug bounty. The FTC criticized Nomad for lacking a clear vulnerability-reporting process.
If you use bridges
- Ask "who can mint?" before you bridge. Read the docs for the verification model: a committee, a fraud window, or a light client.
- Check the upgrade path. Look for timelocks and audits on upgrades.
- Don't park idle value in bridged IOUs. Bridge, use the funds, and redeem to native assets when you're done.
- Diversify bridge exposure. Spreading large positions across different verification models limits correlated losses.
- Revoke stale approvals to bridge routers you no longer use.
- If an exploit is live, don't "rescue" funds yourself. Copying exploit calldata can expose you to legal risk whatever your intent.
Frequently Asked Questions
What caused the Nomad bridge hack?
A June 2022 Replica contract upgrade introduced a flaw that, as commonly described, marked the zero hash (0x00) as a trusted Merkle root, so unproven messages passed the bridge's "proven" check. Solidity returns zero for unset mapping keys, so any new message looked like it was proven against a valid root. Attackers could then craft withdrawal messages without a Merkle proof.
How much was stolen in the Nomad bridge exploit?
About $186 million was drained starting August 1, 2022. Fortune reported the bridge held $190.3M before the attack and $11,815 afterward. About $22M was recovered in the following days, according to the FTC complaint reported by Decrypt.
Why were there so many Nomad attackers?
The exploit could be copied by anyone who replaced the recipient address in a public transaction. It needed no special code, only calldata visible on-chain. One lecture deck claims more than 300 attackers, a figure we could not verify.
Couldn't Nomad's fraud window have stopped the attack?
No, because the attack never submitted a new root for watchers to challenge. Nomad's optimistic model defended against fraudulent root updates. The malicious messages relied on a root that had been accepted since initialization, so the fraud-proof mechanism was never triggered.
Are light-client bridges immune to Nomad-style bugs?
No. Light-client bridges remove trusted signers, but their proof-verification code can still contain bugs. The June 2026 Syscoin bridge exploit came from an SPV proof parsing error, according to Halborn. Rate limits, fuzzing, and fast pauses limit the damage when code fails.
How can I tell if a bridge is safe to use?
Check who can authorize minting, how upgrades are controlled, and whether outflows are rate-limited. Prefer bridges that verify source-chain consensus directly, publish audits, and run a public bug bounty. Hold bridged assets only as long as you need them.
Conclusion
The Nomad bridge hack was not a cryptographic failure. A single default value broke an otherwise reasonable design, and there was no rate limit, pause, or monitoring in place to contain it. Zero values must never authorize anything, a bridge's headline trust model says little about the safety of its upgrade and initialization code, and limiting blast radius matters as much as preventing bugs.
If you're moving Bitcoin across chains, choose a verification model that doesn't depend on a committee, and keep checking the implementation behind it. You can see SPV light-client verification in practice, and track live bridge activity, at teleswap.xyz.