Lowering the gauge weight can disrupt accounting, potentially leading to both excessive fund distribution and a loss of funds.
Similar issues were found by users 0xDetermination and bart1e in the Canto veRWA audit, which uses a similar gauge controller type.\\nWhen the _change_gauge_weight function is called, the `points_weight[addr][next_time].bias` andtime_weight[addr] are updated - the slope is not.\\n```\\ndef _change_gauge_weight(addr: address, weight: uint256):\\n    # Change gauge weight\\n    # Only needed when testing in reality\\n    gauge_type: int128 = self.gauge_types_[addr] - 1\\n    old_gauge_weight: uint256 = self._get_weight(addr)\\n    type_weight: uint256 = self._get_type_weight(gauge_type)\\n    old_sum: uint256 = self._get_sum(gauge_type)\\n    _total_weight: uint256 = self._get_total()\\n    next_time: uint256 = (block.timestamp + WEEK) / WEEK * WEEK\\n\\n    self.points_weight[addr][next_time].bias = weight\\n    self.time_weight[addr] = next_time\\n\\n    new_sum: uint256 = old_sum + weight - old_gauge_weight\\n    self.points_sum[gauge_type][next_time].bias = new_sum\\n    self.time_sum[gauge_type] = next_time\\n\\n    _total_weight = _total_weight + new_sum * type_weight - old_sum * type_weight\\n    self.points_total[next_time] = _total_weight\\n    self.time_total = next_time\\n\\n    log NewGaugeWeight(addr, block.timestamp, weight, _total_weight)\\n```\\n\\nThe equation f(t) = c - mx represents the gauge's decay equation before the weight is reduced. In this equation, `m` is the slope. After the weight is reduced by an amount `k` using the `change_gauge_weight` function, the equation becomes f(t) = c - `k` - mx The slope `m` remains unchanged, but the t-axis intercept changes from t1 = c/m to t2 = (c-k)/m.\\nSlope adjustments that should be applied to the global slope when decay reaches 0 are stored in the `changes_sum` hashmap. And is not affected by changes in gauge weight. Consequently, there's a time window t1 - t2 during which the earlier slope changes applied to the global state when user called `vote_for_gauge_weights` function remains applied even though they should have been subtracted. This in turn creates a situation in which the global weightis less than the sum of the individual gauge weights, resulting in an accounting error.\\nSo, in the `CvgRewards` contract when the `writeStakingRewards` function invokes the `_checkpoint`, which subsequently triggers the `gauge_relative_weight_writes` function for the relevant time period, the calculated relative weight becomes inflated, leading to an increase in the distributed rewards. If all available rewards are distributed before the entire array is processed, the remaining users will receive no rewards."\\nThe issue mainly arises when a gauge's weight has completely diminished to zero. This is certain to happen if a gauge with a non-zero bias, non-zero slope, and a t-intercept exceeding the current time is killed using `kill_gauge` function.\\nAdditionally, decreasing a gauge's weight introduces inaccuracies in its decay equation, as is evident in the t-intercept.
Disable weight reduction, or only allow reset to 0.
The way rewards are calculated is broken, leading to an uneven distribution of rewards, with some users receiving too much and others receiving nothing.
```\\ndef _change_gauge_weight(addr: address, weight: uint256):\\n    # Change gauge weight\\n    # Only needed when testing in reality\\n    gauge_type: int128 = self.gauge_types_[addr] - 1\\n    old_gauge_weight: uint256 = self._get_weight(addr)\\n    type_weight: uint256 = self._get_type_weight(gauge_type)\\n    old_sum: uint256 = self._get_sum(gauge_type)\\n    _total_weight: uint256 = self._get_total()\\n    next_time: uint256 = (block.timestamp + WEEK) / WEEK * WEEK\\n\\n    self.points_weight[addr][next_time].bias = weight\\n    self.time_weight[addr] = next_time\\n\\n    new_sum: uint256 = old_sum + weight - old_gauge_weight\\n    self.points_sum[gauge_type][next_time].bias = new_sum\\n    self.time_sum[gauge_type] = next_time\\n\\n    _total_weight = _total_weight + new_sum * type_weight - old_sum * type_weight\\n    self.points_total[next_time] = _total_weight\\n    self.time_total = next_time\\n\\n    log NewGaugeWeight(addr, block.timestamp, weight, _total_weight)\\n```\\n