Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas Optimizations #311

Open
code423n4 opened this issue Jul 19, 2022 · 0 comments
Open

Gas Optimizations #311

code423n4 opened this issue Jul 19, 2022 · 0 comments
Labels
bug Something isn't working G (Gas Optimization)

Comments

@code423n4
Copy link
Contributor

[G-1]- USE CALLDATA INSTEAD OF MEMORY FOR FUNCTION PARAMETERS TYPE :

If a reference type function parameter is read-only, it is cheaper in gas to use calldata instead of memory. Calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory.

File: contracts/dnssec-oracle/DNSSECImpl.sol

line 80 : function verifyRRSet(RRSetWithSignature[] memory input) external virtual view override returns(bytes memory)
line 91 : function verifyRRSet(RRSetWithSignature[] memory input, uint256 now) public virtual view override returns(bytes memory)

File: contracts/wrapper/ERC1155Fuse.sol

line 188 : function safeBatchTransferFrom(address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)

[G-2]- USE OF ++i COST LESS GAS THAN i++ IN FOR LOOPS :

File: contracts/dnssec-oracle/BytesUtils.sol

line 313 : for(uint256 idx = off; idx < off + len; idx++)

File: contracts/dnssec-oracle/DNSSECImpl.sol

line 93 : for(uint i = 0; i < input.length; i++)

File: contracts/ethregistrar/ETHRegistrarController.sol

line 256 : for (uint256 i = 0; i < data.length; i++)

[G-3]- FUNCTIONS GUARANTEED TO REVERT WHEN CALLED BY NORMAL USERS CAN BE MARKED PAYABLE :

If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for the owner because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are :

CALLVALUE(gas=2), DUP1(gas=3), ISZERO(gas=3), PUSH2(gas=3), JUMPI(gas=10), PUSH1(gas=3), DUP1(gas=3), REVERT(gas=0), JUMPDEST(gas=1), POP(gas=2).

Which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost

File: contracts/dnssec-oracle/DNSSECImpl.sol

line 58 : function setAlgorithm(uint8 id, Algorithm algo) public owner_only
line 69 : function setDigest(uint8 id, Digest digest) public owner_only
line 562 : function _calcPayout(DataTypes.Auction memory auction_, address to, uint256 artIn) internal view returns (uint256 liquidatorCut, uint256 auctioneerCut)

File: contracts/wrapper/NameWrapper.sol

line 105 : function setMetadataService(IMetadataService _newMetadataService) public onlyOwner
line 128 : function setUpgradeContract(INameWrapperUpgrade _upgradeAddress) public onlyOwner
line 251 : function registerAndWrapETH2LD(string calldata label, address wrappedOwner, uint256 duration, address resolver, uint32 fuses, uint64 expiry) external override onlyController returns (uint256 registrarExpiry)
line 271 : function renew(uint256 tokenId, uint256 duration, uint64 expiry) external override onlyController returns (uint256 expires)
line 335 : function unwrapETH2LD(bytes32 labelhash, address newRegistrant, address newController) public override onlyTokenOwner(_makeNode(ETH_NODE, labelhash))

[G-4] USE CUSTOM ERRORS RATHER THAN REQUIRE() STRINGS TO SAVE DEPLOYMENT GAS :

Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met) while providing the same amount of information.

There are many lines with this issue throughout the contracts.

File: contracts/ethregistrar/ETHRegistrarController.sol

line 99 : require(resolver != address(0),"ETHRegistrarController: resolver is required when data is supplied");
line 137 : require( msg.value >= (price.base + price.premium),"ETHRegistrarController: Not enough ether provided");
line 196 : require(msg.value >= price.base,"ETHController: Not enough Ether provided for renewal");
line 233 : require(commitments[commitment] + minCommitmentAge <= block.timestamp,"ETHRegistrarController: Commitment is not valid");
line 238 : require(commitments[commitment] + maxCommitmentAge > block.timestamp,"ETHRegistrarController: Commitment has expired");
line 242 : require(available(name), "ETHRegistrarController: Name is unavailable");
line 259 : require(txNamehash == nodehash,"ETHRegistrarController: Namehash on record do not match the name being registered");

File: contracts/wrapper/BytesUtil.sol

line 28 : require(offset == self.length - 1, "namehash: Junk at end of name");
line 42 : require(idx < self.length, "readLabel: Index out of bounds");

File: contracts/wrapper/ERC1155Fuse.sol

line 61 : require(account != address(0),"ERC1155: balance query for the zero address");
line 85 : require(accounts.length == ids.length,"ERC1155: accounts and ids length mismatch");
line 107 : require(msg.sender != operator,"ERC1155: setting approval status for self");
line 176 : require(to != address(0), "ERC1155: transfer to the zero address");
@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Jul 19, 2022
code423n4 added a commit that referenced this issue Jul 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working G (Gas Optimization)
Projects
None yet
Development

No branches or pull requests

1 participant