# Rounding error in buyQuote might result in free tokens

buyQuote rounds down required base tokens, letting a buyer acquire small amounts of fractional tokens for zero WBTC, shorting LP fees.

- Payout: Contest reward
- Severity: medium
- Program: Caviar
- Credited: Zarf
- Disclosed: 2023-01-26
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-caviar-findings/issues/243
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-caviar%3AM-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** buyQuote pricing function in Caviar AMM contract
**Root cause:** buyQuote divides and rounds down the base-token cost for incoming assets; incoming assets should round up to preserve solvency and fee accrual.
**Steps:**
1. Set reserves: baseTokenReserves=1e7 (0.1 WBTC), fractionalTokenReserves=1e25.
2. Call buyQuote(9e17) for 0.9 fractional tokens.
3. Computation: (9e17*1000*1e7)/((1e25-9e17)*997) = 0.903, which floors to 0.
4. Execute buy with 0 base tokens paid, receiving 0.9 fractional tokens.
**How found:** Code review of buyQuote rounding direction: recognized incoming assets must round up, observed division floors to zero for small outputs relative to large reserves.
**Exploitation:** Buyer repeatedly calls buy with tiny outputAmounts where the floored quote is 0, receiving fractional tokens for free; each buy shrinks fractional reserves until quote exceeds 1 wei.
**Escalation:** Repeating the zero-cost buy drains fractional reserve gradually, reducing LP fee income below the intended 30bps.
**Insight:** In AMM quote math, check rounding direction per asset flow; test tiny outputAmounts against large reserves to see if integer division floors the cost to zero.
