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.
In 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
.
If 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.
The keeper calls the function processDepositFailure(). This function initiates a requestWithdraw
to GMX
to remove the liquidity added by the user deposit (+ the borrowed amount).
After executing the removeLiquidity
, the callback function afterWithdrawalExecution
is triggered. and since the status is deposit_failed
, it invokes the function processDepositFailureLiquidityWithdrawal
.
In processDepositFailureLiquidityWithdrawal
, it first checks if a swap is necessary. If required, it swaps tokens to repay the debt.
The 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.
Note: The swap can fail for various reasons.
In 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.
The 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
.
The strategy remains stuck at the deposit_failed
status, halting any further interactions with the protocol.
Keepers lose gas for each call to processDepositFailure()
.
Users may lose their deposits.
vs code
manual review
Utilize swapExactTokensForTokens
and swap the remaining tokens from tokenIn
after substracting debt need to be repaid of this token.for tokenOut
.
Implement safeguards to calculate the appropriate amount for swapping, avoiding potential reverting transactions. Here's an example of how to calculate the swap amount:
Impact: Medium Likelihood: Medium The keepers can provide additional tokens with the help of the protocol team. Also assuming the sufficient liquidity on exchanges and assuming reasonable slippage, the swap will go through. But this is something that MUST be fixed.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.