# DropPerSecond is not updated homogeneously, the rewards emission can be much higher than expected in some cases

Integer division truncation in Paladin's monthly DropPerSecond update under-decreases emission rate, causing rewards to be emitted far faster than intended.

- Payout: Audit contest
- Severity: high
- Program: Paladin
- Found by: WatchPug
- Disclosed: 2022-05-10
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-03-paladin-findings/issues/44
- Library page: https://bugbountylibrary.com/r/c4%3A2022-03-paladin%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** HolyPaladinToken.sol reward emission rate updater
**Root cause:** nbMonthEllapsed = (block.timestamp - lastDropUpdate) / MONTH truncates fractional months, so each update decreases DropPerSecond by fewer months than actually elapsed; lastDropUpdate is then reset to now, discarding the remainder permanently.
**Steps:**
1. Call `_updateDropPerSecond()` at `lastDropUpdate + (2*MONTH - 1)` seconds.
2. `nbMonthEllapsed` rounds down to 1 despite ~1.99 months elapsed.
3. `dropPerSecondDecrease = dropDecreasePerMonth * 1`, under-decreasing the rate.
4. `lastDropUpdate = block.timestamp` discards the fractional remainder.
5. Repeat each cycle; over `dropDecreaseDuration` only ~half of `(startDropPerSecond - endDropPerSecond)` is decreased, then it snaps to `endDropPerSecond`.
**How found:** Code review of `_updateDropPerSecond` arithmetic, noticing integer division of elapsed time by MONTH truncates and that `lastDropUpdate` reset loses the remainder.
**Insight:** When a rate is decremented per elapsed period, check whether elapsed-time division truncates and whether the timestamp anchor is reset to now (losing remainder) versus advanced by whole periods; the latter accumulates error across calls.
