Instead of using the shorthand of addition/subtraction assignment operators (+=, -=)
it costs less to remove the shorthand (x += y same as x = x+y) saves ~22 gas
For example:
Line 506: balance += tierBalanceOf[_nft][_owner][_i];
Usage of uint/int Smaller Than 32 bytes (256 Bits) Incurs Overhead
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Each operation involving a uint8 costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8) as compared to ones involving uint256, due to the compiler having to clear the higher bits of the memory word before operating on the uint8, as well as the associated stack operations of doing so. Use a larger size then downcast where needed for example:
Line 66: function _truncate(uint8[] memory _array, uint8 _length) private pure returns (uint8[] memory) {;
A function with access control marked as payable will be cheaper for legitimate callers: the compiler removes checks for msg.value, saving approximately 20 gas per function call.
For example:
Line 290 function mintFor(JBTiered721MintForTiersData[] memory _mintForTiersData)
Line 291 external
Line 292 override
Line 293: onlyOwner
Line 321 function adjustTiers(JB721TierParams[] calldata _tiersToAdd, uint256[] calldata _tierIdsToRemove)
Line 322 external
Line 323 override
Line 324: onlyOwner
Uncheck arithmetics operations that can’t underflow/overflow
Solidity version 0.8+ comes with an implicit overflow and underflow checks on unsigned integers. When an overflow or an underflow isn’t possible, some gas can be saved by using an unchecked block.
For example:
for (uint256 i = 0; i < _input.length; i++) {
output[i] = _input[_input.length - 1 - i];
}
for (uint256 i = 0; i < _input.length;) {
output[i] = _input[_input.length - 1 - i];
unchecked {
++i;
}
}
Function Order Affects Gas Consumption
public/external function names and public member variable names can be optimized to save gas. See this link for an example of how it works. Below are the interfaces/abstract contracts that can be optimized so that the most frequently-called functions use the least amount of gas possible during method lookup. Method IDs that have two leading zero bytes can save 128 gas each during deployment, and renaming functions to have lower method IDs will save 22 gas per call, per sorted position shifted
Remove Shorthand Addition/Subtraction Assignment
Instead of using the shorthand of addition/subtraction assignment operators (
+=
,-=
)it costs less to remove the shorthand (
x += y
same asx = x+y
) saves ~22 gas For example:Line 506
could be refactored to
Public Functions Not Called by the Contract Should Be Declared External Instead
Functions not internally called may have their visibility changed to external to save gas. For Example:
Line 214
Usage of
uint
/int
Smaller Than 32 bytes (256 Bits) Incurs OverheadWhen using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Each operation involving a uint8 costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8) as compared to ones involving uint256, due to the compiler having to clear the higher bits of the memory word before operating on the uint8, as well as the associated stack operations of doing so. Use a larger size then downcast where needed for example:
Line 66
Line 48
Functions With Access Control Cheaper if Payable
A function with access control marked as payable will be cheaper for legitimate callers: the compiler removes checks for
msg.value
, saving approximately20
gas per function call.For example:
Line 293
Line 324
Line 370
Uncheck arithmetics operations that can’t underflow/overflow
Solidity version 0.8+ comes with an implicit overflow and underflow checks on unsigned integers. When an overflow or an underflow isn’t possible, some gas can be saved by using an unchecked block. For example:
Line 76-78
could be refactored to as:
Function Order Affects Gas Consumption
public/external function names and public member variable names can be optimized to save gas. See this link for an example of how it works. Below are the interfaces/abstract contracts that can be optimized so that the most frequently-called functions use the least amount of gas possible during method lookup. Method IDs that have two leading zero bytes can save 128 gas each during deployment, and renaming functions to have lower method IDs will save 22 gas per call, per sorted position shifted