20,000 USDC
View results
Submission Details
Severity: high
Valid

`ExactInputSingleParams()` don't have slippage protection

Summary

In Fees.sol we have sellProfits() function. This function swap loan tokens for collateral tokens from liquidations:

function sellProfits(address _profits) public {
require(_profits != WETH, "not allowed");
uint256 amount = IERC20(_profits).balanceOf(address(this));
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter
.ExactInputSingleParams({
tokenIn: _profits,
tokenOut: WETH,
fee: 3000,
recipient: address(this),
deadline: block.timestamp,
amountIn: amount,
amountOutMinimum: 0, //@audit - no slippage
sqrtPriceLimitX96: 0
});
amount = swapRouter.exactInputSingle(params);
IERC20(WETH).transfer(staking, IERC20(WETH).balanceOf(address(this)));
}

This function calls ExactInputSingleParams() from ISwapRouter without any slippage protection.

Vulnerability Details

The functions ExactInputSingleParams(), don't have slippage protection:

ExactInputSingleParams({
tokenIn: _profits,
tokenOut: WETH,
fee: 3000,
recipient: address(this),
deadline: block.timestamp,
amountIn: amount,
amountOutMinimum: 0, //@audit - no slippage
sqrtPriceLimitX96: 0
});

We can see amountOutMinimum is hardcoded to 0. amountOutMinimum is used to prevent high slippage. By setting them to a value greater than zero, you would ensure that the transaction reverts if the amount of tokens that will be added to the liquidity pool is less than these minimums.

In a volatile market, or when dealing with large orders, the price can shift while the transaction is being mined, and the actual amount of tokens added can be less than the desired amount.

Impact

Without slippage, If the price of the tokens changes significantly during the swap, it could result in a large slippage, causing users to lose a significant amount of funds.
An attacker can watch the mempool and then (using flash bots) execute a sandwich attack to manipulate the price before and after the swap.

Tools Used

Visual Studio Code

Recommendations

Do not hardcode amountOutMin to 0, but let the user choose the value.

Support

FAQs

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