# Onyx Protocol: precision-loss liquidation math drains $2M

Precision-loss bug in Onyx Protocol's Compound-fork liquidation math let an attacker flash-loan WETH, mint oPEPE collateral, and liquidate themselves to drain ~$2M across seven markets.

- Payout: Real-world hack
- Severity: high
- Program: OnyxProtocol
- Analysis by: DeFiHackLabs
- Disclosed: 2023-11-01
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-11/OnyxProtocol_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20231101-onyxprotocol
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained vuln:accounting-error vuln:liquidation vuln:precision-loss

**Target:** Compound-fork lending markets (oPEPE, oUSDC, oUSDT, oPAXG, oDAI, oBTC, oLINK, oETHER)
**Root cause:** liquidateCalculateSeizeTokens / seize-token accounting rounds in the attacker's favor when collateral and debt are near-equal, so a self-liquidation returns more collateral value than the repaid debt.
**Steps:**
1. Flash-loan `4000 WETH` from Aave V3 via `flashLoanSimple`.
2. Swap WETH→PEPE on Uniswap V2 PEPE/WETH pair.
3. Deploy `IntermediateContractETH`, transfer PEPE in, call `start()` to supply PEPE as oPEPE collateral via `mint`.
4. Call `oETHER.liquidateBorrow{value:1 wei}(intermediateETH, oPEPE)` to trigger liquidation of the near-equal position, seizing oPEPE at a favorable rounded rate.
5. `oPEPE.redeem(oPEPE.balanceOf(this))` to unwrap seized collateral, then `WETH.deposit` the ETH.
6. Repeat `exploitToken(oUSDC/oUSDT/oPAXG/oDAI/oBTC/oLINK)` — each mints collateral, self-liquidates, redeems, swaps seized token→WETH on Uniswap V2.
7. Swap remaining PEPE→WETH, repay Aave `amount + premium`, keep profit.
**How found:** Public analyses (Phalcon, Decurity) attribute it to precision loss in the liquidation seize-token math of the Compound fork; the attacker likely spotted that self-liquidation with near-equal collateral/debt yields a rounding surplus.
**Exploitation:** Attacker flash-borrowed 4000 WETH, converted to PEPE, supplied as oPEPE collateral, then used a 1-wei oETHER repayment to liquidate their own position. Rounding in the seize-token calculation returned more collateral than the debt repaid; redeeming and swapping each market's seized token back to WETH netted ~$2M after repaying Aave.
**Escalation:** Same rounding primitive was replayed across seven Onyx markets (USDC, USDT, PAXG, DAI, WBTC, LINK, PEPE) in one transaction to compound the drain.
**Insight:** On Compound forks, audit `liquidateCalculateSeizeTokens` and exchange-rate rounding for self-liquidation: if seizeTokens rounds up while repayAmount rounds down, a borrower can liquidate themselves for profit — test with collateral≈debt and 1-wei repayments.

