Platform: Code4rena
Start Date: 25/01/2023
Pot Size: $36,500 USDC
Total HM: 11
Participants: 173
Period: 5 days
Judge: kirk-baird
Total Solo HM: 1
Id: 208
League: ETH
Rank: 98/173
Findings: 2
Award: $17.95
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0xRobocop, 0xmrhoodie, 0xngndev, AkshaySrivastav, ArmedGoose, Atarpara, Bauer, CodingNameKiki, ElKu, Garrett, HollaDieWaldfee, IllIllI, Iurii3, KIntern_NA, KmanOfficial, Lotus, M4TZ1P, MiniGlome, Ruhum, SovaSlava, bin2chen, bytes032, carrotsmuggler, cccz, chaduke, codeislight, cryptonue, doublesharp, evan, fs0c, glcanvas, gzeon, hansfriese, hihen, hl_, holme, horsefacts, ladboy233, lukris02, mahdikarimi, manikantanynala97, martin, mert_eren, mrpathfindr, omis, peakbolt, peanuts, prestoncodes, rbserver, rvierdiiev, sashik_eth, timongty, tnevler, trustindistrust, usmannk, wait, yixxas, zadaru13, zaskoh
0.7512 USDC - $0.75
https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Quest.sol#L76 https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Erc20Quest.sol#L102
onlyAdminWithdrawAfterEnd
modifier doesn't check if msg.sender
is the owner, but the name ensures that it is checked. It results in every user is able to execute withdrawFee
fucntion in Erc20Quest
until the Quest has ended. Therefore performing unauthorized actions is high severity issue.
modifier onlyAdminWithdrawAfterEnd() {
function withdrawFee() public onlyAdminWithdrawAfterEnd { IERC20(rewardToken).safeTransfer(protocolFeeRecipient, protocolFee()); }
Manual audit
Perform onlyOwner check in the onlyAdminWithdrawAfterEnd
.
#0 - c4-judge
2023-02-05T05:59:01Z
kirk-baird marked the issue as duplicate of #23
#1 - c4-judge
2023-02-14T08:59:21Z
kirk-baird marked the issue as satisfactory
🌟 Selected for report: CodingNameKiki
Also found by: 0x1f8b, 0x4non, 0x5rings, 0xAgro, 0xMirce, 0xRobocop, 0xSmartContract, 0xackermann, AkshaySrivastav, ArmedGoose, Aymen0909, BClabs, Breeje, Dewaxindo, Diana, HollaDieWaldfee, IceBear, IllIllI, Iurii3, Josiah, Krayt, PaludoX0, Phenomana, PrasadLak, RaymondFam, Rolezn, SaeedAlipoor01988, SaharDevep, SleepingBugs, adriro, arialblack14, bin2chen, brevis, btk, carlitox477, carrotsmuggler, catellatech, chaduke, chrisdior4, cryptonue, cryptostellar5, csanuragjain, ddimitrov22, fellows, glcanvas, halden, hl_, horsefacts, jat, joestakey, kenta, libratus, lukris02, luxartvinsec, manikantanynala97, martin, matrix_0wl, nadin, nicobevi, oberon, peanuts, prestoncodes, rbserver, sakshamguruji, sashik_eth, sayan, seeu, thekmj, tnevler, trustindistrust, tsvetanovv, xAriextz, zadaru13, zaskoh
17.196 USDC - $17.20
onlyQuestActive
modifier is missing crucial checksonlyQuestActive
modifier doesn't check if contract is had been paused or had ended. It these cases Quest is certainly not active but the logic in the function with such modifiers get executed. This check is however added in claim
function but is absolutely not in place and could easily be forgotten, so this is at least Low severity.
File: /contracts/Quest.sol 88: modifier onlyQuestActive() {
emit
function called earlyFile: /contracts/QuestFactory.sol 87: emit QuestCreated( 118: emit QuestCreated( 227: emit ReceiptMinted(msg.sender, questId_);
File: /contracts/RabbitHoleReceipt.sol 98: function mint(address to_, string memory questId_) public onlyMinter {
_safeMint()
should be used rather than _mint()
wherever possiblesafeMint
does an unsafe external call to the recipient, so there is a reentrency attack vector. Make sure to add 'nonReentrant' modifier.
File: /contracts/QuestFactory.sol 228: rabbitholeReceiptContract.mint(msg.sender, questId_);
File: /contracts/RabbitHoleTickets.sol 84: _mint(to_, id_, amount_, data_);
startTime_
and endTime_
should at least be compared
File: /contracts/QuestFactory.sol 61: function createQuest(
From logical perspective it's always a bad idea. Every variable should have single purpose because otherwise it can easily lead to wrong input data. This combined with zero validation checks for this specific param is vector for Erc20Quest
with wrong data.
File: /contracts/QuestFactory.sol 66: uint256 rewardAmountOrTokenId_,
pragma
should be usedFile: /contracts/QuestFactory.sol File: /contracts/RabbitHoleReceipt.sol File: /contracts/interfaces/IQuest.sol File: /contracts/interfaces/IQuestFactory.sol File: /contracts/Quest.sol File: /contracts/RabbitHoleTickets.sol File: /contracts/TicketRenderer.sol File: /contracts/ReceiptRenderer.sol File: /contracts/Erc20Quest.sol File: /contracts/Erc1155Quest.sol
It is recommended to stricly follow solidity best code-style practices.
File: /contracts/QuestFactory.sol File: /contracts/RabbitHoleReceipt.sol File: /contracts/Quest.sol File: /contracts/Erc20Quest.sol File: /contracts/Erc1155Quest.sol
File: /contracts/QuestFactory.sol 176: /// @dev set or remave a contract address to be used as a reward
File: /contracts/interfaces/IQuest.sol
File: /contracts/Quest.sol 7: import {ECDSA} from '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';
#0 - c4-judge
2023-02-05T05:51:57Z
kirk-baird marked the issue as grade-b
#1 - c4-sponsor
2023-02-08T01:43:23Z
jonathandiep marked the issue as sponsor confirmed