# Abuser can vote twice by voting, withdrawing dct and staking it on another account

Voting power snapshot persists after unstaking DCT, letting a user restake the same tokens on a second account and vote twice.

- Payout: Contest reward
- Severity: medium
- Program: Goat
- Credited: Auditism
- Disclosed: 2024-06-12
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_goat_mar2024.pdf#3.2.6
- Library page: https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.2.6
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic vuln:governance

**Target:** Voting/Controller staking contracts (Solidity)
**Root cause:** _addVoter records voting power from dp2pToken balance at vote time, but lockWithdraw burns dp2pTokens without clearing the voter's recorded powerOf entry, so the prior vote contribution persists.
**Steps:**
1. Stake DCT on account A; receive dp2pTokens minted via calMintStakingPower.
2. Call vote on a challenge; _addVoter reads `_votingToken.balanceOf(voter_)` and stores `vote.powerOf[voter_]`.
3. Call `lockWithdraw()` on A: dp2pTokens burned via `_dP2PDToken.burn`, DCT transferred out; `vote.powerOf[A]` remains.
4. Transfer DCT to account B, stake it, mint fresh dp2pTokens.
5. Vote again from B; both A's and B's power count toward the same challenge.
**How found:** Code reading of _addVoter power accounting versus lockWithdraw burn path; noticed withdrawal never touches stored vote.powerOf, implying stale voting weight.
**Exploitation:** Attacker with a single DCT stake votes on a challenge, unstakes, moves DCT to a fresh address, restakes and votes again, doubling effective voting weight without additional capital.
**Escalation:** Repeat across many addresses to arbitrarily skew attacker/defender power in challenges.
**Insight:** When voting power is snapshotted from a token balance, check every path that burns or moves that token (withdraw, transfer, migration) for whether the stored per-voter power record is invalidated; stale snapshots enable double-counting.
