# Typevotes update error causes vote counts to be off forever

changeGaugeWeight assigns the new vote sum to typeWeights instead of typeVotes, permanently corrupting vote accounting and inflating the coefficient.

- Payout: Contest reward
- Severity: high
- Program: Opal
- Credited: innertia
- Disclosed: 2024-03-30
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_opal_feb2024.pdf#3.2.21
- Library page: https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.21
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:governance

**Target:** GaugeController.sol changeGaugeWeight vote accounting
**Root cause:** In changeGaugeWeight, `typeWeights[gaugeType][nextTimestamp] = newSum` is assigned instead of `typeVotes[gaugeType][nextTimestamp] = newSum`, so the coefficient is overwritten with a vote sum while typeVotes never updates.
**Steps:**
1. Deploy/initialize GaugeController (one default type, typeWeights=1).
2. As opalTeam call `addGauge(gauge, 0, 1e18)`; gaugeVotes and typeVotes both = 1e18, typeWeights = 1.
3. Call `changeGaugeWeight(gauge, 2e18)`.
4. Observe gaugeVotes = 2e18 but typeVotes still 1e18, and typeWeights now = 2e18 instead of 1.
**How found:** Code reading of changeGaugeWeight: noticed the assignment targets typeWeights, a coefficient multiplied by votes, rather than typeVotes; confirmed with a Foundry PoC asserting the mismatch.
**Insight:** When a function updates an aggregate, verify the assignment target matches the variable whose invariant (sum of per-gauge votes) must hold; a coefficient and an accumulator with similar names is a classic swap bug.
