# First Liquidity provider can claim all initial pool rewards

First LP into an empty Salty.IO staking pool gets zero virtualRewards, letting them claim all accumulated pool rewards (~5.5k SALT).

- Payout: Contest reward
- Severity: high
- Program: Salty.IO
- Credited: 0xCiphky
- Disclosed: 2024-04-19
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2024-01-salty-findings/issues/614
- Library page: https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** StakingRewards.sol _increaseUserShare / userRewardForPool
**Root cause:** virtualRewards is only computed when existingTotalShares != 0, so the first depositor gets shares with zero virtualRewards deduction while totalRewards already accrued from upkeep emissions.
**Steps:**
1. Wait until upkeep has emitted rewards into StakingRewards (timer starts at deployment, before exchange goes live).
2. Call `upkeep.performUpkeep()` to push daily rewards into the pool.
3. Be the first depositor: call `depositCollateralAndIncreaseShare(depositedWBTC, depositedWETH, 0, block.timestamp, false)` on an empty pool so existingTotalShares==0 skips virtualRewards.
4. Call `userRewardForPool` — rewardsShare = totalRewards*userShare/totalShares equals full totalRewards, minus 0 virtualRewards.
5. Call `claimAllRewards(poolIDs)` to drain all pool rewards (~5.5k SALT of 555k bootstrap at 1%/day).
**How found:** Code reading of _increaseUserShare noticed the `existingTotalShares != 0` guard skips virtualRewards for the first depositor; cross-referenced userRewardForPool formula and upkeep timer starting at construction to confirm rewards are already present before first LP.
**Exploitation:** Attacker front-runs first liquidity provision: triggers upkeep to load rewards, deposits minimal qualifying liquidity (~$2500) as sole LP, then claims entire pool reward balance since virtualRewards deduction is zero.
**Insight:** When reward accounting uses a virtualRewards offset to prevent late depositors from claiming past rewards, check the zero-shares branch: the first depositor bypasses the offset entirely, so any rewards accrued before first deposit are free.
