Platform: Code4rena
Start Date: 27/11/2023
Pot Size: $60,500 USDC
Total HM: 7
Participants: 72
Period: 7 days
Judge: Picodes
Total Solo HM: 2
Id: 309
League: ETH
Rank: 70/72
Findings: 1
Award: $11.32
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: osmanozdemir1
Also found by: 0xCiphky, Audinarey, Banditx0x, CRYP70, Cryptor, D1r3Wolf, KupiaSec, LokiThe5th, Sathish9098, Skylice, ThenPuli, Topmark, Udsen, ZanyBonzy, baice, ether_sky, fatherOfBlocks, foxb868, grearlake, hihen, hubble, hunter_w3b, lanrebayode77, leegh, lsaudit, minhtrng, nocoder, onchain-guardians, ptsanev, ro1sharkm, seaton0x1, sivanesh_808, t4sk, tapir, tpiliposian, ustas
11.3163 USDC - $11.32
https://github.com/code-423n4/2023-11-panoptic/blob/f75d07c345fd795f907385868c39bafcd6a56624/contracts/SemiFungiblePositionManager.sol#L130-L135 https://github.com/code-423n4/2023-11-panoptic/blob/f75d07c345fd795f907385868c39bafcd6a56624/contracts/SemiFungiblePositionManager.sol#L1250-L1329
The SemiFungiblePositionManager.sol
contract employs a fixed parameter, VEGOID
, assigned a constant value of 2: uint128 private constant VEGOID = 2
used in calculating premiums associated with liquidity utilization. This parameter acts as a multiplier, adjusting the sensitivity of premium calculations to changes in liquidity, akin to Vega in options.
In financial terms, Vega (or VEGOID in this context) measures the sensitivity of an option's price to changes in implied volatility. However, the fixed nature of VEGOID overlooks the dynamic nature of market conditions where volatility (liquidity sensitivity) can vary significantly.
Implied volatility (IV) is a key determinant in options pricing, representing the market's estimation of an asset's future volatility. A higher IV signifies increased uncertainty regarding an asset's price, usually leading to higher option premiums. Vega, in turn, measures an option's price sensitivity concerning a 1% change in implied volatility. It is pivotal for assessing an option's potential to gain value before expiration.
https://corporatefinanceinstitute.com/resources/derivatives/vega/
So, the fixed VEGOID
parameter overlooks the dynamic nature of implied volatility, leading to significant repercussions in options pricing:
VEGOID
parameter for changing market conditions could result in mispriced premiums, potentially causing financial losses for users.uint128 private constant VEGOID = 2;
The function that updates the Owed and Gross account liquidities:
function _getPremiaDeltas( uint256 currentLiquidity, int256 collectedAmounts ) private pure returns (uint256 deltaPremiumOwed, uint256 deltaPremiumGross) { // extract liquidity values uint256 removedLiquidity = currentLiquidity.leftSlot(); uint256 netLiquidity = currentLiquidity.rightSlot(); // premia spread equations are graphed and documented here: https://www.desmos.com/calculator/mdeqob2m04 // explains how we get from the premium per liquidity (calculated here) to the total premia collected and the multiplier // as well as how the value of VEGOID affects the premia // note that the "base" premium is just a common factor shared between the owed (long) and gross (short) // premia, and is only seperated to simplify the calculation // (the graphed equations include this factor without separating it) unchecked { uint256 totalLiquidity = netLiquidity + removedLiquidity; uint128 premium0X64_base; uint128 premium1X64_base; { uint128 collected0 = uint128(collectedAmounts.rightSlot()); uint128 collected1 = uint128(collectedAmounts.leftSlot()); // compute the base premium as collected * total / net^2 (from Eqn 3) premium0X64_base = Math .mulDiv(collected0, totalLiquidity * 2 ** 64, netLiquidity ** 2) .toUint128(); premium1X64_base = Math .mulDiv(collected1, totalLiquidity * 2 ** 64, netLiquidity ** 2) .toUint128(); } { uint128 premium0X64_owed; uint128 premium1X64_owed; { // compute the owed premium (from Eqn 3) uint256 numerator = netLiquidity + (removedLiquidity / 2 ** VEGOID); premium0X64_owed = Math .mulDiv(premium0X64_base, numerator, totalLiquidity) .toUint128(); premium1X64_owed = Math .mulDiv(premium1X64_base, numerator, totalLiquidity) .toUint128(); deltaPremiumOwed = uint256(0).toRightSlot(premium0X64_owed).toLeftSlot( premium1X64_owed ); } } { uint128 premium0X64_gross; uint128 premium1X64_gross; { // compute the gross premium (from Eqn 4) uint256 numerator = totalLiquidity ** 2 - totalLiquidity * removedLiquidity + ((removedLiquidity ** 2) / 2 ** (VEGOID)); premium0X64_gross = Math .mulDiv(premium0X64_base, numerator, totalLiquidity ** 2) .toUint128(); premium1X64_gross = Math .mulDiv(premium1X64_base, numerator, totalLiquidity ** 2) .toUint128(); deltaPremiumGross = uint256(0).toRightSlot(premium0X64_gross).toLeftSlot( premium1X64_gross ); } } } }
Manual review.
Short term: Implement an adjustable VEGOID
within defined limits, allowing authorized entities to update it based on observed market conditions.
Long Term: Develop algorithms to adaptively adjust VEGOID
concerning observed liquidity changes or shifts in market volatility and establish transparent guidelines for VEGOID
updates and educate stakeholders about its pivotal role in pricing accuracy, e.g here:
https://panoptic.xyz/research/streamia-vs-black-scholes
Other
#0 - c4-judge
2023-12-14T16:40:06Z
Picodes marked the issue as primary issue
#1 - c4-sponsor
2023-12-14T18:24:39Z
dyedm1 (sponsor) disputed
#2 - dyedm1
2023-12-14T18:29:26Z
This seems like a feature request rather than an actual issue. Although this mechanism is indeed described as similar to vega in options to help readers get an idea, the intended effect is to keep the liquidity utilization in check by increasing the premium multiplier when there is more demand for options buying than selling. Additionally, there is a disclaimer about the opinionated nature of this mechanism, noting that it may not be a fit for all protocols: https://github.com/code-423n4/2023-11-panoptic/blob/aa86461c9d6e60ef75ed5a1fe36a748b952c8666/contracts/SemiFungiblePositionManager.sol#L282
As long as the relationship between the premium multiplier and liquidity utilization holds as documented, there is no issue here.
#3 - c4-judge
2023-12-20T13:29:27Z
Picodes changed the severity to QA (Quality Assurance)
#4 - c4-judge
2023-12-26T23:14:51Z
Picodes marked the issue as grade-b