settleLongPremium
will not collect long premium from option buyer
#376
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-497
🤖_98_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/PanopticPool.sol#L1600-L1640
https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/CollateralTracker.sol#L1043-L1079
Vulnerability details
Issue Description
Within
PanopticPool
, options sellers are allowed to callPanopticPool::settleLongPremium
to settle all unpaid premium for long legs of a given buyer position.The
PanopticPool::settleLongPremium
function is supposed to calculate the current long premium owed to the buyer using thes_options
leg accumulator, then it must collect that the owed premium from the buyer collaterals by callingCollateralTracker::exercise
function, and finally, the function will update the storage mappingsettledTokens
which represents the per-chunk accumulator for tokens owed to options sellers (which will make the premium available for sellers of that chunk).The issue that it's present in the
PanopticPool::settleLongPremium
function is that it will mint collateral shares to the buyer instead of burning them from his balance and this is due to the fact that the calculatedrealizedPremia
passed toCollateralTracker::exercise
is a positive value. To understand this, let's first look at the function code snippet below:As it can be seen, the
realizedPremia
which represents the long premium owed by the buyer is calculated using the following formula (for both token 0 & 1):If we look at the code above, we can notice that
accumulatedPremium
is of typeLeftRightUnsigned
, meaning that it's a positive number (>= 0), and the chunk liquidity is also a positive number (typeuint256
). This means that the resultantrealizedPremia
value will also be a positive number as it's the multiplication of two positive numbers.As we explained above, to collect the owed premium from the buyer collaterals, the
CollateralTracker::exercise
function is called. This function's logic implies that if the providedrealizedPremia
value is positive, then we must mint new collateral shares to the user, and ifrealizedPremia
is negative, then we should burn from his balance instead, as shown below:So because the
realizedPremia
value calculated insettleLongPremium
is positive and is given toCollateralTracker::exercise
function as a positive value, this later will mint new collateral shares to the buyer instead of burning them from his balance (realizedPremium > 0 ==> tokenToPay=-realizedPremium < 0
).This issue means that whenever the
PanopticPool::settleLongPremium
function is called, the options sellers of that leg chunks being settled will suffer a fund loss as even though thesettledTokens
accumulator will be updated correctly with the long premium, the actual long premium funds will not be collected from the buyer and made available for the sellers; instead, they will be minted to the buyer as additional collaterals.Impact
The
PanopticPool::settleLongPremium
function will not collect long premiums from buyer collateral shares and will instead mint new shares for the buyer, resulting in a loss of funds for all the options sellers.Tools Used
Manual review, VS Code
Recommended Mitigation
When calling
CollateralTracker::exercise
inPanopticPool::settleLongPremium
, the providedrealizedPremia
value shoud be made negative as follows:Assessed type
Context
The text was updated successfully, but these errors were encountered: