# Users can get unlimited votes

VotingEscrow._burn omits _moveTokenDelegates, so burnt locked NFTs keep their delegation checkpoints, letting users mint/transfer repeatedly to inflate votes and gauge rewards.

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

**Target:** VotingEscrow.sol governance/veNFT contract
**Root cause:** _mint and _transferFrom call _moveTokenDelegates to update checkpoints, but _burn removes the token without moving its delegation back to address(0), leaving stale vote checkpoints attributed to the owner.
**Steps:**
1. Deposit tokens and lock them to mint a veNFT (checkpoints delegation to owner via _moveTokenDelegates).
2. Wait for the lock to expire.
3. Transfer the NFT to another address (moves delegates from owner to recipient).
4. Burn the NFT at the recipient; _burn never calls _moveTokenDelegates, so the recipient's checkpoint retains the votes.
5. Repeat: each iteration mints a new NFT and adds checkpoints, inflating getPastVotes() for the account.
6. Use inflated votes to influence governance, gauges, and bribe/reward distribution.
**How found:** Code review comparing _mint and _transferFrom (both call _moveTokenDelegates) against _burn, which lacks the call despite a TODO comment, revealing asymmetric checkpoint handling.
**Exploitation:** Attacker cycles lock→expire→transfer→burn to accumulate phantom delegation checkpoints, then leverages getPastVotes() in governance and gauge/bribe accounting to gain disproportionate voting power and rewards.
**Escalation:** Repeated iterations scale the phantom vote balance arbitrarily, enabling governance control and pool favoritism via gauges.
**Insight:** When auditing vote-escrow/veNFT designs, diff every token lifecycle path (mint, transfer, burn, merge, split) for symmetric checkpoint updates; a missing _moveTokenDelegates on burn silently leaves stale delegation that compounds with repeated mint/burn cycles.
