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: 125/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.6573 USDC - $16.66
Custom error from solidity 0.8.4 are cheaper than revert strings, custom error are defined using the error
statement can use inside and outside the contract.
source https://blog.soliditylang.org/2021/04/21/custom-errors/
i suggest replacing revert / require error strings with custom error.
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L73 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L74 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L81 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L82 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L83 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L90 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L100 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L114 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L117 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L134 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L149 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L152 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L155 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L159 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L174 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L122 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L123 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L124 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L125 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L128 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L132 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L136 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L140 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L133 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L134 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L135 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L136 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L139 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L143 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L147
require()
/revert()
strings longer than 32 bytes cost extra gasEach extra chunk of bytes past the original 32 which costs 3 gas.
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L117 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L205 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L303 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L314
he code should be refactored such that they no longer exist, or the block should do something useful,
such as emitting an event or reverting. If the contract is meant to be extended,
the contract should be abstract
and the function signatures be added without any default implementation.
If the block is an empty if-statement block to avoid doing subsequent checks in the else-if/else conditions,
the else-if/else conditions should be nested under the negation of the if-statement,
because they involve different classes of checks, which may lead to the introduction of errors when the code is
later modified (if(x){}else if(y){...}else{...}
=> if(!x){if(y){...}else{...}}
)
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L186 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOExecutor.sol#L188 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L1030
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOInterfaces.sol#L218 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOInterfaces.sol#L322 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L462
require()
statements that use && save gassee https://github.com/code-423n4/2022-01-xdefi-findings/issues/128 which describes the fact that there is a larger deployment gas cost, but with enough runtime calls, the change ends up being cheaper
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L127 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L131 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L135 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L139 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L640 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L657 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV2.sol#L678
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOProxy.sol#L95
save 6 gas per loop
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L281 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L319 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L346 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L371
You can get cheaper for loops (at least 25 gas, however can be up to 80 gas under certain conditions), by rewriting:
for (uint256 i = 0; i < orders.length; /** NOTE: Removed i++ **/ ) { // Do the thing // Unchecked pre-increment is cheapest unchecked { ++i; } }
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L281 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L319 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L346 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L371
uint256 i
Declaring uint256 i = 0;
means doing an MSTORE of the value 0 Instead you could just declare uint256 i
to declare the variable without assigning it’s default value, saving 3 gas per declaration
POC :
https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L281 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L319 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L346 https://github.com/code-423n4/2022-08-nounsdao/blob/main/contracts/governance/NounsDAOLogicV1.sol#L371