Root Cause
The Supra oracle verifier on Hedera contained a critical flaw in its BLS (Boneh-Lynn-Shacham) signature validation logic. When a price update carried a zeroed-out signature and public key, the contract's pairing check still returned true because both values resolved to the elliptic-curve identity point.
// Simplified pseudocode of the vulnerable pattern:
function verifyBLS(bytes sig, bytes pubKey, bytes message) internal view returns (bool) {
// If sig == 0 and pubKey == 0, pairing returns (1,1)==true trivially
return Pairing.pairing(sig, G2_GENERATOR, neg(pubKey), hashToG2(message));
// Missing guard:
// require(sig != BLS_IDENTITY && pubKey != BLS_IDENTITY);
}
Additionally, the committee ID supplied in the malicious update was out of range; the lookup defaulted to the zero-key rather than reverting, removing the last safety net.
Attack Steps
| Step | Action | Detail |
|---|---|---|
| 1 | Deposit collateral | Attacker deposited 250 SAUCE (~$3) in Bonzo Lend |
| 2 | Submit poisoned price update | Sent a Supra oracle update for SAUCE with zeroed BLS signature and zeroed public key; out-of-range committee ID returned zero key |
| 3 | Pairing passes | Supra verifier accepted the update; SAUCE price recorded at ~10^12 x true market value |
| 4 | Borrow against inflated collateral | 8 seconds after false price landed, borrowed 6.63M USDC + 34.52M wrapped HBAR |
| 5 | Exit | Funds bridged off Hedera and partially laundered via cross-chain swaps |
Impact
- Loss: $9.05M (6.63M USDC + 34.52M wHBAR)
- Protocol TVL: Bonzo Lend's TVL fell 77% immediately after the exploit
- Ecosystem TVL: Hedera's total DeFi TVL dropped ~40% within 24 hours
- Root location: Vulnerability was in Supra's oracle verifier, not Bonzo Lend's own contracts
- Supra deployed a fix post-incident; Bonzo paused markets
Lessons for Auditors
- Validate identity-point inputs before any BLS/pairing check. Assert that both
sigandpubKeyare not the group identity element. A zeroed BLS signature trivially satisfies many pairing equations. - Out-of-bounds committee lookups must revert, not default. Mapping or array lookups that silently return zero on out-of-range access are a dangerous failure mode. Add explicit bounds checks and
require(committeeKey != bytes(0)). - Lending protocols need price-deviation circuit-breakers. A sanity guard in the borrowing path that rejects prices deviating by more than N% from TWAP would have blocked this entirely.
- Third-party oracle dependencies inherit oracle risk. Bonzo Lend's own Solidity was correct. Audits must include the oracle adapter and its upstream verification logic.