Infinity NFT Marketplace contest - fatherOfBlocks's results

The world's most advanced NFT marketplace.

General Information

Platform: Code4rena

Start Date: 14/06/2022

Pot Size: $50,000 USDC

Total HM: 19

Participants: 99

Period: 5 days

Judge: HardlyDifficult

Total Solo HM: 4

Id: 136

League: ETH

Infinity NFT Marketplace

Findings Distribution

Researcher Performance

Rank: 64/99

Findings: 2

Award: $80.20

🌟 Selected for report: 0

🚀 Solo Findings: 0

InfinityToken.sol

  • L47 - In the constructor it is not validated that the timeLockConfig are != 0, this is important since for example getEpochDuration() is used to divide on line 65 and depends on the setting of EPOCH_DURATION in the constructor.

InfinityOrderBookComplication.sol

  • L38/169 - To define the _isTimeValid variable directly, you could call the isTimeValid(OrderTypes.MakerOrder calldata sell, OrderTypes.MakerOrder calldata buy) function on line 169. Another function could be created or modified, so that it only receives a single MakerOrder as an input parameter, this could make it useful, since it could be used in: L91/92/102/103/160/161, while still being usable by lines that already use isTimeValid().

  • L192/205 - The cost of performing a require with an and(&&) is equivalent to performing two requires, therefore it is less expensive to validate in the first line: if(buy.constraints[0] > sell.constraints[0] ) return false; This way it would save executing the for and creating the variables. Then on the last line, just do: return numConstructedItems >= buy.constraints[0];

InfinityStaker.sol

  • L49 - In the constructor it is not validated that INFINITY_TOKEN complies with the IERC20 interface, if it does not comply with the interface, a DoS will be generated in rageQuit() and unstake().

  • L193 - The validation require(totalStaked >= 0) will never return false, since totalStaked is uint256, therefore the validation will always return true.

InfinityExchange.sol

  • L115 - In the constructor it is not validated that WETH complies with the IERC20 interface, if it does not comply with the interface, a DoS will be generated in matchOneToManyOrders(), _execMatchOneToOneOrders(), _execMatchOneMakerSellToManyMakerBuys() and _execMatchOrders().

  • L774-786/818-830 - There is repeated code that could be unified in an internal function.

TimelockConfig.sol

  • L38/51/52/94/112/119/127 - If instead of using a require you use a custom error and an if, you would save gas. Otherwise, another way could be to create a private view function, instead of a modifier.

InfinityToken.sol

  • L61/62/63 - If instead of using a require you use a custom error and an if, you would save gas. Otherwise, another way could be creating a private view function, instead of a modifier.

  • L66 - The operation getMaxEpochs() - currentEpoch, can be unckecked, since in line 61 it is validated that it does not generate underflow.

InfinityOrderBookComplication.sol

  • L42/76/82/108/197/199/214/216/244/246/247/289/290/291/318/320 - no need to set a variable to the default value.

  • L105/106/110/112 - it is not necessary to create a variable to use them inside the if and the else, since only one of the two will be executed. Therefore, gas would be saved if it is called directly on lines 110 and 112.

  • L339 - The elapsedTime > duration operation? PRECISION : ((elapsedTime * PRECISION) / duration), can be unckecked, since duration != 0 by validation in L334, PRECISION is a positive constant and elapsedTime is >= 0.

  • L255 - If instead of using a require you use a custom error and an if, gas would be saved. Otherwise, another way could be creating a private view function, instead of a modifier.

InfinityStaker.sol

  • L68/69/91/92/96/117/123/193/347 - If instead of using a require a custom error and an if are used, gas would be saved. Otherwise, another way could be creating a private view function, instead of a modifier.

  • L94/96 - strings with more than 32 bytes generate a biggest gas cost that string with less than 32 bytes.

  • L234 - Operation userstakedAmounts[user][Duration.NONE].amount is not necessary * 1 is equivalent to userstakedAmounts[user][Duration.NONE].amount.

  • L261/267/268/270 - It is not necessary to create a variable if it is only going to be used once.

InfinityExchange.sol

  • L138/139/150/155/183/184/185/190/263/264/279/306/310/313/314/315/326/342/347/350/351/380/381/ 392/394/395/587/621/649/684/949/1141/1231 - If instead of using a require you use a custom error and an if, you would save gas. Otherwise, another way could be creating a private view function, instead of a modifier.

  • L148/200/219/272/308/349/393/1048/1086/1109/1190/1206 - no need to set a variable to the default value.

  • L392 - Validation numNonces > 0 generates more gas costs than numNonces != 0;

  • L520-529 - Instead of doing an if(bool){return false;}else {return true;}, directly do return (bool;)

  • L1136 - The operation amount - protocolFee; could be unchecked, since protocolFee < amount.

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