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
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
[cryptoslatebonzo2026]— CryptoSlate, "How a zeroed oracle signature unlocked $9M from Hedera DeFi lender Bonzo Lend" (primary technical account: verifier failing to reject zero / identity / off-subgroup inputs,[0,0]signature field, zero-point public-key reference, pairing equation returning true as designed, minute-level timeline): https://cryptoslate.com/how-a-zeroed-oracle-signature-unlocked-9m-from-hedera-defi-lender-bonzo-lend/[theblockbonzo2026]— The Block, "Hedera lending protocol Bonzo Lend hit for $9 million after Supra verifier accepts manipulated price update" (loss breakdown 6.63M USDC + 34.5M wHBAR, 250 SAUCE collateral, ~1e30 price, white-hat ~$1M borrow and total ~$10.06M exposure, ET timeline, Supra fix): https://www.theblock.co/post/407960/hedera-lending-protocol-bonzo-lend-hit-for-9-million-after-supra-verifier-accepts-manipulated-price-update[coindeskbonzo2026]— CoinDesk, "Bonzo Lend's total value locked plunges 77% as $9 million oracle exploit rattles Hedera" (TVL impact on Bonzo and Hedera network-wide): https://www.coindesk.com/web3/2026/07/11/lending-protocol-bonzo-loses-77-of-value-locked-as-usd9-million-oracle-exploit-rattles-hedera[cryptonewsbonzo2026]— crypto.news, "Bonzo Lend loses $9M after oracle flaw inflates SAUCE price" (independent corroboration of mechanism and figures): https://crypto.news/bonzo-lend-loses-9m-after-oracle-flaw-inflates-sauce-price/[cryptotimesbonzo2026]— The Crypto Times, "Hedera's Biggest DeFi Lender Bonzo Lend Hacked for $9M, $5.25M Bridged to Ethereum" (fund flow: $5.25M bridged to Ethereum, WBTC → ETH swap, partial attacker addresses, Tornado Cash seeding): https://www.cryptotimes.io/2026/07/11/hederas-biggest-defi-lender-bonzo-lend-hacked-for-9m-5-25m-bridged-to-ethereum/
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.