# Double Voting and Lock Bypass Vulnerability during Unwinding Epoch Increase

AllocationVoting tracks lastVoteEpoch per unwinding period, so users can vote, increaseUnwindingEpochs to a new period, and vote again in the same epoch, doubling governance weight and bypassing transfer restrictions.

- Payout: Contest reward
- Severity: high
- Program: infiniFi
- Credited: 0xBeastBoy
- Disclosed: 2025-05-23
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_infinifi_april2025.pdf#3.1.1
- Library page: https://bugbountylibrary.com/r/cantina%3Ainfinifi_april2025%3A3.1.1
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic vuln:governance

**Target:** LockingController / AllocationVoting governance contracts
**Root cause:** increaseUnwindingEpochs burns old-period share tokens and mints new-period tokens but never syncs AllocationVoting.lastVoteEpoch, and each unwinding period has its own lastVoteEpoch and transferRestrictions mapping, so state resets across periods.
**Steps:**
1. Create a position with 4-week unwinding via `gateway.createPosition(amount, 4, user)`
2. Advance an epoch, then vote with 4-week tokens: `gateway.vote(usdc, 4, liquidVotes, illiquidVotes)` — sets `lastVoteEpoch[alice][4]` and restricts transfers on 4-week token
3. Call `increaseUnwindingEpochs(shares, 4, 12, alice)` to burn 4-week tokens and mint 12-week tokens (no restriction, `lastVoteEpoch[alice][12]` unset)
4. Vote again in same epoch with 12-week tokens: `gateway.vote(usdc, 12, liquidVotes, illiquidVotes)` — passes `lastVoteEpoch[alice][12] < epoch`
5. Observe farm vote weights exceed a single vote's contribution and 12-week tokens are freely transferable
**How found:** Code reading of AllocationVoting's per-period lastVoteEpoch mapping versus LockingController.increaseUnwindingEpochs, noticing the burn/mint across separate LockedPositionToken contracts never updates vote tracking or transfer restrictions.
**Exploitation:** Attacker locks tokens, votes to influence farm allocation, then increases unwinding period to obtain unrestricted tokens in a fresh period and votes again in the same epoch, amplifying governance weight and moving tokens that should be locked post-vote.
**Insight:** When governance weight and vote-receipt state are keyed per lock-duration/period, any operation that migrates a position between periods (burn+mint) silently resets per-period state — check every cross-period migration path for missing vote/restriction sync.
