Platform: Code4rena
Start Date: 03/07/2023
Pot Size: $100,000 USDC
Total HM: 4
Participants: 36
Period: 10 days
Judge: gzeon
Total Solo HM: 3
Id: 257
League: ETH
Rank: 19/36
Findings: 1
Award: $58.98
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: shark
Also found by: 0xMilenov, Bauchibred, Kaysoft, MohammedRizwan, codegpt, descharre, fatherOfBlocks, ihtishamsudo, klau5, koxuan, nadin
58.9765 USDC - $58.98
Total 04 Low and 06 Non-Critical
Upgrade Plan viii
and ix
transferring ownership of NounsToken and descriptor of NounsToken to V2 treasury
Ownable.sol
.Ownable.sol
has recently undergone a significant change. Earlier, the contract owner was automatically designated as the account that deployed the contract. However, the new update requires the contract owner to be specified explicitly as a constructor argument during deployment. An idea of the details of this modification can be found on this back & forth discussion with OZ, found here.Update all implementations to include the explicit call to the Ownable
constructor to set the owner.
See the following for more info: https://twitter.com/solidity_lang/status/1567953562151579650?s=20&t=fXIo4hRjOiMXl2dqpD5Oyw https://blog.soliditylang.org/2022/09/08/storage-write-removal-before-conditional-termination/
File: NounsDAOLogicV1.sol function getChainIdInternal() internal view returns (uint256) { uint256 chainId; assembly { chainId := chainid() } return chainId; }
File: NounsDAOLogicV2.sol function getChainIdInternal() internal view returns (uint256) { uint256 chainId; assembly { chainId := chainid() } return chainId; }
NounsDAOLogicV2.sol#L1070-L1076
Upgrade pragma to version 0.8.19
An outdated OZ version is used (which has known vulnerabilities, see: https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories). Release: https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v4.9.0
Require dependencies to be at least version of 4.9.0 to include critical vulnerability patches.
File: nouns-monorepo/packages/nouns-contracts/package.json 32: "@openzeppelin/contracts": "^4.1.0", 33: "@openzeppelin/contracts-upgradeable": "^4.1.0",
Update OpenZeppelin Contracts Usage in package.json and require at least version of 4.9.0 via >=4.9.0
== true
or == false
checks== true
or == false
checksThere is no need to verify that == true or == false when the variable checked upon is a boolean as well.
File: NounsDAOV3Votes.sol 219: require(receipt.hasVoted == false, 'NounsDAO::castVoteDuringVotingPeriodInternal: voter already voted'); 282: require(receipt.hasVoted == false, 'NounsDAO::castVoteInternal: voter already voted');
NounsDAOV3Votes.sol#L219 , NounsDAOV3Votes.sol#L282
File: NounsDAOLogicV1Fork.sol 621: require(receipt.hasVoted == false, 'NounsDAO::castVoteInternal: voter already voted');
Instead simply check for variable
or !variable
Immutables should be in uppercase per naming convention. As shown below, some immutables are named using capital letters and underscores while some are not. For a better code quality, please consider naming these immutables using the same naming convention.
File: ForkDAODeployer.sol 35: address public immutable tokenImpl; 38: address public immutable auctionImpl; 41: address public immutable treasuryImpl; 44: address public immutable governorImpl; 47: uint256 public immutable delayedGovernanceMaxDuration; 50: uint256 public immutable initialVotingPeriod; 53: uint256 public immutable initialVotingDelay; 56: uint256 public immutable initialProposalThresholdBPS; 59: uint256 public immutable initialQuorumVotesBPS;
File: NounsDAOForkEscrow.sol 41: address public immutable dao; 44: NounsTokenLike public immutable nounsToken;
NounsDAOForkEscrow.sol#L41-L44
File: DeployDAOV3DataContractsBase.s.sol 12: NounsDAOLogicV1 public immutable daoProxy; 13: address public immutable timelockV2Proxy;
DeployDAOV3DataContractsBase.s.sol#L12-L13
File: DeployDAOV3NewContractsBase.s.sol 20: uint256 public immutable forkDAOVotingPeriod; 21: uint256 public immutable forkDAOVotingDelay; 25: NounsDAOLogicV1 public immutable daoProxy; 26: INounsDAOExecutor public immutable timelockV1; 27: bool public immutable deployTimelockV2Harness; // should be true only for testnets
DeployDAOV3NewContractsBase.s.sol#L20-L21 , DeployDAOV3NewContractsBase.s.sol#L25-L27
File: ProposeDAOV3UpgradeTestnet.s.sol 14: NounsDAOLogicV1 public immutable daoProxyContract; 15: address public immutable timelockV1; 16: address public immutable auctionHouseProxy; 17: address public immutable stETH;
ProposeDAOV3UpgradeTestnet.s.sol#L14-L17
Consider using named parameters in mappings (e.g. mapping(address account => uint256 balance)) to improve readability. This feature is present since Solidity 0.8.18
The highest tier of smart contract behavior assurance is formal mathematical verification. All assertions that are made are guaranteed to be true across all inputs → The quality of your asserts is the quality of your verification
https://twitter.com/0xOwenThurm/status/1614359896350425088?t=dbG9gHFigBX85Rv29lOjIQ&s=19
There are many addresses and constants used in the system. It is recommended to put the most used ones in one file (for example constants.sol, use inheritance to access these values).
This will help with readability and easier maintenance for future changes. This also helps with any issues, as some of these hard-coded values are admin addresses.
Use and import this file in contracts that require access to these values. This is just a suggestion, in some use cases this may result in higher gas usage in the distribution.
#0 - c4-judge
2023-07-25T09:57:39Z
gzeon-c4 marked the issue as grade-b