# Attacker can make stakeRate to be 1 in the StRSR contract and users depositing tokens can lose funds because of the big rounding error

Attacker pre-funds StRSR before init so rsrRewardsAtLastPayout is inflated, forcing stakeRate to 1 and causing rounding losses for stakers.

- Payout: Contest reward
- Severity: medium
- Program: Reserve
- Credited: unforgiven
- Disclosed: 2023-04-27
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-01-reserve-findings/issues/439
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-reserve%3AM-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window technique:source-review vuln:accounting-error vuln:share-inflation

**Target:** StRSR staking contract (Solidity)
**Root cause:** init() sets rsrRewardsAtLastPayout to the contract's current RSR balance, which an attacker can inflate by sending tokens to the precomputed deployment address before deployment; _payoutRewards then computes stakeRate = (totalStakes*FIX_ONE + stakeRSR-1)/stakeRSR which collapses to 1 when stakeRSR is tiny relative to totalStakes.
**Steps:**
1. Compute StRSR deployment address from deployer nonce; front-run deployment by sending `200 * 1e18` RSR to that address.
2. init() runs and sets `rsrRewardsAtLastPayout = 200e18`.
3. Attacker calls `stake()` with 1 wei RSR so `stakeRSR = totalStakes = 1`.
4. Wait `rewardPeriod`, call `payoutReward()`; payoutRatio > 1% makes stakeRSR grow, then `stakeRate = (totalStakes*FIX_ONE + stakeRSR-1)/stakeRSR = 1`.
5. Subsequent `stake()` calls compute `newTotalStakes = stakeRate*newStakeRSR/FIX_ONE`, losing up to 1e18 RSR per deposit to rounding.
6. Attacker unstakes 1 wei stake and receives ~1e18 RSR due to inverse rounding.
**How found:** Code review of init() and _payoutRewards() noting rsrRewardsAtLastPayout is seeded from live balance and stakeRate formula divides by stakeRSR, so a tiny stakeRSR with large rewards collapses the rate to 1.
**Exploitation:** Sandwich the StRSR deployment: pre-send RSR to the deterministic address, stake 1 wei, trigger payoutReward after rewardPeriod to pin stakeRate at 1, then let victims stake at the broken rate and unstake to extract the rounding surplus.
**Insight:** When a contract seeds accounting state from its own token balance at init, check whether the deployment address is predictable and pre-fundable; also check rate formulas for division by attacker-controllable tiny denominators.
