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: 83/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
10e18
instead of 10**18
File Name | SHA-1 Hash |
---|---|
juice-contracts-v2-code4rena/contracts/JBController.sol | c5960f87c250fe3c23c2d1bc3e5af1fe92df0c93 |
juice-contracts-v2-code4rena/contracts/JBDirectory.sol | 366c0456a93cb33810bd51e4e19619b00e69cb95 |
juice-contracts-v2-code4rena/contracts/JBFundingCycleStore.sol | 0c2234d2f6dd49808c2e97d660cd5c1b1f6d7e29 |
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol | 113adeb8f54af7cad12173e59a712d953b00c026 |
juice-contracts-v2-code4rena/contracts/JBSingleTokenPaymentTerminalStore.sol | 93d8e77bd32261e14e79f1a6e1790f515d9058e2 |
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol | 05d0633d4ca9bf92d16a61d112a38377a365ff86 |
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol | d3cd0735082037a1249606c06514b3f4a52b5153 |
Pre-increments cost less gas compared to post-increments.
juice-contracts-v2-code4rena/contracts/JBController.sol::913 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBController.sol::1014 => for (uint256 _i; _i < _fundAccessConstraints.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::139 => for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) {
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::167 => for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++)
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::275 => for (uint256 _i; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::276 => for (uint256 _j = _i + 1; _j < _terminals.length; _j++)
juice-contracts-v2-code4rena/contracts/JBFundingCycleStore.sol::724 => for (uint256 i = 0; i < _discountMultiple; i++) {
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::85 => for (uint256 _i = 0; _i < _permissionIndexes.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::135 => for (uint256 _i = 0; _i < _operatorData.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSingleTokenPaymentTerminalStore.sol::862 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::165 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::204 => for (uint256 _i = 0; _i < _currentSplits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::211 => for (uint256 _j = 0; _j < _splits.length; _j++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::229 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::304 => for (uint256 _i = 0; _i < _splitCount; _i++) {
Change i++
to ++i
.
VS Code
In Solidity 0.8+, there’s a default overflow check on unsigned integers.
juice-contracts-v2-code4rena/contracts/JBController.sol::913 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBController.sol::1014 => for (uint256 _i; _i < _fundAccessConstraints.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::139 => for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) {
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::167 => for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++)
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::275 => for (uint256 _i; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::276 => for (uint256 _j = _i + 1; _j < _terminals.length; _j++)
juice-contracts-v2-code4rena/contracts/JBFundingCycleStore.sol::724 => for (uint256 i = 0; i < _discountMultiple; i++) {
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::85 => for (uint256 _i = 0; _i < _permissionIndexes.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::135 => for (uint256 _i = 0; _i < _operatorData.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSingleTokenPaymentTerminalStore.sol::862 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::165 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::204 => for (uint256 _i = 0; _i < _currentSplits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::211 => for (uint256 _j = 0; _j < _splits.length; _j++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::229 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::304 => for (uint256 _i = 0; _i < _splitCount; _i++) {
One example is the code would go from:
for (uint i = 0; i < _prices.length; i++) { priceAverageCumulative += _prices[i]; }
to:
for (uint i = 0; i < _prices.length;) { priceAverageCumulative += _prices[i]; unchecked { i++; } }
VS Code
If a variable is not set/initialized, it is assumed to have the default value (0
, false
, 0x0
etc depending on the data type). If you explicitly initialize it with its default value, you are just wasting gas.
juice-contracts-v2-code4rena/contracts/JBController.sol::913 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBFundingCycleStore.sol::724 => for (uint256 i = 0; i < _discountMultiple; i++) {
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::85 => for (uint256 _i = 0; _i < _permissionIndexes.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::135 => for (uint256 _i = 0; _i < _operatorData.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSingleTokenPaymentTerminalStore.sol::862 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::165 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::204 => for (uint256 _i = 0; _i < _currentSplits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::211 => for (uint256 _j = 0; _j < _splits.length; _j++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::229 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::304 => for (uint256 _i = 0; _i < _splitCount; _i++) {
juice-contracts-v2-code4rena/contracts/JBPayoutRedemptionPaymentTerminal.sol::594 => for (uint256 _i = 0; _i < _heldFeeLength; ) {
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1008 => for (uint256 _i = 0; _i < _splits.length; ) {
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1396 => for (uint256 _i = 0; _i < _heldFeesLength; ) {
Do not initialize variables with default values.
VS Code
Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack. Caching the array length in the stack saves around 3 gas per iteration.
juice-contracts-v2-code4rena/contracts/JBController.sol::913 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBController.sol::1014 => for (uint256 _i; _i < _fundAccessConstraints.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::139 => for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++) {
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::167 => for (uint256 _i; _i < _terminalsOf[_projectId].length; _i++)
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::275 => for (uint256 _i; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBDirectory.sol::276 => for (uint256 _j = _i + 1; _j < _terminals.length; _j++)
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::85 => for (uint256 _i = 0; _i < _permissionIndexes.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBOperatorStore.sol::135 => for (uint256 _i = 0; _i < _operatorData.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSingleTokenPaymentTerminalStore.sol::862 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::165 => for (uint256 _i = 0; _i < _terminals.length; _i++)
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::204 => for (uint256 _i = 0; _i < _currentSplits.length; _i++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::211 => for (uint256 _j = 0; _j < _splits.length; _j++) {
juice-contracts-v2-code4rena/contracts/JBSplitsStore.sol::229 => for (uint256 _i = 0; _i < _splits.length; _i++) {
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1008 => for (uint256 _i = 0; _i < _splits.length; ) {
Storing the array's length in a variable before the for-loop, and use it instead.
VS Code
variable1 += variable2
costs more gas than variable1 = variable1 + variable2
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::860 => _feeEligibleDistributionAmount += _leftoverDistributionAmount;
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1038 => feeEligibleDistributionAmount += _payoutAmount;
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1103 => feeEligibleDistributionAmount += _payoutAmount;
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1145 => feeEligibleDistributionAmount += _payoutAmount;
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1401 => refundedFees += _feeAmount(
juice-contracts-v2-code4rena/contracts/abstract/JBPayoutRedemptionPaymentTerminal.sol::1417 => refundedFees += _feeAmount(leftoverAmount, _heldFees[_i].fee, _heldFees[_i].feeDiscount);
Use variable1 = variable1 + variable2
instead.
VS Code
10e18
instead of 10**18
10e18
is more gas efficient than 10**18
juice-contracts-v2-code4rena/contracts/JBSingleTokenPaymentTerminalStore.sol ::868 => : PRBMath.mulDiv(_ethOverflow, 10**18, prices.priceFor(JBCurrencies.ETH, _currency, 18));_leftoverDistributionAmount;
Use 10e18
instead.
VS Code