You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1. Unnecessary explicit initialization of variables with default values
If a variable is not set/initialized, it has the default value (0 for uint, false for bool, etc.). Explicitly initializing a variable with its default value is an anti-pattern and wastes gas.
The OrderCombiner.sol contract has more than ten explicit initializations of default values. Other contract have more examples. Examples include:
To fix this, remove explicit initializations for default values.
2. Use unchecked for increment
Consider the following generic for loop:
for (uint i =0; i < length; i++) {
// do something that doesn't change the value of i
}
In this example, the for loop post condition, i.e., i++ involves checked arithmetic, which is not required. This is because the value of i is always strictly less than length <= 2**256 - 1. Therefore, the theoretical maximum value of i to enter the for-loop body is 2**256 - 2. This means that the i++ in the for loop can never overflow. Regardless, the overflow checks are performed by the compiler.
Unfortunately, the Solidity optimizer is not smart enough to detect this and remove the checks. One can manually do this by:
for (uint i =0; i < length; i =unchecked_inc(i)) {
// do something that doesn't change the value of i
}
function unchecked_inc(uinti) returns (uint) {
unchecked {
return i +1;
}
}
Vyper contracts normally use less gas than their solidity counterparts. The possible savings was demonstrated for Seaport by doggo and a more general example was shown here. Seaport is written in solidity and yul, not vyper. Switching some or all of the contracts to vyper can result in gas savings.
To fix, replace solidity contracts with vyper code.
The text was updated successfully, but these errors were encountered:
Unnecessary explicit initialization of variables with default values
In my testing these changes seem to make very little difference.
Use unchecked for increment
This will provide small savings.
iszero assembly should replace == 0
I like how you reference t11s own tweet here :) This could be a worthwhile change to consider including here.
Use vyper instead of solidity
Potentially. I saw 0age mention a working group exploring this more. Very curious to see if that concludes, would love a full featured comparison of Seaport in Solidity/Yul vs Vyper
1. Unnecessary explicit initialization of variables with default values
If a variable is not set/initialized, it has the default value (
0
foruint
,false
forbool
, etc.). Explicitly initializing a variable with its default value is an anti-pattern and wastes gas.The OrderCombiner.sol contract has more than ten explicit initializations of default values. Other contract have more examples. Examples include:
To fix this, remove explicit initializations for default values.
2. Use unchecked for increment
Consider the following generic for loop:
In this example, the for loop post condition, i.e.,
i++
involves checked arithmetic, which is not required. This is because the value ofi
is always strictly less thanlength <= 2**256 - 1
. Therefore, the theoretical maximum value ofi
to enter the for-loop body is2**256 - 2
. This means that thei++
in the for loop can never overflow. Regardless, the overflow checks are performed by the compiler.Unfortunately, the Solidity optimizer is not smart enough to detect this and remove the checks. One can manually do this by:
Above code and explanation from hrkrshnn.
The OrdrCombiner.sol contract has more than 5 loops that can be improved this way. Examples include:
To fix, use unchecked increment in loops.
3. iszero assembly should replace
== 0
The iszero opcode is useful when comparing variables to zero. t11s suggested overusing this improvement on twitter.
The Assertions.sol and OrderCombiner.sol contracts have more than 5 zero comparisons that can be improved this way. Examples include:
To fix, replace
== 0
withiszero
.4. Use vyper instead of solidity
Vyper contracts normally use less gas than their solidity counterparts. The possible savings was demonstrated for Seaport by doggo and a more general example was shown here. Seaport is written in solidity and yul, not vyper. Switching some or all of the contracts to vyper can result in gas savings.
To fix, replace solidity contracts with vyper code.
The text was updated successfully, but these errors were encountered: