Platform: Code4rena
Start Date: 06/03/2023
Pot Size: $36,500 USDC
Total HM: 8
Participants: 93
Period: 3 days
Judge: cccz
Total Solo HM: 3
Id: 218
League: ETH
Rank: 68/93
Findings: 1
Award: $21.70
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0x1f8b, 0xAgro, 0xSmartContract, 0xfuje, 0xkazim, 0xnev, Aymen0909, Bason, Cyfrin, DadeKuma, LethL, Madalad, MohammedRizwan, Rolezn, SAAJ, SunSec, Udsen, Yukti_Chinta, ast3ros, bin2chen, brgltd, bshramin, btk, bugradar, catellatech, cryptostellar5, descharre, dontonka, erictee, fatherOfBlocks, georgits, glcanvas, hl_, horsefacts, igingu, juancito, lukris02, martin, nadin, nomoi, peanuts, pipoca, sakshamguruji, seeu, slvDev, tnevler, zaskoh
21.7018 USDC - $21.70
ILotterySetup.sol - 6
IReferralSystem.sol - 5
IRNSourceController.sol - 5
LotteryToken.sol - 7
Lottery.sol - 6
VRFv2RNSource.sol, IVRFv2RNSource.sol, StakedTokenLock.sol
_safeMint
 over _mint
(but add a nonReentrant
 modifier, since calls to _safeMint
 can reenter)Ticket.sol - 26
RNSourceBase.sol - 11
StakedTokenLock.sol - 16
In RNSourceBase.sol(line 32) it is specified that fulfill()
must be called in the deriving contract's requestRandomnessFromUnderlyingSource
function but then in VRFv2RNSource(that inherits from RNSourceBase
) there is no call to fulfill()
in requestRandomnessFromUnderlyingSource()
. It is actually used in fulfillRandomWords()
.
if else
patternLotterySetup.sol - fixedReward()
if (winTier == selectionSize) { return _baseJackpot(initialPot); } else if (winTier == 0 || winTier > selectionSize) { return 0; } else { uint256 mask = uint256(type(uint16).max) << (winTier * 16); uint256 extracted = (nonJackpotFixedRewards & mask) >> (winTier * 16); return extracted * (10 ** (IERC20Metadata(address(rewardToken)).decimals() - 1)); }
Refactored version:
if (winTier == selectionSize) { return _baseJackpot(initialPot); } if (winTier == 0 || winTier > selectionSize) { return 0; } uint256 mask = uint256(type(uint16).max) << (winTier * 16); uint256 extracted = (nonJackpotFixedRewards & mask) >> (winTier * 16); return extracted * (10 ** (IERC20Metadata(address(rewardToken)).decimals() - 1));
requireFinishedDraw()
must be called inside claimWinningTicket()
to prevent users from claiming winning tickets before the draw is finalised.
#0 - thereksfour
2023-03-12T13:04:08Z
1 L 2 INFO
#1 - c4-judge
2023-03-12T13:04:11Z
thereksfour marked the issue as grade-b
#2 - c4-sponsor
2023-03-14T11:49:46Z
0xluckydev marked the issue as sponsor confirmed
#3 - 0xluckydev
2023-03-14T11:49:57Z
Low importance. _safeMint
not valid