# ERC20Rewards returns wrong rewards if no tokens initially exist

ERC20Rewards skipped updating lastUpdated when totalSupply was zero, so the first mintee claimed all rewards accrued since the period start.

- Payout: Audit contest
- Severity: high
- Program: Yield
- Found by: cmichel
- Disclosed: 2021-09-17
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-08-yield-findings/issues/28
- Library page: https://bugbountylibrary.com/r/c4%3A2021-08-yield%3AH-02
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** ERC20Rewards staking/rewards contract (_updateRewardsPerToken)
**Root cause:** `_updateRewardsPerToken` returns early when `totalSupply == 0` without advancing `rewardsPerToken_.lastUpdated`, leaving the index anchored at `rewardsPeriod.start`.
**Steps:**
1. Configure `rewardsPeriod.start` in the past (e.g. 1 month ago) with `totalSupply == 0`.
2. Call `_mint`: `_updateRewardsPerToken` short-circuits, `lastUpdated` stays at `rewardsPeriod.start`; `_updateUserRewards` yields nothing since balance and index diff are zero.
3. Call `claim`: `_updateRewardsPerToken` computes `timeSinceLastUpdated = block.timestamp - rewardsPeriod.start` (~1 month) and issues all past rewards to the sole holder.
4. First mintee receives the entire accrued reward pool.
**How found:** Code-reading of `_updateRewardsPerToken`'s early-return on zero supply, noticing `lastUpdated` never advances; compared against Unipool.sol's zero-supply guard which returns stored value without corrupting the timestamp.
**Exploitation:** Attacker waits for a rewards period to be initialized while supply is zero, mints the first tokens, then claims to collect all rewards accrued since period start.
**Insight:** In staking/rewards contracts, the zero-supply early-return must still advance the reward index timestamp; otherwise the first depositor back-claims rewards for the empty period. Check every early-return for state that should still be checkpointed.

