Identical long require revert strings occur in all four lines referenced below. It's not clear how to shorten the message without abbreviating 'NibblVaultFactory'
require(basketUpdateTime != 0 && block.timestamp >= basketUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");
Recommendation:
require(basketUpdateTime != 0, "NibblVaultFactory: UPDATE_TIME has not passed");
require(block.timestamp >= basketUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");
Similarly for the three additional instances of '&&' within require functions referenced below:
Under/overflow checks are made every time i++ or (++i) is called. Such checks are unnecessary since i is already limited. Therefore, use unchecked{++i}/unchecked{i++} instead
While, for presentation purposes, I have separated the for loop-related gas savings methods, they should be combined. Below I show how all four of the gas saving methods outlined in this submission can be implemented together.
Require
message is too longThe revert strings below can be shortened to 32 characters or fewer (as shown) to save gas
contracts/NibblVaultFactory.sol: L48
Change message to
NibblVaultFactory: Low res bal
contracts/NibblVaultFactory.sol: L49
Change message to
NibblVaultFactory: Inval sender
Identical long
require
revert strings occur in all four lines referenced below. It's not clear how to shorten the message without abbreviating 'NibblVaultFactory'contracts/NibblVaultFactory.sol: L107 contracts/NibblVaultFactory.sol: L131 contracts/NibblVaultFactory.sol: L149 contracts/NibblVaultFactory.sol: L166
Example:
Use of '&&' within a
require
functionSplitting such
require()
statements into separaterequires
instead of using '&&' saves gascontracts/NibblVaultFactory.sol: L107
Recommendation:
Similarly for the three additional instances of '&&' within
require
functions referenced below:contracts/NibblVaultFactory.sol: L131 contracts/NibblVaultFactory.sol: L149 contracts/NibblVaultFactory.sol: L166
Variables should not be initialized to their default values
For example, initializing
uint
variables to their default value of0
is unnecessary and costs gasThe
for
loop counteri
is initialized unnecessarily to zero in the six loops referenced below:contracts/NibblVault.sol: L506-508 contracts/NibblVault.sol: L525-527 contracts/NibblVault.sol: L547-550 contracts/Basket.sol: L43-46 contracts/Basket.sol: L70-74 contracts/Basket.sol: L93-96
Example:
Change
uint256 i = 0;
touint256 i;
in all casesArray length should not be looked up in every iteration of
for
loopSince calculating the array length costs gas, it's best to read the length of the array from memory before executing the loop
contracts/NibblVault.sol: L506-508
Recommendation:
Similarly for the five
for
loops referenced below:contracts/NibblVault.sol: L525-527 contracts/NibblVault.sol: L547-550 contracts/Basket.sol: L43-46 contracts/Basket.sol: L70-74 contracts/Basket.sol: L93-96
Use of
i++
to increase count in afor
loopSince use of i++ costs more gas, it would be better to use ++i in the six
for
loops referenced below:contracts/NibblVault.sol: L506-508 contracts/NibblVault.sol: L525-527 contracts/NibblVault.sol: L547-550 contracts/Basket.sol: L43-46 contracts/Basket.sol: L70-74 contracts/Basket.sol: L93-96
Use of default "checked" behavior in
for
loopUnder/overflow checks are made every time
i++
or (++i
) is called. Such checks are unnecessary sincei
is already limited. Therefore, useunchecked{++i}
/unchecked{i++}
insteadcontracts/NibblVault.sol: L506-508
Recommendation:
Similarly for the five additional
for
loops that could save gas by usingunchecked
:contracts/NibblVault.sol: L525-527 contracts/NibblVault.sol: L547-550 contracts/Basket.sol: L43-46 contracts/Basket.sol: L70-74 contracts/Basket.sol: L93-96
For
loop gas optimization exampleWhile, for presentation purposes, I have separated the
for
loop-related gas savings methods, they should be combined. Below I show how all four of the gas saving methods outlined in this submission can be implemented together.i
) to zero++i
rather thani++
unchecked
++i
contracts/NibblVault.sol: L506-508
Recommendation:
Storage of uints or ints smaller than 32 bytes
Storage of uints or ints smaller than 32 bytes incurs overhead. Instead, use size of at least 32, then downcast where needed
Recommendation: Use a larger size than
uint8
in the four lines referenced below:contracts/NibblVault.sol: L557 contracts/Twav/Twav.sol: L11 contracts/Twav/Twav.sol: L12 contracts/Twav/Twav.sol: L37