diff --git a/protocol/testing/e2e/gov/add_new_market_test.go b/protocol/testing/e2e/gov/add_new_market_test.go index cdc964f177..72cdf89c02 100644 --- a/protocol/testing/e2e/gov/add_new_market_test.go +++ b/protocol/testing/e2e/gov/add_new_market_test.go @@ -314,6 +314,7 @@ func TestAddNewMarketProposal(t *testing.T) { ctx, tApp, tc.proposedMsgs, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFail, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/bridge_test.go b/protocol/testing/e2e/gov/bridge_test.go index 616a78d0f9..b5c3848e62 100644 --- a/protocol/testing/e2e/gov/bridge_test.go +++ b/protocol/testing/e2e/gov/bridge_test.go @@ -111,6 +111,7 @@ func TestUpdateEventParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFails, tc.expectedProposalStatus, @@ -213,6 +214,7 @@ func TestUpdateProposeParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFails, tc.expectedProposalStatus, @@ -278,6 +280,7 @@ func TestUpdateSafetyParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, false, tc.expectSubmitProposalFails, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/feetiers_test.go b/protocol/testing/e2e/gov/feetiers_test.go index 3335e77359..8434897c93 100644 --- a/protocol/testing/e2e/gov/feetiers_test.go +++ b/protocol/testing/e2e/gov/feetiers_test.go @@ -129,6 +129,7 @@ func TestUpdateFeeTiersModuleParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFails, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/perpetuals_test.go b/protocol/testing/e2e/gov/perpetuals_test.go index e2286a5301..83f56c4d61 100644 --- a/protocol/testing/e2e/gov/perpetuals_test.go +++ b/protocol/testing/e2e/gov/perpetuals_test.go @@ -132,6 +132,7 @@ func TestUpdatePerpetualsModuleParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFail, tc.expectedProposalStatus, @@ -317,6 +318,7 @@ func TestUpdatePerpetualsParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFails, tc.expectedProposalStatus, @@ -467,6 +469,7 @@ func TestSetLiquidityTier(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFails, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/prices_test.go b/protocol/testing/e2e/gov/prices_test.go index c4df1cf917..52531c4ea6 100644 --- a/protocol/testing/e2e/gov/prices_test.go +++ b/protocol/testing/e2e/gov/prices_test.go @@ -181,6 +181,7 @@ func TestUpdateMarketParam(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFails, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/rewards_test.go b/protocol/testing/e2e/gov/rewards_test.go index 9d3c7ee3ca..33399079f1 100644 --- a/protocol/testing/e2e/gov/rewards_test.go +++ b/protocol/testing/e2e/gov/rewards_test.go @@ -120,6 +120,7 @@ func TestUpdateRewardsModuleParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFails, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/sending_test.go b/protocol/testing/e2e/gov/sending_test.go index 80a3f9c6eb..71c547be21 100644 --- a/protocol/testing/e2e/gov/sending_test.go +++ b/protocol/testing/e2e/gov/sending_test.go @@ -1,9 +1,11 @@ package gov_test import ( + "testing" + sdkmath "cosmossdk.io/math" + "github.com/dydxprotocol/v4-chain/protocol/lib" - "testing" "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -106,6 +108,7 @@ func TestSendFromModuleToAccount(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFail, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/stats_test.go b/protocol/testing/e2e/gov/stats_test.go index 5debce0c5a..10939155b1 100644 --- a/protocol/testing/e2e/gov/stats_test.go +++ b/protocol/testing/e2e/gov/stats_test.go @@ -1,10 +1,11 @@ package gov_test import ( - "github.com/dydxprotocol/v4-chain/protocol/lib" "testing" "time" + "github.com/dydxprotocol/v4-chain/protocol/lib" + "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -71,6 +72,7 @@ func TestUpdateParams(t *testing.T) { ctx, tApp, []sdk.Msg{tc.msg}, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFail, tc.expectedProposalStatus, diff --git a/protocol/testing/e2e/gov/vest_test.go b/protocol/testing/e2e/gov/vest_test.go index 4161b1230f..f30d1727b5 100644 --- a/protocol/testing/e2e/gov/vest_test.go +++ b/protocol/testing/e2e/gov/vest_test.go @@ -174,6 +174,7 @@ func TestSetVestEntry_Success(t *testing.T) { ctx, tApp, tc.msgs, + testapp.TestSubmitProposalTxHeight, false, // checkTx should not fail. false, // submitProposal should not fail. govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED, @@ -309,6 +310,7 @@ func TestSetVestEntry_Failure(t *testing.T) { ctx, tApp, tc.msgs, + testapp.TestSubmitProposalTxHeight, tc.expectCheckTxFails, tc.expectSubmitProposalFail, govtypesv1.ProposalStatus_PROPOSAL_STATUS_FAILED, @@ -385,6 +387,7 @@ func TestDeleteVestEntry_Success(t *testing.T) { ctx, tApp, tc.msgs, + testapp.TestSubmitProposalTxHeight, false, // checkTx should not fail. false, // submitProposal should not fail. govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED, @@ -489,6 +492,7 @@ func TestDeleteVestEntry_Failure(t *testing.T) { ctx, tApp, tc.msgs, + testapp.TestSubmitProposalTxHeight, false, // checkTx should not fail. tc.expectSubmitProposalFail, govtypesv1.ProposalStatus_PROPOSAL_STATUS_FAILED, diff --git a/protocol/testing/e2e/gov/wind_down_market_test.go b/protocol/testing/e2e/gov/wind_down_market_test.go new file mode 100644 index 0000000000..ad8ba132b0 --- /dev/null +++ b/protocol/testing/e2e/gov/wind_down_market_test.go @@ -0,0 +1,338 @@ +package gov_test + +import ( + "testing" + + "github.com/cometbft/cometbft/types" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + "github.com/dydxprotocol/v4-chain/protocol/daemons/liquidation/api" + "github.com/dydxprotocol/v4-chain/protocol/indexer" + indexerevents "github.com/dydxprotocol/v4-chain/protocol/indexer/events" + "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" + "github.com/dydxprotocol/v4-chain/protocol/indexer/msgsender" + indexershared "github.com/dydxprotocol/v4-chain/protocol/indexer/shared" + "github.com/dydxprotocol/v4-chain/protocol/lib" + testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" + "github.com/dydxprotocol/v4-chain/protocol/testutil/constants" + clobtypes "github.com/dydxprotocol/v4-chain/protocol/x/clob/types" + perptypes "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/types" + prices "github.com/dydxprotocol/v4-chain/protocol/x/prices/types" + satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types" +) + +func TestWindDownMarketProposal(t *testing.T) { + tests := map[string]struct { + subaccounts []satypes.Subaccount + preexistingStatefulOrders []clobtypes.MsgPlaceOrder + orders []clobtypes.MsgPlaceOrder + + expectedSubaccounts []satypes.Subaccount + }{ + `Succeeds with final settlement deleveraging, non-negative TNC accounts deleveraged + at oracle price`: { + subaccounts: []satypes.Subaccount{ + // well-collateralized long and short positions + constants.Carl_Num0_1BTC_Short_100000USD, + constants.Dave_Num0_1BTC_Long_50000USD, + }, + expectedSubaccounts: []satypes.Subaccount{ + { + Id: &constants.Carl_Num0, + AssetPositions: []*satypes.AssetPosition{ + &constants.Usdc_Asset_50_000, + }, + }, + { + Id: &constants.Dave_Num0, + AssetPositions: []*satypes.AssetPosition{ + &constants.Usdc_Asset_100_000, + }, + }, + }, + }, + `Succeeds with final settlement deleveraging, negative TNC accounts deleveraged at + bankruptcy price`: { + subaccounts: []satypes.Subaccount{ + // negative TNC position + constants.Carl_Num0_1BTC_Short_49999USD, + // offsetting position + constants.Dave_Num0_1BTC_Long_50001USD, + }, + expectedSubaccounts: []satypes.Subaccount{ + { + Id: &constants.Carl_Num0, + }, + { + Id: &constants.Dave_Num0, + AssetPositions: []*satypes.AssetPosition{ + &constants.Usdc_Asset_100_000, + }, + }, + }, + }, + `Succeeds cancelling open stateful orders on both sides from different subaccounts`: { + subaccounts: []satypes.Subaccount{ + constants.Alice_Num0_10_000USD, + constants.Bob_Num0_10_000USD, + }, + preexistingStatefulOrders: []clobtypes.MsgPlaceOrder{ + { + Order: constants.LongTermOrder_Alice_Num0_Id0_Clob0_Buy5_Price5_GTBT5, + }, + { + Order: constants.LongTermOrder_Bob_Num0_Id0_Clob0_Sell10_Price10_GTBT10_PO, + }, + { + Order: constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_SL_50001, + }, + }, + }, + `Succeeds blocking new orders from being placed`: { + subaccounts: []satypes.Subaccount{ + constants.Alice_Num0_10_000USD, + constants.Bob_Num0_10_000USD, + constants.Carl_Num0_10000USD, + }, + orders: []clobtypes.MsgPlaceOrder{ + // Short term orders + { + Order: constants.Order_Alice_Num0_Id0_Clob0_Buy10_Price10_GTB16, + }, + { + Order: constants.Order_Carl_Num0_Id0_Clob0_Buy1BTC_Price50000_GTB20_FOK, + }, + { + Order: constants.Order_Alice_Num0_Id1_Clob0_Buy5_Price15_GTB20_IOC, + }, + { + Order: constants.Order_Alice_Num0_Id1_Clob0_Sell15_Price10_GTB18_PO, + }, + // Stateful orders + { + Order: constants.LongTermOrder_Alice_Num0_Id0_Clob0_Buy5_Price5_GTBT5, + }, + { + Order: constants.LongTermOrder_Bob_Num0_Id0_Clob0_Sell10_Price10_GTBT10_PO, + }, + { + Order: constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_SL_50001, + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + msgSender := msgsender.NewIndexerMessageSenderInMemoryCollector() + appOpts := map[string]interface{}{ + indexer.MsgSenderInstanceForTest: msgSender, + } + + // Initialize test app + tApp := testapp.NewTestAppBuilder(t).WithAppOptions(appOpts).WithGenesisDocFn(func() (genesis types.GenesisDoc) { + genesis = testapp.DefaultGenesis() + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *govtypesv1.GenesisState) { + genesisState.Params.VotingPeriod = &testapp.TestVotingPeriod + }, + ) + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *perptypes.GenesisState) { + genesisState.Params = constants.PerpetualsGenesisParams + genesisState.LiquidityTiers = constants.LiquidityTiers + genesisState.Perpetuals = []perptypes.Perpetual{ + constants.BtcUsd_20PercentInitial_10PercentMaintenance, + } + }, + ) + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *prices.GenesisState) { + // Set oracle prices in the genesis. + pricesGenesis := constants.TestPricesGenesisState + *genesisState = pricesGenesis + }, + ) + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *satypes.GenesisState) { + genesisState.Subaccounts = tc.subaccounts + }, + ) + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *clobtypes.GenesisState) { + genesisState.ClobPairs = []clobtypes.ClobPair{constants.ClobPair_Btc} + genesisState.LiquidationsConfig = constants.LiquidationsConfig_No_Limit + genesisState.EquityTierLimitConfig = clobtypes.EquityTierLimitConfiguration{} + }, + ) + return genesis + }).Build() + ctx := tApp.InitChain() + + for _, order := range tc.preexistingStatefulOrders { + for _, checkTx := range testapp.MustMakeCheckTxsWithClobMsg( + ctx, + tApp.App, + order, + ) { + resp := tApp.CheckTx(checkTx) + require.True( + t, + resp.IsOK(), + "Expected CheckTx to succeed. Response: %+v", + resp, + ) + } + } + + // Place stateful orders in state, verify they were placed + ctx = tApp.AdvanceToBlock(uint32(ctx.BlockHeight())+1, testapp.AdvanceToBlockOptions{}) + for _, order := range tc.preexistingStatefulOrders { + _, exists := tApp.App.ClobKeeper.GetLongTermOrderPlacement(ctx, order.Order.OrderId) + require.True(t, exists) + } + + // Build MsgUpdateClobPair + clobPairId := 0 + clobPair, exists := tApp.App.ClobKeeper.GetClobPair(ctx, clobtypes.ClobPairId(clobPairId)) + require.True(t, exists) + clobPair.Status = clobtypes.ClobPair_STATUS_FINAL_SETTLEMENT + msgUpdateClobPairToFinalSettlement := &clobtypes.MsgUpdateClobPair{ + Authority: lib.GovModuleAddress.String(), + ClobPair: clobPair, + } + + // Submit and Tally Proposal, proposal is executed in this step + ctx = testapp.SubmitAndTallyProposal( + t, + ctx, + tApp, + []sdk.Msg{ + msgUpdateClobPairToFinalSettlement, + }, + uint32(ctx.BlockHeight())+1, + false, + false, + govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED, + ) + + // Verify events emitted by indexer in the last block, the block in which the gov proposal was executed + events := []*indexer_manager.IndexerTendermintEvent{ + { + Subtype: indexerevents.SubtypeUpdateClobPair, + OrderingWithinBlock: &indexer_manager.IndexerTendermintEvent_TransactionIndex{}, + EventIndex: 0, + Version: indexerevents.UpdateClobPairEventVersion, + DataBytes: indexer_manager.GetBytes( + indexerevents.NewUpdateClobPairEvent( + clobPair.GetClobPairId(), + clobPair.Status, + clobPair.QuantumConversionExponent, + clobtypes.SubticksPerTick(clobPair.GetSubticksPerTick()), + satypes.BaseQuantums(clobPair.GetStepBaseQuantums()), + ), + ), + }, + } + for i, order := range tc.preexistingStatefulOrders { + events = append( + events, + &indexer_manager.IndexerTendermintEvent{ + Subtype: indexerevents.SubtypeStatefulOrder, + OrderingWithinBlock: &indexer_manager.IndexerTendermintEvent_TransactionIndex{}, + EventIndex: uint32(i + 1), + Version: indexerevents.StatefulOrderEventVersion, + DataBytes: indexer_manager.GetBytes( + indexerevents.NewStatefulOrderRemovalEvent( + order.Order.OrderId, + indexershared.OrderRemovalReason_ORDER_REMOVAL_REASON_FINAL_SETTLEMENT, + ), + ), + }, + ) + } + expectedOnChainMessageAfterGovProposal := indexer_manager.CreateIndexerBlockEventMessage( + &indexer_manager.IndexerTendermintBlock{ + Height: uint32(ctx.BlockHeight()), + Time: ctx.BlockTime(), + Events: events, + TxHashes: []string{ + string(lib.GetTxHash( + []byte{}, + )), + }, + }, + ) + onchainMessages := msgSender.GetOnchainMessages() + require.Equal( + t, + expectedOnChainMessageAfterGovProposal, + onchainMessages[len(onchainMessages)-1], + ) + + // Verify clob pair is transitioned to final settlement + updatedClobPair, exists := tApp.App.ClobKeeper.GetClobPair(ctx, clobtypes.ClobPairId(clobPairId)) + require.True(t, exists) + require.Equal(t, clobtypes.ClobPair_STATUS_FINAL_SETTLEMENT, updatedClobPair.Status) + + // Verify that open stateful orders are removed from state + for _, order := range tc.preexistingStatefulOrders { + _, exists := tApp.App.ClobKeeper.GetLongTermOrderPlacement(ctx, order.Order.OrderId) + require.False(t, exists) + } + + // Set liquidation daemon info, to simulate liquidations daemon updating SubaccountOpenPositionInfo + _, err := tApp.App.Server.LiquidateSubaccounts( + ctx, + &api.LiquidateSubaccountsRequest{ + SubaccountOpenPositionInfo: []clobtypes.SubaccountOpenPositionInfo{ + { + PerpetualId: 0, + SubaccountsWithShortPosition: []satypes.SubaccountId{ + constants.Carl_Num0, + }, + SubaccountsWithLongPosition: []satypes.SubaccountId{ + constants.Dave_Num0, + }, + }, + }, + }, + ) + require.NoError(t, err) + + // Advance block again to trigger final settlement deleveraging in PrepareCheckState + ctx = tApp.AdvanceToBlock(uint32(ctx.BlockHeight())+1, testapp.AdvanceToBlockOptions{}) + + // Verify that final settlement deleveraging occurs + for _, expectedSubaccount := range tc.expectedSubaccounts { + subaccount := tApp.App.SubaccountsKeeper.GetSubaccount(ctx, *expectedSubaccount.Id) + require.Equal(t, expectedSubaccount, subaccount) + } + + // Attempt to place new orders, should fail validation + for _, order := range tc.orders { + for _, checkTx := range testapp.MustMakeCheckTxsWithClobMsg( + ctx, + tApp.App, + order, + ) { + resp := tApp.CheckTx(checkTx) + require.Contains(t, resp.Log, "trading is disabled for clob pair") + require.False( + t, + resp.IsOK(), + "Expected CheckTx to fail. Response: %+v", + resp, + ) + } + } + }) + } +} diff --git a/protocol/testutil/app/gov.go b/protocol/testutil/app/gov.go index 32b0bd6713..361af86b55 100644 --- a/protocol/testutil/app/gov.go +++ b/protocol/testutil/app/gov.go @@ -2,10 +2,11 @@ package app import ( "bytes" - abcitypes "github.com/cometbft/cometbft/abci/types" "testing" "time" + abcitypes "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/dydxprotocol/v4-chain/protocol/testutil/constants" @@ -35,6 +36,7 @@ func SubmitAndTallyProposal( ctx sdk.Context, tApp *TestApp, messages []sdk.Msg, + submitProposalTxHeight uint32, expectCheckTxFails bool, expectSubmitProposalFails bool, expectedProposalStatus govtypesv1.ProposalStatus, @@ -73,7 +75,7 @@ func SubmitAndTallyProposal( } if expectSubmitProposalFails { - ctx = tApp.AdvanceToBlock(TestSubmitProposalTxHeight, AdvanceToBlockOptions{ + ctx = tApp.AdvanceToBlock(submitProposalTxHeight, AdvanceToBlockOptions{ ValidateFinalizeBlock: func( context sdk.Context, request abcitypes.RequestFinalizeBlock, @@ -92,7 +94,7 @@ func SubmitAndTallyProposal( // Proposal submission failed. Return early. return ctx } else { - ctx = tApp.AdvanceToBlock(TestSubmitProposalTxHeight, AdvanceToBlockOptions{}) + ctx = tApp.AdvanceToBlock(submitProposalTxHeight, AdvanceToBlockOptions{}) } proposalsIterator, err := tApp.App.GovKeeper.Proposals.Iterate(ctx, nil) diff --git a/protocol/testutil/constants/orders.go b/protocol/testutil/constants/orders.go index 70e3f4c1db..01ab55c0b8 100644 --- a/protocol/testutil/constants/orders.go +++ b/protocol/testutil/constants/orders.go @@ -991,6 +991,14 @@ var ( } // IOC orders. + Order_Alice_Num0_Id1_Clob0_Buy5_Price15_GTB20_IOC = clobtypes.Order{ + OrderId: clobtypes.OrderId{SubaccountId: Alice_Num0, ClientId: 1, ClobPairId: 0}, + Side: clobtypes.Order_SIDE_BUY, + Quantums: 5, + Subticks: 15, + GoodTilOneof: &clobtypes.Order_GoodTilBlock{GoodTilBlock: 20}, + TimeInForce: clobtypes.Order_TIME_IN_FORCE_IOC, + } Order_Alice_Num0_Id1_Clob1_Buy5_Price15_GTB20_IOC = clobtypes.Order{ OrderId: clobtypes.OrderId{SubaccountId: Alice_Num0, ClientId: 1, ClobPairId: 1}, Side: clobtypes.Order_SIDE_BUY, @@ -1105,6 +1113,14 @@ var ( GoodTilOneof: &clobtypes.Order_GoodTilBlock{GoodTilBlock: 10}, TimeInForce: clobtypes.Order_TIME_IN_FORCE_FILL_OR_KILL, } + Order_Carl_Num0_Id0_Clob0_Buy1BTC_Price50000_GTB20_FOK = clobtypes.Order{ + OrderId: clobtypes.OrderId{SubaccountId: Carl_Num0, ClientId: 0, ClobPairId: 0}, + Side: clobtypes.Order_SIDE_BUY, + Quantums: 100_000_000, // 1 BTC + Subticks: 50_000_000_000, + GoodTilOneof: &clobtypes.Order_GoodTilBlock{GoodTilBlock: 20}, + TimeInForce: clobtypes.Order_TIME_IN_FORCE_FILL_OR_KILL, + } Order_Carl_Num0_Id0_Clob0_Buy075BTC_Price50000_GTB11_FOK = clobtypes.Order{ OrderId: clobtypes.OrderId{SubaccountId: Carl_Num0, ClientId: 0, ClobPairId: 0}, Side: clobtypes.Order_SIDE_BUY, diff --git a/protocol/testutil/constants/stateful_orders.go b/protocol/testutil/constants/stateful_orders.go index 4aad6edad2..a7060580a6 100644 --- a/protocol/testutil/constants/stateful_orders.go +++ b/protocol/testutil/constants/stateful_orders.go @@ -18,6 +18,18 @@ var ( Subticks: 10, GoodTilOneof: &clobtypes.Order_GoodTilBlock{GoodTilBlock: 5}, } + LongTermOrder_Alice_Num0_Id0_Clob0_Buy5_Price5_GTBT5 = clobtypes.Order{ + OrderId: clobtypes.OrderId{ + SubaccountId: Alice_Num0, + ClientId: 0, + OrderFlags: clobtypes.OrderIdFlags_LongTerm, + ClobPairId: 0, + }, + Side: clobtypes.Order_SIDE_BUY, + Quantums: 5, + Subticks: 5, + GoodTilOneof: &clobtypes.Order_GoodTilBlockTime{GoodTilBlockTime: 5}, + } LongTermOrder_Alice_Num0_Id0_Clob0_Buy5_Price10_GTBT5 = clobtypes.Order{ OrderId: clobtypes.OrderId{ SubaccountId: Alice_Num0, diff --git a/protocol/testutil/constants/subaccounts.go b/protocol/testutil/constants/subaccounts.go index 4ecc8a392f..e8e5bd5230 100644 --- a/protocol/testutil/constants/subaccounts.go +++ b/protocol/testutil/constants/subaccounts.go @@ -342,6 +342,22 @@ var ( }, }, } + Dave_Num0_1BTC_Long_50001USD = satypes.Subaccount{ + Id: &Dave_Num0, + AssetPositions: []*satypes.AssetPosition{ + { + AssetId: 0, + Quantums: dtypes.NewInt(50_001_000_000), // $50,001 + }, + }, + PerpetualPositions: []*satypes.PerpetualPosition{ + { + PerpetualId: 0, + Quantums: dtypes.NewInt(100_000_000), // 1 BTC + FundingIndex: dtypes.NewInt(0), + }, + }, + } Dave_Num0_1BTC_Short_100000USD = satypes.Subaccount{ Id: &Dave_Num0, AssetPositions: []*satypes.AssetPosition{