From 08fa763d77799f16bd9054b15488a1c0e1f59429 Mon Sep 17 00:00:00 2001 From: Dzmitry Hil Date: Mon, 16 Dec 2024 15:02:34 +0300 Subject: [PATCH 1/2] Improve DEX place-order CLI (#1050) --- x/dex/client/cli/tx.go | 49 +++++++++++++++++-------------------- x/dex/client/cli/tx_test.go | 12 +-------- 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/x/dex/client/cli/tx.go b/x/dex/client/cli/tx.go index 6a2adafea..aa957ee70 100644 --- a/x/dex/client/cli/tx.go +++ b/x/dex/client/cli/tx.go @@ -27,10 +27,6 @@ const ( GoodTilBlockHeightFlag = "good-til-block-height" // GoodTilBlockTimeFlag is good til block time flag. GoodTilBlockTimeFlag = "good-til-block-time" - // OrderTypeLimit is limit order type. - OrderTypeLimit = "limit" - // OrderTypeMarket is limit order market. - OrderTypeMarket = "market" // TimeInForce is time-in-force flag. TimeInForce = "time-in-force" ) @@ -60,16 +56,19 @@ func GetTxCmd() *cobra.Command { func CmdPlaceOrder() *cobra.Command { availableTimeInForces := lo.Values(types.TimeInForce_name) sort.Strings(availableTimeInForces) + availableOrderTypes := lo.Values(types.OrderType_name) + sort.Strings(availableTimeInForces) + availableSides := lo.Values(types.Side_name) + sort.Strings(availableTimeInForces) cmd := &cobra.Command{ - Use: "place-order [type (limit,market)] [id] [base_denom] [quote_denom] [quantity] [side] --price 123e-2 --time-in-force=" + strings.Join(availableTimeInForces, ",") + " --good-til-block-height=123 --good-til-block-time=1727124446 --from [sender]", //nolint:lll // string example + Use: "place-order [type (" + strings.Join(availableOrderTypes, ",") + ")] [id] [base_denom] [quote_denom] [quantity] [side (" + strings.Join(availableSides, ",") + ")] --price 123e-2 --time-in-force=" + strings.Join(availableTimeInForces, ",") + " --good-til-block-height=123 --good-til-block-time=1727124446 --from [sender]", //nolint:lll // string example Args: cobra.ExactArgs(6), Short: "Place new order", Long: strings.TrimSpace( fmt.Sprintf(`Place new order. Example: -$ %s tx %s place-order id1 denom1 denom2 123e-2 10000 buy --from [sender] -`, +$ %s tx %s place-order ORDER_TYPE_LIMIT "my-order-id1" denom1 denom2 1000 SIDE_SELL --price 12e-1 --time-in-force=TIME_IN_FORCE_GTC --from [sender]`, //nolint:lll // string example version.AppName, types.ModuleName, ), ), @@ -81,25 +80,8 @@ $ %s tx %s place-order id1 denom1 denom2 123e-2 10000 buy --from [sender] sender := clientCtx.GetFromAddress() - var orderType types.OrderType - timeInForceString, err := cmd.Flags().GetString(TimeInForce) - timeInForceInt, ok := types.TimeInForce_value[timeInForceString] + orderType, ok := types.OrderType_value[args[0]] if !ok { - return errors.Errorf( - "unknown TimeInForce '%s',available TimeInForces: %s", - timeInForceString, strings.Join(availableTimeInForces, ","), - ) - } - if err != nil { - return errors.WithStack(err) - } - timeInForce := types.TimeInForce(timeInForceInt) - switch args[0] { - case OrderTypeLimit: - orderType = types.ORDER_TYPE_LIMIT - case OrderTypeMarket: - orderType = types.ORDER_TYPE_MARKET - default: return errors.Errorf("unknown type '%s'", args[0]) } @@ -109,7 +91,7 @@ $ %s tx %s place-order id1 denom1 denom2 123e-2 10000 buy --from [sender] quantity, ok := sdkmath.NewIntFromString(args[4]) if !ok { - return sdkerrors.Wrap(err, "invalid quantity") + return errors.New("invalid quantity") } side, ok := types.Side_value[args[5]] @@ -144,9 +126,22 @@ $ %s tx %s place-order id1 denom1 denom2 123e-2 10000 buy --from [sender] goodTilBlockTime = lo.ToPtr(time.Unix(goodTilBlockTimeNum, 0)) } + timeInForceString, err := cmd.Flags().GetString(TimeInForce) + timeInForceInt, ok := types.TimeInForce_value[timeInForceString] + if !ok { + return errors.Errorf( + "unknown TimeInForce '%s',available TimeInForces: %s", + timeInForceString, strings.Join(availableTimeInForces, ","), + ) + } + if err != nil { + return errors.WithStack(err) + } + timeInForce := types.TimeInForce(timeInForceInt) + msg := &types.MsgPlaceOrder{ Sender: sender.String(), - Type: orderType, + Type: types.OrderType(orderType), ID: id, BaseDenom: baseDenom, QuoteDenom: quoteDenom, diff --git a/x/dex/client/cli/tx_test.go b/x/dex/client/cli/tx_test.go index d8de18207..facd4de3a 100644 --- a/x/dex/client/cli/tx_test.go +++ b/x/dex/client/cli/tx_test.go @@ -251,18 +251,8 @@ func placeOrder( testNetwork *network.Network, order types.Order, ) { - var orderType string - switch order.Type { - case types.ORDER_TYPE_LIMIT: - orderType = cli.OrderTypeLimit - case types.ORDER_TYPE_MARKET: - orderType = cli.OrderTypeMarket - default: - requireT.Fail(fmt.Sprintf("unknown type '%s'", order.Type)) - } - args := []string{ - orderType, + order.Type.String(), order.ID, order.BaseDenom, order.QuoteDenom, From 764cbf9da77f26d9b032312af45e47dba410dd8a Mon Sep 17 00:00:00 2001 From: Dzmitry Hil Date: Wed, 18 Dec 2024 14:05:58 +0300 Subject: [PATCH 2/2] Improve DEX spec. (#1053) --- x/dex/spec/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/x/dex/spec/README.md b/x/dex/spec/README.md index ab48a43c8..82b065c52 100644 --- a/x/dex/spec/README.md +++ b/x/dex/spec/README.md @@ -16,7 +16,7 @@ Users can place orders with the following attributes: * `quote_denom` - when you buy, you are selling the `quote_denom`, when you sell, you are buying the `quote_denom`. * `price` - value of one unit of the `base_denom` expressed in terms of the `quote_denom`. It indicates how much of the `quote_denom` is needed to buy one unit of the `base_denom`. -* `quantity` - is amount of the base `base_denom` being traded. +* `quantity` - is amount of the `base_denom` being traded. * `side` * `sell` - means that the order is to sell `base_denom` `quantity` with the `price`. * `buy` - means that the order is to buy `base_denom` `quantity` with the `price`. @@ -158,7 +158,7 @@ Tick size example: | unified_ref_amount(AAA) | unified_ref_amount(BBB) | price_tick(AAA/BBB) | price_tick(BBB/AAA) | |-------------------------|-------------------------|---------------------|---------------------| -| 10000.0 | 10000.0 | 10^-5 | 10^-5 | +| 10000.0 | 10000.0 | 10^-8 | 10^-8 | | 3000.0 | 20.0 | 10^-11 | 10^-6 | | 3100000.0 | 8.0 | 10^-14 | 10^-3 | | 0.00017 | 100.0 | 10^-3 | 10^-14 | @@ -192,12 +192,12 @@ Examples: ### Balance locking/freezing/whitelisting/clawback. -When a user places an order we lock the coins in the assetft (similar to freezing), both assetft and native coins. Also, -we reserve the expected receiving amount if whitelisting for the token the user expects to receive is enabled. -At the time of the placement we enforce all assetft rules. If, at the time of matching, the assetft rules for the -maker orders are changed, the orders will be still executed with the amounts in the order book. That's why to avoid -unexpected behavior with the `freezing/whitelisting/clawback` the token admin should [cancel](#Order-cancellation) users -orders before update the rules. +When a user places an order we lock the coins in the assetft (similar to freezing). Also, we reserve the expected +receiving amount if whitelisting for the token the user expects to receive is enabled. At the time of the placement we +enforce all assetft rules. If, at the time of matching, the assetft rules for the maker orders are changed, the orders +will be still executed with the amounts in the order book. That's why to avoid unexpected behavior with the +`freezing/whitelisting/clawback` the token admin should [cancel](#Order-cancellation) user's orders before update the +rules. ### Time in force @@ -233,7 +233,7 @@ The default reserve amount is `10 CORE` and can be updated by the governance. ### Max orders limit The number of active orders a user can have for each denom is limited by a value called `max_orders_per_denom`, -which is determined by DEX governance. +which is determined by DEX governance. The default value is 100. ### Events