RevenueHandler._melt is used to swap normal token to alAsset(for example: WETH->alETH), but the slippage protection is inaccurate. So the function is subject to sandwich attack.
Vulnerability Details
Function RevenueHandler._melt is used to swap normal token to alAsset(for example: WETH -> alETH), and the function uses IERC20(revenueToken).balanceOf(address(this)); as slippage protection.
The issue is that the price between normal token and alAsset isn't 1:1, based on althe and weth, the ratio between WETH and alETH is about 30:27. So it means that the protocol will use 3000$ WETH to swap for 2700$ alETH. Acutally, this is the same issue as https://github.com/sherlock-audit/2024-04-alchemix-judging/issues/5
275function_melt(address revenueToken) internalreturns (uint256) {276 RevenueTokenConfig storage tokenConfig = revenueTokenConfigs[revenueToken];277address poolAdapter = tokenConfig.poolAdapter;278uint256 revenueTokenBalance =IERC20(revenueToken).balanceOf(address(this));279if (revenueTokenBalance ==0) {280return0;281 }282IERC20(revenueToken).safeTransfer(poolAdapter, revenueTokenBalance);283/* 284 minimumAmountOut == inputAmount285 Here we are making the assumption that the price of the alAsset will always be at or below the price of the revenue token.
286 This is currently a safe assumption since this imbalance has always held true for alUSD and alETH since their inceptions.
287 */288return289IPoolAdapter(poolAdapter).melt(290 revenueToken,291 tokenConfig.debtToken,292 revenueTokenBalance,293 revenueTokenBalance <<<--- Here IERC20(revenueToken).balanceOf(address(this)) is used as slippage protection.
294 );295 }
Impact Details
RevenueHandler._melt is used to swap normal token to alAsset(for example: WETH->alETH), but the slippage protection is inaccurate. So the function is subject to sandwich attack.
As we can see above, by using 1e18 weth, we can exchage 1012512998195120273 aleth. But if we set minimumAmountOut == inputAmount. Sandwich attack might happen