31309 - [SC - Critical] slippage protection is inaccurate
Submitted on May 16th 2024 at 21:08:22 UTC by @jasonxiale for Boost | Alchemix
Report ID: #31309
Report type: Smart Contract
Report severity: Critical
Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/RevenueHandler.sol
Impacts:
Protocol insolvency
Description
Brief/Intro
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
275 function _melt(address revenueToken) internal returns (uint256) {
276 RevenueTokenConfig storage tokenConfig = revenueTokenConfigs[revenueToken];
277 address poolAdapter = tokenConfig.poolAdapter;
278 uint256 revenueTokenBalance = IERC20(revenueToken).balanceOf(address(this));
279 if (revenueTokenBalance == 0) {
280 return 0;
281 }
282 IERC20(revenueToken).safeTransfer(poolAdapter, revenueTokenBalance);
283 /*
284 minimumAmountOut == inputAmount
285 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 */
288 return
289 IPoolAdapter(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.
References
https://github.com/sherlock-audit/2024-04-alchemix-judging/issues/5
Proof of Concept
Because there is no WETH/ALETH Curve pool onchain, I will use ETH/ALETH pool as example.
Add the following code in src/test/RevenueHandler.t.sol and run
As we can see above, by using 1e18 weth, we can exchage 1012512998195120273 aleth. But if we set minimumAmountOut == inputAmount. Sandwich attack might happen
Last updated
Was this helpful?