Skip to content

Commit

Permalink
[CT-988] Include position quote balance in nc and mmr calculations (d…
Browse files Browse the repository at this point in the history
  • Loading branch information
jayy04 authored Jul 9, 2024
1 parent 2fb7bac commit 3161af0
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 8 deletions.
38 changes: 36 additions & 2 deletions protocol/indexer/events/subaccount_update.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package events

import (
"math/big"

"github.com/dydxprotocol/v4-chain/protocol/dtypes"
"github.com/dydxprotocol/v4-chain/protocol/indexer/protocol/v1"
v1 "github.com/dydxprotocol/v4-chain/protocol/indexer/protocol/v1"
assettypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types"
salib "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/lib"
satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types"
)

Expand All @@ -21,6 +25,36 @@ func NewSubaccountUpdateEvent(
updatedPerpetualPositions,
fundingPayments,
),
UpdatedAssetPositions: v1.AssetPositionsToIndexerAssetPositions(updatedAssetPositions),
UpdatedAssetPositions: v1.AssetPositionsToIndexerAssetPositions(
AddQuoteBalanceFromPerpetualPositions(
updatedPerpetualPositions,
updatedAssetPositions,
),
),
}
}

func AddQuoteBalanceFromPerpetualPositions(
perpetualPositions []*satypes.PerpetualPosition,
assetPositions []*satypes.AssetPosition,
) []*satypes.AssetPosition {
quoteBalance := new(big.Int)
for _, position := range perpetualPositions {
quoteBalance.Add(quoteBalance, position.GetQuoteBalance())
}

if quoteBalance.Sign() == 0 {
return assetPositions
}

// Add the quote balance to asset positions.
return salib.CalculateUpdatedAssetPositions(
assetPositions,
[]satypes.AssetUpdate{
{
AssetId: assettypes.AssetUsdc.Id,
BigQuantumsDelta: quoteBalance,
},
},
)
}
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 || m.QuoteBalance.IsNil() {
return new(big.Int)
}

return m.QuoteBalance.BigInt()
}

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

0 comments on commit 3161af0

Please sign in to comment.