# StakingRewards reward rate can be dragged out and diluted

notifyRewardAmount(0) rebases leftover rewards over a fresh rewardsDuration, letting a privileged caller repeatedly dilute rewardRate and drag out payouts.

- Payout: Audit contest
- Severity: medium
- Program: Concur Finance
- Found by: cmichel
- Disclosed: 2022-05-24
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-02-concur-findings/issues/183
- Library page: https://bugbountylibrary.com/r/c4%3A2022-02-concur%3AM-30
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** StakingRewards.sol notifyRewardAmount reward accounting
**Root cause:** notifyRewardAmount rebases (reward + leftover) over a full new rewardsDuration each call, so a zero-reward call spreads remaining rewards over a longer window, lowering rewardRate.
**Steps:**
1. Set rewardRate = 1000/rewardsDuration, wait 20% of rewardsDuration.
2. Call `notifyRewardAmount(0)`; new rewardRate = (0 + 800)/rewardsDuration, a 20% drop.
3. Wait another 20% and call `notifyRewardAmount(0)` again; rewardRate = 640/rewardsDuration.
4. Repeat to asymptotically dilute rewards and extend periodFinish indefinitely.
**How found:** Code reading of notifyRewardAmount's rebase formula; noticed leftover is divided by full rewardsDuration on every call, then tested the edge case reward=0 to show rewardRate monotonically decreases.
**Exploitation:** A caller with notifyRewardAmount permission (rewardsDistribution/admin) repeatedly submits zero-reward notifications, each time rebasing leftover rewards over a fresh rewardsDuration, steadily reducing rewardRate and stretching payouts, causing yield loss for all stakers.
**Insight:** On Synthetix-style StakingRewards forks, test notifyRewardAmount with reward=0 or tiny rewards: any call that rebases leftover over a fresh rewardsDuration lets a permitted caller dilute rewardRate; check who can call it and whether periodFinish should be immutable.
