Since there is no code to check whether fee has been drawn, withdrawFee() might be called multiple times.
This allows protocolFeeRecipient to steal all of the unclaimed reward tokens after quest ended.
Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
Tools Used
Sublime Text
Recommended Mitigation Steps
Add a code to confirm that the fee can be withdrawn only once as shown below.
bool public withdrawal = false;
function withdrawFee() public onlyAdminWithdrawAfterEnd {
require(withdrawal == false, "already took withdraw fee");
withdrawal = true;
IERC20(rewardToken).safeTransfer(protocolFeeRecipient, protocolFee());
}
Lines of code
https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Erc20Quest.sol#L102-L104
Vulnerability details
Impact
Since there is no code to check whether fee has been drawn,
withdrawFee()
might be called multiple times. This allows protocolFeeRecipient to steal all of the unclaimed reward tokens after quest ended.Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
Tools Used
Sublime Text
Recommended Mitigation Steps
Add a code to confirm that the fee can be withdrawn only once as shown below.