diff --git a/proto/dex/enums.proto b/proto/dex/enums.proto index 76a88dd05b..49588e2dcf 100644 --- a/proto/dex/enums.proto +++ b/proto/dex/enums.proto @@ -19,6 +19,8 @@ enum OrderType { LIQUIDATION = 2; FOKMARKET = 3; // fill-or-kill market order FOKMARKETBYVALUE = 4; // fill-or-kill market by value order + STOPLOSS = 5; + STOPLIMIT = 6; } enum Unit { diff --git a/proto/dex/genesis.proto b/proto/dex/genesis.proto index d3cf6c842e..9a1320da39 100644 --- a/proto/dex/genesis.proto +++ b/proto/dex/genesis.proto @@ -7,6 +7,7 @@ import "dex/long_book.proto"; import "dex/short_book.proto"; import "dex/twap.proto"; import "dex/tick_size.proto"; +import "dex/order.proto"; // this line is used by starport scaffolding # genesis/proto/import option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; @@ -19,5 +20,6 @@ message GenesisState { repeated Twap twapList = 4; repeated TickSize tickSizeList = 5; // if null, then no restriction, todo(zw) should set it to not nullable? uint64 lastEpoch = 6; + repeated Order triggeredOrdersList = 7 [(gogoproto.nullable) = false]; // this line is used by starport scaffolding # genesis/proto/state } diff --git a/proto/dex/order.proto b/proto/dex/order.proto index fed167a84f..8b366eb6e6 100644 --- a/proto/dex/order.proto +++ b/proto/dex/order.proto @@ -59,6 +59,15 @@ message Order { (gogoproto.nullable) = false, (gogoproto.jsontag) = "nominal" ]; + string triggerPrice = 14 [ + (gogoproto.moretags) = "yaml:\"trigger_price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "trigger_price" + ]; + bool triggerStatus = 15 [ + (gogoproto.jsontag) = "trigger_status" + ]; } message Cancellation { diff --git a/wasmbinding/test/encoder_test.go b/wasmbinding/test/encoder_test.go index 836dd266d5..439c3a707b 100644 --- a/wasmbinding/test/encoder_test.go +++ b/wasmbinding/test/encoder_test.go @@ -31,6 +31,8 @@ func TestEncodePlaceOrder(t *testing.T) { Quantity: sdk.OneDec(), Data: "{\"position_effect\":\"OPEN\", \"leverage\":\"1\"}", Nominal: sdk.ZeroDec(), + TriggerPrice: sdk.ZeroDec(), + TriggerStatus: false, } fund := sdk.NewCoin("usei", sdk.NewInt(1000000000)) msg := bindings.PlaceOrders{ diff --git a/x/dex/cache/order.go b/x/dex/cache/order.go index 87b87f06a2..967da54f2d 100644 --- a/x/dex/cache/order.go +++ b/x/dex/cache/order.go @@ -78,6 +78,20 @@ func (o *BlockOrders) GetLimitOrders(direction types.PositionDirection) []*types return o.getOrdersByCriteria(types.OrderType_LIMIT, direction) } +func (o *BlockOrders) GetTriggeredOrders() []*types.Order { + o.mu.Lock() + defer o.mu.Unlock() + return o.getOrdersByCriteriaMap( + map[types.OrderType]bool{ + types.OrderType_STOPLOSS: true, + types.OrderType_STOPLIMIT: true, + }, + map[types.PositionDirection]bool{ + types.PositionDirection_LONG: true, + types.PositionDirection_SHORT: true, + }) +} + func (o *BlockOrders) getOrdersByCriteria(orderType types.OrderType, direction types.PositionDirection) []*types.Order { res := []*types.Order{} for _, order := range o.internal { diff --git a/x/dex/cache/order_test.go b/x/dex/cache/order_test.go index 56afb231b3..2fbea4d714 100644 --- a/x/dex/cache/order_test.go +++ b/x/dex/cache/order_test.go @@ -139,3 +139,45 @@ func TestGetSortedMarketOrders(t *testing.T) { require.Equal(t, uint64(6), marketSellsWithoutLiquidation[0].Id) require.Equal(t, uint64(5), marketSellsWithoutLiquidation[1].Id) } + +func TestGetTriggeredOrders(t *testing.T) { + ctx := sdk.Context{} + stateOne := dex.NewMemState() + stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLOSS, + Price: sdk.MustNewDecFromStr("150"), + TriggerPrice: sdk.MustNewDecFromStr("100"), + TriggerStatus: false, + }) + stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).Add(&types.Order{ + Id: 2, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLIMIT, + Price: sdk.MustNewDecFromStr("150"), + TriggerPrice: sdk.MustNewDecFromStr("200"), + TriggerStatus: false, + }) + stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).Add(&types.Order{ + Id: 3, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_LIMIT, + Price: sdk.MustNewDecFromStr("100"), + }) + + triggeredOrders := stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).GetTriggeredOrders() + var orderIds []uint64 + for _, order := range triggeredOrders { + orderIds = append(orderIds, order.Id) + } + + require.Equal(t, len(triggeredOrders), 2) + require.ElementsMatch(t, orderIds, []uint64{1, 2}) +} diff --git a/x/dex/client/cli/tx/tx_place_orders.go b/x/dex/client/cli/tx/tx_place_orders.go index 63da4cd675..d147ece99a 100644 --- a/x/dex/client/cli/tx/tx_place_orders.go +++ b/x/dex/client/cli/tx/tx_place_orders.go @@ -60,6 +60,19 @@ func CmdPlaceOrders() *cobra.Command { } newOrder.Nominal = argNominal } + if newOrder.OrderType == types.OrderType_STOPLOSS || newOrder.OrderType == types.OrderType_STOPLIMIT { + triggerPrice, err := sdk.NewDecFromStr(orderDetails[7]) + if err != nil { + return err + } + triggerStatus, err := strconv.ParseBool(orderDetails[8]) + if err != nil { + return err + } + + newOrder.TriggerPrice = triggerPrice + newOrder.TriggerStatus = triggerStatus + } orders = append(orders, &newOrder) } diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go index b78956ead2..03d4858c22 100644 --- a/x/dex/contract/execution.go +++ b/x/dex/contract/execution.go @@ -68,6 +68,7 @@ func ExecutePair( // Fill limit orders limitOrderOutcome := exchange.MatchLimitOrders(ctx, orderbook) totalOutcome := marketOrderOutcome.Merge(&limitOrderOutcome) + UpdateTriggeredOrderForPair(ctx, typedContractAddr, typedPairStr, dexkeeper, totalOutcome) dexkeeperutils.SetPriceStateFromExecutionOutcome(ctx, dexkeeper, typedContractAddr, pair, totalOutcome) dexkeeperutils.FlushOrderbook(ctx, dexkeeper, typedContractAddr, orderbook) @@ -111,6 +112,60 @@ func matchMarketOrderForPair( return marketBuyOutcome.Merge(&marketSellOutcome) } +func MoveTriggeredOrderForPair( + ctx sdk.Context, + typedContractAddr dextypesutils.ContractAddress, + typedPairStr dextypesutils.PairString, + dexkeeper *keeper.Keeper, +) { + priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) + triggeredOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) + for i, order := range triggeredOrders { + if order.TriggerStatus { + if order.OrderType == types.OrderType_STOPLOSS { + triggeredOrders[i].OrderType = types.OrderType_MARKET + } else if order.OrderType == types.OrderType_STOPLIMIT { + triggeredOrders[i].OrderType = types.OrderType_LIMIT + } + dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr).Add(&triggeredOrders[i]) + dexkeeper.RemoveTriggeredOrder(ctx, string(typedContractAddr), order.Id, priceDenom, assetDenom) + } + } +} + +func UpdateTriggeredOrderForPair( + ctx sdk.Context, + typedContractAddr dextypesutils.ContractAddress, + typedPairStr dextypesutils.PairString, + dexkeeper *keeper.Keeper, + totalOutcome exchange.ExecutionOutcome, +) { + // update existing trigger orders + priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) + triggeredOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) + for i, order := range triggeredOrders { + if order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice) { + triggeredOrders[i].TriggerStatus = true + dexkeeper.SetTriggeredOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) + } else if order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { + triggeredOrders[i].TriggerStatus = true + dexkeeper.SetTriggeredOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) + } + } + + // update triggered orders in cache + orders := dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr) + cacheTriggeredOrders := orders.GetTriggeredOrders() + for i, order := range cacheTriggeredOrders { + if order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice) { + cacheTriggeredOrders[i].TriggerStatus = true + } else if order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { + cacheTriggeredOrders[i].TriggerStatus = true + } + dexkeeper.SetTriggeredOrder(ctx, string(typedContractAddr), *cacheTriggeredOrders[i], priceDenom, assetDenom) + } +} + func GetMatchResults( ctx sdk.Context, typedContractAddr dextypesutils.ContractAddress, @@ -168,6 +223,7 @@ func ExecutePairsInParallel(ctx sdk.Context, contractAddr string, dexkeeper *kee pairCopy := pair pairStr := dextypesutils.GetPairString(&pairCopy) + MoveTriggeredOrderForPair(ctx, typedContractAddr, pairStr, dexkeeper) orderbook, found := orderBooks.Load(pairStr) if !found { panic(fmt.Sprintf("Orderbook not found for %s", pairStr)) diff --git a/x/dex/contract/execution_test.go b/x/dex/contract/execution_test.go new file mode 100644 index 0000000000..2e5d93c4d9 --- /dev/null +++ b/x/dex/contract/execution_test.go @@ -0,0 +1,159 @@ +package contract_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/contract" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/sei-protocol/sei-chain/x/dex/types/utils" + "github.com/stretchr/testify/require" +) + +func TEST_PAIR() types.Pair { + return types.Pair{ + PriceDenom: "usdc", + AssetDenom: "atom", + } +} + +const ( + TEST_CONTRACT = "test" + TestTimestamp uint64 = 10000 + TestHeight uint64 = 1 +) + +func TestMoveTriggeredOrderIntoMemState(t *testing.T) { + pair := TEST_PAIR() + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + triggeredOrder := types.Order{ + Id: 8, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("10"), + TriggerStatus: true, + } + + dexkeeper.SetTriggeredOrder(ctx, TEST_CONTRACT, triggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + contract.MoveTriggeredOrderForPair( + ctx, + utils.ContractAddress(TEST_CONTRACT), + utils.GetPairString(&pair), + dexkeeper, + ) + orders := dexkeeper.MemState.GetBlockOrders(ctx, TEST_CONTRACT, utils.GetPairString(&pair)) + cacheMarketOrders := orders.GetSortedMarketOrders(types.PositionDirection_LONG, false) + cacheTriggeredOrders := orders.GetTriggeredOrders() + + triggeredBookOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + + require.Equal(t, len(triggeredBookOrders), 0) + require.Equal(t, len(cacheTriggeredOrders), 0) + require.Equal(t, len(cacheMarketOrders), 1) + require.Equal(t, cacheMarketOrders[0].Id, uint64(8)) + require.Equal(t, cacheMarketOrders[0].OrderType, types.OrderType_MARKET) + require.Equal(t, cacheMarketOrders[0].PositionDirection, types.PositionDirection_LONG) +} + +func TestUpdateTriggeredOrders(t *testing.T) { + pair := TEST_PAIR() + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + shortTriggeredOrder := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLIMIT, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("6"), + TriggerStatus: false, + } + longTriggeredOrder := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("19"), + TriggerStatus: false, + } + shortNotTriggeredOrder := types.Order{ + Id: 3, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + longNotTriggeredOrder := types.Order{ + Id: 4, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLIMIT, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("21"), + TriggerStatus: false, + } + + totalOutcome := exchange.ExecutionOutcome{ + TotalNotional: sdk.MustNewDecFromStr("10"), + TotalQuantity: sdk.MustNewDecFromStr("10"), + Settlements: []*types.SettlementEntry{}, + MinPrice: sdk.MustNewDecFromStr("5"), + MaxPrice: sdk.MustNewDecFromStr("20"), + } + + dexkeeper.SetTriggeredOrder(ctx, TEST_CONTRACT, shortTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + dexkeeper.SetTriggeredOrder(ctx, TEST_CONTRACT, longNotTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + orders := dexkeeper.MemState.GetBlockOrders(ctx, TEST_CONTRACT, utils.GetPairString(&pair)) + orders.Add(&shortNotTriggeredOrder) + orders.Add(&longTriggeredOrder) + + contract.UpdateTriggeredOrderForPair( + ctx, + utils.ContractAddress(TEST_CONTRACT), + utils.GetPairString(&pair), + dexkeeper, + totalOutcome, + ) + + triggeredBookOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + + require.Equal(t, len(triggeredBookOrders), 4) + triggerStatusMap := map[uint64]bool{} + + for _, order := range triggeredBookOrders { + triggerStatusMap[order.Id] = order.TriggerStatus + } + require.Contains(t, triggerStatusMap, uint64(1)) + require.Contains(t, triggerStatusMap, uint64(2)) + require.Contains(t, triggerStatusMap, uint64(3)) + require.Contains(t, triggerStatusMap, uint64(4)) + + require.Equal(t, triggerStatusMap[uint64(1)], true) + require.Equal(t, triggerStatusMap[uint64(2)], true) + require.Equal(t, triggerStatusMap[uint64(3)], false) + require.Equal(t, triggerStatusMap[uint64(4)], false) +} diff --git a/x/dex/exchange/helpers.go b/x/dex/exchange/helpers.go index 57bf15ebbc..026d3c14d5 100644 --- a/x/dex/exchange/helpers.go +++ b/x/dex/exchange/helpers.go @@ -9,6 +9,8 @@ type ExecutionOutcome struct { TotalNotional sdk.Dec TotalQuantity sdk.Dec Settlements []*types.SettlementEntry + MinPrice sdk.Dec + MaxPrice sdk.Dec } func (o *ExecutionOutcome) Merge(other *ExecutionOutcome) ExecutionOutcome { @@ -16,5 +18,7 @@ func (o *ExecutionOutcome) Merge(other *ExecutionOutcome) ExecutionOutcome { TotalNotional: o.TotalNotional.Add(other.TotalNotional), TotalQuantity: o.TotalQuantity.Add(other.TotalQuantity), Settlements: append(o.Settlements, other.Settlements...), + MinPrice: sdk.MinDec(o.MinPrice, other.MinPrice), + MaxPrice: sdk.MaxDec(o.MaxPrice, other.MaxPrice), } } diff --git a/x/dex/exchange/helpers_test.go b/x/dex/exchange/helpers_test.go new file mode 100644 index 0000000000..3b271c3896 --- /dev/null +++ b/x/dex/exchange/helpers_test.go @@ -0,0 +1,64 @@ +package exchange_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMergeExecutionOutcomes(t *testing.T) { + s1 := types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + } + + s2 := types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + } + + e1 := exchange.ExecutionOutcome{ + TotalNotional: sdk.MustNewDecFromStr("1"), + TotalQuantity: sdk.MustNewDecFromStr("2"), + Settlements: []*types.SettlementEntry{&s1, &s2, &s1}, + MinPrice: sdk.MustNewDecFromStr("1"), + MaxPrice: sdk.MustNewDecFromStr("4"), + } + + e2 := exchange.ExecutionOutcome{ + TotalNotional: sdk.MustNewDecFromStr("4"), + TotalQuantity: sdk.MustNewDecFromStr("4"), + Settlements: []*types.SettlementEntry{&s1, &s2}, + MinPrice: sdk.MustNewDecFromStr("0.5"), + MaxPrice: sdk.MustNewDecFromStr("3"), + } + + outcome := e1.Merge(&e2) + + require.Equal(t, outcome.TotalNotional, sdk.MustNewDecFromStr("5")) + require.Equal(t, outcome.TotalQuantity, sdk.MustNewDecFromStr("6")) + require.Equal(t, len(outcome.Settlements), 5) + require.Equal(t, outcome.MinPrice, sdk.MustNewDecFromStr("0.5")) + require.Equal(t, outcome.MaxPrice, sdk.MustNewDecFromStr("4")) +} diff --git a/x/dex/exchange/limit_order.go b/x/dex/exchange/limit_order.go index e531222cc6..48e3b4d7b3 100644 --- a/x/dex/exchange/limit_order.go +++ b/x/dex/exchange/limit_order.go @@ -1,6 +1,8 @@ package exchange import ( + "math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/x/dex/types" ) @@ -11,6 +13,7 @@ func MatchLimitOrders( ) ExecutionOutcome { settlements := []*types.SettlementEntry{} totalExecuted, totalPrice := sdk.ZeroDec(), sdk.ZeroDec() + minPrice, maxPrice := sdk.NewDecFromInt(sdk.NewIntFromUint64(math.MaxInt64)), sdk.OneDec().Neg() longPtr, shortPtr := len(orderbook.Longs.Entries)-1, 0 for longPtr >= 0 && shortPtr < len(orderbook.Shorts.Entries) && orderbook.Longs.Entries[longPtr].GetPrice().GTE(orderbook.Shorts.Entries[shortPtr].GetPrice()) { @@ -26,6 +29,8 @@ func MatchLimitOrders( orderbook.Longs.Entries[longPtr].GetPrice().Add(orderbook.Shorts.Entries[shortPtr].GetPrice()), ), ) + minPrice = sdk.MinDec(minPrice, orderbook.Longs.Entries[longPtr].GetPrice()) + maxPrice = sdk.MaxDec(maxPrice, orderbook.Longs.Entries[longPtr].GetPrice()) orderbook.Longs.AddDirtyEntry(orderbook.Longs.Entries[longPtr]) orderbook.Shorts.AddDirtyEntry(orderbook.Shorts.Entries[shortPtr]) @@ -48,6 +53,8 @@ func MatchLimitOrders( TotalNotional: totalPrice, TotalQuantity: totalExecuted, Settlements: settlements, + MinPrice: minPrice, + MaxPrice: maxPrice, } } diff --git a/x/dex/exchange/limit_order_test.go b/x/dex/exchange/limit_order_test.go index 91b0c3338b..6e5265f434 100644 --- a/x/dex/exchange/limit_order_test.go +++ b/x/dex/exchange/limit_order_test.go @@ -1179,8 +1179,12 @@ func TestMatchMultipleOrderFromMultipleLongBook(t *testing.T) { totalPrice := outcome.TotalNotional totalExecuted := outcome.TotalQuantity settlements := outcome.Settlements + minPrice := outcome.MinPrice + maxPrice := outcome.MaxPrice assert.Equal(t, totalPrice, sdk.NewDec(1216)) assert.Equal(t, totalExecuted, sdk.NewDec(12)) + assert.Equal(t, minPrice, sdk.NewDec(100)) + assert.Equal(t, maxPrice, sdk.NewDec(110)) assert.Equal(t, orderbook.Longs.DirtyEntries.Len(), 2) assert.Equal(t, orderbook.Shorts.DirtyEntries.Len(), 3) _, ok := orderbook.Longs.DirtyEntries.Load(sdk.MustNewDecFromStr("100").String()) diff --git a/x/dex/exchange/market_order.go b/x/dex/exchange/market_order.go index 2c99880ba5..019d9317dd 100644 --- a/x/dex/exchange/market_order.go +++ b/x/dex/exchange/market_order.go @@ -1,6 +1,8 @@ package exchange import ( + "math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/x/dex/types" ) @@ -12,19 +14,20 @@ func MatchMarketOrders( direction types.PositionDirection, ) ExecutionOutcome { totalExecuted, totalPrice := sdk.ZeroDec(), sdk.ZeroDec() + minPrice, maxPrice := sdk.NewDecFromInt(sdk.NewIntFromUint64(math.MaxInt64)), sdk.OneDec().Neg() settlements := []*types.SettlementEntry{} allTakerSettlements := []*types.SettlementEntry{} for _, marketOrder := range marketOrders { switch marketOrder.OrderType { case types.OrderType_FOKMARKETBYVALUE: settlements, allTakerSettlements = MatchByValueFOKMarketOrder( - ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, settlements, allTakerSettlements) + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements) case types.OrderType_FOKMARKET: settlements, allTakerSettlements = MatchFOKMarketOrder( - ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, settlements, allTakerSettlements) + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements) default: settlements, allTakerSettlements = MatchMarketOrder( - ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, settlements, allTakerSettlements) + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements) } } @@ -33,12 +36,15 @@ func MatchMarketOrders( for _, settlement := range allTakerSettlements { settlement.ExecutionCostOrProceed = clearingPrice } + minPrice, maxPrice = clearingPrice, clearingPrice settlements = append(settlements, allTakerSettlements...) } return ExecutionOutcome{ TotalNotional: totalPrice, TotalQuantity: totalExecuted, Settlements: settlements, + MinPrice: minPrice, + MaxPrice: maxPrice, } } @@ -49,6 +55,8 @@ func MatchMarketOrder( direction types.PositionDirection, totalExecuted *sdk.Dec, totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, settlements []*types.SettlementEntry, allTakerSettlements []*types.SettlementEntry, ) ([]*types.SettlementEntry, []*types.SettlementEntry) { @@ -84,6 +92,8 @@ func MatchMarketOrder( *totalPrice = totalPrice.Add( executed.Mul(existingOrder.GetPrice()), ) + *minPrice = sdk.MinDec(*minPrice, existingOrder.GetPrice()) + *maxPrice = sdk.MaxDec(*maxPrice, existingOrder.GetPrice()) orderBookEntries.AddDirtyEntry(existingOrder) takerSettlements, makerSettlements := Settle( @@ -111,6 +121,8 @@ func MatchFOKMarketOrder( direction types.PositionDirection, totalExecuted *sdk.Dec, totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, settlements []*types.SettlementEntry, allTakerSettlements []*types.SettlementEntry, ) ([]*types.SettlementEntry, []*types.SettlementEntry) { @@ -159,6 +171,8 @@ func MatchFOKMarketOrder( *totalPrice = totalPrice.Add( executed.Mul(existingOrder.GetPrice()), ) + *minPrice = sdk.MinDec(*minPrice, existingOrder.GetPrice()) + *maxPrice = sdk.MaxDec(*maxPrice, existingOrder.GetPrice()) orderBookEntries.AddDirtyEntry(existingOrder) takerSettlements, makerSettlements := Settle( @@ -183,6 +197,8 @@ func MatchByValueFOKMarketOrder( direction types.PositionDirection, totalExecuted *sdk.Dec, totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, settlements []*types.SettlementEntry, allTakerSettlements []*types.SettlementEntry, ) ([]*types.SettlementEntry, []*types.SettlementEntry) { @@ -237,6 +253,8 @@ func MatchByValueFOKMarketOrder( *totalPrice = totalPrice.Add( executed.Mul(existingOrder.GetPrice()), ) + *minPrice = sdk.MinDec(*minPrice, existingOrder.GetPrice()) + *maxPrice = sdk.MaxDec(*maxPrice, existingOrder.GetPrice()) orderBookEntries.AddDirtyEntry(existingOrder) takerSettlements, makerSettlements := Settle( diff --git a/x/dex/exchange/market_order_test.go b/x/dex/exchange/market_order_test.go index 9ee3659c06..36aa5cc780 100644 --- a/x/dex/exchange/market_order_test.go +++ b/x/dex/exchange/market_order_test.go @@ -1021,8 +1021,12 @@ func TestMatchMultipleMarketOrderFromMultipleLongBook(t *testing.T) { totalPrice := outcome.TotalNotional totalExecuted := outcome.TotalQuantity settlements := outcome.Settlements + minPrice := outcome.MinPrice + maxPrice := outcome.MaxPrice assert.Equal(t, totalPrice, sdk.NewDec(620)) assert.Equal(t, totalExecuted, sdk.NewDec(6)) + assert.Equal(t, minPrice, sdk.MustNewDecFromStr("103.333333333333333333")) + assert.Equal(t, maxPrice, sdk.MustNewDecFromStr("103.333333333333333333")) assert.Equal(t, entries.DirtyEntries.Len(), 2) _, ok := entries.DirtyEntries.Load(sdk.MustNewDecFromStr("100").String()) assert.True(t, ok) diff --git a/x/dex/genesis.go b/x/dex/genesis.go index bc8df3c225..f993907d17 100644 --- a/x/dex/genesis.go +++ b/x/dex/genesis.go @@ -19,6 +19,11 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) k.SetShortBook(ctx, "genesis", elem) } + for _, elem := range genState.TriggeredOrdersList { + // not sure if it's guaranteed that the Order has the correct Price/Asset/Contract details... + k.SetTriggeredOrder(ctx, "genesis", elem, elem.PriceDenom, elem.AssetDenom) + } + // Set initial tick size for each pair // tick size is the minimum unit that can be traded for certain pair for _, elem := range genState.TickSizeList { diff --git a/x/dex/keeper/msgserver/msg_server_place_orders.go b/x/dex/keeper/msgserver/msg_server_place_orders.go index e5aa326e47..eeb9567599 100644 --- a/x/dex/keeper/msgserver/msg_server_place_orders.go +++ b/x/dex/keeper/msgserver/msg_server_place_orders.go @@ -99,5 +99,9 @@ func (k msgServer) validateOrder(order *types.Order) error { if order.OrderType == types.OrderType_FOKMARKETBYVALUE && (order.Nominal.IsNil() || order.Nominal.IsNegative()) { return fmt.Errorf("invalid nominal value for market by value order: %s", order.Nominal) } + if (order.OrderType == types.OrderType_STOPLIMIT || order.OrderType == types.OrderType_STOPLOSS) && + (order.TriggerPrice.IsNil() || order.TriggerPrice.IsNegative()) { + return fmt.Errorf("invalid trigger price for stop loss/limit order: %s", order.TriggerPrice) + } return nil } diff --git a/x/dex/keeper/msgserver/msg_server_place_orders_test.go b/x/dex/keeper/msgserver/msg_server_place_orders_test.go index 03fc026f86..bc2bf6f069 100644 --- a/x/dex/keeper/msgserver/msg_server_place_orders_test.go +++ b/x/dex/keeper/msgserver/msg_server_place_orders_test.go @@ -38,6 +38,17 @@ func TestPlaceOrder(t *testing.T) { PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom, }, + { + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("10"), + TriggerStatus: false, + }, }, } keeper, ctx := keepertest.DexKeeper(t) @@ -47,9 +58,10 @@ func TestPlaceOrder(t *testing.T) { server := msgserver.NewMsgServerImpl(*keeper) res, err := server.PlaceOrders(wctx, msg) require.Nil(t, err) - require.Equal(t, 2, len(res.OrderIds)) + require.Equal(t, 3, len(res.OrderIds)) require.Equal(t, uint64(0), res.OrderIds[0]) require.Equal(t, uint64(1), res.OrderIds[1]) + require.Equal(t, uint64(2), res.OrderIds[2]) // Ensure that contract addr and account is set in the order require.Equal(t, msg.Orders[0].ContractAddr, TestContract) require.Equal(t, msg.Orders[0].Account, TestCreator) diff --git a/x/dex/keeper/query/grpc_query_order.go b/x/dex/keeper/query/grpc_query_order.go index 6c1904857b..8b2fcb1b03 100644 --- a/x/dex/keeper/query/grpc_query_order.go +++ b/x/dex/keeper/query/grpc_query_order.go @@ -52,6 +52,16 @@ func (k KeeperWrapper) GetOrder(c context.Context, req *types.QueryGetOrderByIDR } } } + + triggeredOrders := k.GetAllTriggeredOrders(ctx, req.ContractAddr) + for i, order := range triggeredOrders { + if order.Id == req.Id { + return &types.QueryGetOrderByIDResponse{ + Order: &triggeredOrders[i], + }, nil + } + } + return &types.QueryGetOrderByIDResponse{}, types.ErrInvalidOrderID } @@ -97,6 +107,10 @@ func (k KeeperWrapper) GetOrders(c context.Context, req *types.QueryGetOrdersReq } } } + triggeredOrders := k.GetAllTriggeredOrders(ctx, req.ContractAddr) + for i := range triggeredOrders { + orders = append(orders, &triggeredOrders[i]) + } return &types.QueryGetOrdersResponse{Orders: orders}, nil } diff --git a/x/dex/keeper/query/grpc_query_order_test.go b/x/dex/keeper/query/grpc_query_order_test.go index f807a7e35f..9bce6cf984 100644 --- a/x/dex/keeper/query/grpc_query_order_test.go +++ b/x/dex/keeper/query/grpc_query_order_test.go @@ -64,11 +64,69 @@ func TestGetOrders(t *testing.T) { }, }, }) + + triggeredOrder := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, triggeredOrder, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + query := types.QueryGetOrdersRequest{ ContractAddr: keepertest.TestContract, Account: keepertest.TestAccount, } resp, err := wrapper.GetOrders(wctx, &query) require.Nil(t, err) - require.Equal(t, 1, len(resp.Orders)) + require.Equal(t, 2, len(resp.Orders)) +} + +func TestGetOrderByIdTriggeredOrder(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := query.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + // active order + keeper.SetLongBook(ctx, keepertest.TestContract, types.LongBook{ + Price: sdk.OneDec(), + Entry: &types.OrderEntry{ + Price: sdk.OneDec(), + Quantity: sdk.MustNewDecFromStr("2"), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Allocations: []*types.Allocation{ + { + Account: keepertest.TestAccount, + OrderId: 1, + Quantity: sdk.MustNewDecFromStr("2"), + }, + }, + }, + }) + + triggeredOrder := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, triggeredOrder, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + + query := types.QueryGetOrderByIDRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Id: 2, + } + resp, err := wrapper.GetOrder(wctx, &query) + require.Nil(t, err) + require.Equal(t, uint64(2), resp.Order.Id) + require.Equal(t, types.OrderStatus_PLACED, resp.Order.Status) + require.Equal(t, types.OrderType_STOPLOSS, resp.Order.OrderType) } diff --git a/x/dex/keeper/trigger_book.go b/x/dex/keeper/trigger_book.go new file mode 100644 index 0000000000..f54b81adfc --- /dev/null +++ b/x/dex/keeper/trigger_book.go @@ -0,0 +1,68 @@ +package keeper + +import ( + "encoding/binary" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k Keeper) SetTriggeredOrder(ctx sdk.Context, contractAddr string, order types.Order, priceDenom string, assetDenom string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + + b := k.Cdc.MustMarshal(&order) + store.Set(GetKeyForOrderID(order.Id), b) +} + +func (k Keeper) RemoveTriggeredOrder(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + store.Delete(GetKeyForOrderID(orderID)) +} + +func (k Keeper) GetTriggeredOrderByID(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) (val types.Order, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + b := store.Get(GetKeyForOrderID(orderID)) + if b == nil { + return val, false + } + k.Cdc.MustUnmarshal(b, &val) + return val, true +} + +func (k Keeper) GetAllTriggeredOrdersForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) (list []types.Order) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Order + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + +func (k Keeper) GetAllTriggeredOrders(ctx sdk.Context, contractAddr string) (list []types.Order) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ContractKeyPrefix(types.TriggerBookKey, contractAddr)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Order + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + +func GetKeyForOrderID(orderID uint64) []byte { + key := make([]byte, 8) + binary.LittleEndian.PutUint64(key, orderID) + + return key +} diff --git a/x/dex/keeper/trigger_book_test.go b/x/dex/keeper/trigger_book_test.go new file mode 100644 index 0000000000..0e360ce50c --- /dev/null +++ b/x/dex/keeper/trigger_book_test.go @@ -0,0 +1,170 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/testutil/nullify" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestTriggeredOrderGetByID(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + order := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, order, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + + got, found := keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&order), nullify.Fill(&got)) + + got, found = keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 2, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, !found) + require.Equal(t, types.Order{}, got) +} + +func TestTriggeredOrderGetAllPair(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + o1 := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o2 := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o3 := types.Order{ + Id: 3, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o2, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o3, "FOO", "BAR") + + orders := keeper.GetAllTriggeredOrdersForPair(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.Equal(t, len(orders), 2) + orders = keeper.GetAllTriggeredOrdersForPair(ctx, keepertest.TestContract, "FOO", "BAR") + require.Equal(t, len(orders), 1) +} + +func TestTriggeredOrderGetAll(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + o1 := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o2 := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o3 := types.Order{ + Id: 3, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o2, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o3, "FOO", "BAR") + + orders := keeper.GetAllTriggeredOrders(ctx, keepertest.TestContract) + require.Equal(t, len(orders), 3) +} + +func TestTriggeredOrderSetOverwrite(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + order := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + overwriteOrder := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLIMIT, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, order, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + got, found := keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&order), nullify.Fill(&got)) + + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, overwriteOrder, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + got, found = keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&overwriteOrder), nullify.Fill(&got)) +} + +func TestTriggeredOrderRemove(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + order := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, order, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + got, found := keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&order), nullify.Fill(&got)) + + keeper.RemoveTriggeredOrder(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + + got, found = keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, !found) + require.Equal(t, types.Order{}, got) +} diff --git a/x/dex/types/enums.pb.go b/x/dex/types/enums.pb.go index 0505e07a64..1690031dec 100644 --- a/x/dex/types/enums.pb.go +++ b/x/dex/types/enums.pb.go @@ -78,6 +78,8 @@ const ( OrderType_LIQUIDATION OrderType = 2 OrderType_FOKMARKET OrderType = 3 OrderType_FOKMARKETBYVALUE OrderType = 4 + OrderType_STOPLOSS OrderType = 5 + OrderType_STOPLIMIT OrderType = 6 ) var OrderType_name = map[int32]string{ @@ -86,6 +88,8 @@ var OrderType_name = map[int32]string{ 2: "LIQUIDATION", 3: "FOKMARKET", 4: "FOKMARKETBYVALUE", + 5: "STOPLOSS", + 6: "STOPLIMIT", } var OrderType_value = map[string]int32{ @@ -94,6 +98,8 @@ var OrderType_value = map[string]int32{ "LIQUIDATION": 2, "FOKMARKET": 3, "FOKMARKETBYVALUE": 4, + "STOPLOSS": 5, + "STOPLIMIT": 6, } func (x OrderType) String() string { @@ -203,30 +209,31 @@ func init() { func init() { proto.RegisterFile("dex/enums.proto", fileDescriptor_b8c5bb23c6eb0b88) } var fileDescriptor_b8c5bb23c6eb0b88 = []byte{ - // 391 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x91, 0xcd, 0x8e, 0xd3, 0x30, - 0x14, 0x85, 0xe3, 0x69, 0x19, 0x4d, 0xef, 0xc0, 0xd4, 0x18, 0x90, 0x58, 0x65, 0x87, 0x84, 0x22, - 0x4d, 0x22, 0x04, 0x2f, 0xe0, 0x49, 0xdc, 0xc1, 0x1a, 0x37, 0x2e, 0xf9, 0x41, 0xc0, 0x66, 0x94, - 0x49, 0x5d, 0x6a, 0xa9, 0x4d, 0xaa, 0xc4, 0x95, 0xda, 0xb7, 0xe0, 0xb1, 0x58, 0x76, 0xc9, 0x12, - 0xb5, 0x2f, 0x82, 0x9c, 0xb6, 0xec, 0xce, 0xb9, 0xf7, 0x44, 0xf7, 0x8b, 0x0f, 0x0c, 0xa7, 0x6a, - 0x13, 0xa8, 0x6a, 0xbd, 0x6c, 0xfd, 0x55, 0x53, 0x9b, 0x9a, 0xbc, 0x6d, 0x95, 0xee, 0x54, 0x59, - 0x2f, 0xfc, 0x56, 0xe9, 0x72, 0x5e, 0xe8, 0xca, 0x9f, 0xaa, 0x8d, 0xf7, 0x1e, 0x5e, 0x4e, 0xea, - 0x56, 0x1b, 0x5d, 0x57, 0x91, 0x6e, 0x54, 0x69, 0x05, 0xb9, 0x82, 0xbe, 0x90, 0xf1, 0x3d, 0x76, - 0xc8, 0x00, 0x9e, 0xa5, 0x9f, 0x65, 0x92, 0x61, 0xe4, 0xbd, 0x83, 0x9b, 0x73, 0x92, 0xcd, 0x66, - 0xaa, 0x34, 0x36, 0x26, 0x27, 0x2c, 0x3e, 0xc6, 0x42, 0x21, 0x53, 0x86, 0x91, 0xf7, 0x0d, 0x06, - 0xb2, 0x99, 0xaa, 0x26, 0xdb, 0xae, 0x94, 0x9d, 0x0b, 0x3e, 0xe6, 0x19, 0x76, 0x08, 0xc0, 0xe5, - 0x98, 0x26, 0x0f, 0x2c, 0xc3, 0x88, 0x0c, 0xe1, 0x5a, 0xf0, 0x2f, 0x39, 0x8f, 0x68, 0xc6, 0x65, - 0x8c, 0x2f, 0xc8, 0x0b, 0x18, 0x8c, 0xe4, 0xc3, 0x69, 0xdf, 0x23, 0xaf, 0x01, 0xff, 0xb7, 0x77, - 0xdf, 0xbf, 0x52, 0x91, 0x33, 0xdc, 0xf7, 0x3e, 0x41, 0x3f, 0xaf, 0xb4, 0x21, 0xcf, 0xe1, 0x2a, - 0xcd, 0x68, 0x1c, 0xd1, 0x24, 0x3a, 0x9e, 0x1e, 0x73, 0x21, 0x38, 0x46, 0x47, 0x19, 0x26, 0x12, - 0x5f, 0x58, 0xb4, 0x98, 0xc6, 0x12, 0xf7, 0x3c, 0x01, 0xd7, 0x1d, 0x4f, 0x6a, 0x0a, 0xb3, 0x6e, - 0x2d, 0xc6, 0x44, 0xd0, 0x90, 0xd9, 0x4f, 0x5f, 0xc1, 0x70, 0x44, 0xb9, 0x60, 0xd1, 0x63, 0x26, - 0x1f, 0xbb, 0x29, 0x46, 0x16, 0x25, 0xa4, 0x71, 0xc8, 0x84, 0x60, 0xd1, 0x89, 0x2c, 0x17, 0x23, - 0xde, 0xd9, 0x9e, 0xf7, 0x01, 0xde, 0x84, 0x45, 0x55, 0xaa, 0xc5, 0xa2, 0xb0, 0x0f, 0xc1, 0x2b, - 0x6d, 0x74, 0x61, 0xea, 0xc6, 0x1e, 0xcc, 0x53, 0x96, 0x60, 0x87, 0xdc, 0x00, 0x9c, 0x7f, 0x8e, - 0x45, 0x18, 0xdd, 0xdd, 0xff, 0xde, 0xbb, 0x68, 0xb7, 0x77, 0xd1, 0xdf, 0xbd, 0x8b, 0x7e, 0x1d, - 0x5c, 0x67, 0x77, 0x70, 0x9d, 0x3f, 0x07, 0xd7, 0xf9, 0x71, 0xfb, 0x53, 0x9b, 0xf9, 0xfa, 0xc9, - 0x2f, 0xeb, 0x65, 0xd0, 0x2a, 0x7d, 0x7b, 0x6e, 0xa8, 0x33, 0x5d, 0x45, 0xc1, 0x26, 0xb0, 0x55, - 0x9a, 0xed, 0x4a, 0xb5, 0x4f, 0x97, 0xdd, 0xfe, 0xe3, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, - 0x0a, 0x70, 0x34, 0xde, 0x01, 0x00, 0x00, + // 404 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x51, 0x5d, 0x6f, 0xd3, 0x30, + 0x14, 0x8d, 0xd7, 0xae, 0x5a, 0xef, 0x60, 0x35, 0x06, 0x24, 0x9e, 0xf2, 0x86, 0x84, 0x22, 0xad, + 0x15, 0x82, 0x3f, 0xe0, 0x25, 0xee, 0xb0, 0xe6, 0xc6, 0x25, 0x1f, 0x48, 0xf0, 0x32, 0x65, 0xa9, + 0xc7, 0x2c, 0x75, 0x49, 0x95, 0x38, 0x52, 0xf7, 0x2f, 0xf8, 0x59, 0x3c, 0xee, 0x91, 0x47, 0xd4, + 0xfe, 0x11, 0x64, 0xa7, 0xe5, 0xed, 0x9c, 0x7b, 0xcf, 0xf5, 0x3d, 0xbe, 0x07, 0x26, 0x2b, 0xb5, + 0x9d, 0xa9, 0xaa, 0x7b, 0x6c, 0xa7, 0x9b, 0xa6, 0x36, 0x35, 0x79, 0xd7, 0x2a, 0xed, 0x50, 0x59, + 0xaf, 0xa7, 0xad, 0xd2, 0xe5, 0x43, 0xa1, 0xab, 0xe9, 0x4a, 0x6d, 0x83, 0x0f, 0xf0, 0x6a, 0x59, + 0xb7, 0xda, 0xe8, 0xba, 0x8a, 0x74, 0xa3, 0x4a, 0x0b, 0xc8, 0x19, 0x0c, 0x85, 0x8c, 0xaf, 0xb1, + 0x47, 0xc6, 0x70, 0x9a, 0x7e, 0x91, 0x49, 0x86, 0x51, 0xf0, 0x1e, 0x2e, 0x8e, 0x4a, 0x76, 0x7f, + 0xaf, 0x4a, 0x63, 0x65, 0x72, 0xc9, 0xe2, 0x5e, 0x16, 0x0a, 0x99, 0x32, 0x8c, 0x82, 0x0e, 0xc6, + 0xb2, 0x59, 0xa9, 0x26, 0x7b, 0xda, 0x28, 0x5b, 0x17, 0x7c, 0xc1, 0x33, 0xec, 0x11, 0x80, 0xd1, + 0x82, 0x26, 0x37, 0x2c, 0xc3, 0x88, 0x4c, 0xe0, 0x5c, 0xf0, 0xaf, 0x39, 0x8f, 0x68, 0xc6, 0x65, + 0x8c, 0x4f, 0xc8, 0x4b, 0x18, 0xcf, 0xe5, 0xcd, 0xa1, 0x3f, 0x20, 0x6f, 0x00, 0xff, 0xa7, 0x57, + 0xdf, 0xbf, 0x51, 0x91, 0x33, 0x3c, 0x24, 0x2f, 0xe0, 0x2c, 0xcd, 0xe4, 0x52, 0xc8, 0x34, 0xc5, + 0xa7, 0x76, 0xc4, 0x31, 0xf7, 0xfc, 0x28, 0xf8, 0x0c, 0xc3, 0xbc, 0xd2, 0xa6, 0x17, 0xd1, 0x38, + 0xa2, 0x49, 0xd4, 0xfb, 0x5a, 0x70, 0x21, 0x38, 0x46, 0x3d, 0x0c, 0x13, 0x89, 0x4f, 0xac, 0xef, + 0x98, 0xc6, 0x12, 0x0f, 0x02, 0x01, 0xe7, 0xce, 0x6c, 0x6a, 0x0a, 0xd3, 0xb5, 0xd6, 0xe3, 0x52, + 0xd0, 0x90, 0xd9, 0xd1, 0xd7, 0x30, 0x99, 0x53, 0x2e, 0x58, 0x74, 0x9b, 0xc9, 0x5b, 0x57, 0xc5, + 0xc8, 0x2e, 0x0d, 0x69, 0x1c, 0x32, 0x21, 0x58, 0x74, 0xb0, 0x9d, 0x8b, 0x39, 0x77, 0x74, 0x10, + 0x7c, 0x84, 0xb7, 0x61, 0x51, 0x95, 0x6a, 0xbd, 0x2e, 0xec, 0x95, 0x78, 0xa5, 0x8d, 0x2e, 0x4c, + 0xdd, 0xd8, 0x85, 0x79, 0xca, 0x12, 0xec, 0x91, 0x0b, 0x80, 0xe3, 0xcf, 0x59, 0x84, 0xd1, 0xd5, + 0xf5, 0xef, 0x9d, 0x8f, 0x9e, 0x77, 0x3e, 0xfa, 0xbb, 0xf3, 0xd1, 0xaf, 0xbd, 0xef, 0x3d, 0xef, + 0x7d, 0xef, 0xcf, 0xde, 0xf7, 0x7e, 0x5c, 0xfe, 0xd4, 0xe6, 0xa1, 0xbb, 0x9b, 0x96, 0xf5, 0xe3, + 0xac, 0x55, 0xfa, 0xf2, 0x18, 0x9f, 0x23, 0x2e, 0xbf, 0xd9, 0x76, 0x66, 0x73, 0x36, 0x4f, 0x1b, + 0xd5, 0xde, 0x8d, 0x5c, 0xff, 0xd3, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0xc8, 0xd2, 0x69, + 0xfb, 0x01, 0x00, 0x00, } diff --git a/x/dex/types/genesis.pb.go b/x/dex/types/genesis.pb.go index e192bb861e..140f71f87e 100644 --- a/x/dex/types/genesis.pb.go +++ b/x/dex/types/genesis.pb.go @@ -25,12 +25,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the dex module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - LongBookList []LongBook `protobuf:"bytes,2,rep,name=longBookList,proto3" json:"longBookList"` - ShortBookList []ShortBook `protobuf:"bytes,3,rep,name=shortBookList,proto3" json:"shortBookList"` - TwapList []*Twap `protobuf:"bytes,4,rep,name=twapList,proto3" json:"twapList,omitempty"` - TickSizeList []*TickSize `protobuf:"bytes,5,rep,name=tickSizeList,proto3" json:"tickSizeList,omitempty"` - LastEpoch uint64 `protobuf:"varint,6,opt,name=lastEpoch,proto3" json:"lastEpoch,omitempty"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + LongBookList []LongBook `protobuf:"bytes,2,rep,name=longBookList,proto3" json:"longBookList"` + ShortBookList []ShortBook `protobuf:"bytes,3,rep,name=shortBookList,proto3" json:"shortBookList"` + TwapList []*Twap `protobuf:"bytes,4,rep,name=twapList,proto3" json:"twapList,omitempty"` + TickSizeList []*TickSize `protobuf:"bytes,5,rep,name=tickSizeList,proto3" json:"tickSizeList,omitempty"` + LastEpoch uint64 `protobuf:"varint,6,opt,name=lastEpoch,proto3" json:"lastEpoch,omitempty"` + TriggeredOrdersList []Order `protobuf:"bytes,7,rep,name=triggeredOrdersList,proto3" json:"triggeredOrdersList"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -108,6 +109,13 @@ func (m *GenesisState) GetLastEpoch() uint64 { return 0 } +func (m *GenesisState) GetTriggeredOrdersList() []Order { + if m != nil { + return m.TriggeredOrdersList + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "seiprotocol.seichain.dex.GenesisState") } @@ -115,30 +123,32 @@ func init() { func init() { proto.RegisterFile("dex/genesis.proto", fileDescriptor_a803aaabd08db59d) } var fileDescriptor_a803aaabd08db59d = []byte{ - // 354 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0x3f, 0x4f, 0xc2, 0x40, - 0x18, 0xc6, 0x5b, 0x41, 0xa2, 0x07, 0x1a, 0x3d, 0x19, 0x1a, 0x62, 0xce, 0x06, 0x17, 0x16, 0xda, - 0x04, 0x37, 0x07, 0x07, 0x12, 0x65, 0x21, 0xd1, 0x14, 0x26, 0x17, 0x72, 0x94, 0x4b, 0x7b, 0xe1, - 0xcf, 0xdb, 0x70, 0x67, 0x40, 0xbe, 0x84, 0x7e, 0x2c, 0x46, 0x46, 0x27, 0x63, 0xe0, 0x8b, 0x98, - 0xbb, 0x1e, 0x08, 0x43, 0xe3, 0x76, 0x7d, 0xde, 0xe7, 0xf9, 0xbd, 0x7f, 0x8a, 0x2e, 0x07, 0x6c, - 0xee, 0x47, 0x6c, 0xc2, 0x04, 0x17, 0x5e, 0x32, 0x05, 0x09, 0xd8, 0x11, 0x8c, 0xeb, 0x57, 0x08, - 0x23, 0x4f, 0x30, 0x1e, 0xc6, 0x94, 0x4f, 0xbc, 0x01, 0x9b, 0x57, 0xca, 0x11, 0x44, 0xa0, 0x4b, - 0xbe, 0x7a, 0xa5, 0xfe, 0xca, 0x85, 0x42, 0x24, 0x74, 0x4a, 0xc7, 0x86, 0x50, 0xb9, 0x52, 0xca, - 0x08, 0x26, 0x51, 0xaf, 0x0f, 0x30, 0x34, 0x62, 0x59, 0x89, 0x22, 0x86, 0xa9, 0xdc, 0x57, 0xcf, - 0x95, 0x2a, 0x67, 0x34, 0xd9, 0x8f, 0x4a, 0x1e, 0x0e, 0x7b, 0x82, 0x2f, 0x58, 0x2a, 0x56, 0x3f, - 0x72, 0xa8, 0xd4, 0x4a, 0x67, 0xec, 0x48, 0x2a, 0x19, 0x7e, 0x40, 0x85, 0xb4, 0xa1, 0x63, 0xbb, - 0x76, 0xad, 0xd8, 0x70, 0xbd, 0xac, 0x99, 0xbd, 0x17, 0xed, 0x6b, 0xe6, 0x97, 0xdf, 0x37, 0x56, - 0x60, 0x52, 0xb8, 0x8d, 0x4a, 0x6a, 0xbc, 0x26, 0xc0, 0xb0, 0xcd, 0x85, 0x74, 0x8e, 0xdc, 0x5c, - 0xad, 0xd8, 0xa8, 0x66, 0x53, 0xda, 0xc6, 0x6d, 0x38, 0x07, 0x69, 0xfc, 0x8c, 0xce, 0xf4, 0x5e, - 0x3b, 0x5c, 0x4e, 0xe3, 0x6e, 0xb3, 0x71, 0x9d, 0xad, 0xdd, 0xf0, 0x0e, 0xf3, 0xf8, 0x1e, 0x9d, - 0xa8, 0x93, 0x68, 0x56, 0x5e, 0xb3, 0x48, 0x36, 0xab, 0x3b, 0xa3, 0x49, 0xb0, 0xf3, 0xe3, 0x27, - 0x54, 0x52, 0xe7, 0xeb, 0xf0, 0x05, 0xd3, 0xf9, 0xe3, 0xff, 0x56, 0xeb, 0x1a, 0x77, 0x70, 0x90, - 0xc3, 0xd7, 0xe8, 0x74, 0x44, 0x85, 0x7c, 0x4c, 0x20, 0x8c, 0x9d, 0x82, 0x6b, 0xd7, 0xf2, 0xc1, - 0x9f, 0xd0, 0x6c, 0x2d, 0xd7, 0xc4, 0x5e, 0xad, 0x89, 0xfd, 0xb3, 0x26, 0xf6, 0xe7, 0x86, 0x58, - 0xab, 0x0d, 0xb1, 0xbe, 0x36, 0xc4, 0x7a, 0xad, 0x47, 0x5c, 0xc6, 0x6f, 0x7d, 0x2f, 0x84, 0xb1, - 0x2f, 0x18, 0xaf, 0x6f, 0x9b, 0xea, 0x0f, 0xdd, 0xd5, 0x9f, 0xfb, 0xfa, 0x27, 0xbf, 0x27, 0x4c, - 0xf4, 0x0b, 0xba, 0x7e, 0xf7, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x16, 0xb8, 0xbf, 0x49, 0x88, 0x02, - 0x00, 0x00, + // 395 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcf, 0x6a, 0xea, 0x40, + 0x18, 0xc5, 0x93, 0xab, 0xd7, 0x7b, 0xef, 0xe8, 0xed, 0x9f, 0xd1, 0x45, 0x90, 0x12, 0x83, 0xdd, + 0xb8, 0x31, 0x01, 0xbb, 0xeb, 0xa2, 0x0b, 0xa1, 0x75, 0x23, 0x58, 0xa2, 0x50, 0xe8, 0x46, 0x62, + 0x32, 0x24, 0x83, 0x7f, 0x26, 0x64, 0xa6, 0x68, 0x7d, 0x8a, 0x3e, 0x96, 0x4b, 0x97, 0x5d, 0x95, + 0xa2, 0x9b, 0x3e, 0x46, 0x99, 0x2f, 0xa3, 0x55, 0x68, 0xe8, 0x6e, 0x3c, 0x73, 0xce, 0xef, 0x7c, + 0xdf, 0x18, 0x74, 0x1e, 0x90, 0x85, 0x13, 0x92, 0x19, 0xe1, 0x94, 0xdb, 0x71, 0xc2, 0x04, 0xc3, + 0x06, 0x27, 0x14, 0x4e, 0x3e, 0x9b, 0xd8, 0x9c, 0x50, 0x3f, 0xf2, 0xe8, 0xcc, 0x0e, 0xc8, 0xa2, + 0x5a, 0x09, 0x59, 0xc8, 0xe0, 0xca, 0x91, 0xa7, 0xd4, 0x5f, 0x3d, 0x93, 0x88, 0xd8, 0x4b, 0xbc, + 0xa9, 0x22, 0x54, 0xcb, 0x52, 0x99, 0xb0, 0x59, 0x38, 0x1c, 0x31, 0x36, 0x56, 0x62, 0x45, 0x8a, + 0x3c, 0x62, 0x89, 0x38, 0x54, 0x4f, 0xa4, 0x2a, 0xe6, 0x5e, 0x7c, 0x18, 0x15, 0xd4, 0x1f, 0x0f, + 0x39, 0x5d, 0x12, 0x25, 0x9e, 0x4a, 0x91, 0x25, 0x01, 0x49, 0x52, 0xa1, 0xfe, 0x91, 0x43, 0xa5, + 0x4e, 0x3a, 0x74, 0x5f, 0x78, 0x82, 0xe0, 0x1b, 0x54, 0x48, 0x27, 0x30, 0x74, 0x4b, 0x6f, 0x14, + 0x5b, 0x96, 0x9d, 0xb5, 0x84, 0x7d, 0x0f, 0xbe, 0x76, 0x7e, 0xf5, 0x56, 0xd3, 0x5c, 0x95, 0xc2, + 0x5d, 0x54, 0x92, 0xf3, 0xb6, 0x19, 0x1b, 0x77, 0x29, 0x17, 0xc6, 0x2f, 0x2b, 0xd7, 0x28, 0xb6, + 0xea, 0xd9, 0x94, 0xae, 0x72, 0x2b, 0xce, 0x51, 0x1a, 0xf7, 0xd0, 0x7f, 0x58, 0x74, 0x8f, 0xcb, + 0x01, 0xee, 0x32, 0x1b, 0xd7, 0xdf, 0xd9, 0x15, 0xef, 0x38, 0x8f, 0xaf, 0xd1, 0x5f, 0xf9, 0x46, + 0xc0, 0xca, 0x03, 0xcb, 0xcc, 0x66, 0x0d, 0xe6, 0x5e, 0xec, 0xee, 0xfd, 0xf8, 0x0e, 0x95, 0xe4, + 0x7b, 0xf6, 0xe9, 0x92, 0x40, 0xfe, 0xf7, 0x4f, 0xab, 0x0d, 0x94, 0xdb, 0x3d, 0xca, 0xe1, 0x0b, + 0xf4, 0x6f, 0xe2, 0x71, 0x71, 0x1b, 0x33, 0x3f, 0x32, 0x0a, 0x96, 0xde, 0xc8, 0xbb, 0x5f, 0x02, + 0x7e, 0x40, 0x65, 0x91, 0xd0, 0x30, 0x24, 0x09, 0x09, 0x7a, 0xf2, 0x9f, 0xe2, 0x50, 0xf6, 0x07, + 0xca, 0x6a, 0xd9, 0x65, 0xe0, 0x55, 0x4b, 0x7f, 0x47, 0x68, 0x77, 0x56, 0x1b, 0x53, 0x5f, 0x6f, + 0x4c, 0xfd, 0x7d, 0x63, 0xea, 0x2f, 0x5b, 0x53, 0x5b, 0x6f, 0x4d, 0xed, 0x75, 0x6b, 0x6a, 0x8f, + 0xcd, 0x90, 0x8a, 0xe8, 0x69, 0x64, 0xfb, 0x6c, 0xea, 0x70, 0x42, 0x9b, 0xbb, 0x02, 0xf8, 0x01, + 0x0d, 0xce, 0xc2, 0x81, 0xcf, 0xe9, 0x39, 0x26, 0x7c, 0x54, 0x80, 0xfb, 0xab, 0xcf, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x78, 0x93, 0xaa, 0xbc, 0xf2, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -161,6 +171,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.TriggeredOrdersList) > 0 { + for iNdEx := len(m.TriggeredOrdersList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TriggeredOrdersList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } if m.LastEpoch != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.LastEpoch)) i-- @@ -281,6 +305,12 @@ func (m *GenesisState) Size() (n int) { if m.LastEpoch != 0 { n += 1 + sovGenesis(uint64(m.LastEpoch)) } + if len(m.TriggeredOrdersList) > 0 { + for _, e := range m.TriggeredOrdersList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -507,6 +537,40 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { break } } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TriggeredOrdersList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TriggeredOrdersList = append(m.TriggeredOrdersList, Order{}) + if err := m.TriggeredOrdersList[len(m.TriggeredOrdersList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/dex/types/keys.go b/x/dex/types/keys.go index a8a283c19a..ed1c5b5c00 100644 --- a/x/dex/types/keys.go +++ b/x/dex/types/keys.go @@ -47,6 +47,15 @@ func OrderBookPrefix(long bool, contractAddr string, priceDenom string, assetDen ) } +func TriggerOrderBookPrefix(contractAddr string, priceDenom string, assetDenom string) []byte { + prefix := KeyPrefix(TriggerBookKey) + + return append( + append(prefix, KeyPrefix(contractAddr)...), + PairPrefix(priceDenom, assetDenom)..., + ) +} + func TwapPrefix(contractAddr string) []byte { return append(KeyPrefix(TwapKey), KeyPrefix(contractAddr)...) } @@ -138,6 +147,8 @@ const ( ShortBookKey = "ShortBook-value-" + TriggerBookKey = "TriggerBook-value-" + OrderKey = "order" AccountActiveOrdersKey = "account-active-orders" CancelKey = "cancel" diff --git a/x/dex/types/keys_test.go b/x/dex/types/keys_test.go index a091dade92..94f303ec66 100644 --- a/x/dex/types/keys_test.go +++ b/x/dex/types/keys_test.go @@ -22,3 +22,15 @@ func TestPricePrefix(t *testing.T) { expectedKey := append(priceContractBytes, pairBytes...) require.Equal(t, expectedKey, types.PricePrefix(testContract, testPriceDenom, testAssetDenom)) } + +func TestTriggerOrderBookPrefix(t *testing.T) { + testContract := "test" + testPriceDenom := "SEI" + testAssetDenom := "ATOM" + + triggerBookContractBytes := append([]byte(types.TriggerBookKey), []byte(testContract)...) + pairBytes := types.PairPrefix(testPriceDenom, testAssetDenom) + expectedKey := append(triggerBookContractBytes, pairBytes...) + + require.Equal(t, expectedKey, types.TriggerOrderBookPrefix(testContract, testPriceDenom, testAssetDenom)) +} diff --git a/x/dex/types/order.pb.go b/x/dex/types/order.pb.go index b02a9967fc..69c89707db 100644 --- a/x/dex/types/order.pb.go +++ b/x/dex/types/order.pb.go @@ -38,6 +38,8 @@ type Order struct { Data string `protobuf:"bytes,11,opt,name=data,proto3" json:"data"` StatusDescription string `protobuf:"bytes,12,opt,name=statusDescription,proto3" json:"status_description"` Nominal github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,13,opt,name=nominal,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"nominal" yaml:"nominal"` + TriggerPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,14,opt,name=triggerPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"trigger_price" yaml:"trigger_price"` + TriggerStatus bool `protobuf:"varint,15,opt,name=triggerStatus,proto3" json:"trigger_status"` } func (m *Order) Reset() { *m = Order{} } @@ -143,6 +145,13 @@ func (m *Order) GetStatusDescription() string { return "" } +func (m *Order) GetTriggerStatus() bool { + if m != nil { + return m.TriggerStatus + } + return false +} + type Cancellation struct { Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id"` Initiator CancellationInitiator `protobuf:"varint,2,opt,name=initiator,proto3,enum=seiprotocol.seichain.dex.CancellationInitiator" json:"initiator"` @@ -289,50 +298,54 @@ func init() { func init() { proto.RegisterFile("dex/order.proto", fileDescriptor_c2d5fab85368797d) } var fileDescriptor_c2d5fab85368797d = []byte{ - // 681 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0x13, 0x3d, - 0x14, 0xcd, 0xa4, 0xf9, 0x75, 0xd3, 0xf4, 0xab, 0x55, 0x55, 0xf3, 0x55, 0x28, 0x13, 0x05, 0x81, - 0x52, 0xa1, 0x66, 0x24, 0xd8, 0x20, 0xc4, 0xa6, 0x43, 0xa4, 0x0a, 0xa1, 0x0a, 0x30, 0xac, 0x10, - 0x28, 0x72, 0x6d, 0xab, 0xb5, 0x48, 0xc6, 0xe9, 0xd8, 0x41, 0xcd, 0x5b, 0xb0, 0x64, 0xc3, 0xfb, - 0x74, 0xd9, 0x25, 0x62, 0x61, 0xa1, 0x76, 0x37, 0xcb, 0x3e, 0x01, 0x9a, 0x3b, 0x33, 0x4d, 0xfa, - 0xa7, 0xd2, 0x45, 0x37, 0x99, 0xeb, 0x73, 0xcf, 0x39, 0xd7, 0x63, 0xdf, 0x3b, 0x41, 0xcb, 0x5c, - 0x1c, 0xfa, 0x2a, 0xe2, 0x22, 0xea, 0x8d, 0x23, 0x65, 0x14, 0x76, 0xb5, 0x90, 0x10, 0x31, 0x35, - 0xec, 0x69, 0x21, 0xd9, 0x3e, 0x95, 0x61, 0x8f, 0x8b, 0xc3, 0xf5, 0xd5, 0x3d, 0xb5, 0xa7, 0x20, - 0xe5, 0x27, 0x51, 0xca, 0x5f, 0x07, 0x03, 0x11, 0x4e, 0x46, 0x3a, 0x05, 0x3a, 0x3f, 0xaa, 0xa8, - 0xfc, 0x36, 0x31, 0xc4, 0xeb, 0xa8, 0x28, 0xb9, 0xeb, 0xb4, 0x9d, 0x6e, 0x29, 0x40, 0x47, 0xd6, - 0x73, 0x62, 0xeb, 0x15, 0x25, 0x27, 0x45, 0xc9, 0xf1, 0x0e, 0xaa, 0x68, 0x43, 0xcd, 0x44, 0xbb, - 0xc5, 0xb6, 0xd3, 0x6d, 0x3e, 0x7d, 0xd4, 0xbb, 0xa9, 0x6e, 0x0f, 0xcc, 0x3e, 0x00, 0x39, 0x68, - 0x66, 0x36, 0x99, 0x98, 0x64, 0x4f, 0xbc, 0x81, 0xaa, 0x94, 0x31, 0x35, 0x09, 0x8d, 0xbb, 0xd0, - 0x76, 0xba, 0xf5, 0x60, 0x39, 0x23, 0xe6, 0x30, 0xc9, 0x03, 0xfc, 0x12, 0x35, 0x98, 0x0a, 0x4d, - 0x44, 0x99, 0xd9, 0xe2, 0x3c, 0x72, 0x4b, 0xc0, 0x77, 0x33, 0xfe, 0x7f, 0x79, 0x6e, 0x40, 0x39, - 0x8f, 0x84, 0xd6, 0xe4, 0x02, 0x1b, 0x7f, 0x41, 0xe5, 0x71, 0x24, 0x99, 0x70, 0xcb, 0x20, 0xdb, - 0x3e, 0xb2, 0x5e, 0xe1, 0xb7, 0xf5, 0x1e, 0xef, 0x49, 0xb3, 0x3f, 0xd9, 0xed, 0x31, 0x35, 0xf2, - 0x99, 0xd2, 0x23, 0xa5, 0xb3, 0xc7, 0xa6, 0xe6, 0x5f, 0x7d, 0x33, 0x1d, 0x0b, 0xdd, 0xeb, 0x0b, - 0x16, 0x5b, 0x2f, 0x95, 0x9f, 0x59, 0xaf, 0x31, 0xa5, 0xa3, 0xe1, 0x8b, 0x0e, 0x2c, 0x3b, 0x24, - 0x85, 0xb1, 0x44, 0xb5, 0x83, 0x09, 0x0d, 0x8d, 0x34, 0x53, 0xb7, 0x02, 0x15, 0x76, 0xee, 0x5c, - 0xe1, 0xdc, 0xe1, 0xcc, 0x7a, 0xcb, 0x69, 0x91, 0x1c, 0xe9, 0x90, 0xf3, 0x24, 0xf6, 0x11, 0x82, - 0x9a, 0x7d, 0x11, 0xaa, 0x91, 0x5b, 0x4d, 0x4f, 0x2d, 0xb6, 0xde, 0x22, 0xa0, 0x03, 0x9e, 0xc0, - 0x64, 0x8e, 0x92, 0x08, 0xa8, 0xd6, 0xc2, 0xa4, 0x82, 0xda, 0x4c, 0x00, 0x68, 0x2e, 0x98, 0x51, - 0xf0, 0x7b, 0x54, 0x87, 0xce, 0xfa, 0x38, 0x1d, 0x0b, 0xb7, 0x0e, 0xd7, 0xfc, 0xf0, 0x96, 0x6b, - 0x4e, 0xa8, 0x41, 0x33, 0xb6, 0x1e, 0x02, 0xe5, 0x20, 0x79, 0x2f, 0x32, 0x73, 0xc1, 0x07, 0x68, - 0x65, 0xac, 0xb4, 0x34, 0x52, 0x85, 0x7d, 0x19, 0x09, 0x96, 0x04, 0x2e, 0x02, 0xeb, 0x27, 0x37, - 0x5b, 0xbf, 0xbb, 0x2c, 0x09, 0xd6, 0x62, 0xeb, 0xe1, 0xdc, 0x69, 0xc0, 0x73, 0x9c, 0x5c, 0x75, - 0xc7, 0x0f, 0x50, 0x89, 0x53, 0x43, 0xdd, 0x45, 0x78, 0xe1, 0x5a, 0x6c, 0x3d, 0x58, 0x13, 0xf8, - 0xc5, 0x7d, 0xb4, 0x92, 0xb6, 0x60, 0x5f, 0x68, 0x16, 0xc9, 0x31, 0x6c, 0xa8, 0x01, 0x54, 0xa8, - 0x91, 0x26, 0x07, 0x7c, 0x96, 0x25, 0x57, 0x05, 0x58, 0xa0, 0x6a, 0xa8, 0x46, 0x32, 0xa4, 0x43, - 0x77, 0x09, 0xb4, 0x6f, 0xee, 0x7c, 0xeb, 0xb9, 0xc1, 0x99, 0xf5, 0x9a, 0xe9, 0xa5, 0x67, 0x40, - 0x87, 0xe4, 0xa9, 0xce, 0xcf, 0x12, 0x6a, 0xbc, 0xa2, 0x21, 0x13, 0xc3, 0x21, 0x85, 0xba, 0x6b, - 0x73, 0x13, 0x5a, 0x99, 0x9b, 0xce, 0xcf, 0xa8, 0x2e, 0x43, 0x69, 0x24, 0x35, 0x2a, 0xca, 0x06, - 0xd4, 0xbf, 0xf9, 0x78, 0xe7, 0x2d, 0x5f, 0xe7, 0xb2, 0x60, 0x29, 0xb6, 0xde, 0xcc, 0x85, 0xcc, - 0xc2, 0x64, 0x58, 0x59, 0x24, 0xc0, 0xfb, 0xd2, 0xb0, 0x66, 0x30, 0xc9, 0x03, 0xfc, 0xfc, 0xda, - 0x61, 0x5d, 0xfd, 0x87, 0x41, 0xbd, 0xd8, 0xde, 0xe5, 0xbb, 0xb6, 0x77, 0xe5, 0xf6, 0xf6, 0xbe, - 0xb6, 0x17, 0xab, 0xf7, 0xda, 0x8b, 0xe7, 0x5f, 0x9f, 0xda, 0x7d, 0x7c, 0x7d, 0x3a, 0x1b, 0xa8, - 0xb1, 0xc5, 0x8c, 0xfc, 0x26, 0x60, 0x16, 0x35, 0xfe, 0x1f, 0x2d, 0x48, 0xae, 0x5d, 0xa7, 0xbd, - 0xd0, 0x2d, 0x05, 0xd5, 0xd8, 0x7a, 0xc9, 0x92, 0x24, 0x3f, 0xc1, 0xf6, 0xd1, 0x49, 0xcb, 0x39, - 0x3e, 0x69, 0x39, 0x7f, 0x4e, 0x5a, 0xce, 0xf7, 0xd3, 0x56, 0xe1, 0xf8, 0xb4, 0x55, 0xf8, 0x75, - 0xda, 0x2a, 0x7c, 0xda, 0x9c, 0xdb, 0x8c, 0x16, 0x72, 0x33, 0x3f, 0x06, 0x58, 0xc0, 0x39, 0xf8, - 0x87, 0x7e, 0xf2, 0xa7, 0x01, 0xfb, 0xda, 0xad, 0x40, 0xfe, 0xd9, 0xdf, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x16, 0x0c, 0xff, 0x27, 0x89, 0x06, 0x00, 0x00, + // 737 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6a, 0xdb, 0x4c, + 0x14, 0xb5, 0x1c, 0xff, 0x4e, 0x1c, 0xfb, 0xcb, 0x10, 0x82, 0xbe, 0x50, 0x2c, 0xa3, 0xd2, 0xe2, + 0x50, 0x62, 0x41, 0xbb, 0x09, 0xa5, 0x9b, 0xa8, 0x86, 0x50, 0x4a, 0x68, 0x3a, 0x2d, 0x14, 0x4a, + 0x8b, 0x51, 0x34, 0x83, 0x33, 0xd4, 0xd6, 0x38, 0x9a, 0x71, 0x89, 0xe9, 0x4b, 0xf4, 0x05, 0xfa, + 0x3e, 0xd9, 0x35, 0xcb, 0xd2, 0x85, 0x28, 0xc9, 0x4e, 0xcb, 0x3c, 0x41, 0xd1, 0x95, 0x26, 0xb6, + 0xf3, 0x43, 0xea, 0x45, 0x36, 0xd6, 0x9d, 0x73, 0xcf, 0x39, 0x57, 0x9a, 0x99, 0x7b, 0x8d, 0x1a, + 0x94, 0x1d, 0x3b, 0x22, 0xa4, 0x2c, 0xec, 0x8c, 0x42, 0xa1, 0x04, 0x36, 0x25, 0xe3, 0x10, 0xf9, + 0x62, 0xd0, 0x91, 0x8c, 0xfb, 0x87, 0x1e, 0x0f, 0x3a, 0x94, 0x1d, 0x6f, 0xac, 0xf5, 0x45, 0x5f, + 0x40, 0xca, 0x49, 0xa2, 0x94, 0xbf, 0x01, 0x06, 0x2c, 0x18, 0x0f, 0x65, 0x0a, 0xd8, 0x3f, 0x2b, + 0xa8, 0xf8, 0x26, 0x31, 0xc4, 0x1b, 0x28, 0xcf, 0xa9, 0x69, 0xb4, 0x8c, 0x76, 0xc1, 0x45, 0x27, + 0x91, 0x65, 0xc4, 0x91, 0x95, 0xe7, 0x94, 0xe4, 0x39, 0xc5, 0x7b, 0xa8, 0x24, 0x95, 0xa7, 0xc6, + 0xd2, 0xcc, 0xb7, 0x8c, 0x76, 0xfd, 0xe9, 0xa3, 0xce, 0x6d, 0x75, 0x3b, 0x60, 0xf6, 0x0e, 0xc8, + 0x6e, 0x3d, 0xb3, 0xc9, 0xc4, 0x24, 0x7b, 0xe2, 0x4d, 0x54, 0xf6, 0x7c, 0x5f, 0x8c, 0x03, 0x65, + 0x2e, 0xb5, 0x8c, 0x76, 0xd5, 0x6d, 0x64, 0x44, 0x0d, 0x13, 0x1d, 0xe0, 0x17, 0xa8, 0xe6, 0x8b, + 0x40, 0x85, 0x9e, 0xaf, 0x76, 0x28, 0x0d, 0xcd, 0x02, 0xf0, 0xcd, 0x8c, 0xff, 0x9f, 0xce, 0xf5, + 0x3c, 0x4a, 0x43, 0x26, 0x25, 0x99, 0x63, 0xe3, 0xcf, 0xa8, 0x38, 0x0a, 0xb9, 0xcf, 0xcc, 0x22, + 0xc8, 0x76, 0x4f, 0x22, 0x2b, 0xf7, 0x3b, 0xb2, 0x1e, 0xf7, 0xb9, 0x3a, 0x1c, 0x1f, 0x74, 0x7c, + 0x31, 0x74, 0x7c, 0x21, 0x87, 0x42, 0x66, 0x8f, 0x2d, 0x49, 0xbf, 0x38, 0x6a, 0x32, 0x62, 0xb2, + 0xd3, 0x65, 0x7e, 0x1c, 0x59, 0xa9, 0xfc, 0x22, 0xb2, 0x6a, 0x13, 0x6f, 0x38, 0x78, 0x6e, 0xc3, + 0xd2, 0x26, 0x29, 0x8c, 0x39, 0xaa, 0x1c, 0x8d, 0xbd, 0x40, 0x71, 0x35, 0x31, 0x4b, 0x50, 0x61, + 0x6f, 0xe1, 0x0a, 0x97, 0x0e, 0x17, 0x91, 0xd5, 0x48, 0x8b, 0x68, 0xc4, 0x26, 0x97, 0x49, 0xec, + 0x20, 0x04, 0x35, 0xbb, 0x2c, 0x10, 0x43, 0xb3, 0x9c, 0xee, 0x5a, 0x1c, 0x59, 0xcb, 0x80, 0xf6, + 0x68, 0x02, 0x93, 0x19, 0x4a, 0x22, 0xf0, 0xa4, 0x64, 0x2a, 0x15, 0x54, 0xa6, 0x02, 0x40, 0xb5, + 0x60, 0x4a, 0xc1, 0x6f, 0x51, 0x15, 0x6e, 0xd6, 0xfb, 0xc9, 0x88, 0x99, 0x55, 0x38, 0xe6, 0x87, + 0x77, 0x1c, 0x73, 0x42, 0x75, 0xeb, 0x71, 0x64, 0x21, 0x50, 0xf6, 0x92, 0xef, 0x22, 0x53, 0x17, + 0x7c, 0x84, 0x56, 0x47, 0x42, 0x72, 0xc5, 0x45, 0xd0, 0xe5, 0x21, 0xf3, 0x93, 0xc0, 0x44, 0x60, + 0xfd, 0xe4, 0x76, 0xeb, 0xfd, 0xab, 0x12, 0x77, 0x3d, 0x8e, 0x2c, 0xac, 0x9d, 0x7a, 0x54, 0xe3, + 0xe4, 0xba, 0x3b, 0x7e, 0x80, 0x0a, 0xd4, 0x53, 0x9e, 0xb9, 0x0c, 0x1f, 0x5c, 0x89, 0x23, 0x0b, + 0xd6, 0x04, 0x7e, 0x71, 0x17, 0xad, 0xa6, 0x57, 0xb0, 0xcb, 0xa4, 0x1f, 0xf2, 0x11, 0xbc, 0x50, + 0x0d, 0xa8, 0x50, 0x23, 0x4d, 0xf6, 0xe8, 0x34, 0x4b, 0xae, 0x0b, 0x30, 0x43, 0xe5, 0x40, 0x0c, + 0x79, 0xe0, 0x0d, 0xcc, 0x15, 0xd0, 0xbe, 0x5e, 0xf8, 0xd4, 0xb5, 0xc1, 0x45, 0x64, 0xd5, 0xd3, + 0x43, 0xcf, 0x00, 0x9b, 0xe8, 0x14, 0xfe, 0x86, 0x6a, 0x2a, 0xe4, 0xfd, 0x3e, 0x0b, 0xf7, 0xe1, + 0x0e, 0xd7, 0xa1, 0xd6, 0x87, 0x85, 0x6b, 0xad, 0x64, 0x2e, 0x3d, 0x7d, 0x97, 0xd7, 0xd2, 0x8a, + 0x73, 0xb0, 0x4d, 0xe6, 0x8a, 0xe1, 0x6d, 0xa4, 0x65, 0x69, 0x2f, 0x9b, 0x8d, 0x96, 0xd1, 0xae, + 0xb8, 0x38, 0x8e, 0xac, 0xba, 0x16, 0x66, 0x5d, 0x3d, 0x4f, 0xb4, 0x7f, 0x14, 0x50, 0xed, 0xa5, + 0x17, 0xf8, 0x6c, 0x30, 0xf0, 0x60, 0xbb, 0xd6, 0x67, 0x06, 0x4b, 0x69, 0x66, 0xa8, 0x7c, 0x42, + 0x55, 0x1e, 0x70, 0xc5, 0x3d, 0x25, 0xc2, 0x6c, 0xae, 0x38, 0xb7, 0xdf, 0x8a, 0x59, 0xcb, 0x57, + 0x5a, 0xe6, 0xae, 0xc4, 0x91, 0x35, 0x75, 0x21, 0xd3, 0x30, 0x99, 0x31, 0x7e, 0xc8, 0xc0, 0xfb, + 0xca, 0x8c, 0xc9, 0x60, 0xa2, 0x03, 0xbc, 0x7d, 0xe3, 0x8c, 0x59, 0xfb, 0x87, 0xf9, 0x32, 0xdf, + 0x95, 0xc5, 0x45, 0xbb, 0xb2, 0x74, 0x77, 0x57, 0xde, 0xd8, 0x42, 0xe5, 0x7b, 0x6d, 0xa1, 0xcb, + 0xa1, 0x59, 0xb9, 0x8f, 0xa1, 0x69, 0x6f, 0xa2, 0xda, 0x8e, 0xaf, 0xf8, 0x57, 0x06, 0x23, 0x44, + 0xe2, 0xff, 0xd1, 0x12, 0xa7, 0xd2, 0x34, 0x5a, 0x4b, 0xed, 0x82, 0x5b, 0x8e, 0x23, 0x2b, 0x59, + 0x92, 0xe4, 0xc7, 0xdd, 0x3d, 0x39, 0x6b, 0x1a, 0xa7, 0x67, 0x4d, 0xe3, 0xcf, 0x59, 0xd3, 0xf8, + 0x7e, 0xde, 0xcc, 0x9d, 0x9e, 0x37, 0x73, 0xbf, 0xce, 0x9b, 0xb9, 0x8f, 0x5b, 0x33, 0x2f, 0x23, + 0x19, 0xdf, 0xd2, 0xdb, 0x00, 0x0b, 0xd8, 0x07, 0xe7, 0xd8, 0x49, 0xfe, 0xeb, 0xe0, 0xbd, 0x0e, + 0x4a, 0x90, 0x7f, 0xf6, 0x37, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x4e, 0x8b, 0xbe, 0x40, 0x07, 0x00, + 0x00, } func (m *Order) Marshal() (dAtA []byte, err error) { @@ -355,6 +368,26 @@ func (m *Order) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TriggerStatus { + i-- + if m.TriggerStatus { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x78 + } + { + size := m.TriggerPrice.Size() + i -= size + if _, err := m.TriggerPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrder(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 { size := m.Nominal.Size() i -= size @@ -626,6 +659,11 @@ func (m *Order) Size() (n int) { } l = m.Nominal.Size() n += 1 + l + sovOrder(uint64(l)) + l = m.TriggerPrice.Size() + n += 1 + l + sovOrder(uint64(l)) + if m.TriggerStatus { + n += 2 + } return n } @@ -1086,6 +1124,60 @@ func (m *Order) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TriggerPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOrder + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrder + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TriggerPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TriggerStatus", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TriggerStatus = bool(v != 0) default: iNdEx = preIndex skippy, err := skipOrder(dAtA[iNdEx:]) diff --git a/x/dex/types/utils/alias.go b/x/dex/types/utils/alias.go index 41d2b32360..f99773c504 100644 --- a/x/dex/types/utils/alias.go +++ b/x/dex/types/utils/alias.go @@ -2,6 +2,7 @@ package utils import ( "fmt" + "strings" "github.com/sei-protocol/sei-chain/x/dex/types" ) @@ -16,3 +17,8 @@ func GetPairString(pair *types.Pair) PairString { fmt.Sprintf("%s|%s", pair.PriceDenom, pair.AssetDenom), ) } + +func GetPriceAssetString(pairString PairString) (string, string) { + output := strings.Split(string(pairString), "|") + return output[0], output[1] +} diff --git a/x/dex/types/utils/alias_test.go b/x/dex/types/utils/alias_test.go index f3077f1121..893b571eb9 100644 --- a/x/dex/types/utils/alias_test.go +++ b/x/dex/types/utils/alias_test.go @@ -13,3 +13,9 @@ func TestGetPairString(t *testing.T) { expected := utils.PairString("USDC|ATOM") require.Equal(t, expected, utils.GetPairString(&pair)) } + +func TestGetPriceAssetString(t *testing.T) { + priceDenom, assetDenom := utils.GetPriceAssetString(utils.PairString("USDC|ATOM")) + require.Equal(t, "USDC", priceDenom) + require.Equal(t, "ATOM", assetDenom) +}