sherlock-audit / 2023-10-real-wagmi-judging

16 stars 14 forks source link

lil.eth - _restoreLiquidity() is extemely easy to manipulate due to how it calculates underlying token balances #183

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

lil.eth

medium

_restoreLiquidity() is extemely easy to manipulate due to how it calculates underlying token balances

Summary

LiquidityManager.sol#_getCurrentSqrtPriceX96 uses the UniV3Pool.slot0 to determine the number of tokens it has in it's position. slot0 is the most recent data point and is therefore extremely easy to manipulate.

Vulnerability Detail

[_restoreLiquidity directly uses the token values returned by LiquidityAmounts#getAmountsForLiquidity](https://github.com/sherlock-audit/2023-10-real-wagmi/blob/main/wagmi-leverage/contracts/abstract/LiquidityManager.sol#L289C21-L302C23). This allows a malicious user to manipulate the valuation of the LP. An example of this kind of manipulation would be to use large buys/sells to alter the composition of the LP to make it worth less or more.

                   // Update the value of sqrtPriceX96 in the cache using the _getCurrentSqrtPriceX96 function
                    cache.sqrtPriceX96 = _getCurrentSqrtPriceX96(
                        params.zeroForSaleToken,
                        cache.saleToken,
                        cache.holdToken,
                        cache.fee
                    );
                    // Calculate the amounts of token0 and token1 for a given liquidity
                    (amount0, amount1) = LiquidityAmounts.getAmountsForLiquidity(
                        cache.sqrtPriceX96,
                        TickMath.getSqrtRatioAtTick(cache.tickLower),
                        TickMath.getSqrtRatioAtTick(cache.tickUpper),
                        loan.liquidity
                    );

Then amount0and amount1 are used in _increaseLiquidity

(uint128 restoredLiquidity, , ) = underlyingPositionManager.increaseLiquidity(
            INonfungiblePositionManager.IncreaseLiquidityParams({
                tokenId: loan.tokenId,
                amount0Desired: amount0,
                amount1Desired: amount1,
                amount0Min: 0,
                amount1Min: 0,
                deadline: block.timestamp
            })
        );
if (restoredLiquidity < loan.liquidity) => Revert

A malicious user could use this to manipulate slot0, make this transaction revert and then benefit from liquidationBonus when collateralBalance is < 0

Impact

Amount of liquidity to be restored can be manipulated leading to repay() revert and borrower unable to repay

Code Snippet

Tool used

Manual Review

Recommendation

Use the TWAP function to get the value of sqrtPriceX96.

Duplicate of #109