Nouns Builder contest - GimelSec's results

A permissionless, governed protocol to deploy nouns-style DAOs complete with treasury, generative collections, and governance mechanisms.

General Information

Platform: Code4rena

Start Date: 06/09/2022

Pot Size: $90,000 USDC

Total HM: 33

Participants: 168

Period: 9 days

Judge: GalloDaSballo

Total Solo HM: 10

Id: 157

League: ETH

Nouns Builder

Findings Distribution

Researcher Performance

Rank: 64/168

Findings: 2

Award: $165.49

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: davidbrai

Also found by: Ch_301, Chom, GimelSec, PwnPatrol, cccz, datapunk, elad, pauliax, rbserver

Labels

bug
duplicate
2 (Med Risk)
old-submission-method

Awards

104.7173 USDC - $104.72

External Links

Lines of code

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/governance/governor/Governor.sol#L362-L364

Vulnerability details

Impact

Anyone can create a proposal if his/her voting weight is greater than or equal to the proposal threshold. But if the proposer's voting weight is equal to the threshold, anyone can cancel this proposal.

Proof of Concept

In propose function, it ensures voting weight is greater than or equal to the proposal threshold:

// Ensure the caller's voting weight is greater than or equal to the threshold if (getVotes(msg.sender, block.timestamp - 1) < proposalThreshold()) revert BELOW_PROPOSAL_THRESHOLD();

But if the proposer's voting weight is equal to the threshold, anyone can call cancel due to this condition:

// Ensure the caller is the proposer or the proposer's voting weight has dropped below the proposal threshold if (msg.sender != proposal.proposer && getVotes(proposal.proposer, block.timestamp - 1) > proposal.proposalThreshold) revert INVALID_CANCEL();

Because the proposer’s voting weight is equal to the proposal.proposalThreshold, it will not be reverted and call cancel successfully.

Tools Used

None

L363 should use >= rather than >:

if (msg.sender != proposal.proposer && getVotes(proposal.proposer, block.timestamp - 1) >= proposal.proposalThreshold) revert INVALID_CANCEL();

#0 - Chomtana

2022-09-19T07:50:12Z

Dup #589

Summary

We list 1 low-critical finding:

  • (Low) It’s better to define uint8 founderPct

(Low) It’s better to define uint8 founderPct

Impact

founderPct is defined as uint256, but it’s used for both uint8 and uint256.

Proof of Concept

founderPct is uint256 but is used by uin8: https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L82 https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L88

uint256 founderPct = _founders[i].ownershipPct; if ((totalOwnership += uint8(founderPct)) > 100) revert INVALID_FOUNDER_OWNERSHIP();

But L102 uint256 again: https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L102

uint256 schedule = 100 / founderPct;

Define uint8 rather than uint256 in L82.

#0 - GalloDaSballo

2022-09-26T21:35:55Z

(Low) It’s better to define uint8 founderPct

R

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