Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CT-988] Include position quote balance in nc and mmr calculations #1869

Merged
merged 4 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions protocol/x/clob/keeper/liquidations.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,13 +451,13 @@ func (k Keeper) GetBankruptcyPriceInQuoteQuantums(
// with a position size of `PS + deltaQuantums`.
// Note that we are intentionally not calculating `DNNV` from `deltaQuantums`
// directly to avoid rounding errors.
riskPosOld := perplib.GetNetCollateralAndMarginRequirements(
riskPosOld := perplib.GetPositionNetNotionalValueAndMarginRequirements(
perpetual,
marketPrice,
liquidityTier,
psBig,
)
riskPosNew := perplib.GetNetCollateralAndMarginRequirements(
riskPosNew := perplib.GetPositionNetNotionalValueAndMarginRequirements(
perpetual,
marketPrice,
liquidityTier,
Expand Down Expand Up @@ -541,7 +541,7 @@ func (k Keeper) GetFillablePrice(
return nil, err
}

riskPos := perplib.GetNetCollateralAndMarginRequirements(
riskPos := perplib.GetPositionNetNotionalValueAndMarginRequirements(
perpetual,
marketPrice,
liquidityTier,
Expand Down
25 changes: 23 additions & 2 deletions protocol/x/perpetuals/lib/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ func GetSettlementPpmWithPerpetual(
return result, fundingIndex
}

// GetNetCollateralAndMarginRequirements returns the net collateral, initial margin requirement,
// GetPositionNetNotionalValueAndMarginRequirements returns the net collateral, initial margin requirement,
// and maintenance margin requirement in quote quantums, given the position size in base quantums.
func GetNetCollateralAndMarginRequirements(
func GetPositionNetNotionalValueAndMarginRequirements(
perpetual types.Perpetual,
marketPrice pricestypes.MarketPrice,
liquidityTier types.LiquidityTier,
Expand All @@ -64,6 +64,27 @@ func GetNetCollateralAndMarginRequirements(
}
}

// GetNetCollateralAndMarginRequirements returns the net collateral, initial margin requirement,
// and maintenance margin requirement in quote quantums, given the position size in base quantums.
func GetNetCollateralAndMarginRequirements(
perpetual types.Perpetual,
marketPrice pricestypes.MarketPrice,
liquidityTier types.LiquidityTier,
quantums *big.Int,
quoteBalance *big.Int,
) (
risk margin.Risk,
) {
risk = GetPositionNetNotionalValueAndMarginRequirements(
perpetual,
marketPrice,
liquidityTier,
quantums,
)
risk.NC.Add(risk.NC, quoteBalance)
return risk
}

// GetNetNotionalInQuoteQuantums returns the net notional in quote quantums, which can be
// represented by the following equation:
//
Expand Down
21 changes: 20 additions & 1 deletion protocol/x/perpetuals/lib/lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,24 +159,42 @@ func TestGetNetCollateralAndMarginRequirements(t *testing.T) {
marketPrice pricestypes.MarketPrice
liquidityTier types.LiquidityTier
quantums *big.Int
quoteBalance *big.Int
}{
"zero quantums": {
perpetual: testPerpetual,
marketPrice: testMarketPrice,
liquidityTier: testLiquidityTier,
quantums: big.NewInt(0),
quoteBalance: big.NewInt(0),
},
"positive quantums": {
perpetual: testPerpetual,
marketPrice: testMarketPrice,
liquidityTier: testLiquidityTier,
quantums: big.NewInt(1_000_000_000_000),
quoteBalance: big.NewInt(0),
},
"negative quantums": {
perpetual: testPerpetual,
marketPrice: testMarketPrice,
liquidityTier: testLiquidityTier,
quantums: big.NewInt(-1_000_000_000_000),
quoteBalance: big.NewInt(0),
},
"positive quote balance": {
perpetual: testPerpetual,
marketPrice: testMarketPrice,
liquidityTier: testLiquidityTier,
quantums: big.NewInt(-1_000_000_000_000),
quoteBalance: big.NewInt(1_000_000_000_000),
},
"negative quote balance": {
perpetual: testPerpetual,
marketPrice: testMarketPrice,
liquidityTier: testLiquidityTier,
quantums: big.NewInt(1_000_000_000_000),
quoteBalance: big.NewInt(-1_000_000_000_000),
},
}
for name, test := range tests {
Expand All @@ -197,8 +215,9 @@ func TestGetNetCollateralAndMarginRequirements(t *testing.T) {
test.marketPrice,
test.liquidityTier,
test.quantums,
test.quoteBalance,
)
require.Equal(t, enc, risk.NC)
require.Equal(t, 0, new(big.Int).Add(enc, test.quoteBalance).Cmp(risk.NC))
require.Equal(t, eimr, risk.IMR)
require.Equal(t, emmr, risk.MMR)
})
Expand Down
2 changes: 2 additions & 0 deletions protocol/x/subaccounts/lib/updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ func CalculateUpdatedPerpetualPositions(
positionsMap[update.PerpetualId] = &types.PerpetualPosition{
PerpetualId: update.PerpetualId,
Quantums: dtypes.NewIntFromBigInt(update.GetBigQuantums()),
QuoteBalance: dtypes.ZeroInt(),
FundingIndex: perpInfo.Perpetual.FundingIndex,
}
}
Expand Down Expand Up @@ -363,6 +364,7 @@ func GetRiskForSubaccount(
perpInfo.Price,
perpInfo.LiquidityTier,
pos.GetBigQuantums(),
pos.GetQuoteBalance(),
)
risk.AddInPlace(r)
}
Expand Down
9 changes: 9 additions & 0 deletions protocol/x/subaccounts/types/position_size.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ func (m *PerpetualPosition) GetBigQuantums() *big.Int {
return m.Quantums.BigInt()
}

// Get the perpetual position quote balance in big.Int.
func (m *PerpetualPosition) GetQuoteBalance() *big.Int {
if m == nil {
return new(big.Int)
}

return m.QuoteBalance.BigInt()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider returning nil in case of a nil receiver.

Returning nil instead of a new big.Int can better indicate the absence of a PerpetualPosition.

-	if m == nil {
-		return new(big.Int)
+	if m == nil {
+		return nil
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Get the perpetual position quote balance in big.Int.
func (m *PerpetualPosition) GetQuoteBalance() *big.Int {
if m == nil {
return new(big.Int)
}
return m.QuoteBalance.BigInt()
}
// Get the perpetual position quote balance in big.Int.
func (m *PerpetualPosition) GetQuoteBalance() *big.Int {
if m == nil {
return nil
}
return m.QuoteBalance.BigInt()
}


func (m *PerpetualPosition) GetIsLong() bool {
if m == nil {
return false
Expand Down
Loading