Forgeries contest - izhelyazkov's results

A protocol for on-chain games with NFT prizes on Ethereum.

General Information

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

Forgeries

Findings Distribution

Researcher Performance

Rank: 55/77

Findings: 1

Award: $25.95

Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

25.9485 USDC - $25.95

Labels

bug
G (Gas Optimization)
grade-b
edited-by-warden
G-18

External Links

Gas optimizations:

  • Replace immutable variables with constant in VRFNFTRandomDraw.sol - the variables don't get instantiated in the constructor, thus have no need to be immutable. Constant variables are cheaper.
  • Settings struct in interfaces/IVRFNFTRandomDraw.sol can be re-ordered to pack the token and subscriptionId variable into a single slot, because token is an address type - 160 bits, and subscriptionId is of uint64 type - 64 bits, their total is 224 bits, which is less than the EVM word size of 256 bits. So, packing them together will save a potential cold read / write.
  • CurrentRequest struct in interfaces/IVRFNFTRandomDraw.sol can be changed to pack hasChosenRandomNumber and drawTimelock in a single slot, again potentially saving additional reads/writes gas cost. This can be done by reducing the number of bits drawTimelock takes - since the drawTimelock represents a timestamp, it can be safely represented in a uint64 type (which accounts for a max timestamp in the next 550 years) or a uint72 type (which can account for max time of the next 150k years). Additionally, currentChosenTokenId in the same struct can be reduced to uint176 type or even less, accounting for the maximum token ids which can be chosen in a given collection (usually less than 10 000 NFTs are in most collections). With smart packing of the variables relative to their maximum values, it may be possible to pack all of the variables into the struct in a single slot.
  • No need to cache msg.sender in makeNewDraw function in VRFNFTRandomDrawFactory.sol or winnerClaimNFT function in VRFNFTRandomDraw.sol - will be more expensive than using msg.sender directly - using msg.sender costs 2 gas, while caching it in a variable costs 3 gas to push in on the stack.
  • transfer / safeTransfer can be used in lastResortTimelockOwnerClaimNFT and winnerClaimNFT function in VRFNFTRandomDraw.sol instead of transferFrom to save on gas.

#0 - c4-judge

2022-12-17T17:40:16Z

gzeon-c4 marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter