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
When using i++ there is an extra operation that can be skipped if you use unchecked{++i}. This saves gas every iteration.
You can also use assembly to save much more gas. This may be challenging though in some for loops due to limitations of inline assembly, however this will save much more gas when applicable.
Use assembly to check for address(0) or any other 0 value
When requiring that an address is not address(0), instead of using require(_address!=address(0)), you can use assembly to save gas. You can package the optimized assembly logic below into a function and call it instead of the require statement.
One limitation to this approach is that there is a limit to the error message length that you can pass in, however this forces you to make the revert message 32 bytes, ensuring that only one 256 bit slot is used.
^^ many other instances like this throughout the codebase.
Optimization
contractUnoptimized{functionunoptimizedGasTest(addressowner)publicview{require(owner!=address(0),"ERC4626: approve from address(0)");}}contractOptimized{functionoptimizedGasTest(addressowner)publicview{assembly{ifiszero(owner){mstore(0x00,"ERC4626: approve from address(0)")revert(0x00,0x20)}}}}
Use assembly to check if msg.sender == owner (or check any stored value)
When requiring that the msg.sender is the owner of the contract, use assembly instead of a require statement. You can package this logic into a function and call the function instead of the require statement.
Using assembly to check any stored value will save gas.
Pack structs by putting data types in ascending size
When defining a struct, pack the values so that the data types are in ascending order. This will make sure that data types that can be put into the same slot are packed together instead of each variable having a separate storage slot.
Gas Optimizations
Use unchecked{++i} instead of i++ in loops
When using
i++
there is an extra operation that can be skipped if you useunchecked{++i}
. This saves gas every iteration.You can also use assembly to save much more gas. This may be challenging though in some for loops due to limitations of inline assembly, however this will save much more gas when applicable.
Examples
Occurrence0
Occurrence1
Occurrence2
Occurrence3
Occurrence4
Occurrence5
Occurrence6
Occurrence7
Occurrence8
Occurrence9
Occurrence10
Occurrence11
Occurrence12
Occurrence13
Occurrence14
Occurrence15
^^ many other instances like this throughout the codebase.
Optimization
Gas report
Use Solmate ERC20 vs Openzeppelin
Link to Solmate ERC20
Use assembly to check for address(0) or any other 0 value
When requiring that an address is not address(0), instead of using
require(_address!=address(0))
, you can use assembly to save gas. You can package the optimized assembly logic below into a function and call it instead of the require statement.One limitation to this approach is that there is a limit to the error message length that you can pass in, however this forces you to make the revert message 32 bytes, ensuring that only one 256 bit slot is used.
Examples
Occurence0
Occurrence1
Occurrence2
^^ many other instances like this throughout the codebase.
Optimization
Gas report
Use assembly to check if msg.sender == owner (or check any stored value)
When requiring that the msg.sender is the owner of the contract, use assembly instead of a require statement. You can package this logic into a function and call the function instead of the require statement.
Using assembly to check any stored value will save gas.
Examples
Occurrence0
Occurrence1
Occurrence2
Occurrence3
Occurrence4
Occurrence5
Occurrence6
^^ many other instances like this throughout the codebase.
Optimization
Gas report
Use assembly to update state variables
Using assembly to update the stored value will save gas with
sstore(owner.slot, newOwnerAddress)
instead ofowner = newOwner;
.Examples
Occurrence0
Occurrence1
Occurrence2
^^ many other instances like this throughout the codebase.
Optimization
Gas report
Break up one multi-condition require statement into multiple require statements
When checking multiple conditions in a single require statement, break it up into multiple require statements.
Examples
Occurrence0
Occurrence1
Occurrence2
Occurrence3
Occurrence4
Occurrence5
Optimization
Gas report
You don't have to use the Safemath library when you are using Solidity version >= 0.8.0
Solidity >= 0.8.0 uses safe math by default. Using Safemath on top of versions >= 0.8.0 is redundant.
Gas report
Pack structs by putting data types in ascending size
When defining a struct, pack the values so that the data types are in ascending order. This will make sure that data types that can be put into the same slot are packed together instead of each variable having a separate storage slot.
Examples
Occurrence0
Occurrence1
Occurrence2
Occurrence3
Optimization
Use assembly for add, sub, mul, div and other math library operations
In the Aura math lib, use assembly instead of solidity to save gas during arithmetic.
Examples
Occurrences
Optimization
Gas report
Use assembly for merkle proof verification
Instead of using openzeppelin's merkle proof verification, use assembly to save significant gas.
Examples
Occurrences
Optimization
Here is a link to my optimized merkle proof verification implementation
Gas report
The text was updated successfully, but these errors were encountered: