# Wrong keeper reward computation

PoolKeeper.keeperReward mixes WAD and Quad units, dividing the keeper tip by 1e18 instead of 100, so keepers receive almost no tip.

- Payout: Audit contest
- Severity: medium
- Program: Tracer
- Found by: cmichel
- Disclosed: 2021-11-15
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2021-10-tracer#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2021-10-tracer%3AM-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** PoolKeeper.keeperReward on-chain contract
**Root cause:** keeperTip() returns a percentage where 1=1%, but the code wraps it as an ABDKMathQuad and then divides _keeperGas*_tipPercent by fixedPoint (1e18 as a quad) as if it were WAD, instead of dividing by 100.
**Steps:**
1. Read keeperReward: `bytes16 _tipPercent = ABDKMathQuad.fromUInt(keeperTip(...))` where keeperTip returns 1=1%, 100=100%.
2. Observe the reward computes `ABDKMathQuad.div(ABDKMathQuad.mul(ABDKMathQuad.fromUInt(_keeperGas), _tipPercent), ABDKMathQuad.fromUInt(100))` — wait, the audit notes the divisor is fixedPoint (1e18) as a quad, not 100.
3. Because _tipPercent is a plain percentage (100=100) not WAD (1e18=100%), dividing by 1e18 makes the tip term near zero.
4. Result: keeper receives only _keeperGas cost, tip portion effectively zero.
**How found:** Code review of the unit conventions: noticed the comment claims 'tip percent in wad units' but keeperTip returns 1=1%, then traced how the Quad value flows into the reward division by fixedPoint.
**Insight:** When a codebase mixes fixed-point libraries (WAD vs ABDKMathQuad), audit every conversion boundary and check the comment's claimed unit against the actual return convention of the source function.

