Open code423n4 opened 2 years ago
Disputed, see #9 for more. Further, we will remove those AUDIT: constants should be literal and their derivation should be in comments
comments as they are no longer relevant.
Disputed, see #9 for more.
Confirmed.
Acknowledged, see #9 for more.
Acknowledged, see #9 for more.
Confirmed.
Gas Report
Table of Contents:
++i
costs less gas compared toi++
ori += 1
Foreword
@audit
tagsFindings
Variables
Constants should be literal and their derivation should be in comments
Due 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.While I'm certain the sponsor is aware of this fact (thanks to the comments
AUDIT: constants should be literal and their derivation should be in comments
), I figured I'd still centralize the impacted lines of codes here:As already proposed by a previous auditor, I suggest hardcoding the computed values from these expressions in the constants variables and add a comment above them to say how the value was calculated.
For-Loops
An array's length should be cached to save gas in for-loops
Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack.
Caching the array length in the stack saves around 3 gas per iteration.
Here, I suggest storing the array's length in a variable before the for-loop, and use it instead:
This is already done at most places in the solution.
++i
costs less gas compared toi++
ori += 1
++i
costs less gas compared toi++
ori += 1
for unsigned integer, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled.i++
incrementsi
and returns the initial value ofi
. Which means:But
++i
returns the actual incremented value:In the first case, the compiler has to create a temporary variable (when used) for returning
1
instead of2
Instances include:
I suggest using
++i
instead ofi++
to increment the value of an uint variable, just like it's done here:Increments can be unchecked
In 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.
ethereum/solidity#10695
Instances include:
The code would go from:
to:
The risk of overflow is inexistant for a
uint256
here.Arithmetics
Unchecking arithmetics operations that can't underflow/overflow
Solidity version 0.8+ comes with implicit overflow and underflow checks on unsigned integers. When an overflow or an underflow isn't possible (as an example, when a comparison is made before the arithmetic operation), some gas can be saved by using an
unchecked
block: https://docs.soliditylang.org/en/v0.8.10/control-structures.html#checked-or-unchecked-arithmeticI suggest wrapping with an
unchecked
block here (see@audit
tags for more details):Errors
Use Custom Errors instead of Revert Strings to save Gas
Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met)
Source: https://blog.soliditylang.org/2021/04/21/custom-errors/:
Custom errors are defined using the
error
statement, which can be used inside and outside of contracts (including interfaces and libraries).Instances include:
I suggest replacing revert strings with custom errors.