# Reward divisor shrinks with tiny supply

Reward math dividing by a user-influenced or mis-derived aggregate that can be driven small

_Area: DeFi accounting and math bugs. Seen in 3 disclosed reports; latest 2023-04-27. Updated 2026-11-02._

## How it works
A reward, interest or prize formula divides by an aggregate — total staked, effective stake, a per-degree prize count. The code assumes that divisor is a stable, honest measure of protocol-wide scale. When the divisor is user-influenced, mis-derived, or shrinks toward a floor, the per-unit payout inflates: the same reward pool is spread over a smaller base, so each unit earns far more than designed. The broken assumption is "the divisor reflects real scale and the claimant cannot shrink it independently of their own claim."

## Where it shows up
- Reward math of the form `inflationPerBlock(x) / x` or `pool / effectiveAmount`, where `effectiveAmount` is built from user-controlled totals [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md)
- Divisors computed as `totalStaked - totalFrozen` or similar subtraction of one aggregate from another [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md)
- Loops that subtract a set of lower-tier counts to derive a per-tier count [E3](https://bugbountylibrary.com/r/c4%3A2021-10-pooltogether%3AH-01.md)
- Multiplier/APY formulas using reciprocals or `divisor - ratio*(divisor-1e18)/1e18` shapes instead of the documented linear form [E1](https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AM-07.md)
- Any division guarded by a floor constant (e.g. `10**18`) — check what happens as the numerator's base approaches it [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md)

## How to review
Identify every divisor in reward/interest/prize math and ask: can a user make this small while keeping their own claim large? The invariant: the divisor must be a quantity the claimant cannot shrink independently of their own stake, and it must match the documented formula exactly. For each divisor, trace its inputs to storage and check whether a user action (a tiny unborrowed stake, a self-loan, a default) reduces it [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md). Re-derive documented formulas symbolically and compare to the code's closed form; plot both curves for intermediate inputs, not just endpoints [E1](https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AM-07.md). For loops, verify the subtraction set is exactly the intended one (previous degree only, not all lower) [E3](https://bugbountylibrary.com/r/c4%3A2021-10-pooltogether%3AH-01.md).

## How finders spotted it
- Read `calculateRewardsByBlocks`, noticed `totalStaked` reduced by `totalFrozen`, making the divisor user-controllable; traced it through `calculateRewards`/`getInflationIndex` to the division, then built a PoC [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md)
- Compared the published linear APY-vs-ratio formula to the Solidity multiplier and plotted both, showing the code curve sits below the spec for intermediate ratios [E1](https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AM-07.md)
- Compared the documented prize-distribution formula to the implementation, saw the loop subtract every lower degree rather than just the previous, and proved the correct closed form two ways [E3](https://bugbountylibrary.com/r/c4%3A2021-10-pooltogether%3AH-01.md)

## Variants seen
- Divisor shrunk by keeping a tiny unborrowed stake so `totalStaked - totalFrozen` stays near the floor [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md)
- Non-linear multiplier formula diverging from a linear documented spec, underpaying most stakers [E1](https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AM-07.md)
- Wrong per-degree prize count from over-subtraction in a loop, feeding payout math and paying larger prizes than designed [E3](https://bugbountylibrary.com/r/c4%3A2021-10-pooltogether%3AH-01.md)

## Impact and severity
Rewards misallocated across all stakers: E2 lets a staker inflate the inflation index and capture rewards, amplified by a second weakness (self-loans and defaults that neutralize protocol totals) [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md); E1 silently underpays almost all stakers with ratios between 0 and 1 [E1](https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AM-07.md); E3 pays larger prizes than designed [E3](https://bugbountylibrary.com/r/c4%3A2021-10-pooltogether%3AH-01.md). Severity rises with how far the effect scales (whole reward pool) and whether it combines with another weakness [E2](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AM-07.md
- E2: https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-05.md
- E3: https://bugbountylibrary.com/r/c4%3A2021-10-pooltogether%3AH-01.md
