code-423n4 / 2022-05-sturdy-findings

7 stars 3 forks source link

Gas Optimizations #143

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Solidity 6.12 you need to use safemath library and in newer version of solidity the compiler checks overflow/underflow which saves gas https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/CollateralAdapter.sol#L2 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L2 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/LidoVault.sol#L2

Make onlyadmin and initializer functions payable because it doesn't check msg.value == 0 because it saves gas https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/CollateralAdapter.sol#L37 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/CollateralAdapter.sol#L45 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L49 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L114 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L68 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L183 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/LidoVault.sol#L32 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L63 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L67 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L76 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L96 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L124

—------------------------------------------------------------------------------------------------------ Use revert instead of require statement and if you upgrade to 0.8.0 and up then gas is lower
https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L51 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L88 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L124 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L173 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L237 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L34 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L40 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L199 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/LidoVault.sol#L95 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/LidoVault.sol#L106 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/LidoVault.sol#L158 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L102 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L218

—---------------------------------------------------------------------------------------------------------------------------- https://docs.soliditylang.org/en/v0.8.13/abi-spec.html#:~:text=Through%20abi.,place%20and%20without%20the%20length. abi.encoded packed, packs the string to ? mayabe use bytes to save gas bec it's less than 32 bytes https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L60 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L59 —---------------------------------------------------------------------------------------------------------------------------- We can make this != because _vault fee cant be less than zero,uint256 internal _vaultFee This will save gas because it only needs to check for anything less than zero https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L95 ///@audit change >0 to != because its uint and is always greater or equal to zero require(yieldStAsset > 0, Errors.VT_PROCESS_YIELD_INVALID);

https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/LidoVault.sol#L40

Waste of variables in memory because we can just put it into function instead https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L97 yieldAmount=yieldAmount.sub(_processTreasury(_asset, yieldAmount)); this instead

you can get rid of baseRewardPool and just put the function inside function bec view function does not cast gas its just reading of blockchain but the variable is mstore https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L117 saves 6 gas mstore and mload just combine and save gas _transferYield(IRewards(IConvexBaseRewardPool(getBaseRewardPool()).extraRewards(i)).rewardToken()); https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L142 —-------------------------------------------- already returns uint8 no need for a extra variable 10**IERC20Detailed(internalAssetToken).decimals()

https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L159 address baseRewardPool = getBaseRewardPool(); IConvexBaseRewardPool(baseRewardPool).withdrawAndUnwrap(_amount, true); We can remove baseRewardPool and just put into the function https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L203 —---------------------------------------------------------------------------------------------------- ///@audit save gas by removing decimal varible bec it already returns a uint8 // uint256 decimal = IERC20Detailed(_asset).decimals();

  _amount = _amountToWithdraw.mul(this.pricePerShare()).div(10**IERC20Detailed(_asset).decimals());

Remove decimal variable https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L136 —--------------------------------------------------------------- uint256 yieldStAsset = _getYieldAmount(_stAsset); Waste of yieldstasset you can just return the function and put it into the line after https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L196 —---------------------------------------------------------- //uint256 treasuryStETH = _processTreasury(yieldStETH); yieldStETH = yieldStETH.sub(_processTreasury(yieldStETH)); You can just remove treasury stEth and save mstore and mload —--------------------------------- a waste of variable you can just use _amount or msg.value in the field assetAmount = msg.value; This it a waste just use msg.value and with the assetAmount you can get rid off because you can just use _amount —------------------------------------------------------- Instead of _amount just put it into the function // uint256 _amount = IERC20Detailed(asset).balanceOf(address(this)); _convertAssetToExchangeToken(asset, IERC20Detailed(asset).balanceOf(address(this)));

https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L132 uint256 _amount = _convertToStableCoin(assetYields[i].asset, assetYields[i].amount); // 3. deposit Yield to pool for suppliers _depositYield(assetYields[i].asset, _amount);

Take out _amount and just put that into _depositYield https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L145

—-------------------------------------------------------------------------------------------------------------------------- ++i costs less gas compared to i++ or i += 1 ++i costs less gas compared to i++ or i += 1 for unsigned integer, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled. i++ increments i and returns the initial value of i. Which means: uint i = 1; i++; // == 1 but i == 2 But ++i returns the actual incremented value: uint i = 1; ++i; // == 2 and i == 2 too, so no need for a temporary variable In the first case, the compiler has to create a temporary variable (when used) for returning 1 instead of 2

https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/ConvexCurveLPVault.sol#L137 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L238 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L127 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L141

make indexed for 3 fields if there are more than 3 fields https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L27 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L29 you can add 256-160 uint96 to this struct if you want without any gas cost https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/GeneralVault.sol#L49 https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L32

you can add 96 uint for free bec mapping starts a new slot and address takes up 160 bits out of 256 bits https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L45 make it _assetList array in memory bec of mappings isn't to bad for gas but its still a lot of gas of storage and its still in a function in a for loop, find way to not use it for a memory variable at least address asset = _assetsList[_offset + i]; https://github.com/code-423n4/2022-05-sturdy/blob/6cc44472f6321d0be6844d6fe7fbd7b78d7602a9/smart-contracts/YieldManager.sol#L129

make it default variable of zero and not initialized the variable to save gas becuase this var is only assigned after and its assignment now is doesn't need it bec it's already a variable in use Also because _totalYieldAmount is used in the math calculation only. uint256 extraYieldAmount = _totalYieldAmount;