Platform: Code4rena
Start Date: 25/08/2022
Pot Size: $75,000 USDC
Total HM: 35
Participants: 147
Period: 7 days
Judge: 0xean
Total Solo HM: 15
Id: 156
League: ETH
Rank: 134/147
Findings: 1
Award: $32.58
๐ Selected for report: 0
๐ Solo Findings: 0
๐ Selected for report: pfapostol
Also found by: 0x040, 0x1f8b, 0x85102, 0xDjango, 0xNazgul, 0xNineDec, 0xSmartContract, 0xkatana, Amithuddar, Aymen0909, Bnke0x0, CertoraInc, Chandr, CodingNameKiki, Deivitto, Dionysus, Diraco, ElKu, Fitraldys, Funen, GalloDaSballo, Guardian, IllIllI, JC, JansenC, Jeiwan, LeoS, Metatron, Noah3o6, RaymondFam, ReyAdmirado, Rohan16, RoiEvenHaim, Rolezn, Ruhum, Saintcode_, Shishigami, Sm4rty, SooYa, StevenL, Tagir2003, The_GUILD, TomJ, Tomo, Waze, __141345__, ajtra, apostle0x01, aviggiano, bobirichman, brgltd, c3phas, cRat1st0s, carlitox477, cccz, ch0bu, chrisdior4, d3e4, delfin454000, djxploit, durianSausage, erictee, exolorkistis, fatherOfBlocks, gogo, grGred, hyh, ignacio, jag, karanctf, kris, ladboy233, lukris02, m_Rassska, martin, medikko, natzuu, ne0n, newfork01, oyc_109, peiw, rbserver, ret2basic, robee, rokinot, rvierdiiev, sikorico, simon135, tnevler, zishansami
32.5835 DAI - $32.58
++i costs about 5 gas less per iteration compared to i++ for unsigned integer. Same thing for decremental with -- operator. This statement is true even with the optimizer enabled. Summarized my results where i is used in a loop, is unsigned integer, and you safely can be changed to ++i without changing any behavior,
** Most places are using best practice (++i and unchecked where possible) - good job Yet I've found 5 locations that can do better:
src/policies/Operator.sol: 487 price_ = price_ / 10; 488: decimals++; 489 } 669 _status.low.observations[regen.nextObservation] = true; 670: _status.low.count++; 671 } 674 _status.low.observations[regen.nextObservation] = false; 675: _status.low.count--; 676 } 685 _status.high.observations[regen.nextObservation] = true; 686: _status.high.count++; 687 } 690 _status.high.observations[regen.nextObservation] = false; 691: _status.high.count--; 692 }
An arrayโs length should be cached to save gas in for-loops Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset). Caching the array length in the stack saves around 3 gas per iteration.
I've found only 1 location to improve:
src/policies/Governance.sol: 277 278: for (uint256 step; step < instructions.length; ) { 279 kernel.executeAction(instructions[step].action, instructions[step].target);
If a variable is not set/initialized, it is assumed to have the default value 0 for uint, and false for boolean.
Explicitly initializing it with its default value is an anti-pattern and wastes gas.
For example: uint8 i = 0;
should be replaced with uint8 i;
I've found 3 locations in 2 files:
src/Kernel.sol: 396 uint256 reqLength = requests_.length; 397: for (uint256 i = 0; i < reqLength; ) { 398 Permissions memory request = requests_[i]; src/utils/KernelUtils.sol: 42 43: for (uint256 i = 0; i < 5; ) { 44 bytes1 char = unwrapped[i]; 57 58: for (uint256 i = 0; i < 32; ) { 59 bytes1 char = unwrapped[i];
!= 0 costs less gas compared to > 0 for unsigned integers even when optimizer enabled All of the following findings are uint (E&OE) so >0 and != have exactly the same effect. ** saves 6 gas ** each
I've found only 1 place to improve - good job on all other uses of !=
src/policies/Governance.sol: 246 247: if (userVotesForProposal[activeProposal.proposalId][msg.sender] > 0) { 248 revert UserAlreadyVoted();
Across the whole solution, the declared pragma is 0.8.15 (good!) Upgrading to 0.8.16 may result in lower gas uses.
Source:
According to the release note of 0.8.16: https://blog.soliditylang.org/2022/08/08/solidity-0.8.16-release-announcement/ ".. there are several minor bug fixes and improvements like more gas-efficient overflow checks for addition and subtraction."