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
Rank: 132/160
Findings: 1
Award: $16.66
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x040, 0x1f8b, 0xDjango, 0xNazgul, 0xNineDec, 0xSmartContract, 0xbepresent, 0xc0ffEE, 0xkatana, 2997ms, ACai, Amithuddar, Aymen0909, Ben, BipinSah, Bjorn_bug, Bnke0x0, CertoraInc, Ch_301, Chom, CodingNameKiki, Deivitto, DevABDee, DimitarDimitrov, Diraco, Dravee, ElKu, EthLedger, Fitraldys, Funen, GalloDaSballo, GimelSec, Guardian, IgnacioB, JC, JohnSmith, Junnon, KIntern_NA, Lambda, LeoS, Noah3o6, Olivierdem, Polandia94, R2, Randyyy, RaymondFam, Respx, ReyAdmirado, Rohan16, RoiEvenHaim, Rolezn, Ruhum, SaharAP, Saintcode_, SerMyVillage, Shishigami, Sm4rty, SooYa, TomJ, Tomio, Tomo, Waze, Yiko, _Adam, __141345__, a12jmx, ajtra, ak1, bobirichman, brgltd, bulej93, c3phas, cRat1st0s, carlitox477, catchup, ch0bu, d3e4, delfin454000, djxploit, durianSausage, erictee, exolorkistis, fatherOfBlocks, francoHacker, gogo, hyh, ignacio, jag, joestakey, karanctf, ladboy233, lucacez, lukris02, m_Rassska, martin, medikko, mics, mrpathfindr, natzuu, newfork01, oyc_109, pauliax, peritoflores, pfapostol, prasantgupta52, rbserver, ret2basic, rfa, robee, rokinot, rotcivegaf, rvierdiiev, sach1r0, saian, samruna, seyni, shark, shr1ftyy, sikorico, simon135, sryysryy, tay054, tnevler, wagmi, zishansami
16.6568 USDC - $16.66
for
and use unchecked
for incrementIn NounsDAOLogicV1.sol: L281, L319, L346, L371 In NounsDAOLogicV2.sol: L292, L330, L357, L382
From:
for (uint256 i; i < array.length; i++) { ... }
To:
uint256 arrayLength = array.length; for (uint256 i; i < arrayLength;) { ... unchecked { ++i; } }
msg.sender != address(0)
it's redundantid
in the Proposal
and ProposalCondensed
structs it's redundantTo simplify code and save gas, remove the id of the structs
In NounsDAOInterfaces.sol file remove the lines: L175-L176, L275-L276, L369-L370
In NounsDAOLogicV1 contract change L216-L267:
- proposalCount++; - Proposal storage newProposal = proposals[proposalCount]; + uint256 _proposalCount = ++proposalCount; + Proposal storage newProposal = proposals[_proposalCount]; - newProposal.id = proposalCount; newProposal.proposer = msg.sender; newProposal.proposalThreshold = temp.proposalThreshold; newProposal.quorumVotes = bps2Uint(quorumVotesBPS, temp.totalSupply); newProposal.eta = 0; newProposal.targets = targets; newProposal.values = values; newProposal.signatures = signatures; newProposal.calldatas = calldatas; newProposal.startBlock = temp.startBlock; newProposal.endBlock = temp.endBlock; newProposal.forVotes = 0; newProposal.againstVotes = 0; newProposal.abstainVotes = 0; newProposal.canceled = false; newProposal.executed = false; newProposal.vetoed = false; - latestProposalIds[newProposal.proposer] = newProposal.id; + latestProposalIds[newProposal.proposer] = _proposalCount; /// @notice Maintains backwards compatibility with GovernorBravo events emit ProposalCreated( - newProposal.id, + _proposalCount, msg.sender, targets, values, signatures, calldatas, newProposal.startBlock, newProposal.endBlock, description ); /// @notice Updated event with `proposalThreshold` and `quorumVotes` emit ProposalCreatedWithRequirements( - newProposal.id, + _proposalCount, msg.sender, targets, values, signatures, calldatas, newProposal.startBlock, newProposal.endBlock, newProposal.proposalThreshold, newProposal.quorumVotes, description ); - return newProposal.id; + return _proposalCount;
In NounsDAOLogicV2 contract
- proposalCount++; - Proposal storage newProposal = _proposals[proposalCount]; - newProposal.id = proposalCount; + uint256 _proposalCount = ++proposalCount; + Proposal storage newProposal = _proposals[_proposalCount]; newProposal.proposer = msg.sender; newProposal.proposalThreshold = temp.proposalThreshold; newProposal.eta = 0; newProposal.targets = targets; newProposal.values = values; newProposal.signatures = signatures; newProposal.calldatas = calldatas; newProposal.startBlock = temp.startBlock; newProposal.endBlock = temp.endBlock; newProposal.forVotes = 0; newProposal.againstVotes = 0; newProposal.abstainVotes = 0; newProposal.canceled = false; newProposal.executed = false; newProposal.vetoed = false; newProposal.totalSupply = temp.totalSupply; newProposal.creationBlock = block.number; - latestProposalIds[newProposal.proposer] = newProposal.id; + latestProposalIds[newProposal.proposer] = _proposalCount; /// @notice Maintains backwards compatibility with GovernorBravo events emit ProposalCreated( - newProposal.id, + _proposalCount, msg.sender, targets, values, signatures, calldatas, newProposal.startBlock, newProposal.endBlock, description ); /// @notice Updated event with `proposalThreshold` and `minQuorumVotes` /// @notice `minQuorumVotes` is always zero since V2 introduces dynamic quorum with checkpoints emit ProposalCreatedWithRequirements( - newProposal.id, + _proposalCount, msg.sender, targets, values, signatures, calldatas, newProposal.startBlock, newProposal.endBlock, newProposal.proposalThreshold, minQuorumVotes(), description ); - return newProposal.id; + return _proposalCount;
- } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < quorumVotes(proposal.id)) { + } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < quorumVotes(proposalId)) {
- id: proposal.id, proposer: proposal.proposer, proposalThreshold: proposal.proposalThreshold, - quorumVotes: quorumVotes(proposal.id), + quorumVotes: quorumVotes(proposalId),
implementation_
to save SLOAD gasIn NounsDAOProxy.sol#L85 use implementation_
instead of implementation
:
emit NewImplementation(oldImplementation, implementation_);