A routine implementation upgrade to Nomad's `Replica` contract changed the initializer such that `committedRoot` was set to `0x00…00` and the constructor / setup path wrote `confirmAt[0x00] = 1` (i.e., zero-hash marked as a confirmed trusted root). The `process(bytes _message)` function called `acceptableRoot(messages[_messageHash])` to gate execution, where `acceptableRoot` returned true if `confirmAt[root] != 0 && block.timestamp >= confirmAt[root]`. Because the zero-root was confirmed, any message whose `messages` slot was still `bytes32(0)` — i.e., any message that had never been proven — satisfied the check. An attacker copied a legitimate `process` calldata, swapped the recipient `_recipientAddress` for their own and the amount field, and the bridge happily released the underlying. Hundreds of copycats replayed the same calldata template, draining ~$190M in 150 minutes.
Reproducible Foundry test fork from SunWeb3Sec/DeFiHackLabs. Clone the repo, run forge test against the file path above, and replay the exploit against a mainnet fork at the historical block. Use for reproduction only — not for live targets.
Classification: Protocol Logic. Technique: Trusted Root Exploit. Bridge hack. Target type: DeFi Protocol. Affected chains: Ethereum. Implementation language: Solidity.
- chain
- ethereum
- protocol
- Nomad
- bug_class
- bridge
- date_occurred
- 2022-08-01
- loss_usd
- $190,000,000
- classification
- Protocol Logic
- technique
- Trusted Root Exploit
- target_type
- DeFi Protocol
- language
- Solidity
- bridge_hack
- YES
- source_id
- dl:1682