sherlock-audit / 2023-09-Gitcoin-judging

11 stars 7 forks source link

Arz - Allocator voiceCreditsCastToRecipient is incremented by the totalCredits instead of the new credits #958

Closed sherlock-admin closed 11 months ago

sherlock-admin commented 11 months ago

Arz

high

Allocator voiceCreditsCastToRecipient is incremented by the totalCredits instead of the new credits

When an allocator allocates votes to the recipients, totalCredits is used to increment the allocator.voiceCreditsCastToRecipient[_recipientId] but the new credits should be used instead because the totalCredits is the sum of the old credits + the new credits.

Vulnerability Detail

In QVBaseStrategy.sol:: _qv_allocate(), the _allocator.voiceCreditsCastToRecipient is used to track the credits that the allocator has already casted but the problem is that it is incremented by totalCredits instead of the new credits.

totalCredits equals to _voiceCreditsToAllocate + creditsCastToRecipient but instead we only need to increment it by the _voiceCreditsToAllocate which are the new credits that are being allocated.

So if an allocator allocates 100 voiceCredits for the first time and then the second time 100 more, the _allocator.voiceCreditsCastToRecipient[_recipientId] will be 300 which is much bigger than its supposed to be and the 3rd time he allocates the votes the results will be completely different from what they are supposed to be

Impact

The results arent going to be correct and the _recipient.totalVotesReceived will be much bigger than its supposed to be which will lead to unfair distribution of funds.

Code Snippet

https://github.com/sherlock-audit/2023-09-Gitcoin/blob/6430c8004017e96ae2f5aac365bdefd0b6eeea72/allo-v2/contracts/strategies/qv-base/QVBaseStrategy.sol#L529

517: uint256 creditsCastToRecipient = _allocator.voiceCreditsCastToRecipient[_recipientId];
518: uint256 votesCastToRecipient = _allocator.votesCastToRecipient[_recipientId];
519: 
520: // get the total credits and calculate the vote result
521: uint256 totalCredits = _voiceCreditsToAllocate + creditsCastToRecipient;
522: uint256 voteResult = _sqrt(totalCredits * 1e18);
523: 
524: // update the values
525: voteResult -= votesCastToRecipient;
526: totalRecipientVotes += voteResult;
527: _recipient.totalVotesReceived += voteResult;
528: 
529: _allocator.voiceCreditsCastToRecipient[_recipientId] += totalCredits;
530: _allocator.votesCastToRecipient[_recipientId] += voteResult;

As you can see here the _allocator.voiceCreditsCastToRecipient[_recipientId] += totalCredits; which will add the old credits + the new credits.

Tool used

Manual Review

Recommendation

Increment by the _voiceCreditsToAllocate instead of the totalCredits

Duplicate of #48