Open code423n4 opened 2 years ago
Duplicated of #2 at For loop optimizaion
Duplicated of #2 at For loop optimizaion
Duplicated of #89 at Use Shift Right/Left instead of Division/Multiplication
Duplicated of #62 at Reduce the size of error messages (Long revert Strings)
Duplicated of #76 at 5. constants should be defined rather than using magic numbers
Duplicated of #58 at Inequality
Gas Optimizations Report
For-loops: Index initialized with default value
Uninitialized
uint
variables are assigned with a default value of0
.Thus, in for-loops, explicitly initializing an index with
0
costs unnecesary gas. For example, the following code:can be changed to:
Consider declaring the following lines without explicitly setting the index to
0
:For-Loops: Index increments can be left unchecked
From Solidity v0.8 onwards, all arithmetic operations come with implicit overflow and underflow checks.
In for-loops, as it is impossible for the index to overflow, it can be left unchecked to save gas every iteration.
For example, the code below:
can be changed to:
Consider making the following change to these lines:
Arithmetics: Use
!= 0
instead of> 0
for unsigned integersuint
will never go below 0. Thus,> 0
is gas inefficient in comparisons as checking if!= 0
is sufficient and costs less gas.Consider changing
> 0
to!= 0
in these lines:Arithmetics: Use Shift Right/Left instead of Division/Multiplication if possible
A division/multiplication by any number
x
being a power of 2 can be calculated by shiftinglog2(x)
to the right/left.While the
DIV
opcode uses 5 gas, theSHR
opcode only uses 3 gas. Furthermore, Solidity's division operation also includes a division-by-0 prevention which is bypassed using shifting.For example, the following code:
can be changed to:
Consider making this change to the following lines:
Visibility: Consider declaring constants as non-public to save gas
If a constant is not used outside of its contract, declaring it as
private
orinternal
instead ofpublic
can save gas.Consider changing the visibility of the following from
public
tointernal
orprivate
:Visibility:
public
functions can be set toexternal
Calls to
external
functions are cheaper thanpublic
functions. Thus, if a function is not used internally in any contract, it should be set toexternal
to save gas and improve code readability.Consider changing following functions from
public
toexternal
:Errors: Reduce the length of error messages (long revert strings)
Shortening revert strings to fit in 32 bytes will decrease deployment time gas and will decrease runtime gas when the revert condition is met.
Revert strings that are longer than 32 bytes require at least one additional
mstore
, along with additional overhead for computing memory offset, etc.In these instances, consider shortening the revert strings to fit within 32 bytes, or using custom errors:
Variables declared as
constant
are expressions, not constantsDue to how
constant
variables are implemented (replacements at compile-time), an expression assigned to aconstant
variable is recomputed each time that the variable is used, which wastes some gas.If the variable was
immutable
instead: the calculation would only be done once at deploy time (in the constructor), and then the result would be saved and read directly at runtime rather than being recalculated.See: ethereum/solidity#9232:
Change these expressions from
constant
toimmutable
and implement the calculation in the constructor. Alternatively, hardcode these values in the constants and add a comment to say how the value was calculated.