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: 81/105
Findings: 1
Award: $38.83
🌟 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.8282 USDC - $38.83
unchecked
block can be used for gas efficiency of the expression that can't overflow/underflowuint256 _discountMultiple = _startDistance / _baseFundingCycle.duration;
_baseFundingCycle.duration > 0
due to check on L704.
if (reclaimAmount > 0) balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId] = balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId] - reclaimAmount;
Can't underflow due to check on L514.
balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId] = balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId] - distributedAmount;
Can't underflow due to check on L589.
return _balanceOf > _distributionLimitRemaining ? _balanceOf - _distributionLimitRemaining : 0;
Can't underflow due to statement logic.
else _claimedTokensToBurn = _unclaimedBalance < _amount ? _amount - _unclaimedBalance : 0;
Can't underflow due to statement logic.
unclaimedBalanceOf[_holder][_projectId] = unclaimedBalanceOf[_holder][_projectId] - _amount;
Can't underflow due to check on L406.
unclaimedBalanceOf[_holder][_projectId] = unclaimedBalanceOf[_holder][_projectId] - _amount;
Can't underflow due to check on L445.
Counter i++
in for
loop could be unchecked
when it cann't overflow:
contracts/JBController.sol:913 for (uint256 _i = 0; _i < _splits.length; _i++) { contracts/JBController.sol:1014 for (uint256 _i; _i < _fundAccessConstraints.length; _i++) { contracts/JBDirectory.sol:139 for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) { contracts/JBDirectory.sol:167 for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) contracts/JBDirectory.sol:275 for (uint256 _i; _i < _terminals.length; _i++) contracts/JBDirectory.sol:276 for (uint256 _j = _i + 1; _j < _terminals.length; _j++) contracts/JBFundingCycleStore.sol:724 for (uint256 i = 0; i < _discountMultiple; i++) { contracts/JBOperatorStore.sol:85 for (uint256 _i = 0; _i < _permissionIndexes.length; _i++) { contracts/JBOperatorStore.sol:135 for (uint256 _i = 0; _i < _operatorData.length; _i++) { contracts/JBOperatorStore.sol:165 for (uint256 _i = 0; _i < _indexes.length; _i++) { contracts/JBSingleTokenPaymentTerminalStore.sol:862 for (uint256 _i = 0; _i < _terminals.length; _i++) contracts/JBSplitsStore.sol:204 for (uint256 _i = 0; _i < _currentSplits.length; _i++) { contracts/JBSplitsStore.sol:211 for (uint256 _j = 0; _j < _splits.length; _j++) { contracts/JBSplitsStore.sol:229 for (uint256 _i = 0; _i < _splits.length; _i++) { contracts/JBSplitsStore.sol:304 for (uint256 _i = 0; _i < _splitCount; _i++) {
Prefix increment is cheaper than postfix increment. Consider using ++i in next lines:
contracts/JBController.sol:913 for (uint256 _i = 0; _i < _splits.length; _i++) { contracts/JBController.sol:1014 for (uint256 _i; _i < _fundAccessConstraints.length; _i++) { contracts/JBDirectory.sol:139 for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) { contracts/JBDirectory.sol:167 for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) contracts/JBDirectory.sol:275 for (uint256 _i; _i < _terminals.length; _i++) contracts/JBDirectory.sol:276 for (uint256 _j = _i + 1; _j < _terminals.length; _j++) contracts/JBFundingCycleStore.sol:724 for (uint256 i = 0; i < _discountMultiple; i++) { contracts/JBOperatorStore.sol:85 for (uint256 _i = 0; _i < _permissionIndexes.length; _i++) { contracts/JBOperatorStore.sol:135 for (uint256 _i = 0; _i < _operatorData.length; _i++) { contracts/JBOperatorStore.sol:165 for (uint256 _i = 0; _i < _indexes.length; _i++) { contracts/JBSingleTokenPaymentTerminalStore.sol:862 for (uint256 _i = 0; _i < _terminals.length; _i++) contracts/JBSplitsStore.sol:204 for (uint256 _i = 0; _i < _currentSplits.length; _i++) { contracts/JBSplitsStore.sol:211 for (uint256 _j = 0; _j < _splits.length; _j++) { contracts/JBSplitsStore.sol:229 for (uint256 _i = 0; _i < _splits.length; _i++) { contracts/JBSplitsStore.sol:304 for (uint256 _i = 0; _i < _splitCount; _i++) {
for
loopsReading storage array length inside for
loop costs more gas than reading its cached value.
contracts/JBDirectory.sol:139 for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) { contracts/JBDirectory.sol:167 for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++)
For the storage variables that will be accessed multiple times, cache and read from the stack can save gas from each read if variable accessed more than once:
contracts/JBDirectory.sol:135 isTerminalOf(_projectId, _primaryTerminalOf[_projectId][_token]) // 2 SLOADs _primaryTerminalOf contracts/JBDirectory.sol:231 controllerOf[_projectId] != address(0) && // 2 SLOADs controllerOf