Lucene search

K
code423n4Code4renaCODE423N4:2023-01-RABBITHOLE-FINDINGS-ISSUES-665
HistoryJan 30, 2023 - 12:00 a.m.

withdrawFee() can be called indefinitely

2023-01-3000:00:00
Code4rena
github.com
6
vulnerability
fund draining
denial of rewards
protocolfeerecipient

Lines of code
<https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Quest.sol#L76-L79&gt;

Vulnerability details

The function withdrawFee() does not account whether the fees have already been collected or not, therefore it can be called multiple times or even indefinitely, until the contract balance reaches zero. All funds will be transferred to the protocolFeeRecipient, but the participating users will not be able to get their reward.
On a side note: the function use the onlyAdminWithdrawAfterEnd(), which only checks whether the endTime has been reached and there is no check on which user do the call, not sure if this is done by design. Anyway this mean that any user can call withdrawFee().

Impact

Contract can be drained (although the funds will go to protocolFeeRecipient), possibly denying the rewards or breaking the contract accounting.

Proof of Concept

In Erc20Quest.spec, copy and paste line 365 multiple times, for example:

await ethers.provider.send('evm_increaseTime', [100001])
await deployedQuestContract.withdrawFee()
await deployedQuestContract.withdrawFee() 
await deployedQuestContract.withdrawFee() 

You can see the call with go through and the contract balance will be less than expected

Tools Used

Manual check

Recommended Mitigation Steps

Make withdrawFee() callable only once


The text was updated successfully, but these errors were encountered:

All reactions