Skip to main content

PanopticPoolV2

Source reference for public revision e3b9d12. For deployed configuration, select the pool's engine on the parameter page.

Git Source

Inherits: Clone, Multicall, TransientReentrancyGuard

Title: The Panoptic Pool: Create permissionless options on a CLAMM.

Author: Axicon Labs Limited

Manages positions, collateral, liquidations and forced exercises.

State Variables
​

MIN_SWAP_TICK
​

Lower price bound used when no slippage check is required.

int24 internal constant MIN_SWAP_TICK = Constants.MIN_POOL_TICK - 1

MAX_SWAP_TICK
​

Upper price bound used when no slippage check is required.

int24 internal constant MAX_SWAP_TICK = Constants.MAX_POOL_TICK + 1

COMPUTE_PREMIA_AS_COLLATERAL
​

Flag that signals to compute premia for both the short and long legs of a position.

bool internal constant COMPUTE_PREMIA_AS_COLLATERAL = true

ONLY_AVAILABLE_PREMIUM
​

Flag that indicates only to include the share of (settled) premium that is available to collect when calling _calculateAccumulatedPremia.

bool internal constant ONLY_AVAILABLE_PREMIUM = false

COMMIT_LONG_SETTLED
​

Flag that signals to commit both collected Uniswap fees and settled long premium to s_settledTokens.

bool internal constant COMMIT_LONG_SETTLED = true

DONOT_COMMIT_LONG_SETTLED
​

Flag that signals to only commit collected Uniswap fees to s_settledTokens.

bool internal constant DONOT_COMMIT_LONG_SETTLED = false

ASSERT_SOLVENCY
​

Flag for _checkSolvency to indicate that an account should be solvent at all input ticks.

bool internal constant ASSERT_SOLVENCY = true

ASSERT_INSOLVENCY
​

Flag for _checkSolvency to indicate that an account should be insolvent at all input ticks.

bool internal constant ASSERT_INSOLVENCY = false

CALL_CT0
​

Flag for calls to CollateralTracker for token0

bool internal constant CALL_CT0 = true

CALL_CT1
​

Flag for calls to CollateralTracker for token1

bool internal constant CALL_CT1 = false

ADD
​

Flag that signals to add a new position to the user's positions hash (as opposed to removing an existing position).

bool internal constant ADD = true

NO_BUFFER
​

Multiplier for the collateral requirement in the general case.

uint24 internal constant NO_BUFFER = 10_000_000

DECIMALS
​

Decimals for computation (1 bps (1 basis point) precision: 0.01%).

uint type for composability with unsigned integer based mathematical operations.

uint256 internal constant DECIMALS = 10_000

PRICE_TRANSIENT_SLOT
​

Transient storage slot for the tick price

bytes32 internal constant PRICE_TRANSIENT_SLOT = keccak256("panoptic.price.snapshot")

SFPM
​

The "engine" of Panoptic - manages AMM liquidity and executes all mints/burns/exercises.

ISemiFungiblePositionManager public immutable SFPM

s_oraclePack
​

Stores a sorted set of 8 price observations used to compute the internal median oracle price.

OraclePack internal s_oraclePack

s_options
​

Nested mapping that tracks the option formation: address => tokenId => leg => premiaGrowth.

Premia growth is taking a snapshot of the chunk premium in SFPM, which is measuring the amount of fees collected for every chunk per unit of liquidity (net or short, depending on the isLong value of the specific leg index).

mapping(address => mapping(TokenId => LeftRightUnsigned[4])) internal s_options

s_grossPremiumLast
​

Per-chunk last value that gives the aggregate amount of premium owed to all sellers when multiplied by the total amount of liquidity totalLiquidity.

totalGrossPremium = totalLiquidity * (grossPremium(perLiquidityX64) - lastGrossPremium(perLiquidityX64)) / 2**64

Used to compute the denominator for the fraction of premium available to sellers to collect.

LeftRight - right slot is token0, left slot is token1.

mapping(bytes32 chunkKey => LeftRightUnsigned lastGrossPremium) internal s_grossPremiumLast

s_settledTokens
​

Per-chunk accumulator for tokens owed to sellers that have been settled and are now available.

This number increases when buyers pay long premium and when tokens are collected from Uniswap.

It decreases when sellers close positions and collect the premium they are owed.

LeftRight - right slot is token0, left slot is token1.

mapping(bytes32 chunkKey => LeftRightUnsigned settledTokens) internal s_settledTokens

s_positionBalance
​

Tracks the position size of a tokenId for a given user, and the pool utilizations and oracle tick values at the time of last mint.

mapping(address account => mapping(TokenId tokenId => PositionBalance positionBalance)) internal s_positionBalance

s_positionsHash
​

Tracks the position list hash (i.e keccak256(XORs of abi.encodePacked(positionIdList))).

A component of this hash also tracks the total number of legs across all positions (i.e. makes sure the length of the provided positionIdList matches).

The purpose of this system is to reduce storage usage when a user has more than one active position.

Instead of having to manage an unwieldy storage array and do lots of loads, we just store a hash of the array.

This hash can be cheaply verified on every operation with a user provided positionIdList - which can then be used for operations without having to every load any other data from storage.

mapping(address account => uint256 positionsHash) internal s_positionsHash

Functions
​

collateralToken0
​

Get the collateral token corresponding to token0 of the Uniswap pool.

function collateralToken0() public pure returns (CollateralTrackerV2);

Returns

NameTypeDescription
<none>CollateralTrackerV2Collateral token corresponding to token0 in Uniswap

collateralToken1
​

Get the collateral token corresponding to token1 of the Uniswap pool.

function collateralToken1() public pure returns (CollateralTrackerV2);

Returns

NameTypeDescription
<none>CollateralTrackerV2Collateral token corresponding to token1 in Uniswap

riskEngine
​

Get the address of the risk engine contract used by this Panoptic Pool.

function riskEngine() public pure returns (IRiskEngine);

Returns

NameTypeDescription
<none>IRiskEngineThe risk engine contract used by this Panoptic Pool

poolManager
​

Retrieve the PoolManager associated with that CollateralTracker.

stored as zero if not a Uniswap v4 pool

function poolManager() public pure returns (address);

Returns

NameTypeDescription
<none>addressThe PoolManager instance associated with that CollateralTracker's uniswap V4 pool

poolId
​

Get the Uniswap Pool ID for the Uniswap pool used by this Panoptic.

function poolId() public pure returns (uint64);

Returns

NameTypeDescription
<none>uint64The Pool ID for this Panoptic Pool

tickSpacing
​

Get the Uniswap tickSpacing for the Uniswap pool used by this Panoptic.

function tickSpacing() public pure returns (int24);

Returns

NameTypeDescription
<none>int24The tickSpacing for this Panoptic Pool

poolKey
​

Get the pool key for the Uniswap pool used by this Panoptic Pool.

For Uniswap v3, this is the address of the UniswapV3Pool

For Uniswap v4, this is Pool Key

For any other AMMs, this is assumed to be an address

function poolKey() public pure returns (bytes calldata key);

Returns

NameTypeDescription
keybytesThe Pool Key for this Panoptic Pool.

onlyRiskEngine
​

Reverts if the associated Risk Engine is not the caller.

modifier onlyRiskEngine() ;

_onlyRiskEngine
​

Internal function to verify that the caller is the risk engine

Reverts with NotGuardian error if msg.sender is not the risk engine

function _onlyRiskEngine() internal view;

lockSafeMode
​

Force safe mode lock: effective safe mode must be treated as level 3.

function lockSafeMode() external onlyRiskEngine;

unlockSafeMode
​

Remove forced safe mode lock.

function unlockSafeMode() external onlyRiskEngine;

constructor
​

Store the address of the canonical SemiFungiblePositionManager (SFPM) contract.

constructor(ISemiFungiblePositionManager _sfpm) ;

Parameters

NameTypeDescription
_sfpmISemiFungiblePositionManagerThe address of the SFPM

initialize
​

Initializes the median oracle of a new PanopticPool instance with median oracle state and performs initial token approvals.

Must be called first (by the factory contract) before any transaction can occur.

function initialize() external;

onERC1155Received
​

Returns magic value when called by the SemiFungiblePositionManager contract to indicate that this contract supports ERC1155.

function onERC1155Received(address, address, uint256, uint256, bytes memory) external pure returns (bytes4);

assertMinCollateralValues
​

Reverts if the caller has a lower collateral balance than required to meet the provided minValue0 and minValue1.

Can be used for composable slippage checks with multicall (such as for a force exercise or liquidation).

function assertMinCollateralValues(uint256 minValue0, uint256 minValue1) external view;

Parameters

NameTypeDescription
minValue0uint256The minimum acceptable token0 value of collateral
minValue1uint256The minimum acceptable token1 value of collateral

assertBlockRange
​

Reverts if the current block number is below minBlockNumber or above maxBlockNumber.

Can be used for composable deadline checks with multicall (such as for RFQ order expiry).

function assertBlockRange(uint256 minBlockNumber, uint256 maxBlockNumber) external view;

Parameters

NameTypeDescription
minBlockNumberuint256The earliest acceptable block number
maxBlockNumberuint256The latest acceptable block number

assertTimestampRange
​

Reverts if the current block timestamp is below minTimestamp or above maxTimestamp.

Can be used for composable deadline checks with multicall (such as for RFQ order expiry).

function assertTimestampRange(uint256 minTimestamp, uint256 maxTimestamp) external view;

Parameters

NameTypeDescription
minTimestampuint256The earliest acceptable block timestamp
maxTimestampuint256The latest acceptable block timestamp

assertTickRange
​

Reverts if the current pool tick is outside the provided range.

Can be used for composable price checks with multicall (such as to verify quoted price is still valid).

function assertTickRange(int24 minTick, int24 maxTick) external view;

Parameters

NameTypeDescription
minTickint24The minimum acceptable tick (inclusive)
maxTickint24The maximum acceptable tick (inclusive)

getAssetsOf
​

Get the balance of underlying collateral tokens (token0 and token1) held by an account.

This queries the CollateralTracker for both tokens and converts shares to underlying asset amounts.

function getAssetsOf(address account) public view returns (uint256 assets0, uint256 assets1);

Parameters

NameTypeDescription
accountaddressThe address of the user to query balances for.

Returns

NameTypeDescription
assets0uint256The total amount of token0 collateral owned by the account.
assets1uint256The total amount of token1 collateral owned by the account.

getChunkData
​

Get onchain data for a liquidity chunk.

Retrieves both active liquidity from the SFPM and settled tokens from the Panoptic Pool's state for a given tick range.

function getChunkData(int24 tickLower, int24 tickUpper)
external
view
returns (
LeftRightUnsigned liquidities0,
LeftRightUnsigned liquidities1,
LeftRightUnsigned settled0,
LeftRightUnsigned settled1
);

Parameters

NameTypeDescription
tickLowerint24The lower tick boundary of the chunk.
tickUpperint24The upper tick boundary of the chunk.

Returns

NameTypeDescription
liquidities0LeftRightUnsignedA packed struct containing the removed/bought liquidity (left slot) and net/available liquidity (right slot) for token0.
liquidities1LeftRightUnsignedA packed struct containing the removed/bought liquidity (left slot) and net/available liquidity (right slot) for token1.
settled0LeftRightUnsignedA packed struct containing settled tokens within the chunk for tokenType = 0.
settled1LeftRightUnsignedA packed struct containing settled tokens within the chunk for tokenType = 1.

validateCollateralWithdrawable
​

Determines if account is eligible to withdraw or transfer collateral.

Checks whether account is solvent with BP_DECREASE_BUFFER according to _validateSolvency.

Prevents insolvent and near-insolvent accounts from withdrawing collateral before they are liquidated.

Reverts if account is not solvent with BP_DECREASE_BUFFER.

function validateCollateralWithdrawable(address user, TokenId[] calldata positionIdList, bool usePremiaAsCollateral)
external
view
ensureNonReentrantView;

Parameters

NameTypeDescription
useraddressThe account to check for collateral withdrawal eligibility
positionIdListTokenId[]The list of all option positions held by user
usePremiaAsCollateralboolWhether to compute accumulated premia for all legs held by the user for collateral (true), or just owed premia for long legs (false)

getFullPositionsData
​

Returns accumulated premium, position balances, per-position collateral requirements, and per-position net premia.

function getFullPositionsData(address user, bool includePendingPremium, TokenId[] calldata positionIdList)
external
view
returns (
LeftRightUnsigned shortPremium,
LeftRightUnsigned longPremium,
PositionBalance[] memory positionBalances,
LeftRightUnsigned[] memory collateralRequirements,
LeftRightSigned[] memory netPremiaPerPosition
);

Parameters

NameTypeDescription
useraddressAddress of the user that owns the positions
includePendingPremiumboolIf true, include pending (unsettled) premium; if false, only settled
positionIdListTokenId[]List of positions. Written as [tokenId1, tokenId2, ...]

Returns

NameTypeDescription
shortPremiumLeftRightUnsignedTotal premium owed to short legs (token0: right, token1: left)
longPremiumLeftRightUnsignedTotal premium owed by long legs (token0: right, token1: left)
positionBalancesPositionBalance[]PositionBalance data for each position
collateralRequirementsLeftRightUnsigned[]Net collateral required per position (token0: right, token1: left)
netPremiaPerPositionLeftRightSigned[]Net premia per position: short minus long (token0: right, token1: left)

_calculateAccumulatedPremia
​

Calculate the accumulated premia owed from the option buyer to the option seller.

function _calculateAccumulatedPremia(
address user,
TokenId[] calldata positionIdList,
bool usePremiaAsCollateral,
bool includePendingPremium,
int24 atTick,
bool perPositionPremia
)
internal
view
returns (
LeftRightUnsigned[2] memory shortLongPremium,
PositionBalance[] memory balances,
LeftRightSigned[] memory netPremiaPerPosition
);

Parameters

NameTypeDescription
useraddressThe holder of options
positionIdListTokenId[]The list of all option positions held by user
usePremiaAsCollateralboolWhether to compute accumulated premia for all legs held by the user for collateral (true), or just owed premia for long legs (false)
includePendingPremiumboolIf true, include premium that is owed to the user but has not yet settled; if false, only include premium that is available to collect
atTickint24The current tick of the Uniswap pool
perPositionPremiaboolIf true, compute and return per-position net premia; if false, netPremiaPerPosition is empty

Returns

NameTypeDescription
shortLongPremiumLeftRightUnsigned[2]The total amount of premium owed (which may includePendingPremium) to the short legs in positionIdList (token0: right slot, token1: left slot)
balancesPositionBalance[]A list of balances and pool utilization for each position, of the form [[tokenId0, balances0], [tokenId1, balances1], ...]
netPremiaPerPositionLeftRightSigned[]The net premia (short minus long) per position (token0: right slot, token1: left slot), empty if perPositionPremia is false

pokeOracle
​

Updates the internal oracle by recording the new exponential moving averages based on the current tick and computing a new median.

This function allows anyone to update the oracle state, which is used for risk calculations and collateral requirements. The oracle values can only be updated once every 64s

function pokeOracle() external nonReentrant;

dispatch
​

Mints or burns each tokenId in `positionIdList.

function dispatch(
TokenId[] calldata positionIdList,
TokenId[] calldata finalPositionIdList,
uint128[] calldata positionSizes,
int24[3][] calldata tickAndSpreadLimits,
bool usePremiaAsCollateral,
uint256 builderCode
) external nonReentrant;

Parameters

NameTypeDescription
positionIdListTokenId[]The list of tokenIds for the option positions to be minted or burnt
finalPositionIdListTokenId[]The final positionIdList after all the tokens have been minted/burnt
positionSizesuint128[]The list of positionSize for the position to be minted (0 for burns)
tickAndSpreadLimitsint24[3][]A Nx3 array containing: the lower [0] and upper [1] bounds of an acceptable open interval for the ending price, and the maximum amount of "spread" defined as removedLiquidity/netLiquidity for a new position and denominated as X10_000 = (ratioLimit * 10_000)
usePremiaAsCollateralboolWhether to compute accumulated premia for all legs held by the user for collateral (true), or just owed premia for long legs (false)
builderCodeuint256The builder code for fee distribution

_mintOptions
​

Validates the current options of the user, and mints a new position.

function _mintOptions(
TokenId tokenId,
uint128 positionSize,
uint24 effectiveLiquidityLimit,
address owner,
int24[2] memory tickLimits,
RiskParameters riskParameters
) internal returns (LeftRightSigned paidAmounts, int24 finalTick);

Parameters

NameTypeDescription
tokenIdTokenIdThe tokenId of the newly minted position
positionSizeuint128The size of the position to be minted, expressed in terms of the asset
effectiveLiquidityLimituint24Maximum amount of "spread" defined as removedLiquidity/netLiquidity for a new position and denominated as X32 = (ratioLimit * 2^32)
owneraddressThe owner of the option position to be minted
tickLimitsint24[2]The lower and upper bound of an acceptable open interval for the ending price
riskParametersRiskParametersThe RiskEngine's core parameters

_payCommissionAndWriteData
​

Take the commission fees for minting tokenId and settle any other required collateral deltas.

function _payCommissionAndWriteData(
TokenId tokenId,
uint128 positionSize,
address owner,
LeftRightSigned netAmmDelta,
RiskParameters riskParameters
) internal returns (uint32 utilizations, LeftRightSigned paidAmounts);

Parameters

NameTypeDescription
tokenIdTokenIdThe option position
positionSizeuint128The size of the position, expressed in terms of the asset
owneraddressThe owner of the option position to be minted
netAmmDeltaLeftRightSignedThe amount of tokens moved during creation of the option position
riskParametersRiskParametersThe RiskEngine's core parameters

Returns

NameTypeDescription
utilizationsuint32Packing of the pool utilization (how much funds are in the Panoptic pool versus the AMM pool at the time of minting), right 64bits for token0 and left 64bits for token1, defined as (inAMM * 10_000) / totalAssets() where totalAssets is the total tracked assets in the AMM and PanopticPool minus fees and donations to the Panoptic pool
paidAmountsLeftRightSignedThe amount of tokens paid when creating that option for token0 (right) and token1 (left)

_settleMint
​

Internal function that calls CollateralTracker to take commission and settle ITM amounts on option creation.

function _settleMint(
address optionOwner,
int128 longAmount,
int128 shortAmount,
int128 ammDeltaAmount,
RiskParameters riskParameters,
bool isCollateralToken0
) internal returns (uint32 utilization, int128 paid);

Parameters

NameTypeDescription
optionOwneraddressThe user minting the option
longAmountint128The amount of longs
shortAmountint128The amount of shorts
ammDeltaAmountint128The amount of tokens moved during creation of the option position
riskParametersRiskParametersThe RiskEngine's core parameters
isCollateralToken0boolThe flag that determines if the call is to ct0 or ct1

Returns

NameTypeDescription
utilizationuint32The final utilization of the collateral vault (in basis points)
paidint128The total amount of tokens paid by the option owner (negative if tokens were received)

_getCt
​

Return the collateral tracker for the given token.

function _getCt(bool isCollateralToken0) internal pure returns (CollateralTrackerV2);

Parameters

NameTypeDescription
isCollateralToken0boolTrue for token0, false for token1

Returns

NameTypeDescription
<none>CollateralTrackerV2The corresponding CollateralTracker

_burnAllOptionsFrom
​

Close all options in positionIdList.

function _burnAllOptionsFrom(
address owner,
int24 tickLimitLow,
int24 tickLimitHigh,
bool commitLongSettled,
TokenId[] calldata positionIdList
) internal returns (LeftRightSigned netPaid, LeftRightSigned[4][] memory premiasByLeg);

Parameters

NameTypeDescription
owneraddressThe owner of the option position to be closed
tickLimitLowint24The lower bound of an acceptable open interval for the ending price on each option close
tickLimitHighint24The upper bound of an acceptable open interval for the ending price on each option close
commitLongSettledboolWhether to commit the long premium that will be settled to storage (disabled during liquidations)
positionIdListTokenId[]The list of option positions to close

Returns

NameTypeDescription
netPaidLeftRightSignedThe net amount of tokens paid after closing the positions
premiasByLegLeftRightSigned[4][]The amount of premia settled by the user for each leg of the position

_burnOptions
​

Close a single option position.

function _burnOptions(
TokenId tokenId,
uint128 positionSize,
int24[2] memory tickLimits,
address owner,
bool commitLongSettled,
RiskParameters riskParameters
) internal returns (LeftRightSigned paidAmounts, LeftRightSigned[4] memory premiaByLeg, int24 finalTick);

Parameters

NameTypeDescription
tokenIdTokenIdThe option position to burn
positionSizeuint128The size of the position to burn
tickLimitsint24[2]The lower and upper bound of an acceptable open interval for the ending price on each option close
owneraddressThe owner of the option position to be burned
commitLongSettledboolWhether to commit the long premium that will be settled to storage (disabled during liquidations)
riskParametersRiskParametersThe RiskEngine's core risk parameters

Returns

NameTypeDescription
paidAmountsLeftRightSignedThe net amount of tokens paid after closing the position
premiaByLegLeftRightSigned[4]The amount of premia settled by the user for each leg of the position
finalTickint24The final tick after burning the options

_settleBurn
​

Internal function that calls CollateralTracker to Exercise an option and pay to the seller what is owed from the buyer.

Called when a position is burnt because it may need to be exercised.

function _settleBurn(
address optionOwner,
int128 longAmount,
int128 shortAmount,
int128 ammDeltaAmount,
int128 realizedPremium,
RiskParameters riskParameters,
bool isCollateralToken0
) internal returns (int128 paid);

Parameters

NameTypeDescription
optionOwneraddressThe owner of the option being burned
longAmountint128The notional value of the long legs of the position (if any)
shortAmountint128The notional value of the short legs of the position (if any)
ammDeltaAmountint128The amount of tokens moved during the option close
realizedPremiumint128Premium to settle on the current positions
riskParametersRiskParametersThe RiskEngine's core risk parameters
isCollateralToken0bool

Returns

NameTypeDescription
paidint128The amount of tokens paid when closing that position

_validateSolvency
​

Validates the solvency of user.

Falls back to the most conservative (least solvent) oracle tick if the sum of the squares of the deltas between all oracle ticks exceeds MAX_TICKS_DELTA^2, defined in the RiskEngine.

Effectively, this means that the users must be solvent at all oracle ticks if the at least one of the ticks is sufficiently stale.

function _validateSolvency(
address user,
TokenId[] calldata positionIdList,
uint32 buffer,
bool usePremiaAsCollateral,
uint8 safeMode
) internal view returns (OraclePack);

Parameters

NameTypeDescription
useraddressThe account to validate
positionIdListTokenId[]The list of positions to validate solvency for
bufferuint32The buffer to apply to the collateral requirement for user
usePremiaAsCollateralboolWhether to compute accumulated premia for all legs held by the user for collateral (true), or just owed premia for long legs (false)
safeModeuint8

Returns

NameTypeDescription
<none>OraclePackIf nonzero (enough time has passed since last observation), the updated value for s_oraclePack with a new observation

_settleOptions
​

Settles an option position by updating settlement data and burning premium from the owner's collateral

Calls _updateSettlementPostBurn to calculate realized premia, then settles the burn in both collateral trackers

function _settleOptions(
address owner,
TokenId tokenId,
uint128 positionSize,
RiskParameters riskParameters,
int24 currentTick
) internal;

Parameters

NameTypeDescription
owneraddressThe address of the position owner whose options are being settled
tokenIdTokenIdThe token ID representing the option position to settle
positionSizeuint128The size of the position in contracts
riskParametersRiskParametersThe risk parameters for this pool
currentTickint24The current tick at which to settle the position

_updateSettlementPostMint
​

Adds collected tokens to s_settledTokens and adjusts s_grossPremiumLast for any liquidity added.

Always called after mintTokenizedPosition.

function _updateSettlementPostMint(
RiskParameters riskParameters,
TokenId tokenId,
LeftRightUnsigned[4] memory collectedByLeg,
uint128 positionSize,
uint24 effectiveLiquidityLimit,
address owner
) internal;

Parameters

NameTypeDescription
riskParametersRiskParameters
tokenIdTokenIdThe option position that was minted
collectedByLegLeftRightUnsigned[4]The amount of tokens collected in the corresponding chunk for each leg of the position
positionSizeuint128The size of the position, expressed in terms of the asset
effectiveLiquidityLimituint24Maximum amount of "spread" defined as removedLiquidity/netLiquidity
owneraddressThe owner of the option position to be minted

_updateSettlementPostBurn
​

Updates settled tokens and grossPremiumLast for a chunk after a burn and returns premium info.

function _updateSettlementPostBurn(
address owner,
TokenId tokenId,
LeftRightUnsigned[4] memory collectedByLeg,
uint128 positionSize,
RiskParameters riskParameters,
LeftRightSigned commitLongSettledAndKeepOpen
) internal returns (LeftRightSigned realizedPremia, LeftRightSigned[4] memory premiaByLeg);

Parameters

NameTypeDescription
owneraddressThe owner of the option position that was burnt
tokenIdTokenIdThe option position that was burnt
collectedByLegLeftRightUnsigned[4]The amount of tokens collected in the corresponding chunk for each leg of the position
positionSizeuint128The size of the position, expressed in terms of the asset
riskParametersRiskParameters
commitLongSettledAndKeepOpenLeftRightSignedWhether to commit the long premium that will be settled to storage (rightSlot != 0) and whether the position is being burned (leftSlot == 0)

Returns

NameTypeDescription
realizedPremiaLeftRightSignedThe amount of premia settled by the user
premiaByLegLeftRightSigned[4]The amount of premia settled by the user for each leg of the position

dispatchFrom
​

Dispatches liquidations, forced exercises, or long premium settlements based on account solvency

This function determines the appropriate action based on solvency checks at multiple price points:

  • If insolvent at all ticks: Execute liquidation (burns all positions)
  • If solvent at all ticks: Execute force exercise or settle long premium based on list lengths
  • Otherwise: Revert as account is not fully margin called

The function uses position list lengths to determine the specific operation:

  • Same length lists between positionIdListTo and positionIdListToFinal: Settle long premium
  • Final list one shorter: Force exercise
  • Final list empty: Liquidation
function dispatchFrom(
TokenId[] calldata positionIdListFrom,
address account,
TokenId[] calldata positionIdListTo,
TokenId[] calldata positionIdListToFinal,
LeftRightUnsigned usePremiaAsCollateral
) external payable nonReentrant;

Parameters

NameTypeDescription
positionIdListFromTokenId[]List of positions held by the caller (msg.sender)
accountaddressThe account being acted upon (liquidated, exercised, or settled)
positionIdListToTokenId[]Current positions of the target account
positionIdListToFinalTokenId[]Expected positions after the operation completes
usePremiaAsCollateralLeftRightUnsignedPacked value indicating whether to use premia as collateral: - leftSlot: For the caller (msg.sender) - rightSlot: For the target account

_accrueInterests
​

Internal function that calls CollateralTracker to accrue the protocol-wide interest.

That call will pay any outstanding interest by the caller and update the unrealizedGlobalInterest, currentBorrowIndex, and currentEpoch

function _accrueInterests() internal;

_delegate
​

Internal function that calls CollateralTracker to increase the share balance of a user by 2^248 - 1 without updating the total supply.

function _delegate(address delegatee, bool isCollateralToken0) internal;

Parameters

NameTypeDescription
delegateeaddressThe account to increase the balance of
isCollateralToken0boolThe flag that determines if the call is to ct0 or ct1

_revoke
​

Internal function that calls CollateralTracker to decrease the share balance of a user by 2^248 - 1 without updating the total supply.

function _revoke(address delegatee, bool isCollateralToken0) internal;

Parameters

NameTypeDescription
delegateeaddressThe account to decrease the balance of
isCollateralToken0boolThe flag that determines if the call is to ct0 or ct1

_refund
​

Internal function that calls CollateralTracker to refunds tokens to refunder from refundee.

function _refund(address refunder, int256 assets, bool isCollateralToken0) internal;

Parameters

NameTypeDescription
refunderaddressThe account refunding tokens to refundee
assetsint256The amount of assets to refund. Positive means a transfer from refunder to refundee, vice versa for negative
isCollateralToken0boolThe flag that determines if the call is to ct0 or ct1

_getRefundAmounts
​

Internal function that calls CollateralTracker to substitute surplus tokens to a caller in exchange for any potential token shortages prior to revoking virtual shares from a payor.

function _getRefundAmounts(address payor, LeftRightSigned fees, int24 atTick)
internal
view
returns (LeftRightSigned refundAmounts);

Parameters

NameTypeDescription
payoraddressThe address of the user being exercised/settled
feesLeftRightSignedIf applicable, fees to debit from caller (rightSlot = currency0 left = currency1), 0 for settleLongPremium
atTickint24The tick at which to convert between currency0/currency1 when redistributing the surplus tokens

Returns

NameTypeDescription
refundAmountsLeftRightSignedThe LeftRight-packed deltas for currency0/currency1 to move from the caller to the payor

_liquidate
​

Liquidates a distressed account. Will burn all positions and issue a bonus to the liquidator.

Will revert if liquidated account is solvent at one of the oracle ticks or if TWAP tick is too far away from the current tick.

function _liquidate(address liquidatee, TokenId[] calldata positionIdList, int24 twapTick, int24 currentTick)
internal;

Parameters

NameTypeDescription
liquidateeaddressAddress of the distressed account
positionIdListTokenId[]List of positions owned by the user. Written as [tokenId1, tokenId2, ...]
twapTickint24
currentTickint24

_forceExercise
​

Force the exercise of a single position. Exercisor will have to pay a fee to the force exercisee.

function _forceExercise(address account, TokenId tokenId, int24 twapTick, int24 currentTick) internal;

Parameters

NameTypeDescription
accountaddressAddress of the distressed account
tokenIdTokenIdThe position to be force exercised
twapTickint24The oracle TWAP tick used for collateral and exercise fee calculations
currentTickint24The current tick of the Uniswap pool

_refundRevoke
​

Settle refund amounts with an account and revoke any remaining delegated virtual shares.

function _refundRevoke(address account, LeftRightSigned refundAmounts) internal;

Parameters

NameTypeDescription
accountaddressThe account to refund and revoke
refundAmountsLeftRightSignedThe refund deltas for token0 (right slot) and token1 (left slot)

_settlePremium
​

Settle unpaid premium on a position owned by owner.

Called by sellers on buyers of their chunk to increase the available premium for withdrawal (before closing their position).

This feature is only available when owner is solvent and has the requisite tokens to settle the premium.

function _settlePremium(address owner, TokenId tokenId, int24 twapTick, int24 currentTick) internal;

Parameters

NameTypeDescription
owneraddressThe owner of the option position to make premium payments on
tokenIdTokenIdThe position to be force exercised; this position must contain at least one option long leg
twapTickint24
currentTickint24

_checkSolvencyAtTicks
​

Check whether an account is solvent at a given atTick with a collateral requirement of buffer/10_000 multiplied by the requirement of positionIdList.

Reverts if account is not solvent at all provided ticks and expectedSolvent == true, or if account is solvent at all ticks and !expectedSolvent.

function _checkSolvencyAtTicks(
address account,
uint8 safeMode,
TokenId[] calldata positionIdList,
int24 currentTick,
int24[] memory atTicks,
bool usePremiaAsCollateral,
uint256 buffer
) internal view returns (uint256);

Parameters

NameTypeDescription
accountaddressThe account to check solvency for
safeModeuint8The current safe mode status
positionIdListTokenId[]The list of positions to check solvency for
currentTickint24The current tick of the Uniswap pool (needed for fee calculations)
atTicksint24[]An array of ticks to check solvency at
usePremiaAsCollateralboolWhether to compute accumulated premia for all legs held by the user for collateral (true), or just owed premia for long legs (false)
bufferuint256The buffer to apply to the collateral requirement

Returns

NameTypeDescription
<none>uint256boolean flag that determines if account is solvent

_isAccountSolvent
​

Check whether an account is solvent at a given atTick with a collateral requirement of buffer/10_000 multiplied by the requirement of positionBalanceArray.

function _isAccountSolvent(
address account,
int24 atTick,
TokenId[] calldata positionIdList,
PositionBalance[] memory positionBalanceArray,
LeftRightUnsigned shortPremium,
LeftRightUnsigned longPremium,
uint256 buffer
) internal view returns (bool);

Parameters

NameTypeDescription
accountaddressThe account to check solvency for
atTickint24The tick to check solvency at
positionIdListTokenId[]The list of all option positions held by the user
positionBalanceArrayPositionBalance[]A list of balances and pool utilization for each position, of the form [[tokenId0, balances0], [tokenId1, balances1], ...]
shortPremiumLeftRightUnsignedThe total amount of premium (prorated by available settled tokens) owed to the short legs of account
longPremiumLeftRightUnsignedThe total amount of premium owed by the long legs of account
bufferuint256The buffer to apply to the collateral requirement

Returns

NameTypeDescription
<none>boolWhether the account is solvent at the given tick

getRiskParameters
​

Get risk parameters from the risk engine.

Also checks whether the current tick has deviated too much from the previously stored ticks. Computed in the RiskEngine

function getRiskParameters(uint256 builderCode)
public
view
returns (RiskParameters riskParameters, int24 currentTick);

isSafeMode
​

Checks whether the current tick has deviated too much from the previously stored ticks. Computed in the RiskEngine

function isSafeMode() external view returns (uint8);

Returns

NameTypeDescription
<none>uint8Whether the current tick has deviated too much to warrant putting the protocol in safe mode

_validatePositionList
​

Makes sure that the positions in the incoming user's list match the existing active option positions.

function _validatePositionList(address account, TokenId[] calldata positionIdList) internal view;

Parameters

NameTypeDescription
accountaddressThe owner of the incoming list of positions
positionIdListTokenId[]The existing list of active options for the owner

_updatePositionsHash
​

Updates the hash for all positions owned by an account. This fingerprints the list of all incoming options with a single hash.

The outcome of this function will be to update the hash of positions. This is done as a duplicate/validation check of the incoming list O(N).

The positions hash is stored as the XOR of the keccak256 of each tokenId. Updating will XOR the existing hash with the new tokenId. The same update can either add a new tokenId (when minting an option), or remove an existing one (when burning it).

function _updatePositionsHash(address account, TokenId tokenId, bool addFlag, uint8 maxLegs) internal;

Parameters

NameTypeDescription
accountaddressThe owner of tokenId
tokenIdTokenIdThe option position
addFlagboolWhether to add tokenId to the hash (true) or remove it (false)
maxLegsuint8

getOracleTicks
​

Computes and returns all oracle ticks.

function getOracleTicks()
external
view
returns (int24 currentTick, int24 spotTick, int24 medianTick, int24 latestTick, OraclePack oraclePack);

Returns

NameTypeDescription
currentTickint24The current tick in the Uniswap pool
spotTickint24The fast oracle tick, sourced from the internal 10-minute EMA.
medianTickint24The slow oracle tick, calculated as the median of the 8 stored price points in the internal oracle.
latestTickint24The reconstructed absolute tick of the latest observation stored in the internal oracle.
oraclePackOraclePackThe current value of the 8-slot internal observation queue (s_oraclePack)

_getOracleTicks
​

Internal call that computes and returns all oracle ticks.

function _getOracleTicks(int24 currentTick)
internal
view
returns (int24 spotTick, int24 medianTick, int24 latestTick);

Parameters

NameTypeDescription
currentTickint24the current pool tick

Returns

NameTypeDescription
spotTickint24The fast oracle tick, sourced from the internal 10-minute EMA.
medianTickint24The slow oracle tick, calculated as the median of the 8 stored price points in the internal oracle.
latestTickint24The reconstructed absolute tick of the latest observation stored in the internal oracle.

numberOfLegs
​

Get the current number of legs across all open positions for an account.

function numberOfLegs(address user) external view ensureNonReentrantView returns (uint256);

Parameters

NameTypeDescription
useraddressThe account to query

Returns

NameTypeDescription
<none>uint256Number of legs across the open positions of user

getTWAP
​

Get the oracle price used to check solvency in liquidations.

function getTWAP() public view returns (int24 twapTick);

Returns

NameTypeDescription
twapTickint24The current oracle price used to check solvency in liquidations

getCurrentTick
​

Get the current tick of the underlying pool.

function getCurrentTick() public view returns (int24 currentTick);

_checkLiquiditySpread
​

Ensure the effective liquidity in a given chunk is above a certain threshold.

function _checkLiquiditySpread(TokenId tokenId, uint256 leg, uint256 effectiveLiquidityLimit)
internal
view
returns (uint256 totalLiquidity);

Parameters

NameTypeDescription
tokenIdTokenIdAn option position
leguint256A leg index of tokenId corresponding to a tickLower-tickUpper chunk
effectiveLiquidityLimituint256Maximum amount of "spread" defined as removedLiquidity/netLiquidity for a new position denominated as X10_000 = (ratioLimit * 10_000)

Returns

NameTypeDescription
totalLiquidityuint256The total liquidity deposited in that chunk: totalLiquidity = netLiquidity + removedLiquidity

_getPremia
​

Compute the premia collected for a single option position tokenId.

function _getPremia(TokenId tokenId, uint128 positionSize, address owner, bool usePremiaAsCollateral, int24 atTick)
internal
view
returns (LeftRightSigned[4] memory premiaByLeg, uint256[2][4] memory premiumAccumulatorsByLeg);

Parameters

NameTypeDescription
tokenIdTokenIdThe option position
positionSizeuint128The number of contracts (size) of the option position
owneraddressThe holder of the tokenId option
usePremiaAsCollateralboolWhether to compute accumulated premia for all legs held by the user for collateral (true), or just owed premia for long legs (false)
atTickint24The tick at which the premia is calculated -> use (atTick < type(int24).max) to compute it up to current block. atTick = type(int24).max will only consider fees as of the last on-chain transaction

Returns

NameTypeDescription
premiaByLegLeftRightSigned[4]The amount of premia owed to the user for each leg of the position
premiumAccumulatorsByLeguint256[2][4]The amount of premia accumulated for each leg of the position

_getAvailablePremium
​

Query the amount of premium available for withdrawal given a certain premiumOwed for a chunk.

Based on the ratio between settledTokens and the total premium owed to sellers in a chunk.

The ratio is capped at 1 (as the base ratio can be greater than one if some seller forfeits enough premium).

function _getAvailablePremium(
uint256 totalLiquidity,
LeftRightUnsigned settledTokens,
LeftRightUnsigned grossPremiumLast,
LeftRightUnsigned premiumOwed,
uint256[2] memory premiumAccumulators
) internal pure returns (LeftRightUnsigned);

Parameters

NameTypeDescription
totalLiquidityuint256The updated total liquidity amount for the chunk
settledTokensLeftRightUnsignedLeftRight accumulator for the amount of tokens that have been settled (collected or paid)
grossPremiumLastLeftRightUnsignedThe last values used with premiumAccumulators to compute the total premium owed to sellers
premiumOwedLeftRightUnsignedThe amount of premium owed to sellers in the chunk
premiumAccumulatorsuint256[2]The current values of the premium accumulators for the chunk

Returns

NameTypeDescription
<none>LeftRightUnsignedThe amount of token0/token1 premium available for withdrawal

_getLiquidities
​

Query the total amount of liquidity sold in the corresponding chunk for a position leg.

totalLiquidity (total sold) = removedLiquidity + netLiquidity (in AMM).

function _getLiquidities(TokenId tokenId, uint256 leg)
internal
view
returns (uint256 totalLiquidity, uint128 netLiquidity, uint128 removedLiquidity);

Parameters

NameTypeDescription
tokenIdTokenIdThe option position
leguint256The leg of the option position to get totalLiquidity for

Returns

NameTypeDescription
totalLiquidityuint256The total amount of liquidity sold in the corresponding chunk for a position leg
netLiquidityuint128The amount of liquidity available in the corresponding chunk for a position leg
removedLiquidityuint128The amount of liquidity removed through buying in the corresponding chunk for a position leg

_getLiquiditiesFromSFPM
​

Query the SFPM for the net and removed liquidity of this pool's account in a given chunk.

function _getLiquiditiesFromSFPM(int24 tickLower, int24 tickUpper, uint256 tokenType)
internal
view
returns (LeftRightUnsigned accountLiquidities);

Parameters

NameTypeDescription
tickLowerint24The lower tick of the chunk
tickUpperint24The upper tick of the chunk
tokenTypeuint256The token type (0 or 1) of the chunk

Returns

NameTypeDescription
accountLiquiditiesLeftRightUnsignedNet liquidity (right slot) and removed liquidity (left slot)

Events
​

AccountLiquidated
​

Emitted when an account is liquidated.

event AccountLiquidated(address indexed liquidator, address indexed liquidatee, LeftRightSigned bonusAmounts);

Parameters

NameTypeDescription
liquidatoraddressAddress of the caller liquidating the distressed account
liquidateeaddressAddress of the distressed/liquidatable account
bonusAmountsLeftRightSignedLeftRight encoding for the the bonus paid for token 0 (right slot) and 1 (left slot) to the liquidator

ForcedExercised
​

Emitted when a position is force exercised.

event ForcedExercised(
address indexed exercisor, address indexed user, TokenId indexed tokenId, LeftRightSigned exerciseFee
);

Parameters

NameTypeDescription
exercisoraddressAddress of the account that forces the exercise of the position
useraddressAddress of the owner of the liquidated position
tokenIdTokenIdTokenId of the liquidated position
exerciseFeeLeftRightSignedLeftRight encoding for the cost paid by the exercisor to force the exercise of the token; the cost for token 0 (right slot) and 1 (left slot) is represented as negative

PremiumSettled
​

Emitted when premium is settled independent of a mint/burn (e.g. during settlePremium).

event PremiumSettled(
address indexed user, TokenId indexed tokenId, uint256 legIndex, LeftRightSigned settledAmounts
);

Parameters

NameTypeDescription
useraddressAddress of the owner of the settled position
tokenIdTokenIdTokenId of the settled position
legIndexuint256The leg index of tokenId that the premium was settled for
settledAmountsLeftRightSignedLeftRight encoding for the amount of premium settled for token0 (right slot) and token1 (left slot)

OptionBurnt
​

Emitted when an option is burned.

event OptionBurnt(
address indexed recipient, uint128 positionSize, TokenId indexed tokenId, LeftRightSigned[4] premiaByLeg
);

Parameters

NameTypeDescription
recipientaddressUser that burnt the option
positionSizeuint128The number of contracts burnt, expressed in terms of the asset
tokenIdTokenIdTokenId of the burnt option
premiaByLegLeftRightSigned[4]LeftRight packing for the amount of premia settled for token0 (right) and token1 (left) for each leg of tokenId

OptionMinted
​

Emitted when an option is minted.

event OptionMinted(address indexed recipient, TokenId indexed tokenId, PositionBalance balanceData);

Parameters

NameTypeDescription
recipientaddressUser that minted the option
tokenIdTokenIdTokenId of the created option
balanceDataPositionBalanceThe PositionBalance data for tokenId containing the number of contracts, pool utilizations, and ticks at mint

Errors
​

Deadline
​

The current block number or timestamp has exceeded the caller-provided deadline

error Deadline();
Table of Contents