# Dividend reward can be gamed

Attacker zeroes normalAverageFee with 20 one-wei trades, then trades to make feeDividend = dailyAllocation/2, draining the reserve via LP dividends.

- Payout: Audit contest
- Severity: high
- Program: Spartan Protocol
- Found by: cmichel
- Disclosed: 2021-09-16
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-07-spartan-findings/issues/182
- Library page: https://bugbountylibrary.com/r/c4%3A2021-07-spartan%3AH-08
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity vuln:accounting-error vuln:business-logic vuln:reward-distribution

**Target:** Router.addDividend / reserve dividend distribution
**Root cause:** normalAverageFee is computed from only the last arrayFeeSize (20) trades, so an attacker can force it to zero with zero-fee one-wei trades, then a single fee-generating trade makes feeDividend equal half of dailyAllocation.
**Steps:**
1. Provide LP to a curated pool, ideally the smallest-liquidity pool since dividends are pool-independent.
2. Trade a single wei in the pool `arrayFeeSize` (20) times via `buyTo`; each trade's fee is zero so `normalAverageFee` becomes zero.
3. Do one trade generating non-zero fees `_fees`, setting `normalAverageFee = _fees`.
4. `feeDividend = _fees * dailyAllocation / (_fees + normalAverageFee) = dailyAllocation / 2`, so half of dailyAllocation is sent to the pool.
5. Repeat until the reserve is nearly empty, then redeem LP tokens for a share of the profits.
**How found:** Code review of Router.addDividend and addTradeFee: noticed normalAverageFee only averages the last 20 trades, making the dividend formula manipulable by controlling recent trade fees.
**Exploitation:** Attacker becomes a large LP holder in a small curated pool, repeatedly resets normalAverageFee to zero with 20 one-wei trades, then triggers a fee trade to capture dailyAllocation/2 each cycle, draining the reserve and redeeming LP tokens for profit.
**Insight:** When a reward formula averages only the last N trades, an attacker can overwrite the window with zero-fee dust trades to reset the baseline, then a single real trade sets the denominator to 2x the numerator, yielding half the allocation per cycle.

