Platform: Code4rena
Start Date: 06/12/2022
Pot Size: $36,500 USDC
Total HM: 16
Participants: 119
Period: 3 days
Judge: berndartmueller
Total Solo HM: 2
Id: 189
League: ETH
Rank: 65/119
Findings: 1
Award: $35.02
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: slvDev
Also found by: 0x4non, Bnke0x0, Diana, Dinesh11G, RaymondFam, ReyAdmirado, adriro, ahmedov, ajtra, c3phas, cryptostellar5, nicobevi, pfapostol, sakshamguruji, tnevler, zaskoh
35.0246 USDC - $35.02
when stack var is not needed in the require checks or if statements make it after them and right before its needed to possibly save gas
make nft
before the for loop (line 65)
make amount
before the third require check
make amount
before the second require check
97 gas cheaper
use temp.price
instead of sale.price
use _sale.saleReceiver
instead of sale.saleReceiver
unchecked {}
for subtractions where the operands cannot underflow because of a previous require()
or if
statementrequire(a <= b); x = b - a => require(a <= b); unchecked { x = b - a } if(a <= b); x = b - a => if(a <= b); unchecked { x = b - a } this will stop the check for overflow and underflow so it will save gas
sale.endTime - block.timestamp
will not underflow
although not checked before it numb - 1
will never underflow so we can use unchecked{} for it
totalSale
is 20 times bigger than fee
so no way it underflows
block.timestamp - start
cant underflow because of check in line 120
<x> += <y>
costs more gas than <x> = <x> + <y>
for state variablesUsing the addition operator instead of plus-equals saves gas
++i/i++
should be unchecked{++i}/unchecked{i++}
when it is not possible for them to overflow, as is the case when used in for-loop and while-loopsIn Solidity 0.8+, there’s a default overflow check on unsigned integers. It’s possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline.
Checks that involve constants should come before checks that involve state variables, function calls, and calculations. By doing these checks first, the function is able to revert before wasting a Gcoldsload (2100 gas*) in a function that may ultimately revert in the unhappy case.
swap the require of L30 to after the other 2
swap the require of L30 to after the other 2
swap the require of L30 to after all the others
If data can fit into 32 bytes, then you should use bytes32 datatype rather than bytes or strings as it is cheaper in solidity.
Contracts are allowed to override their parents’ functions and change the visibility from external to public and can save gas by doing so.
setFeeReceiver
setFeeReceiver
getPrice
startTime
editionContract
available
lowestPrice
timeLeft
addCreator
safeTransferFrom
safeBatchTransferFrom
resetDefaultRoyalty
updateURIDelegate
setFeeReceiver
refund
If variables occupying the same slot are both written the same function or by the constructor, avoids a separate Gsset (20000 gas). Reads of the variables are also cheaper.
we can put amountSold
after factory
to make them into a single slot (factory is in line 11)
#0 - c4-judge
2023-01-04T11:02:29Z
berndartmueller marked the issue as grade-b