Closed code423n4 closed 1 year ago
0xSorryNotSorry marked the issue as primary issue
This is by design, not an issue. We want to allow the DAO to set any value it wants to set; at the edges zero means the DAO wants any single forking token to create its own fork DAO, while at the other edge over 10K it means the DAO decides to turn this feature off.
And let's say we added such hard-coded limits, if a majority agrees to go outside those bounds they can simply upgrade the DAO logic to fit their needs.
Not an issue for us.
eladmallel marked the issue as sponsor disputed
gzeon-c4 marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/nounsDAO/nouns-monorepo/blob/718211e063d511eeda1084710f6a682955e80dcb/packages/nouns-contracts/contracts/governance/NounsDAOV3Admin.sol#L551-L558 https://github.com/nounsDAO/nouns-monorepo/blob/718211e063d511eeda1084710f6a682955e80dcb/packages/nouns-contracts/contracts/governance/NounsDAOLogicV3.sol#L802-L804
Vulnerability details
Impact
Nouns Fork is a Last-Resort Minority Protection Mechanism, created to protect the minority from the tyranny of the majority. As described in this article: https://mirror.xyz/0x10072dfc23771101dC042fD0014f263316a6E400/iN0FKOn_oYVBzlJkwPwK2mhzaeL8K2-W80u82F7fHj8.
In the initial case, if a quorum of 20% of tokens signals to exit, the fork will succeed, but since the system has no reasonable limit to the maximum or minimum value of the fork threshold, the majority can initiate a new proposal to improve the fork Threshold value, for example: 90% or even 100%.
As a result, those who support the fork can never reach the fork threshold. In this case, the fork of DAO will never happen, and the design mechanism to protect the minority from the tyranny of the majority cannot be achieved.
Proof of Concept
Among them,
ds.forkThresholdBPS
is the core parameter for calculating whether DAO has reached the fork threshold, and the calculation code for the fork threshold is:(adjustedTotalSupply(ds) * ds.forkThresholdBPS) / 10_000;
, if the value ofds.forkThresholdBPS
The value is set to 10000 or higher, which can raise the fork threshold to an unreachable height.ds.forkThresholdBPS
to 10000 or higher. Because the majority firmly holds the right to cast the majority of votes, even if a few people object, the proposal will still be easily passed and implemented according to the normal process.Proposal initiation parameter reference:
Tools Used
Visual Studio Code Foundry
Recommended Mitigation Steps
Add two constants in the NounsDAOV3Admin.sol file, such as
Then in the
_setForkThresholdBPS
function, add the verification of the incoming parameternewForkThresholdBPS
, such as the following code:Note:
MAX_FORK_THRESHOLD_BPS = 4000;
only represents personal opinion, and ultimately depends on what percentage of people NounsDao wants to protect. It is recommended that the maximum value should not exceed 4900, which is 49% proportionally.Why set a minimum value? This is because when
ds.forkThresholdBPS
is too low (for example: 0), then only 1 token is needed to fork the DAO. Once the fork occurs, it cannot be canceled. During the fork, the original DAO's proposal will not be executed, and malicious actors may use this mechanism to launch a DOS attack on the system's proposal.Assessed type
Other