G-01: Public functions that could be declared external to save gas
Description
Following functions should be declared external, as functions that are never called by the contract internally should be declared external to save gas.
uint length = arr.length;
for (uint i; i < length; ++i) {
// Operations not effecting the length of the array.
}
G-04: Use unchecked {} primitive within for loops
Given the use of Solidity compiler >= 0.8.0, there are default arithmetic checks for mathematical operations which consume additional gas for such checks internally. In expressions where we are absolutely sure of no overflows/underflows, one can use the unchecked primitive to wrap such expressions to avoid checks and save gas.
Recommended mitigation steps
Adapt foor loops to increase index variable within unchecked block. e.g
for (uint256 i = 0; i < length;) {
// ...
unchecked { ++i; }
}
Gas Optimizations
Table of Contents
> 0
is less efficient than!= 0
for unsigned integersunchecked {}
primitive within for loopsG-01: Public functions that could be declared external to save gas
Description
Following functions should be declared
external
, as functions that are never called by the contract internally should be declared external to save gas.Findings
vaults/yVault/Controller.withdraw()\ vaults/yVault/yVault.setFarmingPool()
Recommended mitigation steps
Use the
external
attribute for functions never called from the contract.G-02:
> 0
is less efficient than!= 0
for unsigned integersDescription
!= 0 is a cheaper (less gas) operation for unsigned integers within
require
statements compared to> 0
.Findings
There are many occurrences of
> 0
withinrequire
statements in the following contracts:lock/JPEGLock.sol\ vaults/FungibleAssetVaultForDAO.sol\ vaults/yVault/strategies/StrategyPUSDConvex.sol\ vaults/yVault/yVault.sol\ vaults/NFTVault.sol\ staking/JPEGStaking.sol\ farming/yVaultLPFarming.sol\ farming/LPFarming.sol\
Recommended mitigation steps
Change
> 0
to!= 0
.G-03: An array's length should be cached to save gas in for-loops
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.
Findings
vaults/yVault/strategies/StrategyPUSDConvex.sol#L145\ vaults/yVault/strategies/StrategyPUSDConvex.sol#L319\ vaults/NFTVault.sol#L181\ vaults/NFTVault.sol#L184\ farming/LPFarming.sol#L348\
Recommended mitigation steps
G-04: Use
unchecked {}
primitive within for loopsGiven the use of Solidity compiler >= 0.8.0, there are default arithmetic checks for mathematical operations which consume additional gas for such checks internally. In expressions where we are absolutely sure of no overflows/underflows, one can use the
unchecked
primitive to wrap such expressions to avoid checks and save gas.Recommended mitigation steps
Adapt
foor
loops to increase index variable withinunchecked
block. e.gFindings
vaults/yVault/strategies/StrategyPUSDConvex.sol#L145\ vaults/yVault/strategies/StrategyPUSDConvex.sol#L231\ vaults/yVault/strategies/StrategyPUSDConvex.sol#L319\ vaults/NFTVault.sol#L181\ vaults/NFTVault.sol#L184\ farming/LPFarming.sol#L281\ farming/LPFarming.sol#L348\