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
NO NEED TO EXPLICITLY INITIALIZE VARIABLES WITH DEFAULT VALUES
If a variable is not set/initialized, it is assumed to have the default value (0 for uint, false for bool, address(0) for address…). Explicitly initializing it with its default value is an anti-pattern and wastes gas.
src/governance/treasury/Treasury.sol
162: for (uint256 i =0; i < numTargets; ++i) {
src/token/metadata/MetadataRenderer.sol
119: for (uint256 i =0; i < numNewProperties; ++i) {
133: for (uint256 i =0; i < numNewItems; ++i) {
189: for (uint256 i =0; i < numProperties; ++i) {
229: for (uint256 i =0; i < numProperties; ++i) {
The demo of the loop gas comparison can be seen here.
X = X + Y / X = X - Y IS CHEAPER THAN X += Y / X -= Y
It is expected that the value should be converted into a constant value at compile time. But the expression is re-calculated each time the constant is referenced.
consequences:
each usage of a "constant" costs ~100gas more on each access (it is still a little better than storing the result in storage, but not much..)
since these are not real constants, they can't be referenced from a real constant environment (e.g. from assembly, or from another library )
Suggestion:
Change these expressions from constant to immutable and implement the calculation in the constructor or hardcode these values in the constants and add a comment to say how the value was calculated.
FUNCTIONS ONLY CALLED OUTSIDE OF THE CONTRACT CAN BE DECLARED AS EXTERNAL
External call cost is less expensive than of public functions.
The difference is because in public functions, Solidity immediately copies array arguments to memory, while external functions can read directly from calldata. Memory allocation is expensive, whereas reading from calldata is cheap.
src/token/metadata/MetadataRenderer.sol
206: function getAttributes(uint256_tokenId) publicviewreturns (bytesmemoryaryAttributes, bytesmemoryqueryString) {
MULTIPLE ADDRESS MAPPINGS CAN BE COMBINED INTO A SINGLE MAPPING OF AN ADDRESS TO A STRUCT WHERE APPROPRIATE
Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.
NO NEED TO EXPLICITLY INITIALIZE VARIABLES WITH DEFAULT VALUES
If a variable is not set/initialized, it is assumed to have the default value (0 for uint, false for bool, address(0) for address…). Explicitly initializing it with its default value is an anti-pattern and wastes gas.
The demo of the loop gas comparison can be seen here.
X = X + Y / X = X - Y
IS CHEAPER THANX += Y / X -= Y
The demo of the gas comparison can be seen here.
Consider use
X = X + Y / X = X - Y
to save gas.EXPRESSIONS FOR CONSTANT VALUES SUCH AS A CALL TO
keccak256()
,` SHOULD USE IMMUTABLE RATHER THAN CONSTANTConstant expressions are left as expressions, not constants.
When a constant declared as:
It is expected that the value should be converted into a constant value at compile time. But the expression is re-calculated each time the constant is referenced.
consequences:
Suggestion:
Change these expressions from constant to immutable and implement the calculation in the constructor or hardcode these values in the constants and add a comment to say how the value was calculated.
reference:
ethereum/solidity#9232
Use bytes32 instead of string
Use bytes32 instead of string to save gas whenever possible.
String is a dynamic data structure and therefore is more gas consuming then bytes32.
Bytes32 can be used instead of string in the following:
USE CALLDATA INSTEAD OF MEMORY
When arguments are read-only on external functions, the data location can be calldata.
The demo of the gas comparison can be seen here.
FUNCTIONS ONLY CALLED OUTSIDE OF THE CONTRACT CAN BE DECLARED AS EXTERNAL
External call cost is less expensive than of public functions.
The difference is because in public functions, Solidity immediately copies array arguments to memory, while external functions can read directly from calldata. Memory allocation is expensive, whereas reading from calldata is cheap.
MULTIPLE ADDRESS MAPPINGS CAN BE COMBINED INTO A SINGLE MAPPING OF AN ADDRESS TO A STRUCT WHERE APPROPRIATE
Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.
Use bit shift instead of power operation or * 2, / 2
`` seem to be frequently called functions.
src/lib/token/ERC721Votes.sol
Suggestion:
Change the above to
The demo of the gas comparison can be seen here.
The text was updated successfully, but these errors were encountered: