The function _updateGaugeWeight() is responsible for adjusting the gauge weight when users change their vote. However, the calculation does not handle the delegation change properly, leading to incorrect weight updates and potential reward misallocations.
Problematic Code:
Incorrect Weight Removal
The function subtracts oldWeight * votingPower / WEIGHT_PRECISION, but only from the same gauge.
If the user is switching from Gauge A → Gauge B, their old weight in Gauge A should be removed first, but this function does not account for inter-gauge transfers.
This leads to inflated weights, where Gauge A still holds a part of the user's weight even after delegation to Gauge B.
Lack of Explicit Delegation Clearing
The function assumes that weight updates are always within the same gauge and does not properly zero out old gauge votes when switching to a new gauge.
Severity Classification (Based on Common Vulnerability Rating Methodology - CVSS)
| Criteria | Severity |
|---|---|
| Financial Impact | High - Direct reward inflation and emissions loss |
| Governance Manipulation | High - Attackers can skew governance outcomes |
| Protocol Stability Risk | Medium - Can cause long-term reward distribution issues |
| Exploit Complexity | Medium - Requires voting power but no special privileges |
| Likelihood of Exploitation | High - Straightforward delegation switching abuse |
Rewards Manipulation:
A malicious user can delegate to multiple gauges without correctly removing their old votes, leading to double staking influence.
Example Exploit Scenario:
User1 votes 50% on Gauge A.
User1 then votes 100% on Gauge B.
Gauge A still holds part of the old weight, but Gauge B now has full voting power.
Result: Rewards are calculated incorrectly leading to inflated emissions.
Manual Review
Ensure Proper Weight Transfer
Maintain Accurate Weight Calculations
The weight update should properly account for previous voting weights before applying the new weight.
Use safe math to prevent potential underflows or overflows.
Track Total Delegated Voting Power Correctly
Ensure that when moving votes from one gauge to another, the previous gauge loses weight correctly before the new one gains it.
Introduce an explicit function to remove previous weight first, preventing unintended accumulation.
Implement Atomic Update for Gauge Weight Transfer
The weight transfer must be fully processed within a single transaction to avoid edge cases where weight gets locked or miscalculated.
If the process fails, it should revert entirely to prevent inconsistent state changes.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.