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 incrementing i in for loops there is no chance of overflow so unchecked can be used to save gas. I ran a simple test in remix and found deployment savings of 31,653 gas and on each function call saved ~141 gas per iteration.
contract Test {
function loopTest() external {
for (uint256 i; i < 1; ++i) {
Deployment Cost: 125,637, Cost on function call: 24,601
vs
for (uint256 i; i < 1; ) {
// for loop body
unchecked { ++i }
Deployment Cost: 93,984, Cost on function call: 24,460
}
}
}
In for loops pre increments can be used to save a small amount of gas per iteration.
I ran a test in remix using a for loop and found the deployment savings of 497 gas and ~5 gas per iteration.
contract Test {
function loopTest() external {
for (uint256 i; i < 1; i++) {
(Deployment cost: 118,408, Cost on function call: 24,532)
vs
for (uint256 i; i < 1; ++i) {
(Deployment cost: 117,911, Cost on function call: 24,527)
}
}
}
As your using a solidity version > 0.8.4 you can replace revert strings with custom errors. This will save in deployment costs and runtime costs.
Based on a test in remix, replacing a single revert string with a custom error saved 12,404 gas in deployment cost and 86 gas on each function call.
contractTest {
uint256 a;
function check() external {
require(a !=0, "check failed");
}
} (Deployment cost: 114,703, Cost on Function call: 23,392)
vs
contractTest {
uint256 a;
error checkFailed();
function check() external {
if (a !=0) revertcheckFailed();
}
} (Deployment cost: 102,299, Cost on Function call: 23,306)
If you opt not to use custom errors keeping revert strings <= 32 bytes in length will save gas.
I ran a test in remix and found the savings for a single short revert string vs long string to be 9,377 gas in deployment cost and 18 gas on function call.
contractTest {
uint256 a;
function check() external {
require(a !=0, "short error message");
(Deployment cost: 114,799, Cost on function call: 23,392)
vs
require(a !=0, "A longer Error Message over 32 bytes in length");
(Deployment cost: 124,176, Cost on function call: 23,410)
}
}
If optimising for runtime costs over deployment costs you can seperate && in require functions into 2 parts. I ran a basic test in remix and it cost an extra 234 gas to deploy but will save ~9 gas everytime the require function is called. (note: If you upgrade to solidity version > 0.8.13 this is no longer true)
contractTest {
uint256 a =0;
uint256 b =1;
function test() external {
require(a ==0&& b > a)
(Deployment cost: 123,291, Cost on function call: 29,371)
vs
require(a ==0);
require(b > a);
(Deployment cost: 123,525, Cost on function call: 29,362)
}
}
[G01] Unchecked Increments in Loops
When incrementing i in for loops there is no chance of overflow so unchecked can be used to save gas. I ran a simple test in remix and found deployment savings of 31,653 gas and on each function call saved ~141 gas per iteration.
For loops that can use unchecked increments:
BytesUtils.sol#L266
BytesUtils.sol#L313
DNSSECImpl.sol#L93
ETHRegistrarController.sol#L256
ERC1155Fuse.sol#L92
ERC1155Fuse.sol#L205
[G02] Pre Increments in Loops
In for loops pre increments can be used to save a small amount of gas per iteration.
I ran a test in remix using a for loop and found the deployment savings of 497 gas and ~5 gas per iteration.
For loops that can use pre increments:
BytesUtils.sol#L266
BytesUtils.sol#L313
DNSSECImpl.sol#L93
ETHRegistrarController.sol#L256
[G03] Custom Errors
As your using a solidity version > 0.8.4 you can replace revert strings with custom errors. This will save in deployment costs and runtime costs.
Based on a test in remix, replacing a single revert string with a custom error saved 12,404 gas in deployment cost and 86 gas on each function call.
Instances where custom errors can be implemented:
RRUtils.sol#L307
ETHRegistrarController.sol#L99-L102
ETHRegistrarController.sol#L137-L139
ETHRegistrarController.sol#L196-L199
ETHRegistrarController.sol#L232-L242
ETHRegistrarController.sol#L259-L261
ReverseRegistrar.sol#L41-L54
BytesUtil.sol#L28
BytesUtil.sol#L42
ERC1155Fuse.sol#L60-L62
ERC1155Fuse.sol#L85-L87
ERC1155Fuse.sol#L107-L109
ERC1155Fuse.sol#L176-L179
ERC1155Fuse.sol#L195-L203
ERC1155Fuse.sol#L215-L217
ERC1155Fuse.sol#L248-L252
ERC1155Fuse.sol#L290-L293
Controllable.sol#L17
[G04] Long Revert Strings
If you opt not to use custom errors keeping revert strings <= 32 bytes in length will save gas.
I ran a test in remix and found the savings for a single short revert string vs long string to be 9,377 gas in deployment cost and 18 gas on function call.
I recommend shortenning the following revert strings to < 32 bytes in length:
ETHRegistrarController.sol#L99-L102
ETHRegistrarController.sol#L137-L139
ETHRegistrarController.sol#L198
ETHRegistrarController.sol#L232-L242
ETHRegistrarController.sol#L259-L261
ReverseRegistrar.sol#L41-L54
ERC1155Fuse.sol#L60-L62
ERC1155Fuse.sol#L85-L87
ERC1155Fuse.sol#L107-L109
ERC1155Fuse.sol#L176-L179
ERC1155Fuse.sol#L195-L203
ERC1155Fuse.sol#L215-L217
ERC1155Fuse.sol#L248-L252
ERC1155Fuse.sol#L290-L293
Controllable.sol#L17
[G05] && in Require Statements
If optimising for runtime costs over deployment costs you can seperate && in require functions into 2 parts. I ran a basic test in remix and it cost an extra 234 gas to deploy but will save ~9 gas everytime the require function is called. (note: If you upgrade to solidity version > 0.8.13 this is no longer true)
Require statements that can be split up:
BytesUtils.sol#L268
ERC1155Fuse.sol#L215-L218
ERC1155Fuse.sol#L290-L293
The text was updated successfully, but these errors were encountered: