Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: medium
Valid

Token Swap and `Repay` Revert Risk in `EmergencyClose` and `processWithdraw` Functions

Summary

The identified vulnerability is related to two instances of token swapping within the functions emergencyClose and processWithdraw. These functions use the balance of the contract as the amountIn for the swaps, potentially resulting in swapped amounts that exceed the available amount the vault can repay. This can lead to a revert in the subsequent repay function.

Vulnerability Details

1st Instance - emergencyClose
In the emergencyClose function, the vulnerability arises when the system checks if a swap is needed (before repay) and then proceeds to swap tokens.

if (_swapNeeded) {
ISwap.SwapParams memory _sp;
_sp.tokenIn = _tokenFrom;
_sp.tokenOut = _tokenTo;
_sp.amountIn = IERC20(_tokenFrom).balanceOf(address(this)); // @audit might use more tokens for swap which will result in repay reverting because it tries to repay more than what the contract has
_sp.amountOut = _tokenToAmt;
_sp.slippage = self.minSlippage;
_sp.deadline = deadline;
GMXManager.swapTokensForExactTokens(self, _sp);
}
GMXManager.repay(self, _rp.repayTokenAAmt, _rp.repayTokenBAmt);

2nd Instance - "processWithdraw"
The same vulnerability pattern occurs in the processWithdraw function.

if (_swapNeeded) {
ISwap.SwapParams memory _sp;
_sp.tokenIn = _tokenFrom;
_sp.tokenOut = _tokenTo;
_sp.amountIn = IERC20(_tokenFrom).balanceOf(address(this)); // @audit might use more tokens for swap which will result in repay reverting because it tries to repay more than what the contract has
_sp.amountOut = _tokenToAmt;
_sp.slippage = self.minSlippage;
_sp.deadline = block.timestamp;
GMXManager.swapTokensForExactTokens(self, _sp);
}

If the amountIn used for the swap are more than expected, the resulting amounts of tokenA/tokenB might less be than what the repay function expects resulting in a revert.

GMXManager.repay(
self,
_rp.repayTokenAAmt,
_rp.repayTokenBAmt
);

MEV bots can also exploit this scenario to extract as much amountIn as possible.

Impact

The impact of this vulnerability is two-fold:

  1. The usage of the contract's balance as the "amountIn" for token swaps may lead to swapped amounts that exceed the available amount the vault can repay. This can result in the subsequent "repay" function reverting, leading to tx failures and DOS.

  2. loss of opportunities for users

  3. Possible loss of funds for the Vault since emergencyClose had to be executed to prevent against an extreme scenario.

Proof of Concept

Consider this scenario;

A. Assuming the keeper initiates a "EmergencyClose" operation due to one or two crucial reasons

B. The function determines whether token A or B swap is required before processing repay.

C. The swap function uses the entire contract balance as "amountIn" for the swap.

D. Due to market volatility, the swap results in an amount larger than the amount the vault can repay.

E. The subsequent "repay" function fails to execute, resulting in a revert of the transaction i.e EmergencyClose reverts and defeats the purpose of the emergency function whose goal is to be able to remove liquidity to try to protect against any extreme scenarios (leading to financial losses)

More info:
https://x.com/puputhrashing/status/1454030019223719937?s=46&t=ahuBu4vx0GHQr2UGnKTzKA

Tools Used

Manual

Recommendations

To mitigate this in short term this i would recommend Validating the Swap Amounts. Implement check to ensure that the amountIn used for swaps does not exceed the amount the vault can repay.

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

Not enough token to repay the debt on emergencyClose

Impact: Medium Likelihood: Low The keepers can send tokens directly before closing. Will leave for a sponsor's review but likely to invalidate.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.