Vulnerability: incorrect handling for deposit failure leads to stuck at `deposit_failed` status .
Severity: medium

Description:
When a deposit fails, the contract can become stuck in a `deposit_failed` status due to improper handling of debt repayment by swapping through the `swapTokensForExactTokens()` function.which leads to gas losses for keeper attempting to handle that and puts user deposits at risk.\\nIn case of a user making a deposit to the `strategy`, it will create a deposit in `GMX`. After a successful deposit, `GMX` will call the callback function `afterDepositExecution`, and the callback function will call `processDeposit`.\\nIf the `processDeposit()` fails in the `try` call for any reason, the function will `catch` that and set the status to `deposit_failed`. An event will be emitted so the keeper can handle it.\\n```\\n  function processDeposit(GMXTypes.Store storage self) external {\\n       // some code ..\\n      try GMXProcessDeposit.processDeposit(self) {\\n           // ..more code\\n        } catch (bytes memory reason) {\\n            self.status = GMXTypes.Status.Deposit_Failed;\\n\\n            emit DepositFailed(reason);\\n        }\\n    }\\n```\\n\\nThe keeper calls the function processDepositFailure(). This function initiates a `requestWithdraw` to `GMX` to remove the liquidity added by the user deposit (+ the borrowed amount).\\nAfter executing the `removeLiquidity`, the callback function `afterWithdrawalExecution` is triggered. and since the status is `deposit_failed`, it invokes the function `processDepositFailureLiquidityWithdrawal`.\\nIn `processDepositFailureLiquidityWithdrawal`, it first checks if a swap is necessary. If required, it swaps tokens to repay the debt.\\n```\\n        (bool _swapNeeded, address _tokenFrom, address _tokenTo, uint256 _tokenToAmt) =\\n            GMXManager.calcSwapForRepay(self, _rp);\\n\\n        if (_swapNeeded) {\\n\\n            ISwap.SwapParams memory _sp;\\n\\n            _sp.tokenIn = _tokenFrom;\\n            _sp.tokenOut = _tokenTo;\\n            _sp.amountIn = IERC20(_tokenFrom).balanceOf(address(this));\\n            _sp.amountOut = _tokenToAmt;\\n            _sp.slippage = self.minSlippage;\\n            _sp.deadline = block.timestamp;\\n            GMXManager.swapTokensForExactTokens(self, _sp);\\n        }\\n```\\n\\nThe problem arises if the swap revert if the `tokenIn` balance is insufficient to cover the `_amountOut` of `_tokenOut`, leading to a failed swap since the swap function is `swapTokensForExactTokens`. Consequently, the status remains `deposit_failed` and the callback revet.\\nNote: The swap can fail for various reasons.\\nIn this scenario, the keeper can only invoke the `processDepositFailure()` function again. During the second call, it directly triggers `processDepositFailureLiquidityWithdrawal` since the `lp` tokens for the failed deposit has already been withdrawn.\\n```\\n function processDepositFailure(GMXTypes.Store storage self, uint256 slippage, uint256 executionFee) external {\\n        GMXChecks.beforeProcessAfterDepositFailureChecks(self);\\n\\n        GMXTypes.RemoveLiquidityParams memory _rlp;\\n\\n        // If current gmx LP amount is somehow less or equal to amount before, we do not remove any liquidity\\n        if (GMXReader.lpAmt(self) <= self.depositCache.healthParams.lpAmtBefore) {\\n            processDepositFailureLiquidityWithdrawal(self);\\n         //// rest of code more code\\n        }}\\n```\\n\\nThe swap will always revert because the contract's balance of `tokenIn` will never be sufficient to cover the `_amountOut` of `_tokenOut`. Consequently, the status remains stuck at `deposit_failed`.

Impact:
The strategy remains stuck at the `deposit_failed` status, halting any further interactions with the protocol.\\nKeepers lose gas for each call to `processDepositFailure()`.\\nUsers may lose their deposits.

Recommended mitigation:
Utilize `swapExactTokensForTokens` and swap the remaining tokens from `tokenIn` after substracting debt need to be repaid of this token.for `tokenOut`.\\nImplement safeguards to calculate the appropriate amount for swapping, avoiding potential reverting transactions. Here's an example of how to calculate the swap amount:\\n` if (rp.repayTokenAAmt > self.tokenA.balanceOf(address(this))) {\\n          // If more tokenA is needed for repayment\\n          if(rp.repayTokenBAmt < self.tokenB.balanceOf(address(this))){\\n            _tokenToAmt = self.tokenB.balanceOf(address(this)) - rp.repayTokenBAmt;\\n            _tokenFrom = address(self.tokenB);\\n            _tokenTo = address(self.tokenA);\\n          }\\n }`