Rewards aren't updated before user's balance change in Gauge's withdrawToken #50
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
sponsor disputed
Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue
Lines of code
https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L548-L561
Vulnerability details
_updateRewardForAllTokens is called in withdraw() only, while both withdraw() and withdrawToken() are public and can be called directly. Reward update is needed on user's balance change, its absence leads to reward data rewriting and rewards losing impact for a user.
Per discussion with project withdrawToken() will not be exposed in UI, so setting the severity to be medium as user's direct usage of the vulnerable function is required here, while the impact is losing of a part of accumulated rewards.
Proof of Concept
withdraw() is a wrapper for withdrawToken(), which changes user's balance. withdrawToken() can be called directly, and in this case there will be no rewards update:
https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L548-L561
This way if a user call withdrawToken(), the associated rewards can be lost due to incomplete reward balance accounting.
References
A showcase of reward update issue:
belbix/solidly#1
It's replicated live with users losing accumulated rewards:
https://github.com/solidlyexchange/solidly/issues/55
Recommended Mitigation Steps
Consider moving rewards update to withdrawToken(), since it is called by withdraw() anyway:
Or, if the intent is to keep withdrawToken() as is, consider making it private, so no direct usage be possible:
The text was updated successfully, but these errors were encountered: