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
Rank: 59/99
Findings: 2
Award: $80.28
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: joestakey
Also found by: 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 0xf15ers, 0xkowloon, 0xmint, 8olidity, BowTiedWardens, Chom, Cityscape, Czar102, ElKu, FSchmoede, Funen, GimelSec, GreyArt, IllIllI, KIntern, Kaiziron, Kenshin, Lambda, MadWookie, MiloTruck, PPrieditis, Picodes, Ruhum, Sm4rty, StErMi, TerrierLover, TomJ, Treasure-Seeker, VAD37, WatchPug, Wayne, _Adam, a12jmx, abhinavmir, antonttc, apostle0x01, asutorufos, berndartmueller, cccz, cloudjunky, codexploder, cryptphi, csanuragjain, defsec, delfin454000, fatherOfBlocks, georgypetrov, hake, hansfriese, horsefacts, hyh, k, kenta, nxrblsrpr, oyc_109, peritoflores, rajatbeladiya, reassor, rfa, robee, sach1r0, saian, samruna, shenwilly, simon135, sorrynotsorry, sseefried, throttle, unforgiven, wagmi, zzzitron
48.9862 USDC - $48.99
Information : Too many digits
InfinityExchange.cancelAllOrders(uint256) (contracts/core/InfinityExchange.sol#379-384) uses literals with too many digits: - require(bool,string)(minNonce < userMinOrderNonce[msg.sender] + 1000000,too many) (contracts/core/InfinityExchange.sol#381)
Use the scientific notation
Information : Variable names too similar
Variable InfinityExchange.MATCH_EXECUTOR (contracts/core/InfinityExchange.sol#59) is too similar to InfinityExchange.updateMatchExecutor(address)._matchExecutor (contracts/core/InfinityExchange.sol#1255) Variable InfinityExchange.MATCH_EXECUTOR (contracts/core/InfinityExchange.sol#59) is too similar to InfinityExchange.constructor(address,address)._matchExecutor (contracts/core/InfinityExchange.sol#104) Variable InfinityExchange._matchOneToOneOrders(OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address).makerOrder1 (contracts/core/InfinityExchange.sol#575) is too similar to InfinityExchange._matchOneToOneOrders(OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address).makerOrder2 (contracts/core/InfinityExchange.sol#576) Variable InfinityExchange._matchOneToOneOrders(OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address).makerOrder1 (contracts/core/InfinityExchange.sol#575) is too similar to InfinityExchange.takeOrders(OrderTypes.MakerOrder[],OrderTypes.OrderItem[][]).makerOrders (contracts/core/InfinityExchange.sol#336) Variable InfinityExchange._matchOneToOneOrders(OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address).makerOrder1 (contracts/core/InfinityExchange.sol#575) is too similar to InfinityExchange.takeMultipleOneOrders(OrderTypes.MakerOrder[]).makerOrders (contracts/core/InfinityExchange.sol#300) Variable InfinityExchange._matchOneToOneOrders(OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address).makerOrder2 (contracts/core/InfinityExchange.sol#576) is too similar to InfinityExchange.takeMultipleOneOrders(OrderTypes.MakerOrder[]).makerOrders (contracts/core/InfinityExchange.sol#300) Variable InfinityExchange._matchOneToOneOrders(OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address).makerOrder2 (contracts/core/InfinityExchange.sol#576) is too similar to InfinityExchange.takeOrders(OrderTypes.MakerOrder[],OrderTypes.OrderItem[][]).makerOrders (contracts/core/InfinityExchange.sol#336) Variable InfinityExchange.matchOneToOneOrders(OrderTypes.MakerOrder[],OrderTypes.MakerOrder[]).makerOrders1 (contracts/core/InfinityExchange.sol#133) is too similar to InfinityExchange.matchOneToOneOrders(OrderTypes.MakerOrder[],OrderTypes.MakerOrder[]).makerOrders2 (contracts/core/InfinityExchange.sol#134) Variable InfinityOrderBookComplication.doTokenIdsIntersect(OrderTypes.OrderItem,OrderTypes.OrderItem).item1TokensLength (contracts/core/InfinityOrderBookComplication.sol#283) is too similar to InfinityOrderBookComplication.doTokenIdsIntersect(OrderTypes.OrderItem,OrderTypes.OrderItem).item2TokensLength (contracts/core/InfinityOrderBookComplication.sol#284) Variable IComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder1 (contracts/interfaces/IComplication.sol#24) is too similar to IComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder2 (contracts/interfaces/IComplication.sol#24) Variable InfinityOrderBookComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder1 (contracts/core/InfinityOrderBookComplication.sol#26) is too similar to InfinityOrderBookComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder2 (contracts/core/InfinityOrderBookComplication.sol#26) Variable IComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder1 (contracts/interfaces/IComplication.sol#24) is too similar to InfinityOrderBookComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder2 (contracts/core/InfinityOrderBookComplication.sol#26) Variable InfinityOrderBookComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder1Price (contracts/core/InfinityOrderBookComplication.sol#43) is too similar to InfinityOrderBookComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder2Price (contracts/core/InfinityOrderBookComplication.sol#44) Variable InfinityOrderBookComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder1 (contracts/core/InfinityOrderBookComplication.sol#26) is too similar to IComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder).makerOrder2 (contracts/interfaces/IComplication.sol#24) Variable InfinityOrderBookComplication.doItemsIntersect(OrderTypes.OrderItem[],OrderTypes.OrderItem[]).order1NftsLength (contracts/core/InfinityOrderBookComplication.sol#237) is too similar to InfinityOrderBookComplication.doItemsIntersect(OrderTypes.OrderItem[],OrderTypes.OrderItem[]).order2NftsLength (contracts/core/InfinityOrderBookComplication.sol#238) Variable InfinityStaker.INFINITY_TREASURY (contracts/staking/InfinityStaker.sol#27) is too similar to InfinityStaker.updateInfinityTreasury(address)._infinityTreasury (contracts/staking/InfinityStaker.sol#375) Variable InfinityStaker.INFINITY_TREASURY (contracts/staking/InfinityStaker.sol#27) is too similar to InfinityStaker.constructor(address,address)._infinityTreasury (contracts/staking/InfinityStaker.sol#49)
Prevent variables from having similar names.
Information : Conformance to Solidity naming conventions Naming convention
Function ERC20Permit.DOMAIN_SEPARATOR() (node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol#73-75) is not in mixedCase Variable ERC20Permit._PERMIT_TYPEHASH (node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol#28-29) is not in mixedCase Function IERC20Permit.DOMAIN_SEPARATOR() (node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol#59) is not in mixedCase Parameter ERC721.safeTransferFrom(address,address,uint256,bytes)._data (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#179) is not in mixedCase Variable EIP712._CACHED_DOMAIN_SEPARATOR (node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol#31) is not in mixedCase Variable EIP712._CACHED_CHAIN_ID (node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol#32) is not in mixedCase Variable EIP712._CACHED_THIS (node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol#33) is not in mixedCase Variable EIP712._HASHED_NAME (node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol#35) is not in mixedCase Variable EIP712._HASHED_VERSION (node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol#36) is not in mixedCase Variable EIP712._TYPE_HASH (node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol#37) is not in mixedCase Parameter InfinityExchange.addCurrency(address)._currency (contracts/core/InfinityExchange.sol#1235) is not in mixedCase Parameter InfinityExchange.addComplication(address)._complication (contracts/core/InfinityExchange.sol#1240) is not in mixedCase Parameter InfinityExchange.removeCurrency(address)._currency (contracts/core/InfinityExchange.sol#1245) is not in mixedCase Parameter InfinityExchange.removeComplication(address)._complication (contracts/core/InfinityExchange.sol#1250) is not in mixedCase Parameter InfinityExchange.updateMatchExecutor(address)._matchExecutor (contracts/core/InfinityExchange.sol#1255) is not in mixedCase Parameter InfinityExchange.updateWethTranferGas(uint32)._wethTransferGasUnits (contracts/core/InfinityExchange.sol#1260) is not in mixedCase Parameter InfinityExchange.setProtocolFee(uint16)._protocolFeeBps (contracts/core/InfinityExchange.sol#1266) is not in mixedCase Variable InfinityExchange.WETH (contracts/core/InfinityExchange.sol#55) is not in mixedCase Variable InfinityExchange.DOMAIN_SEPARATOR (contracts/core/InfinityExchange.sol#57) is not in mixedCase Variable InfinityExchange.MATCH_EXECUTOR (contracts/core/InfinityExchange.sol#59) is not in mixedCase Variable InfinityExchange.WETH_TRANSFER_GAS_UNITS (contracts/core/InfinityExchange.sol#61) is not in mixedCase Variable InfinityExchange.PROTOCOL_FEE_BPS (contracts/core/InfinityExchange.sol#63) is not in mixedCase Parameter InfinityStaker.updateInfinityTreasury(address)._infinityTreasury (contracts/staking/InfinityStaker.sol#375) is not in mixedCase Variable InfinityStaker.INFINITY_TOKEN (contracts/staking/InfinityStaker.sol#25) is not in mixedCase Variable InfinityStaker.INFINITY_TREASURY (contracts/staking/InfinityStaker.sol#27) is not in mixedCase Variable InfinityStaker.BRONZE_STAKE_THRESHOLD (contracts/staking/InfinityStaker.sol#33) is not in mixedCase Variable InfinityStaker.SILVER_STAKE_THRESHOLD (contracts/staking/InfinityStaker.sol#34) is not in mixedCase Variable InfinityStaker.GOLD_STAKE_THRESHOLD (contracts/staking/InfinityStaker.sol#35) is not in mixedCase Variable InfinityStaker.PLATINUM_STAKE_THRESHOLD (contracts/staking/InfinityStaker.sol#36) is not in mixedCase Variable InfinityStaker.THREE_MONTH_PENALTY (contracts/staking/InfinityStaker.sol#40) is not in mixedCase Variable InfinityStaker.SIX_MONTH_PENALTY (contracts/staking/InfinityStaker.sol#41) is not in mixedCase Variable InfinityStaker.TWELVE_MONTH_PENALTY (contracts/staking/InfinityStaker.sol#42) is not in mixedCase Variable TimelockConfig._config (contracts/token/TimelockConfig.sol#28) is not in mixedCase Variable TimelockConfig._configSet (contracts/token/TimelockConfig.sol#29) is not in mixedCase Variable TimelockConfig._pending (contracts/token/TimelockConfig.sol#31) is not in mixedCase Variable TimelockConfig._pendingSet (contracts/token/TimelockConfig.sol#32) is not in mixedCase
Follow the Solidity naming convention.
Information : Low-level calls
Low level call in Address.sendValue(address,uint256) (node_modules/@openzeppelin/contracts/utils/Address.sol#60-65): - (success) = recipient.call{value: amount}() (node_modules/@openzeppelin/contracts/utils/Address.sol#63) Low level call in Address.functionCallWithValue(address,bytes,uint256,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#128-139): - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) Low level call in Address.functionStaticCall(address,bytes,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#157-166): - (success,returndata) = target.staticcall(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#164) Low level call in Address.functionDelegateCall(address,bytes,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#184-193): - (success,returndata) = target.delegatecall(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#191) Low level call in InfinityExchange._transferFees(address,address,uint256,address) (contracts/core/InfinityExchange.sol#1128-1148): - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) Low level call in InfinityExchange.rescueETH(address) (contracts/core/InfinityExchange.sol#1229-1232): - (sent) = destination.call{value: msg.value}() (contracts/core/InfinityExchange.sol#1230) Low level call in InfinityStaker.rescueETH(address) (contracts/staking/InfinityStaker.sol#345-348): - (sent) = destination.call{value: msg.value}() (contracts/staking/InfinityStaker.sol#346)
Avoid low-level calls. Check the call success. If the call is meant for a contract, check for code existence.
solc-0.8.14 is not recommended for deployment
Information : Incorrect versions of Solidity
Pragma version0.8.14 (contracts/MockERC20.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/MockERC721.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/core/InfinityExchange.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/core/InfinityOrderBookComplication.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/interfaces/IComplication.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/interfaces/IStaker.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/libs/OrderTypes.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/libs/SignatureChecker.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/staking/InfinityStaker.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/token/InfinityToken.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7 Pragma version0.8.14 (contracts/token/TimelockConfig.sol#2) necessitates a version too recent to be trusted. Consider deploying with 0.6.12/0.7.6/0.8.7
Consider deploying with 0.6.12/0.7.6/0.8.7
Information : Block timestamp
InfinityExchange.takeMultipleOneOrders(OrderTypes.MakerOrder[]) (contracts/core/InfinityExchange.sol#300-328) uses timestamp for comparisons Dangerous comparisons: - isTimeValid = makerOrders[i].constraints[3] <= block.timestamp && makerOrders[i].constraints[4] >= block.timestamp (contracts/core/InfinityExchange.sol#311-312) - require(bool,string)(isTimeValid,invalid time) (contracts/core/InfinityExchange.sol#313) - require(bool,string)(msg.value >= totalPrice,invalid total price) (contracts/core/InfinityExchange.sol#326) InfinityExchange.takeOrders(OrderTypes.MakerOrder[],OrderTypes.OrderItem[][]) (contracts/core/InfinityExchange.sol#336-364) uses timestamp for comparisons Dangerous comparisons: - require(bool,string)(msg.value >= totalPrice,invalid total price) (contracts/core/InfinityExchange.sol#362) InfinityExchange._transferFees(address,address,uint256,address) (contracts/core/InfinityExchange.sol#1128-1148) uses timestamp for comparisons Dangerous comparisons: - require(bool,string)(sent,failed to send ether to seller) (contracts/core/InfinityExchange.sol#1141) InfinityExchange._getCurrentPrice(OrderTypes.MakerOrder) (contracts/core/InfinityExchange.sol#1153-1165) uses timestamp for comparisons Dangerous comparisons: - priceDiff == 0 || duration == 0 (contracts/core/InfinityExchange.sol#1157) - elapsedTime > duration (contracts/core/InfinityExchange.sol#1162) InfinityOrderBookComplication.canExecMatchOneToOne(OrderTypes.MakerOrder,OrderTypes.MakerOrder) (contracts/core/InfinityOrderBookComplication.sol#26-57) uses timestamp for comparisons Dangerous comparisons: - _isTimeValid = makerOrder2.constraints[3] <= block.timestamp && makerOrder2.constraints[4] >= block.timestamp && makerOrder1.constraints[3] <= block.timestamp && makerOrder1.constraints[4] >= block.timestamp (contracts/core/InfinityOrderBookComplication.sol#38-41) - _isPriceValid = makerOrder2Price >= makerOrder1Price (contracts/core/InfinityOrderBookComplication.sol#47) - _isPriceValid = makerOrder1Price >= makerOrder2Price (contracts/core/InfinityOrderBookComplication.sol#50) - (numItemsValid && _isTimeValid && doItemsIntersect(makerOrder1.nfts,makerOrder2.nfts) && _isPriceValid,execPrice) (contracts/core/InfinityOrderBookComplication.sol#53-56) InfinityOrderBookComplication.canExecMatchOneToMany(OrderTypes.MakerOrder,OrderTypes.MakerOrder[]) (contracts/core/InfinityOrderBookComplication.sol#68-116) uses timestamp for comparisons Dangerous comparisons: - ! isOrdersTimeValid || ! itemsIntersect (contracts/core/InfinityOrderBookComplication.sol#77) - isOrdersTimeValid = isOrdersTimeValid && manyMakerOrders[i].constraints[3] <= block.timestamp && manyMakerOrders[i].constraints[4] >= block.timestamp (contracts/core/InfinityOrderBookComplication.sol#89-92) - _isTimeValid = isOrdersTimeValid && makerOrder.constraints[3] <= block.timestamp && makerOrder.constraints[4] >= block.timestamp (contracts/core/InfinityOrderBookComplication.sol#101-103) - _isPriceValid = sumCurrentOrderPrices >= currentMakerOrderPrice (contracts/core/InfinityOrderBookComplication.sol#110) - _isPriceValid = sumCurrentOrderPrices <= currentMakerOrderPrice (contracts/core/InfinityOrderBookComplication.sol#112) - (numItems == makerOrder.constraints[0]) && _isTimeValid && itemsIntersect && _isPriceValid (contracts/core/InfinityOrderBookComplication.sol#115) InfinityOrderBookComplication.canExecMatchOrder(OrderTypes.MakerOrder,OrderTypes.MakerOrder,OrderTypes.OrderItem[]) (contracts/core/InfinityOrderBookComplication.sol#128-143) uses timestamp for comparisons Dangerous comparisons: - (isTimeValid(sell,buy) && _isPriceValid && areNumItemsValid(sell,buy,constructedNfts) && doItemsIntersect(sell.nfts,constructedNfts) && doItemsIntersect(buy.nfts,constructedNfts) && doItemsIntersect(sell.nfts,buy.nfts),execPrice) (contracts/core/InfinityOrderBookComplication.sol#134-142) InfinityOrderBookComplication.canExecTakeOrder(OrderTypes.MakerOrder,OrderTypes.OrderItem[]) (contracts/core/InfinityOrderBookComplication.sol#154-164) uses timestamp for comparisons Dangerous comparisons: - (makerOrder.constraints[3] <= block.timestamp && makerOrder.constraints[4] >= block.timestamp && areTakerNumItemsValid(makerOrder,takerItems) && doItemsIntersect(makerOrder.nfts,takerItems)) (contracts/core/InfinityOrderBookComplication.sol#160-163) InfinityOrderBookComplication.isTimeValid(OrderTypes.MakerOrder,OrderTypes.MakerOrder) (contracts/core/InfinityOrderBookComplication.sol#169-179) uses timestamp for comparisons Dangerous comparisons: - sell.constraints[3] <= block.timestamp && sell.constraints[4] >= block.timestamp && buy.constraints[3] <= block.timestamp && buy.constraints[4] >= block.timestamp (contracts/core/InfinityOrderBookComplication.sol#174-178) InfinityOrderBookComplication.isPriceValid(OrderTypes.MakerOrder,OrderTypes.MakerOrder) (contracts/core/InfinityOrderBookComplication.sol#182-189) uses timestamp for comparisons Dangerous comparisons: - (currentBuyPrice >= currentSellPrice,currentSellPrice) (contracts/core/InfinityOrderBookComplication.sol#188) InfinityOrderBookComplication._getCurrentPrice(OrderTypes.MakerOrder) (contracts/core/InfinityOrderBookComplication.sol#330-342) uses timestamp for comparisons Dangerous comparisons: - priceDiff == 0 || duration == 0 (contracts/core/InfinityOrderBookComplication.sol#334) - elapsedTime > duration (contracts/core/InfinityOrderBookComplication.sol#339) InfinityStaker.getVestedAmount(address,Duration) (contracts/staking/InfinityStaker.sol#260-271) uses timestamp for comparisons Dangerous comparisons: - secondsSinceStake >= durationInSeconds (contracts/staking/InfinityStaker.sol#270) InfinityToken.advanceEpoch() (contracts/token/InfinityToken.sol#60-82) uses timestamp for comparisons Dangerous comparisons: - require(bool,string)(currentEpoch < getMaxEpochs(),no epochs left) (contracts/token/InfinityToken.sol#61) - require(bool,string)(block.timestamp >= currentEpochTimestamp + getCliff(),cliff not passed) (contracts/token/InfinityToken.sol#62) - require(bool,string)(block.timestamp >= previousEpochTimestamp + getEpochDuration(),not ready to advance) (contracts/token/InfinityToken.sol#63) - epochsPassedSinceLastAdvance > epochsLeft (contracts/token/InfinityToken.sol#67-69) TimelockConfig.confirmChange(bytes32) (contracts/token/TimelockConfig.sol#50-62) uses timestamp for comparisons Dangerous comparisons: - require(bool,string)(block.timestamp >= _pending[configId].timestamp + _config[TIMELOCK],too early) (contracts/token/TimelockConfig.sol#52)
Avoid relying on block.timestamp
.
Information : reentrancy-events check-effects-interactions pattern
Reentrancy in InfinityExchange._execMatchOneMakerBuyToManyMakerSells(bytes32,bytes32,OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint16) (contracts/core/InfinityExchange.sol#810-832): External calls: - _execMatchOneToManyOrders(sell.signer,buy.signer,sell.nfts,buy.execParams[1],remainingAmount) (contracts/core/InfinityExchange.sol#821) - returndata = address(token).functionCall(data,SafeERC20: low-level call failed) (node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol#93) - IERC20(currency).safeTransferFrom(buyer,seller,amount) (contracts/core/InfinityExchange.sol#844) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) External calls sending eth: - _execMatchOneToManyOrders(sell.signer,buy.signer,sell.nfts,buy.execParams[1],remainingAmount) (contracts/core/InfinityExchange.sol#821) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) Event emitted after the call(s): - MatchOrderFulfilled(sellOrderHash,buyOrderHash,seller,buyer,complication,currency,amount) (contracts/core/InfinityExchange.sol#931) - _emitMatchEvent(sellOrderHash,buyOrderHash,sell.signer,buy.signer,buy.execParams[0],buy.execParams[1],execPrice) (contracts/core/InfinityExchange.sol#822-830) Reentrancy in InfinityExchange._execMatchOneMakerSellToManyMakerBuys(bytes32,bytes32,OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address) (contracts/core/InfinityExchange.sol#763-796): External calls: - _execMatchOneToManyOrders(sell.signer,buy.signer,buy.nfts,buy.execParams[1],remainingAmount) (contracts/core/InfinityExchange.sol#777) - returndata = address(token).functionCall(data,SafeERC20: low-level call failed) (node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol#93) - IERC20(currency).safeTransferFrom(buyer,seller,amount) (contracts/core/InfinityExchange.sol#844) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) External calls sending eth: - _execMatchOneToManyOrders(sell.signer,buy.signer,buy.nfts,buy.execParams[1],remainingAmount) (contracts/core/InfinityExchange.sol#777) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) Event emitted after the call(s): - MatchOrderFulfilled(sellOrderHash,buyOrderHash,seller,buyer,complication,currency,amount) (contracts/core/InfinityExchange.sol#931) - _emitMatchEvent(sellOrderHash,buyOrderHash,sell.signer,buy.signer,buy.execParams[0],buy.execParams[1],execPrice) (contracts/core/InfinityExchange.sol#778-786) Reentrancy in InfinityExchange._execMatchOneToOneOrders(bytes32,bytes32,OrderTypes.MakerOrder,OrderTypes.MakerOrder,uint256,uint256,uint16,uint32,address) (contracts/core/InfinityExchange.sol#712-748): External calls: - _transferMultipleNFTs(sell.signer,buy.signer,sell.nfts) (contracts/core/InfinityExchange.sol#727) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) - IERC20(buy.execParams[1]).safeTransferFrom(buy.signer,sell.signer,remainingAmount) (contracts/core/InfinityExchange.sol#729) Event emitted after the call(s): - MatchOrderFulfilled(sellOrderHash,buyOrderHash,seller,buyer,complication,currency,amount) (contracts/core/InfinityExchange.sol#931) - _emitMatchEvent(sellOrderHash,buyOrderHash,sell.signer,buy.signer,buy.execParams[0],buy.execParams[1],execPrice) (contracts/core/InfinityExchange.sol#730-738) Reentrancy in InfinityExchange._execMatchOrders(bytes32,bytes32,OrderTypes.MakerOrder,OrderTypes.MakerOrder,OrderTypes.OrderItem[],uint256,uint256,uint16,uint32,address) (contracts/core/InfinityExchange.sol#861-902): External calls: - _execMatchOrder(sell.signer,buy.signer,sell.constraints[5],buy.constraints[5],constructedNfts,buy.execParams[1],remainingAmount) (contracts/core/InfinityExchange.sol#875-883) - returndata = address(token).functionCall(data,SafeERC20: low-level call failed) (node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol#93) - IERC20(currency).safeTransferFrom(buyer,seller,amount) (contracts/core/InfinityExchange.sol#919) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) External calls sending eth: - _execMatchOrder(sell.signer,buy.signer,sell.constraints[5],buy.constraints[5],constructedNfts,buy.execParams[1],remainingAmount) (contracts/core/InfinityExchange.sol#875-883) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) Event emitted after the call(s): - MatchOrderFulfilled(sellOrderHash,buyOrderHash,seller,buyer,complication,currency,amount) (contracts/core/InfinityExchange.sol#931) - _emitMatchEvent(sellOrderHash,buyOrderHash,sell.signer,buy.signer,buy.execParams[0],buy.execParams[1],execPrice) (contracts/core/InfinityExchange.sol#884-892) Reentrancy in InfinityExchange._execTakeOneOrder(bytes32,OrderTypes.MakerOrder,bool,uint256) (contracts/core/InfinityExchange.sol#989-1003): External calls: - _transferNFTsAndFees(makerOrder.signer,msg.sender,makerOrder.nfts,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#997) - returndata = address(token).functionCall(data,SafeERC20: low-level call failed) (node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol#93) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC20(currency).safeTransferFrom(buyer,seller,remainingAmount) (contracts/core/InfinityExchange.sol#1144) - IERC20(currency).safeTransferFrom(buyer,address(this),protocolFee) (contracts/core/InfinityExchange.sol#1146) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) External calls sending eth: - _transferNFTsAndFees(makerOrder.signer,msg.sender,makerOrder.nfts,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#997) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) Event emitted after the call(s): - TakeOrderFulfilled(orderHash,seller,buyer,order.execParams[0],order.execParams[1],amount) (contracts/core/InfinityExchange.sol#1012) - _emitTakerEvent(makerOrderHash,makerOrder.signer,msg.sender,makerOrder,execPrice) (contracts/core/InfinityExchange.sol#998) Reentrancy in InfinityExchange._execTakeOneOrder(bytes32,OrderTypes.MakerOrder,bool,uint256) (contracts/core/InfinityExchange.sol#989-1003): External calls: - _transferNFTsAndFees(msg.sender,makerOrder.signer,makerOrder.nfts,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#1000) - returndata = address(token).functionCall(data,SafeERC20: low-level call failed) (node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol#93) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC20(currency).safeTransferFrom(buyer,seller,remainingAmount) (contracts/core/InfinityExchange.sol#1144) - IERC20(currency).safeTransferFrom(buyer,address(this),protocolFee) (contracts/core/InfinityExchange.sol#1146) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) External calls sending eth: - _transferNFTsAndFees(msg.sender,makerOrder.signer,makerOrder.nfts,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#1000) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) Event emitted after the call(s): - TakeOrderFulfilled(orderHash,seller,buyer,order.execParams[0],order.execParams[1],amount) (contracts/core/InfinityExchange.sol#1012) - _emitTakerEvent(makerOrderHash,msg.sender,makerOrder.signer,makerOrder,execPrice) (contracts/core/InfinityExchange.sol#1001) Reentrancy in InfinityExchange._execTakeOrders(bytes32,OrderTypes.MakerOrder,OrderTypes.OrderItem[],bool,uint256) (contracts/core/InfinityExchange.sol#963-978): External calls: - _transferNFTsAndFees(makerOrder.signer,msg.sender,takerItems,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#972) - returndata = address(token).functionCall(data,SafeERC20: low-level call failed) (node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol#93) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC20(currency).safeTransferFrom(buyer,seller,remainingAmount) (contracts/core/InfinityExchange.sol#1144) - IERC20(currency).safeTransferFrom(buyer,address(this),protocolFee) (contracts/core/InfinityExchange.sol#1146) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) External calls sending eth: - _transferNFTsAndFees(makerOrder.signer,msg.sender,takerItems,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#972) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) Event emitted after the call(s): - TakeOrderFulfilled(orderHash,seller,buyer,order.execParams[0],order.execParams[1],amount) (contracts/core/InfinityExchange.sol#1012) - _emitTakerEvent(makerOrderHash,makerOrder.signer,msg.sender,makerOrder,execPrice) (contracts/core/InfinityExchange.sol#973) Reentrancy in InfinityExchange._execTakeOrders(bytes32,OrderTypes.MakerOrder,OrderTypes.OrderItem[],bool,uint256) (contracts/core/InfinityExchange.sol#963-978): External calls: - _transferNFTsAndFees(msg.sender,makerOrder.signer,takerItems,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#975) - returndata = address(token).functionCall(data,SafeERC20: low-level call failed) (node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol#93) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) - IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) - IERC20(currency).safeTransferFrom(buyer,seller,remainingAmount) (contracts/core/InfinityExchange.sol#1144) - IERC20(currency).safeTransferFrom(buyer,address(this),protocolFee) (contracts/core/InfinityExchange.sol#1146) - IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) External calls sending eth: - _transferNFTsAndFees(msg.sender,makerOrder.signer,takerItems,execPrice,makerOrder.execParams[1]) (contracts/core/InfinityExchange.sol#975) - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) - (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) Event emitted after the call(s): - TakeOrderFulfilled(orderHash,seller,buyer,order.execParams[0],order.execParams[1],amount) (contracts/core/InfinityExchange.sol#1012) - _emitTakerEvent(makerOrderHash,msg.sender,makerOrder.signer,makerOrder,execPrice) (contracts/core/InfinityExchange.sol#976) Reentrancy in InfinityStaker.rageQuit() (contracts/staking/InfinityStaker.sol#136-145): External calls: - IERC20(INFINITY_TOKEN).safeTransfer(msg.sender,totalToUser) (contracts/staking/InfinityStaker.sol#141) - IERC20(INFINITY_TOKEN).safeTransfer(INFINITY_TREASURY,penalty) (contracts/staking/InfinityStaker.sol#142) Event emitted after the call(s): - RageQuit(msg.sender,totalToUser,penalty) (contracts/staking/InfinityStaker.sol#144) Reentrancy in InfinityStaker.stake(uint256,Duration) (contracts/staking/InfinityStaker.sol#67-77): External calls: - IERC20(INFINITY_TOKEN).safeTransferFrom(msg.sender,address(this),amount) (contracts/staking/InfinityStaker.sol#74) Event emitted after the call(s): - Staked(msg.sender,amount,duration) (contracts/staking/InfinityStaker.sol#76) Reentrancy in InfinityStaker.unstake(uint256) (contracts/staking/InfinityStaker.sol#116-131): External calls: - IERC20(INFINITY_TOKEN).safeTransfer(msg.sender,amount) (contracts/staking/InfinityStaker.sol#128) Event emitted after the call(s): - UnStaked(msg.sender,amount) (contracts/staking/InfinityStaker.sol#130)
Apply the check-effects-interactions pattern.
Information : Calls inside a loop
InfinityExchange.matchOneToOneOrders(OrderTypes.MakerOrder[],OrderTypes.MakerOrder[]) (contracts/core/InfinityExchange.sol#132-169) has external calls inside a loop: (canExec,execPrice) = IComplication(makerOrders1[i].execParams[0]).canExecMatchOneToOne(makerOrders1[i],makerOrders2[i]) (contracts/core/InfinityExchange.sol#151-154) SignatureChecker.verify(bytes32,address,bytes32,bytes32,uint8,bytes32) (contracts/libs/SignatureChecker.sol#51-69) has external calls inside a loop: IERC1271(signer).isValidSignature(digest,abi.encodePacked(r,s,v)) == 0x1626ba7e (contracts/libs/SignatureChecker.sol#65) InfinityExchange._transferNFTs(address,address,OrderTypes.OrderItem) (contracts/core/InfinityExchange.sol#1062-1072) has external calls inside a loop: IERC165(item.collection).supportsInterface(0x80ac58cd) (contracts/core/InfinityExchange.sol#1067) InfinityExchange._transferERC721s(address,address,OrderTypes.OrderItem) (contracts/core/InfinityExchange.sol#1080-1092) has external calls inside a loop: IERC721(item.collection).safeTransferFrom(from,to,item.tokens[i].tokenId) (contracts/core/InfinityExchange.sol#1087) InfinityExchange._transferNFTs(address,address,OrderTypes.OrderItem) (contracts/core/InfinityExchange.sol#1062-1072) has external calls inside a loop: IERC165(item.collection).supportsInterface(0xd9b67a26) (contracts/core/InfinityExchange.sol#1069) InfinityExchange._transferERC1155s(address,address,OrderTypes.OrderItem) (contracts/core/InfinityExchange.sol#1101-1117) has external calls inside a loop: IERC1155(item.collection).safeBatchTransferFrom(from,to,tokenIdsArr,numTokensPerTokenIdArr,0x0) (contracts/core/InfinityExchange.sol#1116) Address.functionCallWithValue(address,bytes,uint256,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#128-139) has external calls inside a loop: (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#137) InfinityExchange.matchOrders(OrderTypes.MakerOrder[],OrderTypes.MakerOrder[],OrderTypes.OrderItem[][]) (contracts/core/InfinityExchange.sol#256-294) has external calls inside a loop: (executionValid,execPrice) = IComplication(sells[i].execParams[0]).canExecMatchOrder(sells[i],buys[i],constructs[i]) (contracts/core/InfinityExchange.sol#274-278) InfinityExchange._transferFees(address,address,uint256,address) (contracts/core/InfinityExchange.sol#1128-1148) has external calls inside a loop: (sent) = seller.call{value: remainingAmount}() (contracts/core/InfinityExchange.sol#1140) InfinityExchange._takeOrders(OrderTypes.MakerOrder,OrderTypes.OrderItem[],uint256) (contracts/core/InfinityExchange.sol#941-951) has external calls inside a loop: executionValid = IComplication(makerOrder.execParams[0]).canExecTakeOrder(makerOrder,takerItems) (contracts/core/InfinityExchange.sol#948)
Favor pull over push strategy for external calls.
Missing zero address validation
InfinityExchange.constructor(address,address)._WETH (contracts/core/InfinityExchange.sol#104) lacks a zero-check on : - WETH = _WETH (contracts/core/InfinityExchange.sol#115) InfinityExchange.constructor(address,address)._matchExecutor (contracts/core/InfinityExchange.sol#104) lacks a zero-check on : - MATCH_EXECUTOR = _matchExecutor (contracts/core/InfinityExchange.sol#116) InfinityExchange.rescueETH(address).destination (contracts/core/InfinityExchange.sol#1229) lacks a zero-check on : - (sent) = destination.call{value: msg.value}() (contracts/core/InfinityExchange.sol#1230) InfinityExchange.updateMatchExecutor(address)._matchExecutor (contracts/core/InfinityExchange.sol#1255) lacks a zero-check on : - MATCH_EXECUTOR = _matchExecutor (contracts/core/InfinityExchange.sol#1256) InfinityStaker.constructor(address,address)._tokenAddress (contracts/staking/InfinityStaker.sol#49) lacks a zero-check on : - INFINITY_TOKEN = _tokenAddress (contracts/staking/InfinityStaker.sol#50) InfinityStaker.constructor(address,address)._infinityTreasury (contracts/staking/InfinityStaker.sol#49) lacks a zero-check on : - INFINITY_TREASURY = _infinityTreasury (contracts/staking/InfinityStaker.sol#51) InfinityStaker.rescueETH(address).destination (contracts/staking/InfinityStaker.sol#345) lacks a zero-check on : - (sent) = destination.call{value: msg.value}() (contracts/staking/InfinityStaker.sol#346) InfinityStaker.updateInfinityTreasury(address)._infinityTreasury (contracts/staking/InfinityStaker.sol#375) lacks a zero-check on : - INFINITY_TREASURY = _infinityTreasury (contracts/staking/InfinityStaker.sol#376)
Check that the address is not zero.
Information : Missing events arithmetic
InfinityStaker.updateStakeLevelThreshold(StakeLevel,uint16) (contracts/staking/InfinityStaker.sol#351-361) should emit an event for: - BRONZE_STAKE_THRESHOLD = threshold (contracts/staking/InfinityStaker.sol#353) - SILVER_STAKE_THRESHOLD = threshold (contracts/staking/InfinityStaker.sol#355) - GOLD_STAKE_THRESHOLD = threshold (contracts/staking/InfinityStaker.sol#357) - PLATINUM_STAKE_THRESHOLD = threshold (contracts/staking/InfinityStaker.sol#359) InfinityStaker.updatePenalties(uint16,uint16,uint16) (contracts/staking/InfinityStaker.sol#364-372) should emit an event for: - THREE_MONTH_PENALTY = threeMonthPenalty (contracts/staking/InfinityStaker.sol#369) - SIX_MONTH_PENALTY = sixMonthPenalty (contracts/staking/InfinityStaker.sol#370) - TWELVE_MONTH_PENALTY = twelveMonthPenalty (contracts/staking/InfinityStaker.sol#371)
Emit an event for critical parameter changes.
Information : Unused return
InfinityExchange.addCurrency(address) (contracts/core/InfinityExchange.sol#1235-1237) ignores return value by _currencies.add(_currency) (contracts/core/InfinityExchange.sol#1236) InfinityExchange.addComplication(address) (contracts/core/InfinityExchange.sol#1240-1242) ignores return value by _complications.add(_complication) (contracts/core/InfinityExchange.sol#1241) InfinityExchange.removeCurrency(address) (contracts/core/InfinityExchange.sol#1245-1247) ignores return value by _currencies.remove(_currency) (contracts/core/InfinityExchange.sol#1246) InfinityExchange.removeComplication(address) (contracts/core/InfinityExchange.sol#1250-1252) ignores return value by _complications.remove(_complication) (contracts/core/InfinityExchange.sol#1251) TimelockConfig.confirmChange(bytes32) (contracts/token/TimelockConfig.sol#50-62) ignores return value by _configSet.add(configId) (contracts/token/TimelockConfig.sol#55) TimelockConfig.confirmChange(bytes32) (contracts/token/TimelockConfig.sol#50-62) ignores return value by _pendingSet.remove(configId) (contracts/token/TimelockConfig.sol#58) TimelockConfig._setRawConfig(bytes32,uint256) (contracts/token/TimelockConfig.sol#66-72) ignores return value by _configSet.add(configId) (contracts/token/TimelockConfig.sol#67)
Ensure that all the return values of the function calls are used.
Information : Tautology or contradiction
InfinityStaker.getRageQuitAmounts(address) (contracts/staking/InfinityStaker.sol#181-203) contains a tautology or contradiction: - require(bool,string)(totalStaked >= 0,nothing staked to rage quit) (contracts/staking/InfinityStaker.sol#193)
Fix the incorrect comparison by changing the value type or the comparison.
Information : Divide before multiply
InfinityOrderBookComplication._getCurrentPrice(OrderTypes.MakerOrder) (contracts/core/InfinityOrderBookComplication.sol#330-342) performs a multiplication on the result of a division: -priceDiff = (priceDiff * portionBps) / PRECISION (contracts/core/InfinityOrderBookComplication.sol#340) -portionBps = ((elapsedTime * PRECISION) / duration) (contracts/core/InfinityOrderBookComplication.sol#339) InfinityToken.advanceEpoch() (contracts/token/InfinityToken.sol#60-82) performs a multiplication on the result of a division: -epochsPassedSinceLastAdvance = (block.timestamp - previousEpochTimestamp) / getEpochDuration() (contracts/token/InfinityToken.sol#65) -supplyToMint = getInflation() * epochsPassedSinceLastAdvance (contracts/token/InfinityToken.sol#76) -epochsPassedSinceLastAdvance = epochsPassedSinceLastAdvance (contracts/token/InfinityToken.sol#67-69)
Consider ordering multiplication before division.
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xAsm0d3us, 0xDjango, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xkowloon, BowTiedWardens, Chom, ElKu, FSchmoede, Funen, GimelSec, Kaiziron, Kenshin, Lambda, MadWookie, MiloTruck, PPrieditis, Picodes, PwnedNoMore, StErMi, Tadashi, TerrierLover, TomJ, Tomio, Wayne, Waze, _Adam, antonttc, apostle0x01, asutorufos, c3phas, codexploder, defsec, delfin454000, fatherOfBlocks, hake, hansfriese, hyh, joestakey, k, kenta, oyc_109, peritoflores, reassor, rfa, robee, sach1r0, simon135, slywaters, zer0dot
31.294 USDC - $31.29
!= 0 will do the same as > 0 for unsigned integers, but != 0 costs less gas compared to > 0 for unsigned integers in require statements with the optimizer enabled.
core/InfinityExchange.sol:392: require(numNonces > 0, 'cannot be empty');
It is recommended to replace > 0
with != 0
, as they do the same thing for unsigned integers, and '!= 0' costs less gas compared to > 0
in require statements with the optimizer enabled, also enable the optimizer.
For example :
core/InfinityExchange.sol:392: require(numNonces != 0, 'cannot be empty');
Uninitialized variables are assigned with the default value of their type, initializing a variable with its default value costs unnecessary gas.
core/InfinityExchange.sol:148: for (uint256 i = 0; i < numMakerOrders; ) { core/InfinityExchange.sol:200: for (uint256 i = 0; i < ordersLength; ) { core/InfinityExchange.sol:219: for (uint256 i = 0; i < ordersLength; ) { core/InfinityExchange.sol:272: for (uint256 i = 0; i < numSells; ) { core/InfinityExchange.sol:308: for (uint256 i = 0; i < numMakerOrders; ) { core/InfinityExchange.sol:349: for (uint256 i = 0; i < ordersLength; ) { core/InfinityExchange.sol:393: for (uint256 i = 0; i < numNonces; ) { core/InfinityExchange.sol:1048: for (uint256 i = 0; i < numNfts; ) { core/InfinityExchange.sol:1086: for (uint256 i = 0; i < numTokens; ) { core/InfinityExchange.sol:1109: for (uint256 i = 0; i < numNfts; ) { core/InfinityExchange.sol:1190: for (uint256 i = 0; i < numNfts; ) { core/InfinityExchange.sol:1206: for (uint256 i = 0; i < numTokens; ) { core/InfinityOrderBookComplication.sol:76: for (uint256 i = 0; i < ordersLength; ) { core/InfinityOrderBookComplication.sol:82: for (uint256 j = 0; j < nftsLength; ) { core/InfinityOrderBookComplication.sol:197: uint256 numConstructedItems = 0; core/InfinityOrderBookComplication.sol:199: for (uint256 i = 0; i < nftsLength; ) { core/InfinityOrderBookComplication.sol:214: uint256 numTakerItems = 0; core/InfinityOrderBookComplication.sol:216: for (uint256 i = 0; i < nftsLength; ) { core/InfinityOrderBookComplication.sol:244: uint256 numCollsMatched = 0; core/InfinityOrderBookComplication.sol:246: for (uint256 i = 0; i < order2NftsLength; ) { core/InfinityOrderBookComplication.sol:247: for (uint256 j = 0; j < order1NftsLength; ) { core/InfinityOrderBookComplication.sol:289: uint256 numTokenIdsPerCollMatched = 0; core/InfinityOrderBookComplication.sol:290: for (uint256 k = 0; k < item2TokensLength; ) { core/InfinityOrderBookComplication.sol:291: for (uint256 l = 0; l < item1TokensLength; ) { core/InfinityOrderBookComplication.sol:318: uint256 sum = 0; core/InfinityOrderBookComplication.sol:320: for (uint256 i = 0; i < ordersLength; ) { MockERC721.sol:11: for (uint256 i = 0; i < 100; i++) {
It is recommended to initialize variables without assigning them the default value, for example :
core/InfinityOrderBookComplication.sol:318: uint256 sum;
If the divisor/multiplier x
is a power of 2, it can be calculated by shifting log2(x)
to the right/left. Division with /
cost more gas compared to bitwise shifting.
staking/InfinityStaker.sol:235: (userstakedAmounts[user][Duration.THREE_MONTHS].amount * 2) + staking/InfinityStaker.sol:237: (userstakedAmounts[user][Duration.TWELVE_MONTHS].amount * 4)) / (10**18);
It is recommended to replace /
and *
with >>
and <<
respectively and divisor/multiplier x
to log2(x)
, for division/multiplication where the divisor/multiplier is a power of 2, for example :
staking/InfinityStaker.sol:235: (userstakedAmounts[user][Duration.THREE_MONTHS].amount << 1) +
Prefix increment ++i
returns the updated value after it's incremented and postfix increment i++
returns the original value then increments it. Prefix increment costs less gas compared to postfix increment.
MockERC721.sol:11: for (uint256 i = 0; i < 100; i++) { MockERC721.sol:12: _safeMint(msg.sender, numMints++);
It is recommended to use prefix increment instead of postfix one when the return value is not needed, as both of them will give the same result and prefix increment costs less gas.
For example :
MockERC721.sol:11: for (uint256 i = 0; i < 100; ++i) {
Shortening revert strings to fit in 32 bytes will decrease gas costs for deployment and gas costs when the revert condition has been met.
core/InfinityExchange.sol:395: require(!isUserOrderNonceExecutedOrCancelled[msg.sender][orderNonces[i]], 'nonce already executed or cancelled'); staking/InfinityStaker.sol:96: require(newDuration > oldDuration, 'new duration must be greater than old duration');
It is recommended to use error code and providing a reference to the error code instead of a long revert string., for example :
// Link to the reference of error codes staking/InfinityStaker.sol:96: require(newDuration > oldDuration, 'ERR');
Public functions that are never called by the contract should be declared external to save gas.
renounceOwnership() should be declared external: - Ownable.renounceOwnership() (node_modules/@openzeppelin/contracts/access/Ownable.sol#54-56) transferOwnership(address) should be declared external: - Ownable.transferOwnership(address) (node_modules/@openzeppelin/contracts/access/Ownable.sol#62-65) balanceOf(address) should be declared external: - ERC721.balanceOf(address) (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#62-65) name() should be declared external: - ERC721.name() (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#79-81) symbol() should be declared external: - ERC721.symbol() (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#86-88) approve(address,uint256) should be declared external: - ERC721.approve(address,uint256) (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#112-122) setApprovalForAll(address,bool) should be declared external: - ERC721.setApprovalForAll(address,bool) (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#136-138) transferFrom(address,address,uint256) should be declared external: - ERC721.transferFrom(address,address,uint256) (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#150-159) safeTransferFrom(address,address,uint256) should be declared external: - ERC721.safeTransferFrom(address,address,uint256) (node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol#164-170) getUserTotalStaked(address) should be declared external: - InfinityStaker.getUserTotalStaked(address) (contracts/staking/InfinityStaker.sol#154-160) getUserTotalVested(address) should be declared external: - InfinityStaker.getUserTotalVested(address) (contracts/staking/InfinityStaker.sol#167-173)
Use the external attribute for functions never called from the contract.