Nouns DAO contest - _Adam's results

A DAO-driven NFT project on Ethereum.

General Information

Platform: Code4rena

Start Date: 22/08/2022

Pot Size: $50,000 USDC

Total HM: 4

Participants: 160

Period: 5 days

Judge: gzeon

Total Solo HM: 2

Id: 155

League: ETH

Nouns DAO

Findings Distribution

Researcher Performance

Rank: 75/160

Findings: 2

Award: $52.10

🌟 Selected for report: 0

🚀 Solo Findings: 0

[L01] Unlocked Pragma

Description: Non Library/Interface contracts should be deployed with a locked pragma version. This prevents the contract being deployed with a version that wasn't thoroughly tested against in development.

LOC: NounsDAOLogicV1.sol#L61 NounsDAOLogicV2.sol#L53 NounsDAOProxy.sol#L36 ERC721Checkpointable.sol#L35 ERC721Enumerable.sol#L28

Recommendation: Lock the pragma the version that was used in testing.

[N01] Incorrect Comment

Description: A comment has been copy and pasted from a previous function and doesnt match the code it is referencing.

LOC: NounsDAOLogicV2.sol#L852

Recommendation: Delete/update to correct comment.

[N02] Typos

Description: There is a typo in the comment, 4,000 is written where 6,000 was intended.

LOC: NounsDAOLogicV2.sol#L86

Recommendation: Change to // 6,000 basis points or 60%

[G01] Duplicate Require Statement

Description: In NounsDAOLogicV2 the exact same require statement that is checked in burnVetoPower on line 853 is also checked in setVetoer on line 840. It is unnecessary to check that msg.sender == vetoer twice and can be removed from burnVetoPower. (Same for v1 just on line 651 instead)

LOC: NounsDAOLogicV2.sol#L853 NounsDAOLogicV1.sol#L651

Recommendation: Remove the duplicate require statement from burnVetoPower.

[G02] For Loop Optimisations

Description: When incrementing i in for loops there is no chance of overflow so unchecked can be used to save gas. You can also save a small amount of gas by replacing post increments with pre. It is also more expensive to loop over a state variable and you can save some gas by cacheing the value.

LOC: NounsDAOLogicV1.sol#L281-L289 NounsDAOLogicV1.sol#L319-L327 NounsDAOLogicV1.sol#L346-L354 NounsDAOLogicV1.sol#L371-L379 NounsDAOLogicV2.sol#L292-L300 NounsDAOLogicV2.sol#L330-L338 NounsDAOLogicV2.sol#L357-L365 NounsDAOLogicV2.sol#L382-L390

Recommendation: Change for loops from:

for (uint256 i; i < variable.length; i++) { } to uint256 len = variable.length; (uint256 i; i < len;) { // for loop body unchecked { ++i; } }

[G03] Default Values for State Variables

Description: When initialising state variables to their default value it is cheaper to just leave the value blank.

LOC: ERC721Checkpointable.sol#L41 NounsDAOLogicV2.sol#L231 NounsDAOLogicV2.sol#L238-L243

Recommendation: Remove = 0/false from the variable initialisations.

[G04] Custom Errors

Description: As your using a solidity version > 0.8.4 you can replace revert strings with cheaper custom errors.

LOC: There are 95 revert strings throughout the various contracts that can be replaced with custom errors.

Recommendation: Replace revert strings with custom errors.

[G05] Long Revert Strings

Description: If you opt not to use custom errors keeping revert strings <= 32 bytes in length will save gas.

LOC: There are 87 revert strings > 32 bytes in length throughout the various contracts.

Recommendation: Either replace with custom errors or shorten the revert strings to be < 32 bytes in length.

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