# Possible rounding during the reward calculation

RewardableERC20 truncates rewardsPerShare on each claim; frequent small claims with low-decimal reward tokens lose ~50% of rewards locked in contract.

- Payout: Contest reward
- Severity: medium
- Program: Reserve
- Credited: auditor0517
- Disclosed: 2023-11-13
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-07-reserve-findings/issues/30
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-reserve%3AM-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss vuln:reward-distribution

**Target:** RewardableERC20 / RewardableERC20Wrapper staking reward accounting
**Root cause:** rewardsPerShare increment uses integer division (delta * one) / totalSupply, truncating remainders; since _claimAndSyncRewards runs on every transfer, frequent small deltas round to near-zero.
**Steps:**
1. Set underlyingDecimals=18, totalSupply=1e6*1e18, rewardToken 6 decimals, 1M rewardToken/year.
2. Trigger _claimAndSyncRewards every ~1 min via deposits/transfers.
3. Expected per-minute reward = 1.9e6 wei; computed deltaPerShare = 1900000*1e18/(1e6*1e18) = 1 (truncated).
4. Observe ~50% of rewards lost and locked in contract.
**How found:** Code review of _claimAndSyncRewards division; noticed `one` multiplier equals underlying decimals and function is invoked on every _beforeTokenTransfer, amplifying truncation.
**Insight:** When a per-share accumulator is updated on every transfer rather than lazily, integer truncation compounds; check reward-token decimals vs share decimals and call frequency to bound the loss.
