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

6 stars 4 forks source link

Gas Optimizations #202

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Gas

Use unchecked decrement in while loop

The while loop inside BkdLocker#executeUnlocks can safely use an unchecked decrement.

Impact: 63 gas per loop iteration.

BkdLocker#executeUnlocks

        require(length > 0, "No entries");
        uint256 i = length;
        while (i > 0) {
            i = i - 1;
            if (stashedWithdraws[i].releaseTime <= block.timestamp) {
                totalAvailableToWithdraw += stashedWithdraws[i].amount;

                stashedWithdraws[i] = stashedWithdraws[stashedWithdraws.length - 1];

                stashedWithdraws.pop();
            }
        }

Using unchecked decrement:

        require(length > 0, "No entries");
        uint256 i = length;
        while (i > 0) {
            unchecked { i = i - 1; }
            if (stashedWithdraws[i].releaseTime <= block.timestamp) {
                totalAvailableToWithdraw += stashedWithdraws[i].amount;

                stashedWithdraws[i] = stashedWithdraws[stashedWithdraws.length - 1];

                stashedWithdraws.pop();
            }
        }

Use unchecked math in StakerVault#transferFrom

Since earlier require statements in StakerVault#transferFrom ensure that startingAllowance and srcTokens are >= the specified transfer amount, subtraction to calculate new allowance and balance can be performed safely using unchecked math.

Impact: 190 gas.

StakerVault#transferFrom:

        require(startingAllowance >= amount, Error.INSUFFICIENT_BALANCE);

        uint256 srcTokens = balances[src];
        require(srcTokens >= amount, Error.INSUFFICIENT_BALANCE);

        address lpGauge = currentAddresses[_LP_GAUGE];
        if (lpGauge != address(0)) {
            ILpGauge(lpGauge).userCheckpoint(src);
            ILpGauge(lpGauge).userCheckpoint(dst);
        }
        ILiquidityPool pool = controller.addressProvider().getPoolForToken(token);
        pool.handleLpTokenTransfer(src, dst, amount);

        uint256 allowanceNew = startingAllowance - amount; // Cannot underflow due to first require on L#152
        uint256 srcTokensNew = srcTokens - amount; // Cannot underflow due to second require on L#155
        uint256 dstTokensNew = balances[dst] + amount;

Using unchecked math:

        require(startingAllowance >= amount, Error.INSUFFICIENT_BALANCE);

        uint256 srcTokens = balances[src];
        require(srcTokens >= amount, Error.INSUFFICIENT_BALANCE);

        address lpGauge = currentAddresses[_LP_GAUGE];
        if (lpGauge != address(0)) {
            ILpGauge(lpGauge).userCheckpoint(src);
            ILpGauge(lpGauge).userCheckpoint(dst);
        }
        ILiquidityPool pool = controller.addressProvider().getPoolForToken(token);
        pool.handleLpTokenTransfer(src, dst, amount);

        unchecked {
            uint256 allowanceNew = startingAllowance - amount;
            uint256 srcTokensNew = srcTokens - amount;
        }
        uint256 dstTokensNew = balances[dst] + amount;