Skip to content

Commit

Permalink
[TRA-64] Use market specific insurance fund for cross or isolated mar…
Browse files Browse the repository at this point in the history
…kets (dydxprotocol#1132)

Signed-off-by: Shrenuj Bansal <shrenuj@dydx.exchange>
Signed-off-by: Eric <eric.warehime@gmail.com>
  • Loading branch information
shrenujb authored and Eric-Warehime committed Mar 12, 2024
1 parent 929f09e commit 12506a1
Show file tree
Hide file tree
Showing 29 changed files with 412 additions and 94 deletions.
2 changes: 1 addition & 1 deletion protocol/app/module_accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var (
bridgemoduletypes.ModuleName: {authtypes.Minter},
// subaccounts module account holds tokens for all subaccounts.
satypes.ModuleName: nil,
// clob insurance fund account manages insurance fund for liquidations.
// insurance fund account manages insurance fund for liquidations.
perpetualsmoduletypes.InsuranceFundName: nil,
// rewards treasury account distribute funds trading accounts.
rewardsmoduletypes.TreasuryAccountName: nil,
Expand Down
4 changes: 3 additions & 1 deletion protocol/daemons/liquidation/client/grpc_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package client_test

import (
"context"
"cosmossdk.io/log"
"errors"
"testing"

"cosmossdk.io/log"

"github.com/cosmos/cosmos-sdk/types/query"
"github.com/dydxprotocol/v4-chain/protocol/daemons/flags"
"github.com/dydxprotocol/v4-chain/protocol/daemons/liquidation/api"
Expand Down Expand Up @@ -409,6 +410,7 @@ func TestGetAllMarketPrices(t *testing.T) {
response2 := &pricestypes.QueryAllMarketPricesResponse{
MarketPrices: []pricestypes.MarketPrice{
constants.TestMarketPrices[2],
constants.TestMarketPrices[3],
},
}
mck.On("AllMarketPrices", mock.Anything, req2).Return(response2, nil)
Expand Down
2 changes: 1 addition & 1 deletion protocol/mocks/ClobKeeper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion protocol/testing/e2e/gov/perpetuals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

var (
TEST_PERPETUAL_PARAMS = perptypes.PerpetualParams{
Id: 765,
Id: 0,
Ticker: "BTC-ADV4TNT",
MarketId: 123,
AtomicResolution: -8,
Expand Down
52 changes: 52 additions & 0 deletions protocol/testutil/constants/perpetuals.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,60 @@ var (
},
FundingIndex: dtypes.ZeroInt(),
}
IsoUsd_IsolatedMarket = perptypes.Perpetual{
Params: perptypes.PerpetualParams{
Id: 3,
Ticker: "ISO-USD",
MarketId: uint32(3),
AtomicResolution: int32(-9),
DefaultFundingPpm: int32(0),
LiquidityTier: uint32(3),
MarketType: perptypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_ISOLATED,
},
FundingIndex: dtypes.ZeroInt(),
}
)

var TestMarketPerpetuals = []perptypes.Perpetual{
{
Params: perptypes.PerpetualParams{
Id: 0,
Ticker: "BTC-USD",
MarketId: uint32(0),
AtomicResolution: int32(-10),
DefaultFundingPpm: int32(0),
LiquidityTier: uint32(0),
MarketType: perptypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_CROSS,
},
FundingIndex: dtypes.ZeroInt(),
},
{
Params: perptypes.PerpetualParams{
Id: 1,
Ticker: "ETH-USD",
MarketId: uint32(1),
AtomicResolution: int32(-9),
DefaultFundingPpm: int32(0),
LiquidityTier: uint32(0),
MarketType: perptypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_CROSS,
},
FundingIndex: dtypes.ZeroInt(),
},
{
Params: perptypes.PerpetualParams{
Id: 2,
Ticker: "SOL-USD",
MarketId: uint32(2),
AtomicResolution: int32(-9),
DefaultFundingPpm: int32(0),
LiquidityTier: uint32(3),
MarketType: perptypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_CROSS,
},
FundingIndex: dtypes.ZeroInt(),
},
IsoUsd_IsolatedMarket,
}

// AddPremiumVotes messages.
var (
TestAddPremiumVotesMsg = &perptypes.MsgAddPremiumVotes{
Expand Down
10 changes: 10 additions & 0 deletions protocol/testutil/constants/pricefeed.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var (
MarketId0 = uint32(0)
MarketId1 = uint32(1)
MarketId2 = uint32(2)
MarketId3 = uint32(3)

MarketId7 = uint32(7)
MarketId8 = uint32(8)
Expand Down Expand Up @@ -269,23 +270,32 @@ var (
Exchange2_Price2_TimeT,
},
},
{
MarketId: MarketId3,
ExchangePrices: []*api.ExchangePrice{
Exchange3_Price3_TimeT,
},
},
}
AtTimeTSingleExchangeSmoothedPrices = map[uint32]uint64{
MarketId0: Exchange0_Price4_TimeT.Price,
MarketId1: Exchange1_Price1_TimeT.Price,
MarketId2: Exchange2_Price2_TimeT.Price,
MarketId3: Exchange3_Price3_TimeT.Price,
}

AtTimeTSingleExchangeSmoothedPricesPlus10 = map[uint32]uint64{
MarketId0: Exchange0_Price4_TimeT.Price + 10,
MarketId1: Exchange1_Price1_TimeT.Price + 10,
MarketId2: Exchange2_Price2_TimeT.Price + 10,
MarketId3: Exchange3_Price3_TimeT.Price + 10,
}

AtTimeTSingleExchangeSmoothedPricesPlus7 = map[uint32]uint64{
MarketId0: Exchange0_Price4_TimeT.Price + 7,
MarketId1: Exchange1_Price1_TimeT.Price + 7,
MarketId2: Exchange2_Price2_TimeT.Price + 7,
MarketId3: Exchange3_Price3_TimeT.Price + 7,
}

MixedTimePriceUpdate = []*api.MarketPriceUpdate{
Expand Down
26 changes: 26 additions & 0 deletions protocol/testutil/constants/prices.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
MaticUsdPair = "MATIC-USD"
SolUsdPair = "SOL-USD"
LtcUsdPair = "LTC-USD"
IsoUsdPair = "ISO-USD"

BtcUsdExponent = -5
EthUsdExponent = -6
Expand All @@ -34,6 +35,7 @@ const (
CrvUsdExponent = -10
SolUsdExponent = -8
LtcUsdExponent = -7
IsoUsdExponent = -8

CoinbaseExchangeName = "Coinbase"
BinanceExchangeName = "Binance"
Expand Down Expand Up @@ -201,6 +203,15 @@ var TestMarketExchangeConfigs = map[pricefeedclient.MarketId]string{
}
]
}`,
exchange_config.MARKET_ISO_USD: `{
"exchanges": [
{
"exchangeName": "Binance",
"ticker": "ISOUSDT",
"adjustByMarket": "USDT-USD"
}
]
}`,
}

var TestMarketParams = []types.MarketParam{
Expand Down Expand Up @@ -228,6 +239,14 @@ var TestMarketParams = []types.MarketParam{
MinPriceChangePpm: 50,
ExchangeConfigJson: TestMarketExchangeConfigs[exchange_config.MARKET_SOL_USD],
},
{
Id: 3,
Pair: IsoUsdPair,
Exponent: IsoUsdExponent,
MinExchanges: 1,
MinPriceChangePpm: 50,
ExchangeConfigJson: TestMarketExchangeConfigs[exchange_config.MARKET_ISO_USD],
},
}

var TestMarketPrices = []types.MarketPrice{
Expand All @@ -246,12 +265,18 @@ var TestMarketPrices = []types.MarketPrice{
Exponent: SolUsdExponent,
Price: FiveBillion, // 50$ == 1 SOL
},
{
Id: 3,
Exponent: IsoUsdExponent,
Price: FiveBillion, // 50$ == 1 ISO
},
}

var TestMarketIdsToExponents = map[uint32]int32{
0: BtcUsdExponent,
1: EthUsdExponent,
2: SolUsdExponent,
3: IsoUsdExponent,
}

var TestPricesGenesisState = types.GenesisState{
Expand All @@ -264,6 +289,7 @@ var (
types.NewMarketPriceUpdate(MarketId0, Price5),
types.NewMarketPriceUpdate(MarketId1, Price6),
types.NewMarketPriceUpdate(MarketId2, Price7),
types.NewMarketPriceUpdate(MarketId3, Price4),
}

// `MsgUpdateMarketPrices`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ const (
// MARKET_TEST_USD is the id used for the TEST-USD market pair.
MARKET_TEST_USD types.MarketId = 33

// Arbitrary isolated market
MARKET_ISO_USD types.MarketId = 999_999

// Non-trading markets.
// MARKET_USDT_USD is the id for the USDT-USD market pair.
MARKET_USDT_USD types.MarketId = 1_000_000
Expand Down
16 changes: 16 additions & 0 deletions protocol/testutil/keeper/perpetuals.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,22 @@ func PopulateTestPremiumStore(
}
}

func CreateTestPerpetuals(t *testing.T, ctx sdk.Context, k *keeper.Keeper) {
for _, p := range constants.TestMarketPerpetuals {
_, err := k.CreatePerpetual(
ctx,
p.Params.Id,
p.Params.Ticker,
p.Params.MarketId,
p.Params.AtomicResolution,
p.Params.DefaultFundingPpm,
p.Params.LiquidityTier,
p.Params.MarketType,
)
require.NoError(t, err)
}
}

func CreateTestLiquidityTiers(t *testing.T, ctx sdk.Context, k *keeper.Keeper) {
for _, l := range constants.LiquidityTiers {
_, err := k.SetLiquidityTier(
Expand Down
2 changes: 1 addition & 1 deletion protocol/x/clob/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func EndBlocker(
// Emit relevant metrics at the end of every block.
metrics.SetGauge(
metrics.InsuranceFundBalance,
metrics.GetMetricValueFromBigInt(keeper.GetInsuranceFundBalance(ctx)),
metrics.GetMetricValueFromBigInt(keeper.GetCrossInsuranceFundBalance(ctx)),
)
}

Expand Down
39 changes: 26 additions & 13 deletions protocol/x/clob/keeper/deleveraging.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"math/big"
"time"

types2 "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/types"
perptypes "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/types"

errorsmod "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/telemetry"
Expand Down Expand Up @@ -130,20 +130,36 @@ func (k Keeper) MaybeDeleverageSubaccount(
return quantumsDeleveraged, err
}

// GetInsuranceFundBalance returns the current balance of the insurance fund (in quote quantums).
// GetInsuranceFundBalance returns the current balance of the specific insurance fund based on the
// perpetual (in quote quantums).
// This calls the Bank Keeper’s GetBalance() function for the Module Address of the insurance fund.
func (k Keeper) GetInsuranceFundBalance(
ctx sdk.Context,
) (
balance *big.Int,
) {
func (k Keeper) GetInsuranceFundBalance(ctx sdk.Context, perpetualId uint32) (balance *big.Int) {
usdcAsset, exists := k.assetsKeeper.GetAsset(ctx, assettypes.AssetUsdc.Id)
if !exists {
panic("GetInsuranceFundBalance: Usdc asset not found in state")
}
insuranceFundAddr, err := k.perpetualsKeeper.GetInsuranceFundModuleAddress(ctx, perpetualId)
if err != nil {
return nil
}
insuranceFundBalance := k.bankKeeper.GetBalance(
ctx,
types2.InsuranceFundModuleAddress,
insuranceFundAddr,
usdcAsset.Denom,
)

// Return as big.Int.
return insuranceFundBalance.Amount.BigInt()
}

func (k Keeper) GetCrossInsuranceFundBalance(ctx sdk.Context) (balance *big.Int) {
usdcAsset, exists := k.assetsKeeper.GetAsset(ctx, assettypes.AssetUsdc.Id)
if !exists {
panic("GetCrossInsuranceFundBalance: Usdc asset not found in state")
}
insuranceFundBalance := k.bankKeeper.GetBalance(
ctx,
perptypes.InsuranceFundModuleAddress,
usdcAsset.Denom,
)

Expand Down Expand Up @@ -261,18 +277,15 @@ func (k Keeper) GateWithdrawalsIfNegativeTncSubaccountSeen(
// fund delta. Specifically, this function returns true if either of the following are true:
// - The `insuranceFundDelta` is non-negative.
// - The insurance fund balance + `insuranceFundDelta` is greater-than-or-equal-to 0.
func (k Keeper) IsValidInsuranceFundDelta(
ctx sdk.Context,
insuranceFundDelta *big.Int,
) bool {
func (k Keeper) IsValidInsuranceFundDelta(ctx sdk.Context, insuranceFundDelta *big.Int, perpetualId uint32) bool {
// Non-negative insurance fund deltas are valid.
if insuranceFundDelta.Sign() >= 0 {
return true
}

// The insurance fund delta is valid if the insurance fund balance is non-negative after adding
// the delta.
currentInsuranceFundBalance := k.GetInsuranceFundBalance(ctx)
currentInsuranceFundBalance := k.GetInsuranceFundBalance(ctx, perpetualId)
return new(big.Int).Add(currentInsuranceFundBalance, insuranceFundDelta).Sign() >= 0
}

Expand Down
Loading

0 comments on commit 12506a1

Please sign in to comment.