# Voting overwrites checkpoint.voted in last checkpoint, so users can just vote right before claiming rewards

Velodrome Gauge.earned only checks the last checkpoint's voted flag, so users can vote just before claiming to collect full-period rewards without sustained voting.

- Payout: Contest reward
- Severity: high
- Program: Velodrome Finance
- Credited: smiling_heretic
- Disclosed: 2022-08-08
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-05-velodrome-findings/issues/206
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-velodrome%3AH-05
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** Gauge.sol reward accounting (earned/setVoteStatus checkpoints)
**Root cause:** setVoteStatus overwrites the voted flag in the last checkpoint rather than creating a new checkpoint, so earned() only sees the most recent voted state and cannot verify the user was voted for the whole accrual period.
**Steps:**
1. Observe Gauge.earned gates rewards on `if (cp0.voted)` using the last checkpoint only.
2. User does not vote for the gauge during the 6-day period.
3. Right before claiming (same tx), call vote to set voted=true on the last checkpoint.
4. Call gauge.earned/claim to receive rewards for the full period since last interaction.
5. Optionally call voter.reset in the same transaction after claiming to withdraw the vote.
**How found:** Code reading of Gauge.earned's `if (cp0.voted)` reward gate; noticed the intent was to reward sustained voting but the check only reads the last checkpoint, which setVoteStatus overwrites, so a just-in-time vote satisfies it.
**Exploitation:** Attacker withholds votes for the gauge, then in a single transaction votes for the gauge and claims rewards, receiving the same VELO as a user who voted the entire period, then resets votes.
**Insight:** When reward eligibility is gated on a boolean stored in a checkpoint, check whether that boolean is overwritten in place versus appended as a new checkpoint; if overwritten, eligibility collapses to the state at claim time and can be satisfied just-in-time in the same transaction.
