# StakingRewards pools are not given their promised share of rewards due to incorrect calculation

RewardsEmitter compounds pending rewards downward each upkeep, so frequent performUpkeep calls disburse far less than the promised daily rate and dust never fully pays out.

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

**Target:** RewardsEmitter.performUpkeep reward distribution
**Root cause:** Each upkeep subtracts amountToAddForPool from pendingRewards and recomputes the percentage on the reduced balance, producing Principle*(1-rate)^time instead of a linear daily disbursement.
**Steps:**
1. Add 10 ether pending rewards to a pool via `addSALTRewards`.
2. Call `liquidityRewardsEmitter.performUpkeep(1 days)` 40 times as upkeep.
3. Observe `pendingLiquidityRewardsForPool` = 3.632 ether, not 0.
4. Repeat 40 more times; still 1.319 ether remains.
5. With 1% daily rate and 100M ether rewards, call `performUpkeep(15 minutes)` 96 times; only ~99.5M disbursed vs expected 99M deduction.
**How found:** Author read the performUpkeep code, noticed pendingRewards is decremented before recomputing the percentage, and recognized the classic negative-compounding formula; cross-checked against the protocol's own comment in StakingRewards.sol claiming $1000/day equals $10 per 15-minute upkeep, then wrote Foundry PoCs to confirm.
**Exploitation:** A malicious actor can grief the protocol by calling performUpkeep frequently (every 15 minutes) to diminish and delay reward emissions to stakers, exploiting the negative compounding so pools receive less than the promised 1% per day.
**Insight:** When a contract applies a percentage to a shrinking balance each call, check whether the intended semantics are linear per-period disbursement; compare against protocol comments stating per-period expected amounts to spot compounding drift.
