Quest owner will receive less funds when withdrawing remaining tokens from the Erc20Quest
if protocol fees are withdraw first
#603
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
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-122
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Erc20Quest.sol#L85
Vulnerability details
After a
Erc20Quest
has ended, the owner of the quest can withdraw the remaining tokens from the contract by calling thewithdrawRemainingTokens
function:https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Erc20Quest.sol#L81-L87
The calculation is done by fetching the current token balance of the contract and subtracting the protocol fees and the tokens corresponding to unclaimed receipts.
The contract also implements a separate function to withdraw protocol fees called
withdrawFee
:https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Erc20Quest.sol#L102-L104
If the
withdrawFee
function is called before callingwithdrawRemainingTokens
, then protocol fees will be accounted twice in the calculation. WhenwithdrawFee
is called it will transfer the funds to the protocol fee recipient, which means the balance of the contract will be reduced by that amount. But thenwithdrawRemainingTokens
will use that balance and will also subtract again the protocol fee.Impact
If the quest has protocol fees (i.e.
protocolFee() > 0
) and if thewithdrawFee
function is called before the owner callswithdrawRemainingTokens
(assuming not all participants completed the quest), then the owner will receive less tokens than expected.As discussed in the previous section, the implementation subtracts the protocol fee from the current token balance of the contract. If the fees have already been withdrawn, the token balance already reflects this, and subtracting the fees will result in the owner receiving fewer tokens than expected by the amount of
protocolFee()
.Note that there's also the possibility of an arithmetic overflow. If the actual remaining tokens are less than the protocol fee, then the subtraction will cause an overflow due to the unsigned integer arithmetic.
PoC
In the following test, protocol fees are withdrawn before the owner calls
withdrawRemainingTokens
. The owner of the quest receives less than the expected amount of tokens.Recommendation
Add a flag to indicate if the protocol fees were already withdrawn and use this to check if the fees amount needs to be subtracted in the calculation for the
withdrawRemainingTokens
function.The text was updated successfully, but these errors were encountered: