OAK — OnChain Attack Knowledge

Worked example · 2026-07

Bonzo Lend — an all-zero signature satisfies Supra's oracle verifier trivially, inflating SAUCE by ~12 orders of magnitude to borrow $9.05M against 250 tokens — Bonzo Lend / Supra (Hedera) — 2026-07-12

Loss
~$9.05M realised — 6.63M USDC and 34.5M wrapped HBAR borrowed against collateral of 250 SAUCE tokens worth a few dollars. A separate ~$1M borrow by a white-hat, executed against the same forged price to deny the attacker the remaining liquidity, was returned and is excluded from the headline figure; total drawn against the manipulated price was roughly $10.06M. About $5.25M was bridged to Ethereum. Bonzo Lend's TVL fell 77% and Hedera's network-wide TVL fell close to 40% within 24 hours.
OAK Techniques observed
OAK-T9.015 (Degenerate-Input Signature-Verification Bypass — primary, confirmed mechanism. Supra's on-demand oracle verifier did not reject zero, identity, or off-subgroup inputs before evaluating its pairing check. The attacker submitted a price update whose signature field was [0,0] and whose public-key reference was the zero point — the point at infinity. With both sides of the pairing equation collapsing to the identity of the target group, the equation returned true as designed, and the verifier read that trivially-true result as proof of a committee signature. No key was compromised and no market was touched. See techniques/T9.015-degenerate-input-signature-verification-bypass.md). OAK-T9.001 (Oracle Price Manipulation — the downstream outcome, not the mechanism. The forged update priced SAUCE at 1 followed by 30 zeroes against a real market price near 0.2 HBAR, roughly 12 orders of magnitude high, and Bonzo consumed that value as collateral valuation with no plausibility bound. Recorded because the incident presents as an oracle exploit to a defender watching the lending market, but the oracle-resilience mitigation family only bounds this loss — it does not close it, because nobody moved SAUCE). The outflow to Ethereum is OAK-T7.003; the attacker's wallet was seeded from Tornado Cash, OAK-T7.001.
Attribution
pseudonymous. No named individual or group. On-chain identifiers only: the Ethereum-side addresses 0x9A4..6a494 and 0xaf2…6dD93e (partial forms are what public reporting disclosed; OAK has not independently resolved the full addresses), with the operating wallet funded out of Tornado Cash before the event — a deliberate pre-funding step consistent with premeditation rather than opportunistic discovery. Nothing links the operator to a tracked OAK actor. A white-hat borrowed roughly $1M against the same forged price to deny the attacker remaining liquidity and returned it; that actor is distinct from the attacker and is not treated as a participant.
Key teaching point
A verifier that does not validate its inputs will happily prove that nobody signed something. Every authorisation control around Supra's oracle was intact — the signing committee, the quorum, the key management. The failure sat one level below all of them, in the primitive that answers whether a signature satisfies the policy, and an all-zero byte string was enough to make it answer yes. The fix is mechanical and cheap: reject zero, identity, off-curve, and off-subgroup elements at the verifier boundary before any pairing operation, as the CFRG BLS specification has mandated for years. The structural lesson is about ownership of the defect versus ownership of the loss: Bonzo did not write the broken verifier, could not see inside it, and had no control that would have caught it — Supra shipped the bug and Bonzo paid for it. That asymmetry is why the compensating control matters as much as the fix. A deviation circuit breaker on the consuming market would have rejected a 12-orders-of-magnitude jump no matter how well-signed it looked, and turned a total drain into a rejected transaction. Bonzo had no such bound, so a price of 1e30 was accepted as collateral valuation and borrowed against within eight seconds.

Summary

Bonzo Lend was the largest lending market on Hedera. It priced collateral using Supra, a third-party oracle offering an on-demand update model in which a caller submits a signed price report and the verifier contract checks the signing committee's signature before writing the value on-chain.

Supra's verifier contained an input-validation defect. Before evaluating its pairing-based signature check, it did not test whether the values it had been handed were legitimate group elements — specifically, it did not reject the zero scalar, the identity element (point at infinity), or points outside the correct prime-order subgroup. On 2026-07-12, an attacker submitted a price update for the SAUCE/wHBAR pair carrying a signature field of [0,0] and a public-key reference resolving to the zero point. Because the pairing equation is satisfied trivially when both inputs are the identity, the check returned true, and the contract treated that as proof that Supra's committee had signed the report.

The forged report valued SAUCE at 1 followed by 30 zeroes; the token was trading near 0.2 HBAR. Having deposited 250 SAUCE — worth a few dollars — as collateral eleven minutes earlier, the attacker borrowed 6.63M USDC within eight seconds of the price landing, then 34.5M wrapped HBAR. A white-hat, seeing the same open window, borrowed roughly $1M against the forged price to deny the attacker the remainder and later returned it.

Supra's legitimate oracle restored the correct SAUCE price about 45 minutes later, and Bonzo paused its lending pool five minutes after that. Roughly $5.25M was bridged from Hedera to Ethereum and swapped into ETH. Supra acknowledged the flaw and deployed a verifier fix; Bonzo Lend's lending pool and points programme remained paused, with vaults, bridge, and staking left operational, and no reimbursement terms announced. Hedera's network TVL fell nearly 40% in a day, most of it Bonzo's 77% decline.

Timeline (UTC)

When Event OAK ref
(standing) Supra's on-demand verifier omits zero / identity / subgroup checks on its inputs before the pairing evaluation (standing T9.015 surface)
(pre-event) Attacker's operating wallet funded out of Tornado Cash T7.001
2026-07-12 00:40 Attacker deposits 250 SAUCE (worth a few dollars) as collateral on Bonzo Lend (setup)
2026-07-12 00:51 Forged price update with signature [0,0] and zero-point public key passes the verifier; SAUCE written on-chain at ~1e30, roughly 12 orders of magnitude above market T9.015
2026-07-12 00:51 (+8s) Attacker borrows 6.63M USDC against the 250-SAUCE position T9.001 outcome
2026-07-12 ~00:52 Attacker borrows 34.5M wrapped HBAR T9.001 outcome
2026-07-12 (same window) White-hat borrows ~$1M against the same forged price to deny remaining liquidity; later returned (third-party mitigation)
2026-07-12 01:36 Supra's legitimate oracle restores the correct SAUCE price (detection)
2026-07-12 01:41 Bonzo pauses its lending pool M34
2026-07-12 onward ~$5.25M bridged Hedera → Ethereum, swapped WBTC → ETH T7.003
post-event Supra acknowledges the verifier flaw and deploys a fix; Bonzo lending and points remain paused, vaults/bridge/staking operational (operator response)

Public reporting predominantly dates this incident 2026-07-11, using US Eastern time (the forged price landed at 20:51 ET Friday). OAK dates in UTC throughout, which places the event on 2026-07-12. Both refer to the same moment.

What defenders observed

  • Pre-event (a third-party verifier nobody downstream had read). The defect was in Supra's contract, not Bonzo's. Bonzo's own code, quorum, and key management were not implicated at any point. The pre-event control is an explicit inventory of which external verifier contracts a protocol trusts and whether any audit scope actually covered their internals — consuming an oracle means inheriting its input-validation quality, and that inheritance is usually invisible from the consumer's side (M16).
  • At-event (an all-zero signature is a decisive, near-zero-false-positive signal). The forged call's signature field was literally [0,0]. Legitimate signatures are never zero, so screening verification-bearing entrypoints for all-zero or identity-valued signature, proof, and public-key fields is a cheap rule that would have fired on the exact transaction. This is the prevention-grade control and it belongs inside the verifier: reject degenerate inputs before any pairing operation.
  • At-event (verified on-chain, never signed off-chain). No member of Supra's committee produced a signature for this report; the on-chain artefact claimed one that never existed. Reconciling each accepted committee-signed update against a matching off-chain signing record catches this class even when the degenerate value is not literally zero (M39).
  • At-event (the consuming market had no plausibility bound). A price 12 orders of magnitude above the previous accepted value was consumed as collateral valuation without question. A deviation circuit breaker on the consumer side would have rejected it regardless of signature quality — this is the control that bounds a verifier bug you cannot see (M09).
  • Detection (extraction was near-instant; the pause was 50 minutes later). Borrowing began eight seconds after the forged price landed, against collateral worth a few dollars. Oracle-write-to-borrow proximity, especially against thin collateral, is the runtime signal; per-block caps would have converted a total drain into a partial and observable one (M11). Recovery of the correct price at 01:36 and the pause at 01:41 both came long after the money was gone — they bounded the incident, they did not prevent it.

Public references

Discussion

Bonzo is the anchor OAK uses to separate T9.015 from T9.001, and the separation is worth the trouble because the two imply different defences. Read as an oracle exploit, the natural response is the oracle-resilience family — TWAP windows, multi-venue aggregation, deviation breakers. Every one of those controls assumes the attacker moved a real price on a real venue and the feed faithfully reported it. Nobody moved SAUCE. The value was asserted out of thin air and a broken verifier vouched for it, which means TWAP and multi-venue aggregation are irrelevant to the mechanism and only the deviation breaker helps — and it helps by limiting damage, not by closing the hole. Recording T9.015 as primary keeps the actual fix (validate inputs before the pairing) attached to the incident, and recording T9.001 as the outcome keeps the compensating control (M09) attached too.

The other reason to preserve this case carefully is the split between who shipped the defect and who absorbed the loss. Bonzo's contracts were sound. Its quorum was sound. Its key management was never touched. It lost $9M because it consumed a third-party verifier whose internals it had no practical way to inspect, and the only thing standing between an external dependency's input-validation bug and a total drain of the lending pool would have been a sanity bound on the value that dependency returned. Protocol teams reading this should take the inventory question seriously — which external verifiers do we trust, and did anyone's audit scope actually cover them — because the answer is very often "we don't know" and "no".

Finally, the cryptographic hazard here is old, which is what makes the case a warning rather than a curiosity. Subgroup-membership and identity-element validation are explicit, long-standing requirements in BLS standardisation; small-subgroup and invalid-curve attacks predate crypto by well over a decade. What changed is the deployment surface: pairing-based verifiers for oracle attestations, threshold committees, and proof systems have proliferated quickly, they are usually third-party dependencies, and the distance between "the specification says validate your inputs" and "the shipped contract validates its inputs" is exactly where this class lives. Contributors encountering any incident where verification passed on zero, identity, or off-subgroup input — in an oracle, a bridge, a threshold committee, or a zk proof verifier — should map it to T9.015 and record which primitive and which omitted check were load-bearing.

Techniques demonstrated (4)