PartialLiquidations
We allow liquidations to happen in parts when the position is spread across more than one tranche. These partial liquidations allow the liquidator to specify how many tranches they are liquidating based on how much they are repaying. Fewer tranches will result in a higher LTV as they start with the portion of the position closest to the price and move outward. In most cases, one tranche will be liquidated at once, but in some cases, a sliver of liquidity in the first tranche may not be worth the cost to liquidate until it and the next tranche have become profitable to liquidate. Once we determine the number of tranches of a position they want to liquidate, we mutate the position getting liquidated to a smaller scaled portion of the initial position. To calculate the portion of a position, we start with the following requirements:
State Variables
EXPECTED_SATURATION_LTV_MAG2_INT
int256 internal constant EXPECTED_SATURATION_LTV_MAG2_INT = int256(EXPECTED_SATURATION_LTV_MAG2);
MAG2_INT
int256 internal constant MAG2_INT = int256(MAG2);
Q72_INT
int256 internal constant Q72_INT = int256(Q72);
Functions
calculatePartialLiquidation
function calculatePartialLiquidation(
Saturation.SaturationPair[] memory satPairPerTranche,
int16 lastTranche,
uint256[6] memory userAssets,
uint256 activeLiquidityAssets,
uint256 netRepaidLAssets,
uint256 netSeizedLAssets,
bool netDebtX
) internal pure returns (uint256[6] memory liquidation);
calcMutation
function calcMutation(
uint256[6] memory userAssets,
uint256 trancheBoundarySqrtPriceQ72,
uint256 partialSaturation,
uint256 totalSaturation,
uint256 activeLiquidityAssets,
bool netDebtX
) private pure returns (uint256[6] memory);
calcXWeightQ72
calculates partial liquidation weight for asset X.
*formulas for w_X derived from:
w_X &= \large \frac{ 1- \sqrt{w_s} }{ \sqrt{w_e}-\sqrt{w_s} } ```* ```solidity function calcXWeightQ72( uint256 sqrtStartWeightQ72, uint256 sqrtEndWeightQ72 ) private pure returns (uint256 xWeightQ72);calcYWeightQ72
calculates partial liquidation weight for asset Y.
*formulas for w_Y derived from:
calcLWeightQ72
calculates partial liquidation weight for asset L.
*formula for w_L is derived from:
where for the tranche boundary of the tranche being liquidated.*
function calcLWeightQ72(
uint256[6] memory userAssets,
int256 xWeightQ72,
int256 yWeightQ72,
uint256 sqrtStartWeightQ72,
uint256 tranchesSqrtPriceQ72,
bool netDebtX
) private pure returns (uint256 lWeightQ72);
calcSqrtStartWeightQ72
calculates weight based on the formula below. Note that we don't use all of the active liquidity assets, must the max allowed saturation.
\begin{equation} w_s = \begin{cases} \frac{sat}}{MAX\_SAT\RATIO \cdot L} ( B - 1 ) + 1 & \text{ if net debt of X } \\ \frac{ 1 }{ \frac{sat}}{MAX\_SAT\RATIO \cdot L} ( B - 1 ) + 1 } & \text{ if net debt of Y} \end{cases} \end{equation}function calcSqrtStartWeightQ72(
uint256 partialSaturation,
uint256 activeLiquidityAssets,
bool netDebtX
) private pure returns (uint256 sqrtStartWeightQ72);
calcSqrtEndWeightQ72
calculates weight based on the formula below.
function calcSqrtEndWeightQ72(
uint256 partialSaturation,
uint256 totalSaturation,
uint256 activeLiquidityAssets,
bool netDebtX
) private pure returns (uint256 sqrtEndWeightQ72);
weightInNumeratorOrDenominator
function weightInNumeratorOrDenominator(
uint256 sqrtWeight,
bool netDebtX
) private pure returns (uint256 adjustedSqrtWeight);
mutatePosition
function mutatePosition(
uint256[6] memory userAssets,
uint256 lWeightQ72,
uint256 xWeightQ72,
uint256 yWeightQ72
) internal pure returns (uint256[6] memory);
netAssets
function netAssets(
uint256[6] memory userAssets
) internal pure returns (int256 netL, int256 netX, int256 netY);
Structs
LoopMemoryState
struct LoopMemoryState {
uint256 satArrayLength;
uint256 partialSatInLAssets;
uint256 includedTranches;
uint256 partialSatLimit;
}