Skip to main content

Saturation

Git Source

Author: imi@1m1.io

Saturation (=sat) is defined as the net borrow. In theory, we would want to divide net borrow by the total liquidity; in practice, we keep the net borrow only in the tree. The unit of sat if LAssets. Keeps the sat in a tree, starting with a root, levels and leafs. We keep 2 trees, one for net X borrows, another for net Y borrows. The price is always the price of Y in units of X. Mostly, the code works with the sqrt of price. A net X borrow refers to a position that if liquidated would cause the price to become smaller; the opposite for net Y positions. Ticks are along the price dimension and int16. Tranches are combine 232^3 ticks, stored as int16. Leafs (uint16) split the sat, which is uint112, into 2122^{12} intervals. From left to right, the leafs of the tree cover the sat space in increasing order. Each account with a position has a price at which its LTV would reach LTVMAX, which is its liquidation (=liq) price. The liq price belongs to a tranche. A Tranche contains multiple accounts and thus a total sat. The tranches' sat assigns it to a leaf. Each leaf can contain multiple tranches and thus has a total actual sat whilst representing a specific sat per tranche range. Leafs and thus tranches and thus accounts above a certain sat threshold are considered over saturated. These accounts are penalized for being over saturated. Each account, tranche and leaf has a total penalty that needs to be repayed to flatten the position fully. Sat is distributed over multiple tranches, in case a single tranche does not have enough available sat left. Sat is kept cumulatively in the tree, meaning a node contains the sum of the sat of its parents. Updating a sat at the bottom of the tree requires updating all parents. Penalty is kept as a path sum, in uints of LAssets, meaning the penalty of an account is the sum of the penalties of all its parents. Updating the penalty for a range of leafs only requires updating the appropriate parent. Position (=pos) refers to the relative index of a child within its parent. Index refers to the index of a node in within its level

State Variables

SATURATION_TIME_BUFFER_IN_MAG2

uint256 internal constant SATURATION_TIME_BUFFER_IN_MAG2 = 0x6e;

MAX_HEALTHY_SATURATION_RATIO_IN_MAG2

uint256 internal constant MAX_HEALTHY_SATURATION_RATIO_IN_MAG2 = 0x50;

START_SATURATION_PENALTY_RATIO_IN_MAG2

uint256 internal constant START_SATURATION_PENALTY_RATIO_IN_MAG2 = 0x46;

PENALTY_FACTOR_IN_MAG2

uint256 private constant PENALTY_FACTOR_IN_MAG2 = 0xa;

MAX_SATURATION_DISTRIBUTION_TRANCHES

uint256 internal constant MAX_SATURATION_DISTRIBUTION_TRANCHES = 0x3;

AMMALGAMPAIR_MINIMUM_LIQUIDITY

uint256 internal constant AMMALGAMPAIR_MINIMUM_LIQUIDITY = 0x3e8;

SAT_TO_LEAF_MIN_IN_Q128

uint256 private constant SAT_TO_LEAF_MIN_IN_Q128 = 0x3e272007bf43f051cf6f4632ccfc54317b;

SAT_TO_LEAF_MAX_IN_Q128

uint256 private constant SAT_TO_LEAF_MAX_IN_Q128 = 0xfe93f7ee948afecf9909a051669b4878e0846dd2ce13c096be6a7890625;

SAT_TO_LEAF_BASE_CHANGE_IN_Q128

uint256 private constant SAT_TO_LEAF_BASE_CHANGE_IN_Q128 = 0x1cfc0000000000000000000000000000;

SAT_TO_LEAF_SHIFT

uint256 private constant SAT_TO_LEAF_SHIFT = 0xef;

INT_ONE

int256 private constant INT_ONE = 1;

LEVELS_WITHOUT_LEAFS

uint256 internal constant LEVELS_WITHOUT_LEAFS = 0x3;

LOWEST_LEVEL_INDEX

uint256 internal constant LOWEST_LEVEL_INDEX = 0x2;

LEAFS_IN_BITS

uint256 private constant LEAFS_IN_BITS = 0xc;

LEAFS

uint256 internal constant LEAFS = 0x1000;

CHILDREN_PER_NODE_IN_BITS

uint256 private constant CHILDREN_PER_NODE_IN_BITS = 0x4;

CHILDREN_PER_NODE

uint256 internal constant CHILDREN_PER_NODE = 0x10;

TICKS_PER_TRANCHE

int256 private constant TICKS_PER_TRANCHE = 0x64;

TWO_DIV_ONE_MINUS_ONE_OVER_BASE_TRANCHE_OVER_IN_Q128

uint256 constant TWO_DIV_ONE_MINUS_ONE_OVER_BASE_TRANCHE_OVER_IN_Q128 = 0xb4337207340fdfaf6710a40d6e575cd9c;

MIN_TRANCHE

int256 internal constant MIN_TRANCHE = -0xc7;

MAX_TRANCHE

int256 internal constant MAX_TRANCHE = 0xc6;

TOTAL_BITS

uint256 private constant TOTAL_BITS = 0x100;

FIELD_BITS

uint256 private constant FIELD_BITS = 0x10;

SAT_BITS

uint256 private constant SAT_BITS = 0x70;

TRANCHE_COUNT_BITS

uint256 private constant TRANCHE_COUNT_BITS = 0x10;

EMPTY_BITS

uint256 private constant EMPTY_BITS = 0x70;

FIELD_NODE_MASK

uint256 private constant FIELD_NODE_MASK = 0xffff;

SAT_NODE_MASK

uint256 private constant SAT_NODE_MASK = 0xffffffffffffffffffffffffffff0000;

TRANCHE_COUNT_NODE_MASK

uint256 private constant TRANCHE_COUNT_NODE_MASK = 0xffff00000000000000000000000000000000;

Functions

initTree

initializes the satStruct, allocating storage for all nodes

initCheck can be removed once the tree structure is fixed

function initTree(
SaturationStruct storage satStruct
) external;

Parameters

NameTypeDescription
satStructSaturationStructcontains the entire sat data

update

update the borrow position of an account and potentially check (and revert) if the resulting sat is too high

function update(
SaturationStruct storage satStruct,
Validation.InputParams memory inputParams,
address account
) external;

Parameters

NameTypeDescription
satStructSaturationStructmain data struct
inputParamsValidation.InputParamscontains the position and pair params, like account borrows/deposits, current price and active liquidity
accountaddressfor which is position is being updated

accruePenalties

accrue penalties since last accrual based on all over saturated positions

function accruePenalties(
SaturationStruct storage satStruct,
uint256 activeLiquidityInLAssets,
uint256 duration,
uint256 maxUtilizationInWad
) external returns (uint256 penaltyInLAssets);

Parameters

NameTypeDescription
satStructSaturationStructmain data struct
activeLiquidityInLAssetsuint256of the pair
durationuint256since last accrual of penalties
maxUtilizationInWaduint256is the max of the L, X, Y borrow vs deposit utilizations

Returns

NameTypeDescription
penaltyInLAssetsuint256the amount to be added to the liquidity assets to benefit the liquidity providers from the penalty available

calcPenaltyForRepay

calc and decrease the penalty that an account owes to repay for its borrow position

function is called with 0<repayAmountLInLAssets && repayAmountXInXAssets==repayAmountYInYAssets==0 xor 0==repayAmountLInLAssets && (0<repayAmountXInXAssets || 0<repayAmountYInYAssets)

function calcPenaltyForRepay(
SaturationStruct storage satStruct,
address account,
uint256 currentSqrtPriceInXInQ128,
uint256 repayAmountLInLAssets,
uint256 repayAmountXInXAssets,
uint256 repayAmountYInYAssets
)
external
returns (
uint256 overSaturationPenaltyRemovedLInLAssets,
uint256 overSaturationPenaltyRemovedXInXAssets,
uint256 overSaturationPenaltyRemovedYInYAssets
);

Parameters

NameTypeDescription
satStructSaturationStructmain data struct
accountaddresswhos position is being considered
currentSqrtPriceInXInQ128uint256of the pair
repayAmountLInLAssetsuint256being repayed on behalf of the account
repayAmountXInXAssetsuint256being repayed on behalf of the account
repayAmountYInYAssetsuint256being repayed on behalf of the account

Returns

NameTypeDescription
overSaturationPenaltyRemovedLInLAssetsuint256over sat penalty decreased for the account, upto repaid amount
overSaturationPenaltyRemovedXInXAssetsuint256over sat penalty decreased for the account, upto repaid amount
overSaturationPenaltyRemovedYInYAssetsuint256over sat penalty decreased for the account, upto repaid amount

updatePenaltyForRepayXYGivenTree

function updatePenaltyForRepayXYGivenTree(
Tree storage tree,
address account,
uint256 currentSqrtPriceInXInQ128,
uint256 repayAmountInAssets
) internal returns (uint256 overSaturationPenaltyRemovedInAssets);

Parameters

NameTypeDescription
treeTreeto be considered
accountaddresswhos position is being considered
currentSqrtPriceInXInQ128uint256of the pair
repayAmountInAssetsuint256being repayed on behalf of the account

Returns

NameTypeDescription
overSaturationPenaltyRemovedInAssetsuint256over sat penalty decreased for the account, upto repaid amount

initTree

init the nodes of the tree

function initTree(
Tree storage tree
) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to

check

check and revert in case the highest sat is too high

function check(uint256 activeLiquidityInLAssets, uint256 highestSetLeaf) internal pure;

Parameters

NameTypeDescription
activeLiquidityInLAssetsuint256of the pair
highestSetLeafuint256highest leaf with a tranche

updateTreeGivenAccountAndInputParams

internal update function given a tree, an account, its params and liq price

function updateTreeGivenAccountAndInputParams(
Tree storage tree,
Validation.InputParams memory inputParams,
address account,
uint256 liqSqrtPriceInXInQ128
) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
inputParamsValidation.InputParamscontains the position and pair params, like account borrows/deposits, current price and active liquidity
accountaddresswhos position is being considered
liqSqrtPriceInXInQ128uint256price at which the positions' LTV would reach LTVMAX

updateTreeGivenAccountTrancheAndSat

internal update that removes the account from the tree (if it exists) from its prev position and adds it to its new position

function updateTreeGivenAccountTrancheAndSat(
Tree storage tree,
address account,
int256 newTranche,
uint256 newSatInLAssets,
uint256 activeLiquidityInLAssets
) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
accountaddresswhos position is being considered
newTrancheint256the new tranche of the account
newSatInLAssetsuint256the new sat of the account, in units of LAssets
activeLiquidityInLAssetsuint256of the pair

removeSatFromTranche

remove sat from tree, for each tranche in a loop that could hold sat for the account

function removeSatFromTranche(
Tree storage tree,
uint112[MAX_SATURATION_DISTRIBUTION_TRANCHES] memory accountToSatPerTranche,
uint256[MAX_SATURATION_DISTRIBUTION_TRANCHES] memory accountTreePenaltyAtOnsetInLAssetsPerSatInQ128PerTranche,
address account,
int256 trancheDirection
) internal returns (bool highestSetLeafRemoved);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
accountToSatPerTrancheuint112[MAX_SATURATION_DISTRIBUTION_TRANCHES]array holding the sat per tranche given the account
accountTreePenaltyAtOnsetInLAssetsPerSatInQ128PerTrancheuint256[MAX_SATURATION_DISTRIBUTION_TRANCHES]
accountaddresswhos position is being considered
trancheDirectionint256direction of sat distribution depending on netX/netY

Returns

NameTypeDescription
highestSetLeafRemovedboolflag indicating whether we removed sat from the highest leaf xor not

removeSatFromTrancheStateUpdates

depending on old and new leaf of the tranche, update the sats, fields and penalties of the tree

function removeSatFromTrancheStateUpdates(
Tree storage tree,
int256 tranche,
uint256 oldLeaf,
uint256 oldTrancheSatInLAssets,
uint256 oldAccountSatInTrancheInLAssets,
address account,
uint256 oldAccountTreePenaltyAtOnsetInLAssetsPerSatInQ128
) internal returns (uint256 newLeafPenaltyAtOnsetInLAssetsPerSatInQ128);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
trancheint256under consideration
oldLeafuint256
oldTrancheSatInLAssetsuint256tranche sat
oldAccountSatInTrancheInLAssetsuint256account sat
accountaddresswhos position is being considered
oldAccountTreePenaltyAtOnsetInLAssetsPerSatInQ128uint256penalty offset at the old leaf

Returns

NameTypeDescription
newLeafPenaltyAtOnsetInLAssetsPerSatInQ128uint256the new offset penalty to be stored

addSatToTranche

add sat to tree, for each tranche in a loop as needed. we add to each tranche as much as it can bear.

function addSatToTranche(
Tree storage tree,
uint112[MAX_SATURATION_DISTRIBUTION_TRANCHES] memory accountToSatPerTranche,
uint256[MAX_SATURATION_DISTRIBUTION_TRANCHES] memory accountTreePenaltyAtOnsetInLAssetsPerSatInQ128PerTranche,
address account,
int256 trancheDirection,
int256 newTranche,
uint256 newSatInLAssets,
uint256 activeLiquidityInLAssets
) internal returns (bool highestSetLeafAdded);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
accountToSatPerTrancheuint112[MAX_SATURATION_DISTRIBUTION_TRANCHES]array holding the sat per tranche given the account, set at the end of this function
accountTreePenaltyAtOnsetInLAssetsPerSatInQ128PerTrancheuint256[MAX_SATURATION_DISTRIBUTION_TRANCHES]
accountaddresswhos position is being considered
trancheDirectionint256direction of sat distribution depending on netX/netY
newTrancheint256the new tranche of the account
newSatInLAssetsuint256the new sat of the account, in units of LAssets
activeLiquidityInLAssetsuint256of the pair

Returns

NameTypeDescription
highestSetLeafAddedboolflag indicating whether we removed sat from the highest leaf xor not

getAddSatToTrancheStateUpdatesParams

convenience struct holding the params needed to run addSatToTrancheStateUpdates

function getAddSatToTrancheStateUpdatesParams(
Tree storage tree,
int256 tranche,
uint256 newSatInLAssets,
uint256 activeLiquidityInLAssets,
address account
) internal view returns (AddSatToTrancheStateUpdatesStruct memory addSatToTrancheStateUpdatesParams);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
trancheint256under consideration
newSatInLAssetsuint256in units of LAssets
activeLiquidityInLAssetsuint256of the pair
accountaddresswhos position is being considered

Returns

NameTypeDescription
addSatToTrancheStateUpdatesParamsAddSatToTrancheStateUpdatesStructthe struct with required params to

addSatToTrancheStateUpdates

depending on old and new leaf of the tranche, update the sats, fields and penalties of the tree

function addSatToTrancheStateUpdates(Tree storage tree, AddSatToTrancheStateUpdatesStruct memory params) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
paramsAddSatToTrancheStateUpdatesStructconvenience struct holding params needed for these updates

removeTrancheToLeaf

removing a tranche from a leaf, update the fields and sats up the tree

function removeTrancheToLeaf(Tree storage tree, int256 tranche, uint256 trancheSatInLAssets, uint256 leaf) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
trancheint256that is being moved
trancheSatInLAssetsuint256sat of tranche being moved
leafuint256the leaf

addTrancheToLeaf

adding a tranche from a leaf, update the fields and sats up the tree

function addTrancheToLeaf(Tree storage tree, int256 tranche, uint256 trancheSatInLAssets, uint256 leaf) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
trancheint256that is being moved
trancheSatInLAssetsuint256sat of tranche being moved
leafuint256the leaf

addSatUpTheTree

recursively add sat up the tree

function addSatUpTheTree(Tree storage tree, uint256 level, uint256 nodeIndex, int256 satInLAssets) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
leveluint256level being updated
nodeIndexuint256index is the position (0 based) of the node in its level
satInLAssetsint256sat to add to the current node, usually uint112, int to allow subtracting sat up the tree

accruePenaltiesGivenTree

internal function to calc and add penalty for all over saturation positions

function accruePenaltiesGivenTree(
Tree storage tree,
uint256 thresholdLeaf,
uint256 duration,
uint256 maxUtilizationInWad
) internal returns (uint256 penaltyInLAssets);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
thresholdLeafuint256where penalties begin
durationuint256in seconds since last update
maxUtilizationInWaduint256is the max of the L, X, Y borrow vs deposit utilizations

Returns

NameTypeDescription
penaltyInLAssetsuint256the amount to be added to the liquidity assets to benefit the liquidity providers from the penalty available

updatePenalties

update penalties in the tree given

function updatePenalties(Tree storage tree, uint256 thresholdLeaf, uint256 addPenaltyInLAssetsPerSatInQ128) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
thresholdLeafuint256from which leaf on the penalty needs to be added inclusive
addPenaltyInLAssetsPerSatInQ128uint256the penalty to be added

updatePenaltiesDownTheTree

update penalties in the tree given recursively downwards, always with perfect cover if a node exactly covers our threshold, we only update that node and all right siblings. the node that is over covering our threshold is used as the parent for the recursion to get the coverage exactly

function updatePenaltiesDownTheTree(
Tree storage tree,
uint256 thresholdLeaf,
uint256 addPenaltyInLAssetsPerSatInQ128,
uint256 level,
uint256 nodeIndex,
uint256 totalNodesAtLevel
) private;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
thresholdLeafuint256from which leaf on the penalty needs to be added inclusive
addPenaltyInLAssetsPerSatInQ128uint256the penalty to be added
leveluint256
nodeIndexuint256
totalNodesAtLeveluint256

calcPenaltyPerSatFromLeafToRoot

recursive function to sum penalties from leaf to root

function calcPenaltyPerSatFromLeafToRoot(
Tree storage tree,
uint256 level,
uint256 nodeIndex,
uint256 leaf
) internal view returns (uint256 penaltyInLAssetsPerSatInQ128);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
leveluint256level being read
nodeIndexuint256index is the position (0 based) of the node in its level
leafuint256index (0 based) of the leaf

Returns

NameTypeDescription
penaltyInLAssetsPerSatInQ128uint256total penalty at the leaf, non-negative but returned as an int for recursion

accrueAccountPenalty

calc penalty owed by account for repay, total over all the tranches that might contain this accounts' sat

function accrueAccountPenalty(Tree storage tree, address account) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
accountaddresswhos position is being considered

calcTotalSatAfterLeafInclusive

calc total sat of all accounts/tranches/leafs higher (and same) as the threshold

function calcTotalSatAfterLeafInclusive(
Tree storage tree,
uint256 thresholdLeaf
) internal view returns (uint256 satInLAssets, uint256 trancheCount);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
thresholdLeafuint256leaf to start adding sat from

Returns

NameTypeDescription
satInLAssetsuint256total sat of all accounts with tranche in a leaf from at least thresholdLeaf
trancheCountuint256

satToLeaf

convert sat to leaf

function satToLeaf(
uint256 satLAssets
) internal pure returns (uint256 leaf);

Parameters

NameTypeDescription
satLAssetsuint256sat to convert

Returns

NameTypeDescription
leafuint256resulting leaf from 0 to 2**12-1

calcMaxSatInTranche

calc max sat in a tranche such that a liq swap does not cross an entire tranches worth

function calcMaxSatInTranche(
uint256 activeLiquidityInLAssets
) internal pure returns (uint256 maxSatInTranche);

Parameters

NameTypeDescription
activeLiquidityInLAssetsuint256in the pair

Returns

NameTypeDescription
maxSatInTrancheuint256in LAssets

calcSatAvailableToAddToTranche

calc how much sat can be added to a tranche such that it is healthy

function calcSatAvailableToAddToTranche(
uint256 activeLiquidityInLAssets,
uint256 targetSatToAddInLAssets,
uint256 currentTrancheSatInLAssets
) internal pure returns (uint256 satAvailableToAddInLAssets);

Parameters

NameTypeDescription
activeLiquidityInLAssetsuint256of the pair
targetSatToAddInLAssetsuint256the sat that we want to add
currentTrancheSatInLAssetsuint256the sat that the tranche already hols

Returns

NameTypeDescription
satAvailableToAddInLAssetsuint256considering the currentTrancheSatInLAssets and the max a tranche can have

calcSat

calc sat given position using LTV calc from Validation

function calcSat(
Validation.InputParams memory inputParams,
uint256 liqSqrtPriceInXInQ128
) internal pure returns (uint256 satInLAssets);

Parameters

NameTypeDescription
inputParamsValidation.InputParamsposition
liqSqrtPriceInXInQ128uint256liq price

Returns

NameTypeDescription
satInLAssetsuint256sat

convertLToXXorY

function convertLToXXorY(
Tree storage tree,
uint256 currentSqrtPriceInXInQ128,
uint256 amountInLAssets,
Math.Rounding rounding
) private view returns (uint256);

convertXorYToL

function convertXorYToL(
Tree storage tree,
uint256 currentSqrtPriceInXInQ128,
uint256 amountInAssets,
Math.Rounding rounding
) private view returns (uint256);

setXorUnsetFieldBitUpTheTree

recursive function to unset the field when removing a tranche from a leaf

function setXorUnsetFieldBitUpTheTree(
Tree storage tree,
uint256 level,
uint256 nodeIndex,
uint256 lowerNodePos,
uint256 set
) internal;

Parameters

NameTypeDescription
treeTreethat is being read from or written to
leveluint256level being updated
nodeIndexuint256index is the position (0 based) of the node in its level
lowerNodePosuint256pos is the relative position (0 bsaed) of the node in its parent
setuint2561 for set, 0 for unset

getLeftEdgeThatCoversLeaf

calc level (and nodes at that level) that covers a threshold node from the left

function getLeftEdgeThatCoversLeaf(
uint256 thresholdLeaf
) internal pure returns (uint256 level, uint256 totalNodesAtLevel);

Parameters

NameTypeDescription
thresholdLeafuint256threshold to cover inclusively

Returns

NameTypeDescription
leveluint256level at which the left most node would cover the thresholdLeaf
totalNodesAtLeveluint256total nodes at our level

findHighestSetLeafUpwards

recursive function to find the highest set leaf starting from a leaf, first upwards, until a set field is found, then downwards to find the best set leaf

function findHighestSetLeafUpwards(
Tree storage tree,
uint256 level,
uint256 nodeIndex
) private view returns (uint256 highestSetLeaf);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
leveluint256that we are checking
nodeIndexuint256corresponding to our leaf at our level

Returns

NameTypeDescription
highestSetLeafuint256highest leaf that is set in the tree

findHighestSetLeafDownwards

recursive function to find the highest set leaf starting from a node, downwards

internal for testing only

function findHighestSetLeafDownwards(
Tree storage tree,
uint256 level,
uint256 nodeIndex
) internal view returns (uint256 leaf);

Parameters

NameTypeDescription
treeTreethat is being read from or written to
leveluint256that we are starting from
nodeIndexuint256that we are starting from

Returns

NameTypeDescription
leafuint256highest leaf under the node that is set

calcMaxCompoundInterest

calc total interest for duration using the rate of the most utilized of L,X,X todo get from Interest or somewhere

function calcMaxCompoundInterest(
uint256 duration,
uint256 maxUtilizationInWad
) internal pure returns (uint256 compoundedInterestRateInWAD);

Parameters

NameTypeDescription
durationuint256time since last update
maxUtilizationInWaduint256is the max of the L, X, Y borrow vs deposit utilizations

Returns

NameTypeDescription
compoundedInterestRateInWADuint256total interest

getTrancheAtSqrtPriceX

calc tranche given a sqrt price

function getTrancheAtSqrtPriceX(
uint256 sqrtPriceInXInQ128
) internal pure returns (int256 tranche);

Parameters

NameTypeDescription
sqrtPriceInXInQ128uint256value to convert

Returns

NameTypeDescription
trancheint256converted tranche

calcLiqSqrtPrice

Calc sqrt price at which positions' LTV would reach LTVMAX

Output guarantees 0liqSqrtPriceXInQ128uint256(type(uint56).max)<<1280 \le liqSqrtPriceXInQ128 \le uint256(type(uint56).max) << 128 (fuzz tested and logic)

Outside above range, outputs 0 (essentially no liq)

Does not revert if LTVMAX<LTVLTVMAX < LTV, rather LTVMAX<LTVLTVMAX < LTV causing liq points are returned as 0, as if they do not exist, based on the assumption LTVLTVMAXLTV \le LTVMAX

function calcLiqSqrtPrice(
Validation.InputParams memory inputParams
) internal pure returns (uint256 netXLiqSqrtPriceXInQ128, uint256 netYLiqSqrtPriceXInQ128);

Parameters

NameTypeDescription
inputParamsValidation.InputParamsThe position

Returns

NameTypeDescription
netXLiqSqrtPriceXInQ128uint2560 if no netX liq price exists
netYLiqSqrtPriceXInQ128uint2560 if no netY liq price exists

calcLiqSqrtPriceHandleAllABCNonZero

calc liq price when the quadratic has all 3 terms, netY,netL,netX, i.e. X, Y, L are all significant

function calcLiqSqrtPriceHandleAllABCNonZero(
CalcLiqSqrtPriceHandleAllABCNonZeroStruct memory input
) internal pure returns (uint256 netXLiqSqrtPriceXInQ128, uint256 netYLiqSqrtPriceXInQ128);

Parameters

NameTypeDescription
inputCalcLiqSqrtPriceHandleAllABCNonZeroStructthe position

Returns

NameTypeDescription
netXLiqSqrtPriceXInQ128uint2560 if no netX liq price exists
netYLiqSqrtPriceXInQ128uint2560 if no netY liq price exists

readFieldBitFromNode

read single bit value from the field of a node

function readFieldBitFromNode(uint256 node, uint256 bitPos) internal pure returns (uint256 bit);

Parameters

NameTypeDescription
nodeuint256the full node
bitPosuint256position of the bit 16\le 16

Returns

NameTypeDescription
bituint256the resulting bit, 0 xor 1, as a uint

writeFlippedFieldBitToNode

write to node

function writeFlippedFieldBitToNode(uint256 nodeIn, uint256 bitPos) internal pure returns (uint256 nodeOut);

Parameters

NameTypeDescription
nodeInuint256node to read from
bitPosuint256position of the bit 16\le 16

Returns

NameTypeDescription
nodeOutuint256node with bit flipped

readFieldFromNode

read field from node

function readFieldFromNode(
uint256 node
) internal pure returns (uint256 field);

Parameters

NameTypeDescription
nodeuint256node to read from

Returns

NameTypeDescription
fielduint256field of the node

readSatFromNode

read sat from node

function readSatFromNode(
uint256 node
) internal pure returns (uint256 saturationInLAssets);

Parameters

NameTypeDescription
nodeuint256node to read from

Returns

NameTypeDescription
saturationInLAssetsuint256sat in node

writeSatToNode

write sat to node

function writeSatToNode(uint256 saturationInLAssets, uint256 nodeIn) internal pure returns (uint256 nodeOut);

Parameters

NameTypeDescription
saturationInLAssetsuint256sat to write
nodeInuint256node to read from

Returns

NameTypeDescription
nodeOutuint256node with sat written

readTrancheCountFromNode

read tranche count from node

function readTrancheCountFromNode(
uint256 node
) internal pure returns (uint256 trancheCount);

Parameters

NameTypeDescription
nodeuint256node to read from

Returns

NameTypeDescription
trancheCountuint256number of tranches under this node

writeTrancheCountToNode

write tranche count to node

function writeTrancheCountToNode(uint256 trancheCount, uint256 nodeIn) internal pure returns (uint256 nodeOut);

Parameters

NameTypeDescription
trancheCountuint256tranche count to write
nodeInuint256node to read from

Returns

NameTypeDescription
nodeOutuint256node with trancheCount written

Errors

TooMuchSaturationToAdd

error TooMuchSaturationToAdd();

MaxTrancheOverSaturated

error MaxTrancheOverSaturated();

Structs

SaturationStruct

struct SaturationStruct {
Tree netXTree;
Tree netYTree;
}

Tree

struct Tree {
bool netX;
uint16 highestSetLeaf;
uint256[][LEVELS_WITHOUT_LEAFS] nodes;
uint256[][LEVELS_WITHOUT_LEAFS] penaltyInLAssetsPerSatInQ128;
Leaf[LEAFS] leafs;
mapping(int16 => uint16) trancheToLeaf;
mapping(int16 => uint112) trancheToSatInLAssets;
mapping(address => Account) accountData;
}

Leaf

struct Leaf {
Uint16Set.Set tranches;
uint112 satInLAssets;
uint256 penaltyInLAssetsPerSatInQ128;
}

Account

struct Account {
bool exists;
int16 tranche;
uint112[MAX_SATURATION_DISTRIBUTION_TRANCHES] satInLAssetsPerTranche;
uint112 penaltyInLAssets;
uint256[MAX_SATURATION_DISTRIBUTION_TRANCHES] treePenaltyAtOnsetInLAssetsPerSatInQ128PerTranche;
}

CalcLiqSqrtPriceHandleAllABCNonZeroStruct

struct CalcLiqSqrtPriceHandleAllABCNonZeroStruct {
int256 netL;
int256 netX;
int256 netY;
uint256 netYAbs;
uint256 borrowedXAssets;
uint256 borrowedYAssets;
}

AddSatToTrancheStateUpdatesStruct

struct AddSatToTrancheStateUpdatesStruct {
int256 tranche;
uint256 newLeaf;
uint256 oldTrancheSatInLAssets;
uint256 newTrancheSatInLAssets;
uint256 satAvailableToAddInLAssets;
address account;
}