Platform: Code4rena
Start Date: 13/12/2022
Pot Size: $36,500 USDC
Total HM: 5
Participants: 77
Period: 3 days
Judge: gzeon
Total Solo HM: 1
Id: 191
League: ETH
Rank: 51/77
Findings: 1
Award: $25.95
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: c3phas
Also found by: 0x1f8b, Aymen0909, Bnke0x0, Bobface, IllIllI, PaludoX0, Rahoz, RaymondFam, ReyAdmirado, Rolezn, Sathish9098, adriro, chaduke, codeislight, ctrlc03, indijanc, izhelyazkov, kuldeep, nadin, neko_nyaa, nicobevi, rvierdiiev, shark
25.9485 USDC - $25.95
When call VRFNFTRandomDraw.startDraw it does check request.currentChainlinkRequestId then inside _requestRoll(), it check again.
https://github.com/code-423n4/2022-12-forgeries/blob/fc271cf20c05ce857d967728edfb368c58881d85/src/VRFNFTRandomDraw.sol#L175 https://github.com/code-423n4/2022-12-forgeries/blob/fc271cf20c05ce857d967728edfb368c58881d85/src/VRFNFTRandomDraw.sol#L144
Remove the check in _requestRoll
When initialize, it already check _settings.drawingTokenEndId > _settings.drawingTokenStartId, then when we calculate tokenRange in fulfillRandomWords, it can be added unchecked
When call VRFNFTRandomDraw.redraw, it will delete the request state, then call to _requestRoll which will update the drawTimelock and currentChainlinkRequestId. It will cost gas to update state from non-zero to zero, then assign them into non-zero again
We can set request.currentChosenTokenId and request.hasChosenRandomNumber to zero and false instead of delete the request state. Then when it call _requestRoll, the value request.currentChainlinkRequestId and request.drawTimelock will be update
Struct Settings can be packed to save gas
struct Settings { /// @notice Token ID to put up for raffle uint256 tokenId; /// @notice Start token ID for the drawing (if totalSupply = 20 but the first token is 5 (5-25), setting this to 5 would fix the ordering) uint256 drawingTokenStartId; /// @notice End token ID for the drawing (exclusive) (token ids 0 - 9 would be 10 in this field) uint256 drawingTokenEndId; /// @notice Draw buffer time – time until a re-drawing can occur if the selected user cannot or does not claim the NFT. uint256 drawBufferTime; /// @notice block.timestamp that the admin can recover the NFT (as a safety fallback) uint256 recoverTimelock; /// @notice Token that each (sequential) ID has a entry in the raffle. address drawingToken; /// @notice Token Contract to put up for raffle address token; /// @notice Chainlink gas keyhash bytes32 keyHash; /// @notice Chainlink subscription id uint64 subscriptionId; }
#0 - c4-judge
2022-12-17T17:49:25Z
gzeon-c4 marked the issue as grade-b