Pool lp value can be manipulated and cause other users to receive less lp tokens.
Vulnerability Detail
Panoptic is using slot0 to calculate several variables in their codebase:
slot0 is the most recent data point and is therefore extremely easy to manipulate.
function _mintFullRange(
IUniswapV3Pool v3Pool,
address token0,
address token1,
uint24 fee
) internal returns (uint256, uint256) {
@audit-issue : use of slot0 can lead to price manipulation .
(uint160 currentSqrtPriceX96, , , , , , ) = v3Pool.slot0();
uint128 fullRangeLiquidity;
unchecked {
// Since we know one of the tokens is WETH, we simply add 0.1 ETH +
worth in tokens
if (token0 == WETH) {
fullRangeLiquidity = uint128(
Math.mulDiv96RoundingUp(FULL_RANGE_LIQUIDITY_AMOUNT_WETH,
currentSqrtPriceX96)
);
} else if (token1 == WETH) {
fullRangeLiquidity = uint128(
Math.mulDivRoundingUp(
FULL_RANGE_LIQUIDITY_AMOUNT_WETH,
Constants.FP96,
currentSqrtPriceX96
)
);
} else {
// Find the resulting liquidity for providing 1e6 of both tokens
uint128 liquidity0 = uint128(
Math.mulDiv96RoundingUp(FULL_RANGE_LIQUIDITY_AMOUNT_TOKEN,
currentSqrtPriceX96)
);
uint128 liquidity1 = uint128(
Math.mulDivRoundingUp(
FULL_RANGE_LIQUIDITY_AMOUNT_TOKEN,
Constants.FP96,
currentSqrtPriceX96
)
);
fullRangeLiquidity = liquidity0 > liquidity1 ? liquidity0 : liquidity1;
}
}
// The maximum range we can mint is determined by the tickSpacing of the
pool
// The upper and lower ticks must be divisible by `tickSpacing`, so
// tickSpacing = 1: tU/L = +/-887272
// tickSpacing = 10: tU/L = +/-887270
// tickSpacing = 60: tU/L = +/-887220
// tickSpacing = 200: tU/L = +/-887200
int24 tickLower;
int24 tickUpper;
unchecked {
int24 tickSpacing = v3Pool.tickSpacing();
tickLower = (Constants.MIN_V3POOL_TICK / tickSpacing) * tickSpacing;
tickUpper = -tickLower;
}
bytes memory mintCallback = abi.encode(
CallbackLib.CallbackData({
poolFeatures: CallbackLib.PoolFeatures({token0: token0, token1: token1, fee: fee}),
payer: msg.sender
})
);
return
IUniswapV3Pool(v3Pool).mint(
address(this),
tickLower,
tickUpper,
fullRangeLiquidity,
mintCallback
);
}
If the currentSqrtPriceX96 is increased by the attacker more then FULL_RANGE_LIQUIDITY_AMOUNT_WETH it will convert the fullRangeLiquidity to zero which can lead to the huge loss of the protocol .
Tools Used
Manual review
Recommended Mitigation Steps
To make any calculation use a TWAP instead of slot0.
Lines of code
https://github.com/code-423n4/2024-06-panoptic/blob/153f0d82440b7e63075d55b0659706531431145f/contracts/PanopticFactory.sol#L321 https://github.com/code-423n4/2024-06-panoptic/blob/153f0d82440b7e63075d55b0659706531431145f/contracts/PanopticFactory.sol#L315-L391
Vulnerability details
Description
Usage of slot0 is extremely easy to manipulate
Impact
Pool lp value can be manipulated and cause other users to receive less lp tokens.
Vulnerability Detail
Panoptic is using slot0 to calculate several variables in their codebase: slot0 is the most recent data point and is therefore extremely easy to manipulate.
The main problem can come there
If the currentSqrtPriceX96 is increased by the attacker more then FULL_RANGE_LIQUIDITY_AMOUNT_WETH it will convert the fullRangeLiquidity to zero which can lead to the huge loss of the protocol .
Tools Used
Manual review
Recommended Mitigation Steps
To make any calculation use a TWAP instead of slot0.
Assessed type
Uniswap