# Voting power double-counted or replayed

Vote receipt keyed to address, period, or live state instead of the power unit itself

_Area: Smart contract access control and control flow. Seen in 27 disclosed reports; latest 2025-07-03. Updated 2026-10-23._

## How it works
Governance assumes each unit of voting power casts at most one vote per proposal or epoch. The invariant that must hold: the vote receipt (a "voted" flag, checkpoint, or per-period counter) is co-located with the power unit and moves with it. It breaks when the receipt is keyed to something that changes independently of the power — an address, a current-state flag, a period that can be re-entered, or a global aggregate mutated twice. Power stays constant while the receipt resets, so the same weight votes again.

## Where it shows up
- Vote weight read from live/current state rather than a finalized past snapshot [E3](https://bugbountylibrary.com/r/c4%3A2022-09-party%3AH-01.md).
- "Voted" flag keyed on `msg.sender` while weight is bound to a tokenId/NFT [E6](https://bugbountylibrary.com/r/c4%3A2025-05-blackhole%3AM-17.md).
- Same-block `ownershipChange` guard not set on every balance-mutating path (merge, split, deposit) [E4](https://bugbountylibrary.com/r/cantina%3Azerolend_jan2024%3A3.1.3.md).
- Per-period vote counters not synced when a position is burned and re-minted into a new period [E7](https://bugbountylibrary.com/r/cantina%3Ainfinifi_april2025%3A3.1.1.md).
- Delegation grants a fresh unvoted slot per delegate while weight stays on the locked position [E5](https://bugbountylibrary.com/r/c4%3A2023-08-verwa%3AH-02.md).
- Transfer hook updates rewards but never moves voting power with the transferred amount [E8](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.1.md).
- Global aggregate (total stake) mutated on a state transition that already accounted for the amount [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-polygon-consensus-bypass-bugfix-review.md).
- Stake can exit between validator selection and header commitment while power persists [E2](https://bugbountylibrary.com/r/sherlock%3A2025-06-symbiotic-relay%3AM-7.md).

## How to review
Identify the unit of voting power and the unit of the vote receipt; they must be the same object, or the receipt must move with the power. Check: (1) weight is read from a snapshot at or before proposal creation, not current state; (2) the voted flag is keyed to the token/lock, not the caller; (3) every path that moves or mutates a position updates the receipt and any same-block guard; (4) migrating a position between periods/epochs carries or invalidates its prior votes; (5) delegation does not create a new unvoted slot for the same underlying weight; (6) token transfers move or invalidate power; (7) selection and commitment are atomic or stake is locked through commitment. False positive to exclude: a legitimate re-vote after a delegation change that correctly moves the receipt with the power.

## Variants seen
- Same-block NFT transfer and re-vote against a live snapshot [E3](https://bugbountylibrary.com/r/c4%3A2022-09-party%3AH-01.md).
- Per-address voted flag with token-bound weight [E6](https://bugbountylibrary.com/r/c4%3A2025-05-blackhole%3AM-17.md).
- Merge not resetting the destination's ownership-change guard [E4](https://bugbountylibrary.com/r/cantina%3Azerolend_jan2024%3A3.1.3.md).
- Burn+mint across unwinding periods resetting `lastVoteEpoch` [E7](https://bugbountylibrary.com/r/cantina%3Ainfinifi_april2025%3A3.1.1.md).
- Fresh delegate address re-voting the same gauge weight [E5](https://bugbountylibrary.com/r/c4%3A2023-08-verwa%3AH-02.md).
- Transfer hook that moves rewards but not voting power [E8](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.1.md).
- Double-subtracted stake on migrate-out of an already-unstaked validator [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-polygon-consensus-bypass-bugfix-review.md).
- Stake withdrawal between selection and commitment [E2](https://bugbountylibrary.com/r/sherlock%3A2025-06-symbiotic-relay%3AM-7.md).

## Impact and severity
Passing proposals and stealing assets [E3](https://bugbountylibrary.com/r/c4%3A2022-09-party%3AH-01.md), inflated governance weight [E4](https://bugbountylibrary.com/r/cantina%3Azerolend_jan2024%3A3.1.3.md)[E5](https://bugbountylibrary.com/r/c4%3A2023-08-verwa%3AH-02.md)[E6](https://bugbountylibrary.com/r/c4%3A2025-05-blackhole%3AM-17.md)[E7](https://bugbountylibrary.com/r/cantina%3Ainfinifi_april2025%3A3.1.1.md)[E8](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.1.md), and consensus control without slashing risk [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-polygon-consensus-bypass-bugfix-review.md)[E2](https://bugbountylibrary.com/r/sherlock%3A2025-06-symbiotic-relay%3AM-7.md). Severity rises when the flaw is reachable by any holder and repeatable within one block or epoch.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-polygon-consensus-bypass-bugfix-review.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2025-06-symbiotic-relay%3AM-7.md
- E3: https://bugbountylibrary.com/r/c4%3A2022-09-party%3AH-01.md
- E4: https://bugbountylibrary.com/r/cantina%3Azerolend_jan2024%3A3.1.3.md
- E5: https://bugbountylibrary.com/r/c4%3A2023-08-verwa%3AH-02.md
- E6: https://bugbountylibrary.com/r/c4%3A2025-05-blackhole%3AM-17.md
- E7: https://bugbountylibrary.com/r/cantina%3Ainfinifi_april2025%3A3.1.1.md
- E8: https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.1.md
