Voting overwrites checkpoint.voted in last checkpoint, so users can just vote right before claiming rewards #206
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
sponsor acknowledged
Technically the issue is correct, but we're not going to resolve it for XYZ reasons
Lines of code
https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L195
https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L489-L490
https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L499-L500
Vulnerability details
Impact
this line in
gauge.earned
function looks like the intention here is to incentivize users to keep theirescrow.balanceOfNft
voted for this gauge.However, it's enough to vote just before claiming rewards (even in the same transaction) and
voter.reset
just after receiving rewards to pass thisif
and get rewards for full period since last interaction with the gauge.Proof of Concept
I'm pasting my test file:
Note, that Bob kept his votes for this gauge for full 6-day period but Alice just voted before claiming rewards. In logs, we can see that they both received the same (non-zero) amount of VELO tokens.
Alice can reset her votes in the same transaction after claiming rewards, if she decides to do so.
Tools Used
Foundry
Recommended Mitigation Steps
A partial solution would be to create a new checkpoint each time user's
voted
status changes (setVoteStatus
is called) instead of overwriting thevoted
in last one.However, even then, users can just assign very small weight to this gauge, and lock very little VELO, so I don't think this
if
statement helps with anything. I think, it's better to rethink how to incentivize users to vote for specific gauges.The text was updated successfully, but these errors were encountered: