Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: high
Invalid

Front-Running attack can deny vault closure

Summary

The 2-step protection used for transactions such as using GMX is not applicable in the function to perform a token "swap."
Some functions are vulnerable to front-running attacks and emergencyClose() can be denied.

Vulnerability Details

The damage of the front-running type attack is well known, but what could the damage be in our scenario.

For example, if for any reason they want to close the vault, you call emergencyClose() in GMXEmergency.sol, to try to return the money, but if you need more TokenA or TokenB tokens, you must make an swap for make the repay, and the key is in the parameters that are used.

_sp.tokenIn = _tokenFrom;
_sp.tokenOut = _tokenTo;
_sp.amountIn = IERC20(_tokenFrom).balanceOf(address(this)); // @audit
_sp.amountOut = _tokenToAmt;
_sp.slippage = self.minSlippage;

So the protocol needs to exchange a token A -> B (or vice versa), because the amount is not enough.

(
bool _swapNeeded, // their return is true because they need more token a/b
address _tokenFrom,
address _tokenTo,
uint256 _tokenToAmt
) = GMXManager.calcSwapForRepay(self, _rp);

Since _swapNeeded is true, have to go through this conditional to perform the swap:

if (_swapNeeded) {
ISwap.SwapParams memory _sp;
_sp.tokenIn = _tokenFrom;
_sp.tokenOut = _tokenTo;
_sp.amountIn = IERC20(_tokenFrom).balanceOf(address(this));
_sp.amountOut = _tokenToAmt;
_sp.slippage = self.minSlippage;
_sp.deadline = deadline;
GMXManager.swapTokensForExactTokens(self, _sp);
}
  1. The attacker can manipulate the price before the swap by causing it to exceed the slippage limit and reverse it.

  2. If the "slippage" continues to increase to avoid the attacker, it may result in the token used to make the swap being less than the amount needed to make the repay after the swap is made.

This then gives the attacker the opportunity to see the "slippage" and amount of the secondary token before the function is executed to attack and prevent the vault from being closed.

Impact

High, the result is that the vault cannot be closed and users cannot perform emergencyWithdraw() and lending vaults not getting paid back.

Tools Used

Manual Code Review

Recommendations

A good option is to use the exchange mechanism on GMX with 2 steps for the transaction.

Updates

Lead Judging Commences

hans Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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