# RewardThrottle.checkRewardUnderflow() might track the cumulative APRs wrongly.

RewardThrottle._sendToDistributor early-returns on zero amount, skipping cumulative APR updates for gap epochs, corrupting cashflowAverageApr and targetAPR.

- Payout: Contest reward
- Severity: high
- Program: Malt Protocol
- Credited: hansfriese
- Disclosed: 2023-05-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-02-malt-findings/issues/23
- Library page: https://bugbountylibrary.com/r/c4%3A2023-02-malt%3AH-01
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** RewardThrottle.sol reward accounting contract
**Root cause:** _sendToDistributor returns immediately when amount==0, so state[epoch+1].cumulativeApr/cumulativeCashflowApr are never advanced for epochs where the overflow pool had no capital, leaving stale cumulative values.
**Steps:**
1. Set activeEpoch=100, epoch=103 (active epoch not updated for 2 epochs).
2. Call checkRewardUnderflow(); _fillInEpochGaps settles gaps, then loop requests capital per epoch.
3. At epoch 100 overflowPool returns positive balance; _sendToDistributor updates cumulative APR for epoch 101.
4. Overflow pool now empty; for epochs 101,102 requestCapital returns 0, so `_sendToDistributor(0, i)` hits `if (amount == 0) return;` at L576 and skips cumulative APR update for epoch 102.
5. activeEpoch becomes 103, so epoch 102 cumulative values are never corrected.
6. updateDesiredAPR() computes cashflowAverageApr over smoothingPeriod including the stale epoch, yielding a too-small targetAPR.
**How found:** Code reading of checkRewardUnderflow's multi-epoch loop combined with the early-return guard in _sendToDistributor; noticed cumulative APR state is only written on nonzero transfers, so gap epochs with empty overflow pool leave cumulative values unadvanced.
**Insight:** When a loop iterates over multiple epochs and calls a state-updating helper, check whether the helper has an early-return guard that skips state advancement for some iterations; cumulative/accumulator variables must be advanced even on zero-value iterations or later epochs inherit stale baselines.
