Please, consider everything described below as a general recommendation. These notes will represent potential possibilities to optimize gas consumption. It's okay, if something is not suitable in your case. Just let me know the reason in the comments section. Enjoy!
[G-01] Try ++i instead of i++
Description:
In case of i++, the compiler needs to create a temp variable to return and then it gets incremented.
In case of ++i, the compiler just simply returns already incremented value.
Recommendations:
Use prefix increment instead of postfix.
All occurances:
Contracts:
file: src/Vault.sol
...............................
// Lines: [78-78]
for (uint256 i = 0; i < length; i++) {}
// Lines: [104-104]
for (uint256 i = 0; i < length; i++) {}
[G-02] Try unchecked{++i}; instead of i++; in loops
Description:
If the for loop runs 100 times, it's about 10k units of gas which can be saved in comparison. Don't worry about overflow, when the number is just simply getting incremented by 1. There are ~1e80 atoms in the universe, so 2^256 is closed to that number, therefore it's no a way to be overflowed, because of the gas limit as well.
Recommendations:
Try to use unchecked{} box where it's no a way to get a overflow/underflow. Significant gas usage optimization.
All occurances:
Contracts:
file: src/Vault.sol
...............................
// Lines: [78-78]
for (uint256 i = 0; i < length; i++) {}
// Lines: [104-104]
for (uint256 i = 0; i < length; i++) {}
[G-03] Consider a = a + b instead of a += b
Description:
It has an impact on the deployment cost and the cost for distinct transaction.
[G-04] Consider marking onlyOwner functions as payable
Description:
A little optmization in comparison between payable and non-payable functions. Also, there is a little tradeoff here between readability and optimization.
[G-11] Functions which are invoked inside the SC should be marked as internal
Description:
If i'm not mistaken, these getter functions should be defined as internal.
All occurances:
Contracts:
file: src/FERC1155.sol
...............................
// Lines: [309-316]
function INITIAL_CONTROLLER() public pure returns (address) {
return _getArgAddress(0);
}
function VAULT_REGISTRY() public pure returns (address) {
return _getArgAddress(20);
}
[G-12] Redundant gas usage
Description:
Extra gas usage without the reason, use _selectors.length in loops.
Table of contents
unchecked{++i}
instead ofi++
in loopsa = a + b
instead ofa += b
a / 2^x, x > 0
MLOAD
<<SLOAD
immutable
instead of state variablesconstants/immutable/state
asprivate/internal
calldataloud
vsmload
Internal
functions can be inlinedDisclaimer
[G-01] Try ++i instead of i++
Description:
Recommendations:
All occurances:
Contracts:
[G-02] Try
unchecked{++i};
instead ofi++;
in loopsDescription:
Recommendations:
All occurances:
Contracts:
[G-03] Consider
a = a + b
instead ofa += b
Description:
All occurances:
Contracts:
[G-04] Consider marking onlyOwner functions as payable
Description:
All occurances:
Contracts:
[G-05] Use binary shifting instead of
a / 2^x, x > 0
Description:
All occurances:
Contracts:
[G-06] Cache state variables,
MLOAD
<<SLOAD
Description:
MLOAD
costs only 3 units of gas,SLOAD
(warm access) is about 100 units. Therefore, cache, when it's possible.All occurances:
Contracts:
[G-07] Declare
immutable
instead of state variablesDescription:
All occurances:
Contracts:
[G-08] Define public
constants/immutable/state
asprivate/internal
Description:
All occurances:
Contracts:
[G-09] Check out
calldataloud
vsmload
Description:
All occurances:
Contracts:
[G-10]
Internal
functions can be inlinedDescription:
JUMP
s which costs around 12 gas uints for eachJUMP
.All occurances:
Contracts:
[G-11] Functions which are invoked inside the SC should be marked as internal
Description:
All occurances:
Contracts:
[G-12] Redundant gas usage
Description:
All occurances:
Contracts:
[G-13] Remove unnecessary explicit casts
Description:
address
toaddress
, etc...All occurances:
Contracts:
Kudos for the quality of the code! It's pretty easy to explore!