You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Mar 24, 2024. It is now read-only.
sherlock-admin opened this issue
Sep 22, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
[H-02] Tracking of voiceCredits in QVSimpleStrategy is not done which can be used to allocate votes indefinitely.
Tracking of voiceCredits in QVSimpleStrategy with QVBaseStrategy::_qv_allocate() is not done which can be used to allocate votes indefinitely when using QVBaseStrategy.
Vulnerability Detail
When we are using QVSimpleStrategy which calls QVBaseStrategy::_qv_allocate() , there are some checks in QVSimpleStrategy::_allocate() which is only effective when voiceCredits are properly tracked and subtracted when they are used up by QVBaseStrategy::_qv_allocate(). Which is not done.
As it stands now, allocator can call allocate as much as they want and allocate votes as long as the voiceCreditsToAllocate is =< maxVoiceCreditsPerAllocator.
Impact
A allocator can knowingly or unknowingly call allocate when using QVBaseStrategy as strategy to allocate votes to a recipient indefinitely. Thus enabling the recipient to get very large majority in terms of votes, thus breaking the strategy.
Here is a coded PoC depicting that allocate can be called multiple times as long as each call has voiceCreditsToAllocate =< maxVoiceCreditsPerAllocator.
This can be pasted into test/foundry/strategies/QVSimpleStrategy.t.sol. Here maxVoiceCreditsPerAllocator is defined with a value of 100.
//File::test/foundry/strategies/QVSimpleStrategy.t.solfunctiontest_allocate_VoiceTokensNotTracked()public{//@audit POC for QVSimpleStrategy-issue-1addressrecipientId=__register_accept_recipient();vm.warp(allocationStartTime+10);addressallocator=randomAddress();vm.startPrank(pool_manager1());qvSimpleStrategy().addAllocator(allocator);bytesmemoryallocateData=__generateAllocation(recipientId,100);// vm.expectRevert(INVALID.selector);vm.startPrank(address(allo()));qvSimpleStrategy().allocate(allocateData,allocator);uint256votesBefore=qvSimpleStrategy().getRecipientVotes(recipientId);//do it againqvSimpleStrategy().allocate(allocateData,allocator);//can be as many as times as neededuint256votesAfter=qvSimpleStrategy().getRecipientVotes(recipientId);//We can see that the votes of the recipient has increased.assertTrue(votesAfter>votesBefore);}
I have used a small helper function getRecipientVotes() to get the totalVotesReceived of a recipient.
function_qv_allocate(Allocatorstorage_allocator,Recipientstorage_recipient,address_recipientId,uint256_voiceCreditsToAllocate,address_sender)internalonlyActiveAllocation{// check the `_voiceCreditsToAllocate` is > 0if(_voiceCreditsToAllocate==0)revertINVALID();// get the previous valuesuint256creditsCastToRecipient=_allocator.voiceCreditsCastToRecipient[_recipientId];uint256votesCastToRecipient=_allocator.votesCastToRecipient[_recipientId];// get the total credits and calculate the vote resultuint256totalCredits=_voiceCreditsToAllocate+creditsCastToRecipient;uint256voteResult=_sqrt(totalCredits*1e18);// update the valuesvoteResult-=votesCastToRecipient;totalRecipientVotes+=voteResult;_recipient.totalVotesReceived+=voteResult;_allocator.voiceCreditsCastToRecipient[_recipientId]+=totalCredits;_allocator.votesCastToRecipient[_recipientId]+=voteResult;// emit the event with the vote resultsemitAllocated(_recipientId,voteResult,_sender);}
Tool used
Manual Review
Recommendation
Subtract the votes used from _allocator.voiceCredits to effectively track voiceCredits and then the checks in QVSimpleStrategy::_allocate will be effective.
github-actionsbot
added
Excluded
Excluded by the judge without consulting the protocol or the senior
Medium
A valid Medium severity issue
Duplicate
A valid issue that is a duplicate of an issue with `Has Duplicates` label
and removed
Excluded
Excluded by the judge without consulting the protocol or the senior
labels
Oct 1, 2023
sherlock-admin2
changed the title
Electric Tiger Bull - [H-02] Tracking of voiceCredits in QVSimpleStrategy is not done which can be used to allocate votes indefinitely.
Kral01 - [H-02] Tracking of voiceCredits in QVSimpleStrategy is not done which can be used to allocate votes indefinitely.
Oct 14, 2023
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
Kral01
high
[H-02] Tracking of
voiceCredits
inQVSimpleStrategy
is not done which can be used to allocate votes indefinitely.Tracking of
voiceCredits
inQVSimpleStrategy
withQVBaseStrategy::_qv_allocate()
is not done which can be used to allocate votes indefinitely when usingQVBaseStrategy
.Vulnerability Detail
When we are using
QVSimpleStrategy
which calls QVBaseStrategy::_qv_allocate() , there are some checks in QVSimpleStrategy::_allocate() which is only effective whenvoiceCredits
are properly tracked and subtracted when they are used up byQVBaseStrategy::_qv_allocate()
. Which is not done.As it stands now, allocator can call
allocate
as much as they want and allocate votes as long as thevoiceCreditsToAllocate
is =<maxVoiceCreditsPerAllocator
.Impact
A allocator can knowingly or unknowingly call
allocate
when usingQVBaseStrategy
as strategy to allocate votes to a recipient indefinitely. Thus enabling the recipient to get very large majority in terms of votes, thus breaking the strategy.Here is a coded PoC depicting that allocate can be called multiple times as long as each call has
voiceCreditsToAllocate
=<maxVoiceCreditsPerAllocator
.This can be pasted into test/foundry/strategies/QVSimpleStrategy.t.sol. Here
maxVoiceCreditsPerAllocator
is defined with a value of 100.I have used a small helper function
getRecipientVotes()
to get thetotalVotesReceived
of a recipient.Code Snippet
The voice credits of allocator is not decremented by the votes used in QVBaseStrategy::_qv_allocate().
Tool used
Manual Review
Recommendation
Subtract the votes used from
_allocator.voiceCredits
to effectively trackvoiceCredits
and then the checks inQVSimpleStrategy::_allocate
will be effective.Duplicate of #150
The text was updated successfully, but these errors were encountered: