Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

hash - Killing a gague can lead to bricking of the protocol #192

Closed
sherlock-admin2 opened this issue Nov 29, 2023 · 10 comments
Closed

hash - Killing a gague can lead to bricking of the protocol #192

sherlock-admin2 opened this issue Nov 29, 2023 · 10 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Escalation Resolved This issue's escalations have been approved/rejected High A valid High severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed

Comments

@sherlock-admin2
Copy link
Contributor

sherlock-admin2 commented Nov 29, 2023

hash

high

Killing a gague can lead to bricking of the protocol

Summary

Slopes are not handled correctly when a gauge is killed. This can cause incorrect accounting for sum and total weights and lead to bricking the protocol in certain scenarios.

Vulnerability Detail

Points are accounted using bias,slope and slope end time. The bias is gradually decreased by its slope eventually reaching 0 at the slope end time / lock end time. In case the bias is suddenly reduced without handling/removing its slope, there will reach a time before the slope end time where the bias will drop below 0.
points_sum uses points to calculate the sum of individual gauge weights of a particular type at any time. The above case of bias dropping below 0 is handled as follows in _get_sum:

            d_bias: uint256 = pt.slope * WEEK
            if pt.bias > d_bias:
                pt.bias -= d_bias
                d_slope: uint256 = self.changes_sum[gauge_type][t]
                pt.slope -= d_slope
            else:
                pt.bias = 0
                pt.slope = 0

Whenever bias drops below 0 the slope is also made 0 without removing the slope end accounting in changes_sum. Afterwards, if a scenario occurs where the pt.bias regains a value greater than the pt.slope * WEEK, the true part of the if condition executes which can cause it to revert if at any point self.changes_sum[gauge_type][t] is greater than the current pt.slope.

The sudden drop in points_sum bias can happen due to the following:

  1. killing of a gauge
  2. admin calls change_gauge_weight with a lower value than current

From this moment the accounting of points_sum is broken and depending on the current slope, changes_sum, bias and activity following this, the points_sum.bias can go to 0 ( an attacker wanting to cause grief has the option to accelarate the dropping of bias to 0 by front-running a kill and increasing its slope )

Once bias goes to 0, it can regain a value greater than the pt.slope * WEEK due to the following:

  1. another gauge of the same type is added later with a weight
  2. a user votes for a gauge of the same type
  3. admin calling the change_gauge_weight increasing a gauge's weight

Scenario 2 is almost sure to happen following which all calls to _get_sum can revert which will cause the protocol to brick since even the cycle update involves a call to _get_sum

POC

Gauges A and B are of same type

At t = 0
a_bias = b_bias = 100 , a_slope = b_slope = 1 , slope_end : t = 100 
sum_bias = 200 , sum_slope = 2 , slope_end : t = 100

At t = 50 before kill
a_bias = b_bias = 50 , a_slope = b_slope = 1 
sum_bias = 100 , sum_slope = 2

at t = 50 kill A
a_bias = 0 , a_slope = 1
b_bias = 50 , b_slope = 1
sum_bias = 50 , sum_slope = 2

at t = 75
b_bias = 25 , b_slope = 1
sum_bias = 0 , sum_slope = 0 (pt.slope set to 0 when bias !> d.slope)

at t = 75
another user votes for B with bias = 100 and slope = 1
b_bias = 125 , b_slope = 2
sum_bias = 100 , sum_slope = 1

at t = 100
sum_slope -= 2 ( a_slope_end = b_slope_end : t = 100)

this will cause _get_sum to revert

Runnable foundry test gist link:
https://gist.github.com/10xhash/b65867b99841a88e078e34f094fc0554

Impact

Bricking of the protocol,locked user funds , incorrect sum and total weight values

Code Snippet

_change_gauge_weight sets weight directly without handling slope
https://github.com/sherlock-audit/2023-11-convergence/blob/main/sherlock-cvg/contracts/Locking/GaugeController.vy#L568-L582

kill_gauge calls _change_gauge_weight
https://github.com/sherlock-audit/2023-11-convergence/blob/main/sherlock-cvg/contracts/Locking/GaugeController.vy#L603C5-L609

Tool used

Manual Review

Recommendation

When killing the gauge, decrease its slope from the sum and iterate over all future weeks till the max limit and remove any gauge-associated-slope changes from the changes_sum. Handle the user removing a vote from a killed gauge seperately from the general vote function.

Duplicate of #94

@github-actions github-actions bot added High A valid High severity issue Has Duplicates A valid issue with 1+ other issues describing the same vulnerability labels Dec 2, 2023
@0xR3vert 0xR3vert added Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed labels Dec 15, 2023
@0xR3vert
Copy link

Hello,

Thanks a lot for your attention.

Thank you for your insightful observation. Upon thorough examination, we acknowledge that such an occurrence could indeed jeopardize the protocol. We are currently exploring multiple solutions to address this issue.
We are considering removing the function change_gauge_weight entirely and not distributing CVG inflation on killed gauges, similar to how Curve Protocol handles their gauges.

Therefore, in conclusion, we must consider your issue as valid.

Regards,
Convergence Team

@sherlock-admin2 sherlock-admin2 changed the title Proper Lemonade Sealion - Killing a gague can lead to bricking of the protocol hash - Killing a gague can lead to bricking of the protocol Dec 24, 2023
@sherlock-admin2 sherlock-admin2 added the Reward A payout will be made for this issue label Dec 24, 2023
@CergyK
Copy link

CergyK commented Dec 26, 2023

Escalate

Killing a gauge is an admin endpoint, and an exceptional measure.
An admin can be trusted to take preventive measures such as waiting that voting for a gauge is stopped and zero, before killing a gauge.

By sherlock rules this is of low severity

@sherlock-admin2
Copy link
Contributor Author

Escalate

Killing a gauge is an admin endpoint, and an exceptional measure.
An admin can be trusted to take preventive measures such as waiting that voting for a gauge is stopped and zero, before killing a gauge.

By sherlock rules this is of low severity

You've created a valid escalation!

To remove the escalation from consideration: Delete your comment.

You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.

@sherlock-admin sherlock-admin added the Escalated This issue contains a pending escalation label Dec 26, 2023
@10xhash
Copy link

10xhash commented Dec 26, 2023

The ability to kill a gauge is a feature that the protocol team intended to make use of as implemented. Such a use would have resulted in the entire protocol being bricked which includes almost all user's loosing their funds.

@nevillehuang
Copy link
Collaborator

See comments here

@Czar102
Copy link

Czar102 commented Jan 12, 2024

For a misbehaving admin function, we can always say that the admin was supposed to use it only for a set of edge cases for which it accidentally works fine.

I believe this is an issue within the admin function and I think it is a valid issue. The issue leads to an unintentional bricking of the protocol, so I think High is an adequate severity. Planning to reject the escalation.

@Czar102 Czar102 closed this as completed Jan 13, 2024
@Czar102
Copy link

Czar102 commented Jan 13, 2024

Result:
High
Duplicate of #94

@sherlock-admin2
Copy link
Contributor Author

sherlock-admin2 commented Jan 13, 2024

Escalations have been resolved successfully!

Escalation status:

@sherlock-admin sherlock-admin removed the Escalated This issue contains a pending escalation label Jan 13, 2024
@sherlock-admin2 sherlock-admin2 added the Escalation Resolved This issue's escalations have been approved/rejected label Jan 13, 2024
@sherlock-admin2 sherlock-admin2 added Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label and removed Has Duplicates A valid issue with 1+ other issues describing the same vulnerability labels Jan 14, 2024
@walk-on-me
Copy link

Hello, we fixed this issue on this PR.

You can see on these comments, description of the fix :

@IAm0x52
Copy link
Collaborator

IAm0x52 commented Jan 20, 2024

Fix looks good. Gauges have been modified to match CRV gauges and prevent this behavior

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Escalation Resolved This issue's escalations have been approved/rejected High A valid High severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

9 participants