OAK — OnChain Attack Knowledge

Worked example · 2026-07

Wanchain Cardano bridge — 14 variable-length fields concatenated without separators make the signed message non-injective, so a signature for 3,110 NIGHT authorises 203,001,692 — Wanchain / Midnight NIGHT (Cardano ⇄ BNB Chain) — 2026-07-20/21

Loss
~515.2M NIGHT drained from the bridge's Cardano-side reserve — approximately 97.8% of the reserve's contents. Dollar valuation is reported inconsistently and OAK records both: ~$10M (The Crypto Times) and ~$13M (TokenPost, CoinGape), the spread reflecting which NIGHT price the outlet marked against during a selloff. NIGHT fell more than 30% to a record low near $0.016, then rebounded roughly 19% over the following day. The Midnight chain itself was not touched; only the Wanchain-operated bridge was. Reported incident date differs by outlet — The Crypto Times' weekly recap dates it 2026-07-21, its own technical write-up 2026-07-20; the withdrawal sequence itself spanned about nine minutes.
OAK Techniques observed
OAK-T10.002 (Message-Verification Bypass — primary, confirmed mechanism, in its encoding-ambiguity sub-class. The bridge's TreasuryCheck validator built the message it signed by concatenating 14 variable-length redeemer fields with no separators and no length prefixes. That encoding is non-injective: two different field assignments can serialise to the same byte string, and therefore to the same hash. Every signature check passed on a genuinely valid signature. See techniques/T10.002-message-verification-bypass.md). OAK-T10.003 (Cross-Chain Replay — cross-referenced, and the reason the amount gap was so large: the signature the attacker reused had been issued to authorise roughly 3,110 NIGHT on BNB Chain, and was re-presented on Cardano against a different field arrangement decoding to 203,001,692 NIGHT — more than 65,000× the authorised amount. The reuse is across chains, which is what let a small legitimate authorisation and a huge fraudulent one share one signed preimage). OAK-T10 (Bridge / Cross-Chain parent).
Attribution
pseudonymous. No named individual or group, and no public link to a tracked OAK actor. The four withdrawals landed in a single attacker-controlled wallet, from which roughly 90% of the haul was liquidated through decentralised exchanges and DeFi protocols on Cardano. Wanchain took the bridge offline and opened an investigation; the Midnight Foundation confirmed the Midnight blockchain was unaffected. On 2026-07-31 Wanchain made a public negotiated-return offer: a 10% white-hat bounty in exchange for returning the other 90% of the stolen NIGHT by an 2026-08-06 deadline, with a pledge not to pursue civil claims if accepted. Note the tension between the two facts — the attacker had already sold approximately the share Wanchain was asking to have returned, so compliance would require repurchasing NIGHT in a market the liquidation itself had moved.
Key teaching point
A threshold signature scheme protects who signs, never what the signature means. Wanchain ran a 25-node validator network requiring 17 signatures, and that machinery worked exactly as specified — no key was stolen, no quorum was subverted, and every honest validator signed an authorisation it had legitimately approved. The defect sat one layer beneath the signing policy, in how the payload was serialised before hashing. Because the 14 redeemer fields were concatenated with nothing marking where each one ended, a single byte string had more than one valid reading, and the attacker chose the reading worth 65,000× more. The fix was already sitting in the contract and simply was not wired to the signing path: Cardano's SerialiseData produces an unambiguous, length-delimited encoding, and signing Sha3_256(SerialiseData(...)) rather than a raw concatenation would have made the two field arrangements hash differently. The generalisable rule is that any signed message assembled by concatenating variable-length fields is a vulnerability until proven injective — the same rule that Solidity's abi.encodePacked collision class enforces on the EVM side.

Summary

Wanchain operates a cross-chain bridge connecting Cardano and BNB Chain, used among other things to move NIGHT, the token of the Midnight network. Bridge withdrawals are authorised by a 25-node validator set with a 17-signature threshold; a withdrawal is honoured when a validator-signed message attests to it.

The Cardano-side TreasuryCheck validator constructed that signed message by concatenating 14 variable-length redeemer fields directly, with no separators and no length prefixes. This makes the encoding non-injective — moving bytes across a field boundary produces a different set of field values that serialise to an identical byte string. Two economically unrelated withdrawals can therefore share a single hash and a single valid signature.

An attacker took a legitimate signature that authorised approximately 3,110 NIGHT on BNB Chain and presented it on Cardano with a different arrangement of the redeemer fields — one whose parse yielded a withdrawal of 203,001,692 NIGHT. The validator recomputed the hash over the supplied fields, matched it against the signature, and approved.

Over roughly nine minutes, four withdrawals removed approximately 203.0M, 129.6M, 120.4M, and 62.1M NIGHT — about 515.2M NIGHT in total, or 97.8% of the reserve. Wanchain took the bridge offline and began investigating. The Midnight Foundation confirmed the Midnight blockchain was not affected. The exploit triggered a selloff that took NIGHT down more than 30% to a record low near $0.016.

Timeline (UTC)

When Event OAK ref
(standing) TreasuryCheck builds the signed message by concatenating 14 variable-length redeemer fields with no separators or length prefixes; contract contains SerialiseData but does not use it on the signing path (standing T10.002 surface)
(prior) Validator set legitimately signs an authorisation for ~3,110 NIGHT on BNB Chain (legitimate authorisation)
2026-07-20/21 Attacker re-presents that signature on Cardano with a different redeemer-field arrangement decoding to 203,001,692 NIGHT; hash matches, signature verifies T10.002 / T10.003 exploitation
same window (~9 min) Four withdrawals of ~203.0M, ~129.6M, ~120.4M, ~62.1M NIGHT — ~515.2M total, ~97.8% of reserve — land in one attacker wallet T10.002 extraction
after Wanchain takes the bridge offline and opens an investigation; Midnight Foundation confirms the Midnight chain is unaffected; NIGHT falls >30% to ~$0.016 (operator response)
after Attacker consolidates into a primary Cardano wallet and liquidates ~90% of the haul via Cardano DEXs and DeFi protocols T7.007
2026-07-31 Wanchain publicly offers a 10% white-hat bounty for return of the remaining 90% by a 2026-08-06 deadline, pledging not to pursue civil claims if accepted (negotiated-return offer)

What defenders observed

  • Pre-event (the encoding, not the key management, was the reviewable artefact). Everything a conventional bridge security review looks at was in good order: a 25-node validator set, a 17-of-25 threshold, no compromised keys. The defect was in a serialisation routine, and it is statically visible — a concatenation of variable-length fields with no delimiters is a structural property of the code, not a runtime condition. Reviews that treat "how is the message encoded before it is hashed?" as a first-class question catch this class; reviews that stop at signing policy do not.
  • Pre-event (SerialiseData was present and unused). The safe primitive was already a dependency. That is a recurring shape: the codebase contains the canonical encoder, and the signing path takes a hand-rolled shortcut instead. Grepping for a canonical-serialisation function and checking whether the hash-and-sign path actually calls it is a cheap, mechanical audit step.
  • At-event (the amount ratio is the detection signal). A withdrawal of 203,001,692 NIGHT against an authorisation for 3,110 is a 65,000× discrepancy. A bound comparing the withdrawal to plausible per-authorisation size — or to a fraction of reserve — would have rejected all four transactions regardless of signature validity. A single withdrawal taking a double-digit percentage of a bridge reserve should never clear without a circuit breaker (M04, M05).
  • At-event (97.8% of reserve in nine minutes). The reserve had no rate limit and no per-window cap. Nine minutes is ample for an automated pause if any threshold existed to trip; there was none, so the drain ran to near-completion.
  • Response (the honest-validator paradox). No validator misbehaved and no key was compromised, so every key-rotation and quorum-hardening response available to the operator addresses a failure that did not occur. The only fix that closes this is changing the encoding, which is why correctly classifying the mechanism matters operationally rather than just taxonomically.

Public references

Discussion

This is the Cardano-side twin of examples/2026-05-map-protocol-butter-bridge-encodepacked-collision.md, and reading the two together is the point. MAP Protocol's Butter bridge lost funds to abi.encodePacked collisions — Solidity's packed encoder concatenating dynamic types without length prefixes so that ("a","bc") and ("ab","c") produce identical bytes. Wanchain lost funds to the same mathematical defect expressed in Plutus rather than Solidity, on a validator that had the length-delimited alternative available and did not call it. Neither is an EVM quirk. Non-injective encoding is a property of concatenation, not of a language, and any chain whose tooling offers both a packed and a canonical encoder will keep producing this class until reviewers treat the choice between them as security-relevant.

The second thing worth extracting is how thoroughly this defeats the standard bridge-security narrative. The industry has spent several years converging on "decentralise the signer set, raise the threshold" as the answer to bridge risk, and by that metric Wanchain scored well: 25 independent nodes, a 17-signature threshold, no single point of key failure. All of that was intact, and none of it was relevant. Threshold cryptography answers who authorised this; it has nothing to say about what the authorisation means once the message is ambiguous. A defender modelling this bridge's risk from validator-set decentralisation alone would have rated it strong right up to the moment 97.8% of the reserve left in nine minutes.

Contributors documenting future cases in this class should record the authorised-amount to withdrawn-amount ratio explicitly — here 3,110 against 203,001,692. That ratio is the cleanest artefact distinguishing encoding-ambiguity reuse from ordinary key compromise: a stolen key produces withdrawals that are unauthorised but internally coherent, while encoding ambiguity produces withdrawals that carry a real signature for a completely different number.

Techniques demonstrated (3)