LOW severity: [TOKE-7] Missing deadline parameter in _performLiquidation. **Severity:** Medium

**Path:** src/liquidation/LiquidationRow.sol::_performLiquidation()#L292-L369

**Description:**

The `_performLiquidation()` function in the `LiquidationRow.sol` contract uses a price margin (`priceMarginBps`) to ensure that the swap price is fair. However, the liquidation...

Vulnerable code:
function _performLiquidation(
        uint256 gasBefore,
        address fromToken,
        address asyncSwapper,
        IDestinationVault[] memory vaultsToLiquidate,
        SwapParams memory params,
        uint256 totalBalanceToLiquidate,
        uint256[] memory vaultsBalances
    ) private {
        // Ensure the amount to liquidate matches the vault balance.
        // If not, either the vault balance changed or swapper parameters are incorrect.
        if (params.sellAmount != totalBalanceToLiquidate) {
            revert SellAmountMismatch(totalBalanceToLiquidate, params.sellAmount);
        }

        uint256 amountReceived = params.buyAmount;
        uint256 length = vaultsToLiquidate.length;

        // Swap only if the sellToken is different than the vault rewardToken
        if (fromToken != params.buyTokenAddress) {
            // Use the price oracle to ensure we swapped at a fair price
            // Retrieve prices before the swap to ensure accuracy unaffected by market changes.
            IRootPriceOracle oracle = systemRegistry.rootPriceOracle();
            uint256 sellTokenPrice = oracle.getPriceInEth(fromToken);
            uint256 buyTokenPrice = oracle.getPriceInEth(params.buyTokenAddress);

            // the swapper checks that the amount received is greater or equal than the params.buyAmount
            bytes memory data = asyncSwapper.functionDelegateCall(
                abi.encodeWithSelector(IAsyncSwapper.swap.selector, params), "SwapFailed"
            );

            amountReceived = abi.decode(data, (uint256));

            // Expected buy amount from Price Oracle
            uint256 expectedBuyAmount = (params.sellAmount * sellTokenPrice) / buyTokenPrice;

            // Allow a margin of error for the swap
            // slither-disable-next-line divide-before-multiply
            uint256 minBuyAmount = (expectedBuyAmount * (MAX_PCT - priceMarginBps)) / MAX_PCT;

            if (amountReceived < minBuyAmount) {
                revert InsufficientAmountReceived(minBuyAmount, amountReceived);
            }
        } else {
            // Ensure that if no swap is needed, the sell and buy amounts are the same.
            if (params.sellAmount != params.buyAmount) revert AmountsMismatch(params.sellAmount, params.buyAmount);
        }

        // if the fee feature is turned on, send the fee to the fee receiver
        if (feeReceiver != address(0) && feeBps > 0) {
            uint256 fee = calculateFee(amountReceived);
            emit FeesTransferred(feeReceiver, amountReceived, fee);

            // adjust the amount received after deducting the fee
            amountReceived -= fee;
            // transfer fee to the fee receiver
            IERC20(params.buyTokenAddress).safeTransfer(feeReceiver, fee);
        }

        uint256 gasUsedPerVault = (gasBefore - gasleft()) / vaultsToLiquidate.length;
        for (uint256 i = 0; i < length; ++i) {
            IDestinationVault vaultAddress = vaultsToLiquidate[i];
            IMainRewarder mainRewarder = IMainRewarder(vaultAddress.rewarder());

            if (mainRewarder.rewardToken() != params.buyTokenAddress) {
                revert InvalidRewardToken();
            }

            uint256 amount = amountReceived * vaultsBalances[i] / totalBalanceToLiquidate;

            // approve main rewarder to pull the tokens
            LibAdapter._approve(IERC20(params.buyTokenAddress), address(mainRewarder), amount);
            mainRewarder.queueNewRewards(amount);

            emit VaultLiquidated(address(vaultAddress), fromToken, params.buyTokenAddress, amount);
            emit GasUsedForVault(address(vaultAddress), gasUsedPerVault, bytes32("liquidation"));
        }
    }