Platform: Code4rena
Start Date: 01/07/2022
Pot Size: $75,000 USDC
Total HM: 17
Participants: 105
Period: 7 days
Judge: Jack the Pug
Total Solo HM: 5
Id: 143
League: ETH
Rank: 90/105
Findings: 1
Award: $38.24
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xA5DF
Also found by: 0v3rf10w, 0x09GTO, 0x1f8b, 0x29A, 0xDjango, 0xKitsune, 0xNazgul, 0xdanial, 0xf15ers, Aymen0909, Bnke0x0, Ch_301, Cheeezzyyyy, Chom, ElKu, Funen, Hawkeye, IllIllI, JC, JohnSmith, Kaiziron, Lambda, Limbooo, Meera, Metatron, MiloTruck, Noah3o6, Picodes, Randyyy, RedOneN, ReyAdmirado, Rohan16, Saintcode_, Sm4rty, TomJ, Tomio, Tutturu, UnusualTurtle, Waze, _Adam, __141345__, ajtra, apostle0x01, asutorufos, brgltd, c3phas, cRat1st0s, codexploder, defsec, delfin454000, djxploit, durianSausage, exd0tpy, fatherOfBlocks, hake, horsefacts, ignacio, jayfromthe13th, joestakey, jonatascm, kaden, kebabsec, m_Rassska, mektigboy, mrpathfindr, oyc_109, rajatbeladiya, rbserver, rfa, robee, sach1r0, sashik_eth, simon135
38.2406 USDC - $38.24
The current flow assigns _claimedTokensToBurn to 0 when _claimedBalance == 0, since _claimedTokensToBurn is already 0 by default this can be avoided, saving about 10 gas on average.
There is 1 instance of this issue
Current implementation:
if (_claimedBalance == 0) _claimedTokensToBurn = 0; else if (_preferClaimedTokens) _claimedTokensToBurn = _claimedBalance < _amount ? _claimedBalance : _amount; else _claimedTokensToBurn = _unclaimedBalance < _amount ? _amount - _unclaimedBalance : 0;
Proposed change:
if (_claimedBalance != 0) { if (_preferClaimedTokens) _claimedTokensToBurn = _claimedBalance < _amount ? _claimedBalance : _amount; else _claimedTokensToBurn = _unclaimedBalance < _amount ? _amount - _unclaimedBalance : 0; }
Both implementations should be functionally identical but the proposed change is very slightly cheaper and improves readability.
This saves about 100 gas per warm storage read.
There are 3 instances of this issue in JBTokenStore.sol:
There is 1 instances of this issue in JBSingleTokenPaymentTerminalStore.sol:
balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId]
can be stored in memory to avoid 1 storage read. Affected lines: L589 and L599Caching the length in memory instead of reading from storage on each iteration of the loop saves about 100 gas per iteration due to avoiding a warm storage read.
There is 1 instance of this issue in JBDirectory.sol on line 139
Current implementation:
for (uint256 _i; _i < _terminalsLength; _i++) {
Proposed implementation:
uint256 _terminalsLength = _terminalsOf[_projectId].length; for (uint256 _i; _i < _terminalsLength; _i++) {
Using unchecked when incrementing a value that can't realistically underflow or overflow reduces gas cost. Since _discountMultiple cannot realistically overflow, this should be safe to do.
There is 1 instance of this issue in JBFundingCycleStore.sol on line 724-734
Current implementation:
for (uint256 i = 0; i < _discountMultiple; i++) { weight = PRBMath.mulDiv( weight, JBConstants.MAX_DISCOUNT_RATE - _baseFundingCycle.discountRate, JBConstants.MAX_DISCOUNT_RATE ); if (weight == 0) break; }
Proposed implementation:
for (uint256 i = 0; i < _discountMultiple;) { weight = PRBMath.mulDiv( weight, JBConstants.MAX_DISCOUNT_RATE - _baseFundingCycle.discountRate, JBConstants.MAX_DISCOUNT_RATE ); if (weight == 0) break; unchecked { ++i; } }