# Reward Rate Manipulation via Dust Attacks

Dust transfers of reward tokens to MultiFeeDistribution reset rewardPerSecond over full stream time, diluting rewards for all stakers.

- Payout: Contest reward
- Severity: medium
- Program: Defi App
- Credited: aksoy
- Disclosed: 2025-03-27
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_defi_app_february2025.pdf#3.2.6
- Library page: https://bugbountylibrary.com/r/cantina%3Adefi_app_february2025%3A3.2.6
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** MultiFeeDistribution reward accounting (MFDLogic.sol)
**Root cause:** trackUnseenReward treats any balance delta (including direct dust transfers) as new reward and recomputes rewardPerSecond = (dust+leftover)*PRECISION/rewardStreamTime, spreading the whole leftover over a fresh full stream window.
**Steps:**
1. Admin distributes 100 ether reward token; rewardPerSecond = 165343915343915343915343915343915
2. `vm.warp(block.timestamp + 3 days)`
3. Attacker sends 10 wei of reward token directly to staker contract
4. Call `claimRewards([rewardToken])` triggering trackUnseenReward -> _handleUnseenReward
5. rewardPerSecond drops to 94482237339380196539351851851851
6. Repeat warp + 10 wei dust + claimRewards; rate falls to 53989849908217255180224867724867 then 30851342804695574404761904761904
**How found:** Code review of claimRewards -> trackUnseenReward -> _handleUnseenReward; noticed balance-delta detection includes direct transfers and the formula divides total leftover by full rewardStreamTime, then confirmed with a Foundry PoC measuring rewardPerSecond after dust sends.
**Exploitation:** Attacker repeatedly sends 10 wei of the reward token to the staker and calls claimRewards; each call resets periodFinish to now+rewardStreamTime and recomputes rewardPerSecond over the full window, permanently stretching vesting and lowering per-second rewards for all stakers at negligible gas cost.
**Insight:** When a reward accumulator derives 'new rewards' from raw balanceOf deltas, any direct token transfer becomes an input; check whether the recompute divides accumulated leftover by the full stream duration, which lets 1 wei reset the whole schedule.
