# Hack Analysis: BonqDAO, February 2023

Permissionless TellorFlex spot price feed let attacker report inflated then deflated WALBT price, borrowing 100M BEUR and liquidating 30+ troves for ~113M WALBT.

- Payout: Real-world hack
- Severity: critical
- Program: BonqDAO
- Credited: Immunefi
- Disclosed: 2023-03-24
- Write-up quality: 8/10
- Original: https://immunefi.com/blog/bug-fix-reviews/hack-analysis-bonqdao-february-2023/
- Library page: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-hack-analysis-bonqdao-february-2023
- Tags: domain:web3 impact:funds-loss kind:incident platform:immunefi sev:critical tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:liquidation vuln:oracle-manipulation

**Target:** TellorFlex oracle / Trove lending contracts on Polygon
**Root cause:** Protocol used the last reported TellorFlex spot price as the authoritative price, and submitValue is permissionless with only a per-reporter timelock, so anyone could momentarily set arbitrary prices.
**Steps:**
1. Fork Polygon at block 38792977 (1 block before hack).
2. Deploy a fresh delegatooor clone per submission to bypass the per-reporter timelock.
3. Stake TRB via `depositStake` and call `submitValue(queryId=keccak256(abi.encode('SpotPrice',abi.encode('albt','usd'))), value=abi.encode(5_000_000_000 ether), 0, queryData)`.
4. Create WALBT trove, transfer 0.1 WALBT, call `increaseCollateral(0, address(0))`, then `borrow(attacker, 100_000_000 ether, address(0))`.
5. Create second WALBT trove with 13 WALBT collateral to absorb liquidations.
6. Wait >=1 block, submit new price `100_000_000_000` (tiny) via a new delegatooor.
7. Enumerate troves via `firstTrove`/`nextTrove`/`troveCount` and call `liquidate()` on each indebted trove except own two.
8. Approve max BEUR to second trove, `repay(type(uint).max, address(0))`, then `decreaseCollateral` to withdraw ~113.8M WALBT.
**How found:** Code review of TellorFlex.submitValue revealed it is permissionless with only a per-reporter timelock, and protocol contracts treat the last reported value as spot price, making arbitrary momentary price setting possible.
**Exploitation:** Attacker staked TRB, deployed throwaway reporter clones to dodge the reporting timelock, inflated WALBT spot price to borrow 100M BEUR against 0.1 WALBT, then crashed the price to liquidate 30+ troves at a discount and repaid using the borrowed BEUR to seize ~113M WALBT collateral.
**Escalation:** Two-step price swing: inflate to mint unbacked BEUR, then deflate to trigger mass liquidation and buy discounted collateral with the same borrowed BEUR.
**Insight:** When a lending protocol reads a permissionless oracle's last-reported value as spot price, check whether the reporter timelock is per-address; if so, fresh clone contracts per submission let you swing the price twice in consecutive blocks to both over-borrow and force liquidations.
