Platform: Code4rena
Start Date: 01/08/2022
Pot Size: $50,000 USDC
Total HM: 26
Participants: 133
Period: 5 days
Judge: Jack the Pug
Total Solo HM: 6
Id: 151
League: ETH
Rank: 125/133
Findings: 1
Award: $21.72
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: c3phas
Also found by: 0x040, 0x1f8b, 0xA5DF, 0xNazgul, 0xSmartContract, 0xSolus, 0xc0ffEE, 0xkatana, 0xsam, 8olidity, Aymen0909, Bnke0x0, CertoraInc, Chinmay, Chom, CodingNameKiki, Deivitto, Dravee, ElKu, Extropy, Fitraldys, Funen, GalloDaSballo, Guardian, IllIllI, JC, Lambda, MEP, Metatron, MiloTruck, Noah3o6, NoamYakov, PaludoX0, ReyAdmirado, Rohan16, Rolezn, Ruhum, Sm4rty, SooYa, TomJ, Tomio, Waze, _Adam, __141345__, a12jmx, ajtra, ak1, apostle0x01, asutorufos, ballx, benbaessler, bharg4v, bobirichman, brgltd, cryptonue, defsec, delfin454000, dharma09, djxploit, durianSausage, eierina, erictee, fatherOfBlocks, gerdusx, gogo, hake, hyh, ignacio, jag, kaden, kyteg, lucacez, mics, minhquanym, oyc_109, pfapostol, rbserver, ret2basic, robee, rokinot, sach1r0, saian, samruna, scaraven, sikorico, simon135, supernova, teddav, tofunmi, zeesaw
21.7225 USDC - $21.72
Explicitly initializing a variable with it's default value costs unnecesary gas.
contracts/Community.sol::624 => for (uint256 i = 0; i < _communities[_communityID].memberCount; i++) { contracts/HomeFiProxy.sol::87 => for (uint256 i = 0; i < _length; i++) { contracts/HomeFiProxy.sol::136 => for (uint256 i = 0; i < _length; i++) { contracts/Project.sol::248 => for (uint256 i = 0; i < _length; i++) { contracts/Project.sol::311 => for (uint256 i = 0; i < _length; i++) { contracts/Project.sol::322 => for (uint256 i = 0; i < _length; i++) { contracts/libraries/Tasks.sol::181 => for (uint256 i = 0; i < _length; i++) _alerts[i] = _self.alerts[i];
Caching the array length outside a loop saves reading it on each iteration, as long as the array's length is not changed during the loop.
./contracts/Project.sol:603: for (; i < _changeOrderedTask.length; i++) {
When dealing with unsigned integer types, comparisons with != 0 are cheaper then with > 0.
contracts/Community.sol::764 => require(_repayAmount > 0, "Community::!repay"); contracts/Project.sol::195 => require(_cost > 0, "Project::!value>0");
In Solidity 0.8+, there's a default overflow check on unsigned integers. It's possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline.
Instances include:
./contracts/HomeFiProxy.sol:87: for (uint256 i = 0; i < _length; i++) { ./contracts/HomeFiProxy.sol:136: for (uint256 i = 0; i < _length; i++) { ./contracts/Project.sol:248: for (uint256 i = 0; i < _length; i++) { ./contracts/Project.sol:311: for (uint256 i = 0; i < _length; i++) { ./contracts/Project.sol:322: for (uint256 i = 0; i < _length; i++) { ./contracts/Project.sol:603: for (; i < _changeOrderedTask.length; i++) { ./contracts/Community.sol:624: for (uint256 i = 0; i < _communities[_communityID].memberCount; i++) { ./contracts/libraries/Tasks.sol:181: for (uint256 i = 0; i < _length; i++)
The code would go from:
for (uint256 i = 0; i < _length; i++) { // ... }
to:
for (uint256 i = 0; i < _length;) { // ... unchecked { ++i; } }
The risk of overflow is inexistant for a uint256 here.