Submitted by hash, also found by critical-or-high, 0xCiphky, Udsen, ptsanev, Neon2835, lanrebayode77, and Topmark
When burning a long token, the removedLiquidity is subtracted in an unchecked block.
https://github.com/code-423n4/2023-11-panoptic/blob/main/contracts/SemiFungiblePositionManager.sol#L936-L980
An underflow can be produced here by the following (burning is done after transferring the current position):
The ability to obtain such a position allows an attacker to perform a variety of attacks.
If the totalLiquidity of a position is equal to 2 ** 128, the premia calculation will revert due to division by zero.
https://github.com/code-423n4/2023-11-panoptic/blob/main/contracts/SemiFungiblePositionManager.sol#L1313-L1322
An attacker can exploit this by creating a position with removedLiquidity == 2 ** 128 - depositorLiquidity and netLiquidity == 0. The attacker can then front run and transfer this position to the depositor following which the funds will be lost/locked if burn is attempted without adding more liquidity or fees has been accrued on the position (causable by the attacker).
Instead of matching exactly with 2 ** 128 - depositorLiquidity an attacker can also keep removedLiquidity extremely close to type(uint128).max; in which case depending on the depositors amount, a similar effect will take place due to casting errors.
Another less severe possibility for the attacker is to keep netLiquidity slightly above 0 (some other amount which will cause fees collected to be non-zero and hence, invoke the _getPremiaDeltas) and transfer to target address causing DOS since any attempt to mint will result in revert due to premia calculation.
Instead of making totalLiquidity == 2 ** 128, an attacker can choose values for netLiquidity and removedLiquidity such that totalLiquidity > 2 ** 128. This will disrupt the premia calculation.
Example values:
Set fork_block_number = 18706858.
For the division by 0 revert lock run: forge test --mt testHash_DepositAmountLockDueToUnderflowDenomZero.
For the casting error revert lock run: forge test --mt testHash_DepositAmountLockDueToUnderflowCastingError.
Check if removedLiquidity is greater than chunkLiquidity before subtracting.
Under/Overflow
dyedm1 (Panoptic) confirmed, but disagreed with severity and commented via duplicate issue #332:
Picodes (judge) decreased severity to Medium
Picodes (judge) commented via duplicate issue #332:
