# Repeatable reward accrual inflation

Reward or bonus credited more than once, sized from global totals, or re-triggerable without time or stake limits

_Area: DeFi accounting and math bugs. Seen in 3 disclosed reports; latest 2026-09-30. Updated 2026-11-01._

## How it works
Reward math assumes each payout is earned once, over time, against real stake. These bugs break that assumption: a bonus is credited twice, a reward is sized from a global total another address can move, or a mint/distribute function can be called again and again. In each case the contract pays out more than the deposit or stake justifies, and the excess is withdrawable.

## Where it shows up
- Deposit functions that both refund a bonus in native token and credit it as a redeemable balance [E1](https://bugbountylibrary.com/r/dhl%3A20260930-mus.md)
- Reward formulas reading global totals (e.g. total contributed) instead of per-user time-weighted stake [E2](https://bugbountylibrary.com/r/dhl%3A20260319-revamp.md)
- Caps on reward size with no time or stake condition, so a second address's large contribution pushes an earlier address's pending reward to the cap [E2](https://bugbountylibrary.com/r/dhl%3A20260319-revamp.md)
- Public `distribute()`/`rebase()`/mint functions with no rate limit or caller gate [E3](https://bugbountylibrary.com/r/dhl%3A20250525-dumbo.md)
- Reward paths that compound into a stake the caller controls within one transaction [E3](https://bugbountylibrary.com/r/dhl%3A20250525-dumbo.md)
- Missing caller/owner gates on deposit and withdraw, widening the drain [E1](https://bugbountylibrary.com/r/dhl%3A20260930-mus.md)

## How to review
For every reward or bonus path, state the invariant: total payout to a user must not exceed what their own deposit and elapsed time justify. Check that:
- A bonus is credited in exactly one form, not refunded and credited again; total payout (refund + redeemable) is capped at the deposit [E1](https://bugbountylibrary.com/r/dhl%3A20260930-mus.md)
- Reward depends on the caller's own stake and time, not on a global total another address can move [E2](https://bugbountylibrary.com/r/dhl%3A20260319-revamp.md)
- Any cap is paired with a time or stake condition, not reachable by one large contribution [E2](https://bugbountylibrary.com/r/dhl%3A20260319-revamp.md)
- Mint/distribute functions are gated or rate-limited, and cannot be looped to compound into caller-owned stake in one tx [E3](https://bugbountylibrary.com/r/dhl%3A20250525-dumbo.md)
- Deposit and withdraw have appropriate access control [E1](https://bugbountylibrary.com/r/dhl%3A20260930-mus.md)

## Variants seen
- Double-counted first-deposit bonus: refunded as ETH and credited as allocation, drained by deposit-withdraw cycles [E1](https://bugbountylibrary.com/r/dhl%3A20260930-mus.md)
- Global-total reward sizing: a second address's contribution inflates the first address's pending reward to the 2x cap [E2](https://bugbountylibrary.com/r/dhl%3A20260319-revamp.md)
- Repeatable distributor: permissionless distribute() mints and compounds rewards into stake, then unstaked and sold [E3](https://bugbountylibrary.com/r/dhl%3A20250525-dumbo.md)

## Impact and severity
Direct pool drain in all three: ETH drained via bonus cycles [E1](https://bugbountylibrary.com/r/dhl%3A20260930-mus.md), 2.99 BNB profit [E2](https://bugbountylibrary.com/r/dhl%3A20260319-revamp.md), 628 BUSD profit [E3](https://bugbountylibrary.com/r/dhl%3A20250525-dumbo.md). Severity is high because the loss is the pool's real balance, not a paper figure. Worse when functions are permissionless and the cycle completes in one transaction [E3](https://bugbountylibrary.com/r/dhl%3A20250525-dumbo.md), and when no invariant caps total payout at the deposit [E1](https://bugbountylibrary.com/r/dhl%3A20260930-mus.md).

## Evidence
- E1: https://bugbountylibrary.com/r/dhl%3A20260930-mus.md
- E2: https://bugbountylibrary.com/r/dhl%3A20260319-revamp.md
- E3: https://bugbountylibrary.com/r/dhl%3A20250525-dumbo.md
