Users can get too many rewards in ProfitManager due to incorrect calculation of userGaugeProfitIndex #263
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-1194
satisfactory
satisfies C4 submission criteria; eligible for awards
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/volt-protocol/ethereum-credit-guild/blob/4d33abf95fee69391af0652e3cbe5e0cffa25f9f/src/governance/ProfitManager.sol#L416-L427
Vulnerability details
Description
If user weight sets on gauges then they can get a part of the profit if the gauge makes profit. The profits are distributed via the ProfitManager with
notifyPnL
. Each gauge has a profit index that is stored in the mappinggaugeProfitIndex
and increased in the event of a profit. Each user also has a Profit Index. Whenever a user collects his profit, the profit index is set to that of the gauge. Both profit indexes begin at 0. The problem is that when a user sets weight to a gauge for the first time, his profit index remains at 0. This leads to a problem if the gauge the user is settting weight on has already made a profit and therefore the profit index of the gauge is already higher. Since the amount of profit a user gets is determined with_gaugeProfitIndex - _userGaugeProfitIndex
, the user would get more profit than he should actually get:File: src/governance/ProfitManager.sol
In this way, all profits that existed before the user even put weight on the gauge are calculated for the user.
Impact
User gets part of the profits that were already distributed before he put weight on the gauge. Since these rewards have normally already been distributed to all users who should correctly receive the profits, the new user accidentally gets a part of the surplus buffer without the ProfitManager accounting for it. So it may be that some losses can no longer be modified because there is no longer enough surplus buffer.
Proof of Concept
Here is a POC:
This test can be added to the file
test/unit/governance/ProfitManager.t.sol
and started with this command:forge test --match-test testPOC1
Tools Used
VSCode, Foundry
Recommended Mitigation Steps
When a user sets weight to a gauge for the first time, their profit index should be set to that of the gauge so as not to mistakenly get any of the previous profits.
File: src/governance/ProfitManager.sol
function claimGaugeRewards( address user, address gauge ) public returns (uint256 creditEarned) { uint256 _userGaugeWeight = uint256( GuildToken(guild).getUserGaugeWeight(user, gauge) ); if (_userGaugeWeight == 0) { + userGaugeProfitIndex[user][gauge] = gaugeProfitIndex[gauge]; return 0; }
Assessed type
Other
The text was updated successfully, but these errors were encountered: