code-423n4 / 2022-04-backd-findings

6 stars 4 forks source link

Gas Optimizations #143

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

gas 1. Title: Unnecessary lockAmount MSTORE

https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L43 Chacing 'lockAmount' into amountLeft is unnecessary since loading parameter var cost same gas fee as reading from memory and parameter value can be rewritten. Remove L43 and replace all LockAmount in the function:

    function lockFunds(
        address stakerVaultAddress,
        address payer,
        address token,
        uint256 lockAmount,
        uint256 depositAmount
    ) external {
        IStakerVault stakerVault = IStakerVault(stakerVaultAddress);

        // stake deposit amount
        if (depositAmount > 0) {
            depositAmount = depositAmount > lockAmount ? lockAmount : depositAmount;
            IERC20(token).safeTransferFrom(payer, address(this), depositAmount);
            IERC20(token).safeApprove(stakerVaultAddress, depositAmount);
            stakerVault.stake(depositAmount);
            stakerVault.increaseActionLockedBalance(payer, depositAmount);
            lockAmount -= depositAmount;
        }

        // use stake vault allowance if available and required
        if (lockAmount > 0) {
            uint256 balance = stakerVault.balanceOf(payer);
            uint256 allowance = stakerVault.allowance(payer, address(this));
            uint256 availableFunds = balance < allowance ? balance : allowance;
            if (availableFunds >= lockAmount) {
                stakerVault.transferFrom(payer, address(this), lockAmount);
                lockAmount = 0;
            }
        }

        require(lockAmount == 0, Error.INSUFFICIENT_UPDATE_BALANCE);
    }

2. Title: Tight variable packing in ExecuteLocalVars struct

https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L116-L140 By placing bool success near address underlying () can save 1 slot Change to:

    struct ExecuteLocalVars {
        uint256 minActionAmountToTopUp;
        uint256 actionTokenAmount;
        uint256 depositTotalFeesAmount;
        uint256 actionAmountWithFees;
        uint256 userFactor;
        uint256 rate;
        uint256 depositAmountWithFees;
        uint256 depositAmountWithoutFees;
        uint256 actionFee;
        uint256 totalActionTokenAmount;
        uint128 totalTopUpAmount;
        bytes topupResult;
        uint256 gasBankBalance;
        uint256 initialGas;
        uint256 gasConsumed;
        uint256 userGasPrice;
        uint256 estimatedRequiredGas;
        uint256 estimatedRequiredWeiForGas;
        uint256 requiredWeiForGas;
        uint256 reimbursedWeiForGas;
        address underlying;
        bool removePosition;
    bool success;
    }

3. Title: Using unchecked and prefix increment on i in for()

Occurence: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L188 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L456 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L479 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L891

Using unchecked and prefix increment is more effective for gas saving:

        for (uint256 i = 0; i < protocols.length;) {
            bytes32 protocolKey = _getProtocolKey(protocols[i]);
            _setConfig(protocolKey, handlers[i]);
            _updateTopUpHandler(protocols[i], address(0), handlers[i]);
    unchecked{++i;}
        }

4. Title: Using != is more efficient than >

https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L210 Using =! To validate that value is not zero is gas saving than >

        require(record.singleTopUpAmount != 0, Error.INVALID_AMOUNT);

5. Title: Using && in require() isn't effective

Occurrences: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L359-L363 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L676 Using multiple require instead of using && is cheaper for execution gas cost Change to:

        require(
            newSwapperSlippage >= _MIN_SWAPPER_SLIPPAGE &&,
            Error.INVALID_AMOUNT
        );
        require(
                newSwapperSlippage <= _MAX_SWAPPER_SLIPPAGE,
            Error.INVALID_AMOUNT
        );

6. Title: Initializing var with default value is gas consuming

Occurence: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L452 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L452 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L188 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L456 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L479 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L891 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/vault/Vault.sol#L135

By just declaring the var without set the value to 0 is gas effective

7. Title: Set function to external

https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/strategies/BkdTriHopCvx.sol#L136-L142 Some function can be set to external to be more effective for gas opt. Those function are not called inside the contract.