Audit review for 2024-04-panoptic from code4rena

https://github.com/code-423n4/2024-04-panoptic-findings

High Risk

1.SettleLongPremium is incorrectly implemented: premium should be deducted instead of added

summary

1
2
3
4
5
            // current available assets belonging to PLPs (updated after settlement) excluding any premium paid
int256 updatedAssets = int256(uint256(s_poolAssets)) - swappedAmount;

// add premium to be paid/collected on position close
> int256 tokenToPay = -realizedPremium;

In the code, the int type is used for numbers, and the sign of the subtrahend is used to control whether the final result is an increase or a decrease.

root cause

As a result, an error in the sign of the input parameters leads to the final operation being contrary to the expectation.

learned

When we use the int type, we need to pay special attention to the sign of the values

2.

summary

1
2
3
4
5
6
7
unchecked {
assets = Math.mulDivRoundingUp(
shares * DECIMALS,
totalAssets(),
totalSupply * (DECIMALS - COMMISSION_FEE)
);
}

unchecked block can lead to silent overflow

root cause

Due to user can mint huge amounts of shares for free the shares can be much greater than expected.

learned

Double check the unchecked block make sure it can’t overflow.

Medium Risk

1.PanopticFactory uses spot price when deploying new pools, resulting in liquidity manipulation when minting

summary

1
@>	(uint160 currentSqrtPriceX96, , , , , , ) = v3Pool.slot0();

When deployNewPool is called it uses the spot price of the pool, which can be manipulated through a flashloan and thus could return a highly inaccurate result.

root cause

uses spot price

learned

spot price can be manipulated through a flashloan, try to use TWAP price instead.

2._validatePositionList() does not check for duplicate tokenIds, allowing attackers to bypass solvency checks

summary

The user can pass in an array of tokenIds, but there is no check for duplicates.

root cause

no check for duplicates

learned

Think about if pass in array need to be checked for duplicates.

3.Removed liquidity can overflow when calling SemiFungiblePositionManager.mintTokenizedPosition function

summary

1
2
3
4
5
6
if (!isBurn) {
// we can't remove more liquidity than we add in the first place, so this can't overflow
unchecked {
removedLiquidity += chunkLiquidity;
}
}

options can be repeatly which can lead to removedLiquidity sum up mutiple times.

root cause

unchecked block overflow

learned

need to double check the unchecked block make sure it can not be overflow

4.Wrong leg chunkKey calculation in haircutPremia function

summary

when loop tokenId , uses always the index 0 when calculating the leg chunkKey instead of using the actual leg index

root cause

logic error

learned

pay more attention to the logic.

5.Panoptic pool can be non-profitable by specific Uniswap governance

summary

The developers only considered the current range of Uniswap fees, but these fees may change through governance, affecting the existing logic.

root cause

fee may changes in the future.

learned

It is necessary to consider the impact of governance on the current fees.

Comments