# StakingRewards.sol#notifyRewardAmount() Improper reward balance checks can make some users unable to withdraw their rewards

notifyRewardAmount checks only token balance, not unclaimed user rewards, so a second notify without funding overstates rewards and later getReward reverts.

- Payout: Contest reward
- Severity: medium
- Program: Y2k Finance
- Credited: cccz
- Disclosed: 2023-01-09
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-09-y2k-finance-findings/issues/50
- Library page: https://bugbountylibrary.com/r/c4%3A2022-09-y2k-finance%3AM-10
- Tags: domain:web3 impact:dos 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 validates rewardRate against the contract's full rewardsToken balance, which includes already-earned but unclaimed user rewards, so it can accept a reward amount not actually backed by new funds.
**Steps:**
1. Set rewardsDuration = 7 days.
2. Alice stakes 1,000 stakingToken.
3. rewardsDistribution sends 100 rewardsToken and calls `notifyRewardAmount(100)`.
4. After 7 days Alice's `earned()` = 100 but she does not call `getReward()`.
5. rewardsDistribution calls `notifyRewardAmount(100)` again without transferring funds; tx succeeds because balance check passes.
6. After 7 more days `earned()` = 200; Alice's `getReward()` reverts due to insufficient rewardsToken balance.
**How found:** Compared the balance check to the Concur prior finding; observed that balanceOf includes unclaimed user rewards, so the check does not guarantee solvency for newly notified rewards.
**Exploitation:** Requires the trusted rewardsDistribution to mistakenly call notifyRewardAmount without funding; the contract then over-accrues rewards, and users who claim later find the contract underfunded and their getReward reverts.
**Insight:** When auditing staking/reward contracts, check whether solvency checks use total token balance that already includes accrued-but-unclaimed user liabilities; the correct check must exclude outstanding earned rewards or pull funds via transferFrom.
