Nouns DAO contest - 0x1337'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: 120/160

Findings: 1

Award: $35.44

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2022-08-nounsdao/blob/c1c7c6201d0247f92472419ff657b570f9104565/contracts/governance/NounsDAOInterfaces.sol#L126-L400

Vulnerability details

Impact

For upgradeable contracts, there must be storage gap to “allow developers to freely add new state variables in the future without compromising the storage compatibility with existing deployments” (quote OpenZeppelin). Otherwise it may be very difficult to write new implementation code. Without storage gap, the variable in child contract might be overwritten by the upgraded base contract if new variables are added to the base contract. This could have unintended and very serious consequences to the child contracts, potentially causing loss of user fund or cause the contract to malfunction completely.

Refer to the bottom part of this article: https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable

In this project, the various NounsDAOStorage contracts serve as the base contract for the various NounsDAOLogic contracts, and these base contracts do not contain storage gap. Similar findings have been confirmed in other contests, such as https://github.com/code-423n4/2022-05-alchemix-findings/issues/44

Proof of Concept

The NounsDAOProxyStorage, NounsDAOStorageV1, NounsDAOStorageV1Adjusted, and NounsDAOStorageV2 contracts are used as the base contract for NounsDAOLogicV1 or NounsDAOLogicV2 contracts. However, these base contracts do not contain storage gaps.

The storage gap is essential for upgradeable contract because "It allows us to freely add new state variables in the future without compromising the storage compatibility with existing deployments". Refer to the bottom part of this article:

https://docs.openzeppelin.com/contracts/3.x/upgradeable

As an example, any deletion/modification/addition in the NounsDAOProxyStorage contract would be impossible due to the lack of storage gap, and modification of the structs declared in NounsDAOStorageV1 could also cause potential collisions.

Tools Used

Manual Review

Recommend adding appropriate storage gap at the end of upgradeable contracts such as the below. Please reference OpenZeppelin upgradeable contract templates.

uint256[50] private __gap;

#0 - eladmallel

2022-08-30T19:49:56Z

We're simply using a different pattern that does not depend on having the ability to add storage variables to contracts high in the inheritance tree; our approach of append-only in inherited contracts seems to work well.

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