Skip to content

Latest commit

 

History

History
97 lines (62 loc) · 4.29 KB

153.md

File metadata and controls

97 lines (62 loc) · 4.29 KB

Upbeat Fossilized Boa

Medium

Missing Check for Full BOOST Token Swap in _mintAndSellBoost Function Could Lead to Leftover Tokens and Transaction Inconsistencies

Summary

The _mintAndSellBoost function lacks a check to ensure that the full boostAmount is swapped, potentially leaving leftover tokens and causing inconsistencies in the transaction.

https://github.com/sherlock-audit/2024-10-axion/blob/c65e662999d0c79439703fc6713814b4ad023e01/liquidity-amo/contracts/SolidlyV2AMO.sol#L156-L193

Root Cause

The root cause is the missing validation that the entire boostAmount is swapped, which can result in a smaller-than-expected boostAmountIn.

Internal pre-conditions

No response

External pre-conditions

boostAmount > boostAmoutIn

Attack Path

Assume the _mintAndSellBoost function mints 1,000 BOOST tokens and intends to swap them for USD. However, due to slippage or liquidity limitations, only 900 BOOST tokens are swapped instead of the full 1,000.

In this scenario:

boostAmountIn will be 900 (the actual amount swapped), but the code does not check that this is less than the intended boostAmount (1,000). The leftover 100 BOOST tokens remain unswapped in the contract, potentially leading to accounting discrepancies and affecting the expected USD output. This lack of validation could cause the function to behave incorrectly, especially if downstream logic assumes the full boostAmount was swapped.

Impact

The impact of not checking if boostAmountIn equals boostAmount in _mintAndSellBoost can lead to several potential issues:

Accounting Discrepancies: The leftover unswapped BOOST tokens (if boostAmountIn < boostAmount) can cause accounting issues, as the contract may assume the full amount was swapped.

Unreliable USD Output: Since the entire BOOST amount is not being swapped, the actual USD received (usdAmountOut) may be lower than expected, leading to insufficient funds for subsequent transactions.

Inefficient Liquidity Usage: The unswapped BOOST tokens may remain locked in the contract, leading to inefficient use of liquidity and suboptimal swaps.

Inconsistent Behavior: The contract logic might expect that the full boostAmount is always used in the swap, which could lead to inconsistencies in the system's behavior or downstream logic, potentially causing transaction failures or unexpected results.

This issue could undermine the stability and predictability of the system, especially in environments with high liquidity volatility or slippage.

PoC

No response

Mitigation

 function _mintAndSellBoost(
        uint256 boostAmount,
        uint256 minUsdAmountOut,
        uint256 deadline
    ) internal override returns (uint256 boostAmountIn, uint256 usdAmountOut) {
        // Mint the specified amount of BOOST tokens
        IMinter(boostMinter).protocolMint(address(this), boostAmount);

        // Approve the transfer of BOOST tokens to the router
        IERC20(boost).approve(router, boostAmount);

        // Define the route to swap BOOST tokens for USD tokens
        ISolidlyRouter.route[] memory routes = new ISolidlyRouter.route[](1);
        routes[0] = ISolidlyRouter.route(boost, usd, true);

        if (minUsdAmountOut < toUsdAmount(boostAmount)) minUsdAmountOut = toUsdAmount(boostAmount);

        uint256 usdBalanceBefore = balanceOfToken(usd);
        // Execute the swap and store the amounts of tokens involved
        uint256[] memory amounts = ISolidlyRouter(router).swapExactTokensForTokens(
            boostAmount,
            minUsdAmountOut,
            routes,
            address(this),
            deadline
        );
        uint256 usdBalanceAfter = balanceOfToken(usd);
        boostAmountIn = amounts[0];
        usdAmountOut = amounts[1];

+    if(boostAmountIn != boostAmount) revert("Not all boost is swapped.");

        // we check that selling BOOST yields proportionally more USD
        if (usdAmountOut != usdBalanceAfter - usdBalanceBefore)
            revert UsdAmountOutMismatch(usdAmountOut, usdBalanceAfter - usdBalanceBefore);

        if (usdAmountOut < minUsdAmountOut) revert InsufficientOutputAmount(usdAmountOut, minUsdAmountOut);

        emit MintSell(boostAmount, usdAmountOut);
    }