code-423n4 / 2024-06-vultisig-findings

2 stars 0 forks source link

`claim` Function Fails to Protect Stakeholders from Slippage #97

Closed howlbot-integration[bot] closed 4 months ago

howlbot-integration[bot] commented 4 months ago

Lines of code

https://github.com/code-423n4/2024-06-vultisig/blob/main/src/ILOPool.sol#L184

Vulnerability details

[M-05] claim Function Fails to Protect Stakeholders from Slippage

Proof of Concept

Stakeholders are allowed to claim their Sale and Raise tokens for the liquidity positions when the Pool officially launches.

The claim function in the contract burns the stakeholder's claimable liquidity from Uniswap V3 Pool, deducts platform and performance fees, and sends the net tokens to the stakeholder by adding fees their position generated.

However, the current implementation fails to protect against slippage, which can lead to unexpected result for Stakeholders/loss of funds.


    function claim(uint256 tokenId)
        external
        payable
        override
        isAuthorizedForToken(tokenId)
        returns (uint256 amount0, uint256 amount1)
    {
        // SNIP
        {
            // SNIP

            // get amount of token0 and token1 that pool will return for us
1->         (amount0, amount1) = pool.burn(TICK_LOWER, TICK_UPPER, liquidity2Claim);

            // get amount of token0 and token1 after deduct platform fee
2->         (amount0, amount1) = _deductFees(amount0, amount1, _project.platformFee);

            bytes32 positionKey = PositionKey.compute(address(this), TICK_LOWER, TICK_UPPER);

            // calculate amount of fees that position generated
            (, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = pool.positions(positionKey);
            uint256 fees0 = FullMath.mulDiv(feeGrowthInside0LastX128 - position.feeGrowthInside0LastX128, positionLiquidity, FixedPoint128.Q128);

            uint256 fees1 = FullMath.mulDiv(feeGrowthInside1LastX128 - position.feeGrowthInside1LastX128, positionLiquidity, FixedPoint128.Q128);

            // amount of fees after deduct performance fee
3->         (fees0, fees1) = _deductFees(fees0, fees1, _project.performanceFee);

            // fees is combined with liquidity token amount to return to the user
            amount0 += fees0;
            amount1 += fees1;

            position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128;
            position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128;

            // subtraction is safe because we checked positionLiquidity is gte liquidity2Claim
            position.liquidity = positionLiquidity - liquidity2Claim;
            emit DecreaseLiquidity(tokenId, liquidity2Claim, amount0, amount1);

        }
        // SNIP
    }

Let's focus on each 3 points marked above:

  1. burning Liquidity:

    • Once the Pool launches, interaction directly with Uniswap V3 Pool is allowed. Users can swap to influence the balance of the pool.

    • The amount of tokens received from the Uniswap V3 Pool function while burning might be manipulated by front-runners due to the decentralized nature of AMMs.

    • Lack of slippage protection exposes users to such attacks.

  2. Deducting Platform Fees:

    • Platform Fees can be updated by the Owner of ILOManager through the setPlatformFee function.

    • If the owner updates the fees while a user's transaction is pending, it can lead to unexpected and unfair outcomes for the user if the fee is increased.

  3. Deducting Performance Fees:

    • Again, Performance Fees can also be updated by the Owner of ILOManager through the setPerformanceFee function.

    • If the owner updates the fees while a user's transaction is pending, it can lead to unexpected and unfair outcomes for the user if the fee is increased.

Due to these factors, validating amount0 and amount1 is crucial to ensure they meet the user's expectations.

Impact

Loss of funds due to slippage and unexpected fee increases.

Tools Used

VS Code

Recommended Mitigation Steps

Consider adding amount0Min and amount1Min parameters in function definition and ensure that Stakeholders receive atleast those tokens at the end.

Assessed type

Other

c4-judge commented 4 months ago

alex-ppg marked the issue as satisfactory