code-423n4 / 2022-10-juicebox-findings

2 stars 0 forks source link

Gas Optimizations #199

Open code423n4 opened 1 year ago

code423n4 commented 1 year ago

Gas Optimizations Report for Juicebox contest

Overview

During the audit, 6 gas issues were found.
Total savings ~2030.

Title Instance Count
G-1 Use unchecked blocks for incrementing i 7
G-2 Use unchecked blocks for subtractions where underflow is impossible 1
G-3 Use calldata instead of memory for read-only arguments 17
G-4 Use inline function for internal function called once 3
G-5 Cache state variables instead of reading them from storage multiple times 6
G-6 Use local variable cache instead of accessing mapping or array 1

Gas Optimizations Findings (6)

G-1. Use unchecked blocks for incrementing i

Description

In Solidity 0.8+, there’s a default overflow and underflow check on unsigned integers. In the loops, "i" will not overflow because the loop will run out of gas before that.

Instances
Recommendation

Change:

for (uint256 i; i < n; ++i) {
 // ...
}

to:

for (uint256 i; i < n;) { 
 // ...
 unchecked { ++i; }
}
Saved

This saves ~30-40 gas per iteration.
So, ~35*7 = 245

#

G-2. Use unchecked blocks for subtractions where underflow is impossible

Description

In Solidity 0.8+, there’s a default overflow and underflow check on unsigned integers. When an overflow or underflow isn’t possible (after require or if-statement), some gas can be saved by using unchecked blocks.

Instances
Saved

This saves ~35.
So, ~35*1 = 35

#

G-3. Use calldata instead of memory for read-only arguments

Description

Since Solidity v0.6.9, memory and calldata are allowed in all functions regardless of their visibility type (See "Calldata Variables" section here).
When function arguments should not be modified, it is cheaper to use calldata.

Instances
Recommendation

Use calldata where possible.

Saved

This saves at least 60 gas per iteration.
So, ~60*17 = 1020

#

G-4. Use inline function for internal function called once

Description

Function calls need two extra JUMP instructions and other stack operations.

Instances
Saved

This saves ~20-40. So, ~30*3 = 90

#

G-5. Cache state variables instead of reading them from storage multiple times

Description

Stack read is much cheaper than storage read.

Instances
Saved

This saves ~100.
So, ~100*6 = 600

#

G-6. Use local variable cache instead of accessing mapping or array multiple times

Description

It saves gas due to not having to perform the same key’s keccak256 hash and/or offset recalculation.

Instances
Saved

This saves ~40.
So, ~40*1 = 40

c4-judge commented 1 year ago

Picodes marked the issue as grade-b