# Inflation rate can be reduced by half at most if it gets called every 1.99 interval

GoGoPool inflate() resets inflation start time to block.timestamp instead of advancing by whole intervals, so sub-interval calls permanently lose accrued inflation.

- Payout: Contest reward
- Severity: medium
- Program: GoGoPool
- Credited: wagmi
- Disclosed: 2023-03-21
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-gogopool-findings/issues/648
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-gogopool%3AM-06
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** Solidity RewardsPool inflation logic (getInflationIntervalsElapsed/inflate)
**Root cause:** getInflationIntervalsElapsed floors (block.timestamp - startTime)/intervalSeconds, but inflate() sets InflationIntervalStartTime to the current timestamp rather than oldStartTime + intervalsElapsed*intervalSeconds, discarding the remainder each call.
**Steps:**
1. Set InflationIntervalStartTime=100, InflationIntervalSeconds=50.
2. Call inflate() at timestamp=199: intervalsElapsed=(199-100)/50=1, one inflation applied.
3. Observe start time updated to 199 instead of 150.
4. Repeat at 298, 397, 496, 595: only 5 inflations applied though (595-100)/50=9 are due.
**How found:** Code reading of the interval math: noticed floor division in getInflationIntervalsElapsed versus full-timestamp reset in inflate(), then constructed a timestamp sequence to show cumulative drift.
**Exploitation:** Anyone can call inflate() slightly before a full interval elapses; each early call resets the start time and permanently forfeits the partial interval, halving effective inflation rate if called every 1.99 intervals.
**Insight:** When a function floors elapsed periods for computation but stores the raw current timestamp as the new epoch, the remainder is silently burned; check every 'start time = now' reset against the period math that consumes it.
