ENS contest - Aymen0909's results

Decentralised naming for wallets, websites, & more.

General Information

Platform: Code4rena

Start Date: 12/07/2022

Pot Size: $75,000 USDC

Total HM: 16

Participants: 100

Period: 7 days

Judge: LSDan

Total Solo HM: 7

Id: 145

League: ETH

ENS

Findings Distribution

Researcher Performance

Rank: 90/100

Findings: 1

Award: $39.87

🌟 Selected for report: 0

🚀 Solo Findings: 0

[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");
AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter