# THE first AMM Staker may not receive according rewards because of poor checkpoints

First staker in Backd's AmmGauge loses most rewards because poolCheckpoint mishandles zero-total-stake state, undercounting their share.

- Payout: Contest reward
- Severity: medium
- Program: Backd
- Credited: 0xNineDec
- Disclosed: 2022-07-19
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-05-backd-findings/issues/111
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-backd%3AM-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** AmmGauge staking/rewards contract
**Root cause:** poolCheckpoint does not correctly update per-user staked integral when total staked is zero, so the first staker's rewards are computed from a stale/zero checkpoint until the next stake triggers an update.
**Steps:**
1. Deploy AmmGauge with fixed inflation 0.001 and DummyERC20.
2. Call `poolCheckpoint()` then advance time 1 day.
3. Alice calls `stake(10e18)`; no external `poolCheckpoint()` after.
4. Bob, Charlie, David each call `stake(10e18)` 1 hour apart (each stake triggers internal checkpoint).
5. Advance 5 days; call `claimableRewards(alice)` and `claimRewards(alice)`.
6. Observe Alice receives ~6.6 vs ~115.5 when `poolCheckpoint()` is called between stakes.
**How found:** Warden reasoned about the zero-total-stake edge case in poolCheckpoint and built a test harness toggling intermediate poolCheckpoint calls to compare reward outcomes.
**Exploitation:** No attacker profit; the first staker is unintentionally under-rewarded due to missing checkpoint after their stake, while later stakers receive correct rewards.
**Insight:** In staking/reward contracts, test the very first deposit and transitions from totalStaked==0; checkpoint math often divides by or branches on zero and can silently mis-account the first staker until the next stake.
