sherlock-audit / 2023-09-Gitcoin-judging

11 stars 7 forks source link

Arz - The voiceCredits of the allocator are not updated when he allocates his voice credits #944

Closed sherlock-admin closed 11 months ago

sherlock-admin commented 11 months ago

Arz

medium

The voiceCredits of the allocator are not updated when he allocates his voice credits

When an allocater allocates his voice credits in QVBaseStrategy the voice credits cannot exceed the available voice credits for the allocator. However when _qv_allocate() is called the voiceCredits for the allocator are not updated so he will always have unlimited voiceCredits to allocate to the recipients.

Vulnerability Detail

Each allocator should have a limited amount of votes to cast to the recipients. However allocator.voiceCredits which is supposed to be used to track the allocator voiceCredits isnt updated so the allocator can exceed the max limit and because it isnt updated he will have unlimited voice credits.

Impact

The allocator can use more than allowed voice credits which will lead to unfair voting because anyone can just allocate as much as they want to and the funds will then be distributed in an unfair way.

Code Snippet

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


File: strategies/qv-base/QVBaseStrategy.sol

506: function _qv_allocate(
507:     Allocator storage _allocator,
508:     Recipient storage _recipient,
509:     address _recipientId,
510:     uint256 _voiceCreditsToAllocate,
511:     address _sender
512: ) internal onlyActiveAllocation {
513:     // check the `_voiceCreditsToAllocate` is > 0
514:     if (_voiceCreditsToAllocate == 0) revert INVALID();
515: 
516:     // get the previous values
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;
531: 
532:     // emit the event with the vote results
533:     emit Allocated(_recipientId, voteResult, _sender);
534: }

As you can see in _qv_allocate() the _allocator.voiceCredits are not updated.

Tool used

Manual Review

Recommendation

Update the voiceCredits in _qv_allocate()

_allocator.voiceCredits += _voiceCreditsToAllocate;

Duplicate of #150