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: 69/173
Findings: 3
Award: $36.65
🌟 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
In the ERC20Quest Contract, the withdrawFee() function can be called after the quest is ended and if the contract has funds that are not claimed by the claimers, by that time this function can be called and claim all the remaining funds in the contract.
For example, suppose there are 101 tokens in the contract so 100 tokens are been allocated to claimers and 1 token to the protocolFeeRecipient and after the Quest Ends, they are 50 tokens unclaimed by claimers and 1 token for protocolFeeRecipient, and now the withdrawFee() function can be called a few times and all 51 tokens can be claimed by the protocolFeeRecipient.
Pen and paper
Have a check that the function should only be called once basically like having a variable like bool protocolFeeRecipientClaimedFees = false initially and once the withdrawFee() function is called after the quest then make it protocolFeeRecipientClaimedFees = true and basically if it called again revert it because the Fee is already claimed.
#0 - c4-judge
2023-02-06T08:43:40Z
kirk-baird marked the issue as duplicate of #23
#1 - c4-judge
2023-02-06T08:43:45Z
kirk-baird marked the issue as partial-50
#2 - kirk-baird
2023-02-06T08:43:54Z
Partial credit due to low quality of write-up
#3 - c4-judge
2023-02-14T08:56:27Z
kirk-baird marked the issue as satisfactory
🌟 Selected for report: carlitox477
Also found by: 0xRobocop, 0xbepresent, ArmedGoose, Atarpara, IllIllI, Tointer, UdarTeam, adriro, betweenETHlines, cryptojedi88, evan, glcanvas, gzeon, horsefacts, ladboy233, libratus, lukris02, luxartvinsec, manikantanynala97, minhquanym, mookimgo, p4st13r4, simon135, thekmj, trustindistrust
18.6976 USDC - $18.70
https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/Quest.sol#L96-L118 https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleReceipt.sol#L106-L135
If they are many tokens to be claimed by the claim() function this will actually exceed the block.gaslimit and the claimer cannot claim any token. This is because the claim function calls the getOwnedTokenIdsOfQuest() function which has two loops going on it, the claim() function checks in a loop whether the tokens are claimed and also it calls the _setClaimed() function which consists of a loop.
Suppose they are 50 tokens to be claimed by the claimer now the function will surely revert due to block.gaslimit and as mentioned above why will it happens.
Pen and Paper
It is always recommended to have a maximum claiming of rewards per transaction instead of claiming all the tokens at a time. For example, it is better to claim rewards for 10 tokens at a time if the claimer has 50 tokens so that the person can call the function 5 times and claim all the tokens.
#0 - c4-judge
2023-02-06T22:48:20Z
kirk-baird marked the issue as duplicate of #135
#1 - c4-judge
2023-02-14T09:17:08Z
kirk-baird changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-02-14T09:17:14Z
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
Precision Loss varies according to the token for the given Formula ie basically for USDC the decimal points are 6 and whereas for ETH it is 18
Check the nonClaimableTokens before transferring by calling the safe transfer function.
#0 - c4-judge
2023-02-06T22:33:08Z
kirk-baird marked the issue as grade-c
#1 - c4-judge
2023-02-16T06:26:15Z
kirk-baird marked the issue as grade-b
#2 - kirk-baird
2023-02-16T06:27:15Z
Upgrading to grade-b due to #543
This issue barely scrapes a grade-b. It can be improved with more issues, code snippets with more detail in the description of findings.