# cachedUserRewards variable is never reset, so user can steal all rewards

cachedUserRewards in Olympus SingleSidedLiquidityVault is never reset after claim, letting a user repeatedly claim rewards and drain the vault.

- Payout: Contest reward
- Severity: high
- Program: Olympus
- Credited: CRYP70
- Disclosed: 2023-03-06
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-02-olympus-judging/issues/43
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-olympus%3AH-3
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** SingleSidedLiquidityVault reward accounting (Solidity)
**Root cause:** In _withdrawUpdateRewardState, when rewardDebtDiff exceeds userRewardDebts, the debt is zeroed and the excess is added to cachedUserRewards; _claimInternalRewards adds cachedUserRewards to payout but never zeroes it.
**Steps:**
1. Deposit into SingleSidedLiquidityVault and accrue rewards.
2. Withdraw with claim_=false so rewardDebtDiff > userRewardDebts, populating cachedUserRewards[user][token].
3. Call claimRewards to receive cachedUserRewards amount.
4. Call claimRewards again repeatedly; cachedUserRewards is never reset, so each call pays out the same amount until vault balance is drained.
**How found:** Code review of the withdraw/claim reward accounting path; noticed cachedUserRewards is written in _withdrawUpdateRewardState and read in _claimInternalRewards but never reset to zero after payout.
**Exploitation:** Attacker accrues a cached reward balance via a non-claiming withdraw, then repeatedly calls claimRewards; since cachedUserRewards is never zeroed, each call re-pays the same amount, draining all reward tokens held by the vault.
**Insight:** When a contract caches a pending payout in storage and later pays it out, verify the cache is zeroed on claim; grep for every write and read of accumulator/cache mappings to find missing resets.
