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: 9/36
Findings: 1
Award: $1,405.81
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: 0xnev
Also found by: 0xSmartContract, K42, Matin, ihtishamsudo, shark
1405.8126 USDC - $1,405.81
Nouns is a generative NFT project on Ethereum, where a new Noun is minted and auctioned off every day, and each token represents one vote where proposers who hold a noun and create and vote on governance proposals, which execute transactions on the ethereum blockchain when approved.
To summarize the NounsDAO protocol, it will be helpful to look at the various states introduced in the NounsDaoV3 contracts. But first lets look at the creation of proposals.
propose/proposeOnTimelockV1/proposeBySigs
updateProposal()/updateProposalTransactions()/updateProposalBySigs()
and updateProposalDescription()
respectivelyblock.number
reaches the starting block.support
represents the vote value, with 0 = against, 1 = for and 2 = abstaincastVote()/castVoteWithReason()/castVoteBySig()
castRefundableVote()/castRefundableVoteWithReason()
NounsDaoExecutorV2.sol
contractqueueTransaction()
and executed via executeTransaction()
Canceled/Defeated/Expired/Executed/Vetoed
).Currently, the Nouns Dao introduce a objection period where there is a last-minute proposal swing from defeated to successful, affording against voters more reaction time.
This could be unfair to the for voters, where the reverse could happen, when there is a last-minute proposal swing from successful to defeated, but no time is allowed for for voters to react. Hence, protocol could introduce a new mechanism/state to allow this to happen, where similarly, only a against vote casted in the last minute voting block can trigger this period.
Currently, there are no mechanisms for voters to unvote or update their votes, and they can only ever vote once due to the hasVoted
flag. Consider implementing a mechanism to unvote and/or update vote choice.
Queued proposals are still active, since it has not been executed. As such, consider not allowing creation of proposal when proposal state is queued. Given Nouns Dao only allow 1 active proposal per proposer, there could be a scenario where there are multiple proposals queued if proposals are not yet executed.
In the contest Docs, it is stated that any token holder can execute fork if fork threshold is met. However, anybody, not just token holders can execute fork via executeFork()
once threshold is met. Since Nouns govern Noun DAO, consider only allowing only token holders to execute fork.
_refundGas
Any one can fund the NounsDAOV3Votes.sol
contract, but it is presumably the DAO funding it to refund gas for voters. If contract ETH balance is insufficient, voters may not get refunded their gas when voting.
In the new NounsDaoV3Logic, all proposal thresholds are calculated using an adjusted total supply instead of the fixed nouns supply previously. This adjusted total supply represents the total supply of nouns minus nouns owed by DAO. If in any of the address the Nouns DAO mints/transfer nouns tokens, it could affect proposal thresholds by increasing/decreasing it respectfully, potentially preventing/allowing proposals to be created.
In NounsDAOForkEscrow.sol
, any nouns tokens sent to the contract to be escrowed faces a potential risk of DAO closing escrow at anytime, essentially locking up the tokens and cannot be unescrowed, with the tokens only being able to be withdrawn by the DAO.
NounsDAOV3Proposals.cancel()
: Signers can collude to cancel proposer proposal anytime by adjusting voting powerWith the introduction of proposing proposals with other signers, it also gives the power to signers to cancel proposals at anytime without the need to consult proposer/other signers. This opens up the ability for any signers or even the proposer to invalidate votes simply by cancelling the proposal if they do not agree with the direction of the state that proposal is approaching (Defeated/Succeeded
).
48 hours
#0 - c4-pre-sort
2023-07-20T13:01:28Z
0xSorryNotSorry marked the issue as high quality report
#1 - c4-judge
2023-07-25T10:25:28Z
gzeon-c4 marked the issue as grade-a
#2 - c4-judge
2023-07-25T10:26:34Z
gzeon-c4 marked the issue as selected for report