# User can drain entire reward balance due to accounting issue in _claimInternalRewards and _claimExternalRewards

Precision mismatch in SingleSidedLiquidityVault reward debt accounting lets a user repeatedly claim rewards and drain the entire reward balance.

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

**Target:** SingleSidedLiquidityVault reward claim functions (_claimInternalRewards/_claimExternalRewards)
**Root cause:** userRewardDebts is stored as 36 dp (lpPosition * accumulatedRewardsPerShare) but on claim it is incremented by the raw 18 dp reward amount, so debt is under-counted by 1e18.
**Steps:**
1. Deposit into SingleSidedLiquidityVault to accrue rewards.
2. Call claim to receive reward; observe userRewardDebts[msg.sender][token] incremented by `reward` (18 dp) instead of `reward * 1e18` (36 dp).
3. Repeatedly call claim: owed = lpPositions*accumulatedRewardsPerShare - userRewardDebts stays positive because debt barely grows.
4. Each claim transfers full reward again, draining the vault's reward token balance.
**How found:** Code review of reward accounting: noticed userRewardDebts is written as 36 dp in _depositUpdateRewardDebts (lpReceived * accumulatedRewardsPerShare) but as 18 dp in the claim functions, a unit mismatch.
**Exploitation:** Attacker deposits, then loops claim calls; since userRewardDebts is incremented by 1e18 too little each time, the computed owed amount remains large and the contract keeps paying out rewards until the reward balance is exhausted.
**Insight:** When a contract mixes fixed-point accumulators (X*Y products) with raw token amounts, audit every write to the debt/checkpoint variable for consistent scaling; a single unscaled increment in a claim path enables repeat-claim drains.
