Closed c4-bot-3 closed 3 months ago
True, but don't see a failure case here. The protocol is designed to handle the swaps/token deltas occuring partially or not at all, and makes the user compensate for any discrepancies in the token amounts. That 1 wei taken from the user is important, because it means that they borrowed 1 wei less than what was required to mint their option.
Picodes changed the severity to QA (Quality Assurance)
Invalidating in the absence of impact
Lines of code
https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/CollateralTracker.sol#L1105 https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/libraries/PanopticMath.sol#L390-L410 https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/libraries/PanopticMath.sol#L574-L599
Vulnerability details
Impact
An extra 1 wei amount of token is taken from user each time minting an OTM short option.
Bug Description
intrinsicValue
should be 0 when minting OTM short options, however, due to rounding issues, it may be 1 wei ifassetType != tokenType
.The issue here is that
swappedAmount
(actual amount that is moved to uniswap) may be larger thanshortAmount
, which is calculated byPanopticMath.computeExercisedAmounts()
.Let's first see how
swappedAmount
is calculated in (SqrtPriceMath.sol)[https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/SqrtPriceMath.sol]. We can see if liquidity is positive (minting), it uses roundUp == true.Then, for
PanopticMath.computeExercisedAmounts()
, the call stack leads toPanopticMath.getAmountsMoved()
, which by default uses round down for liquidity calculation.This rounding difference can cause non-zero intrinsic value even when minting short options OTM, which is unexpected.
Proof of Concept
Run
test_Fail_mintOptions_OTMShortCall_NotEnoughCollateral
unit test.Add the following console.log in
CollateralTracker.sol
, and every time it will log out theswappedAmount
is 1 wei larger thanshortAmount
.An example output is:
Tools Used
Foundry
Recommended Mitigation Steps
Handle roundup issues when calculating
PanopticMath.computeExercisedAmounts()
, just like what uniswap did.Assessed type
Uniswap