Governance
Proposing a New Market

Proposing a new market

💡 Important: always test proposals on testnets before submitting to any production environment.

Proposal Messages

The proposal should consist of 4 messages to be executed atomically and in order when the proposal passes onchain.

Message IndexMessageDescriptionParams Documentation
0MsgCreateOracleMarket (opens in a new tab)Sets the oracle list and other parameters in x/prices, used by the protocol to track an oracle priceMarketParams (opens in a new tab)
1MsgCreatePerpetual (opens in a new tab)Sets the perpetual parameters in x/perpetuals, used by the protocol to represent a perpetual market.Params (opens in a new tab)
2MsgCreateClobPair (opens in a new tab)Sets the orderbook parameters in x/clob, used by protocol to set up the market orderbook (in INITIALIZING status).ClobPair (opens in a new tab)
3MsgDelayMessage (opens in a new tab)Transitions the orderbook created by MsgCreateClobPair to ACTIVE status, after some amount of blocksdelay_blocks (opens in a new tab)

Notes:

  • For guideline on choosing values for individual params, see next section.
  • Liquidity tiers are mentioned throughout this page. The liquidity tier documentation can be found here.
  • The exact ordering of messages above is necessary for successful onchain execution.
  • Each of the 4 top-level messages should have Authority = dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky, the gov module (opens in a new tab).
  • The MsgCreateClobPair message wrapped in messages[3]: MsgDelayMessage should have Authority = dydx1mkkvp26dngu6n8rmalaxyp3gwkjuzztq5zx6tr, the delaymsg module (opens in a new tab).
  • The identifier fields must be consistent for a perpetual market: params.id, params.market_id, clob_pair.id, clob_pair.perpetual_clob_metadata.perpertual_id. An id value is valid as long as it's a uint32 unique from existing markets (they do not need to follow existing market ids).

Choosing Values for Market Parameters

The following decribes how to set various parameters for a new market and assumes that the market listed is:

  • Safe (Not susceptible to market manipulation e.g. Mango (opens in a new tab))
  • Worth listing (Will this generate sufficient trading volume to consume throughput?)
  • Oracle sources are known (Which spot exchanges should be selected when determining the oracle price?)

Inputs

  • Ticker Symbol (e.g. BTC-USD )
  • Reference price (e.g. 40,000) and p value
    • Defines the exponent on the reference price as p:=FLOOR(log10(reference_price)). For example: p:=FLOOR(log10(40,000))=4
  • Exchanges required for oracles (exchange_config_json)
  • Liquidity Tier (can be updated through governance vote at a later date.)
    • 0: Large Cap (BTC/ETH)
    • 1: Mid-Cap (Markets with at least 8 robust oracle sources with liquidity >= 50K on both sides and 30d daily spot trading volume >= $100M.)
    • 2: Long-tail (All others)

Outputs

Message TypeFieldDescriptionValue
MsgCreateOracleMarketexponentDenotes the number of decimals a value should be shifted in the price daemonp-9
MsgCreateOracleMarketmin_exchangesUsed for an index price to be valid.3
MsgCreateOracleMarketmin_price_change_ppmThe minimum amount the index price has to change for an oracle price update to be valid.Liquidity Tier 0: 1000 Liquidity Tier 1: 2500 Liquidity Tier 2: 4000
MsgCreateOracleMarketexchange_config_jsonSpot exchange query configuration for the oracle priceSee below
MsgCreatePerpetualatomic_resolutionL the exponent for converting an atomic amount (size = 1) to a full coin.-6 - p
MsgCreatePerpetualdefault_funding_ppmThe default funding payment if there is no price premium. In parts-per-million.0
Msg[Update/Create]ClobPairquantum_conversion_exponent10^quantum_conversion_exponent gives the number of quote quantum traded per base quantum.-9
Msg[Update/Create]ClobPairsubticks_per_tickDefines the tick size of the orderbook by defining how many subticks are in one tick.Liquidity Tier 0: 100000 Liquidity Tier 1 and 2 : 1000000
Msg[Update/Create]ClobPairstep_base_quantums(aka step size): min increment in the size of orders (number of coins) on the CLOB in base quantums.1000000
MsgDelayMessagedelay_blocksnumber of blocks before which the MsgUpdateClobPair is executed and transitions the market to ACTIVE3600 (equal to an hour at 1 sec blocktime)

Choosing oracle sources

To select oracle sources, follow the procedure below:

  1. Find spot market tickers from eligible exchanges with the desired symbol as the base asset and USD or USDT as the quote asset. See below for a list of eligible exchanges.
  • If the quote asset is USDT, add the following flag "adjustByMarket":"USDT-USD". This flag ensures that the base asset oracle price is adjusted by the USDT oracle price.
  1. Currently the software supports only one source from an exchange per market. Among the tickers from an exchange, choose the most liquid spot market with the highest trading volume. If one market is more liquid but another has more trading volume, choose the one with deeper liquidity.
  2. Exclude oracle sources that do not meet the depth and daily trading volume threshold over the past month.
  • Both sides of liquidity at 2% from the midprice should be at least $50,000.
  • The average daily trading volume should be at least $100,000.
  1. Ensure there are at least 6 sources. If there are less than 6 sources, this market should not be added to prevent potential market manipulation attacks and consensus failures from oracle price updates unless more robust oracle sources are available.

List of eligible exchanges

Recommended Exchanges:

  • Binance
  • Coinbase
  • OKX
  • Bybit
  • Gate
  • Kraken
  • Kucoin
  • MEXC

Only use if necessary:

  • HTX (previously Huobi)
  • Bitstamp

Not recommended:

  • Bitfinex
  • BinanceUS
  • Crypto.com

Exchanges not included in the above list are not currently supported by the software.

Example

Example of markets with robust oracle sources

Here is a list (opens in a new tab) of a few markets and their oracle sources evaluated based on the methodology above.

exchange_config_json

Below is an example json string for exchange_config_json. To convert this string into a single-line, quote-escaped string:

cat exchange_config.json | jq -c . | sed 's/"/\\"/g'
{
   "exchanges":[
      {
         "exchangeName":"Binance",
         "ticker":"BTCUSDT",
         "adjustByMarket":"USDT-USD"
      },
      {
         "exchangeName":"Bybit",
         "ticker":"BTCUSDT",
         "adjustByMarket":"USDT-USD"
      },
      {
         "exchangeName":"CoinbasePro",
         "ticker":"BTC-USD"
      },
      {
         "exchangeName":"Huobi",
         "ticker":"btcusdt",
         "adjustByMarket":"USDT-USD"
      },
      {
         "exchangeName":"Kraken",
         "ticker":"XXBTZUSD"
      },
      {
         "exchangeName":"Kucoin",
         "ticker":"BTC-USDT",
         "adjustByMarket":"USDT-USD"
      },
      {
         "exchangeName":"Mexc",
         "ticker":"BTC_USDT",
         "adjustByMarket":"USDT-USD"
      },
      {
         "exchangeName":"Okx",
         "ticker":"BTC-USDT",
         "adjustByMarket":"USDT-USD"
      }
   ]
}

Example Proposal Json

Below is an example proposal JSON file to propose adding BTC-USD as a new perpetual market (if it had not been added yet).

{
    "title": "Add BTC-USD perpetual market",
    "deposit": "10000000000000000000000adv4tnt",
    "summary": "Add the `x/prices`, `x/perpetuals` and `x/clob` parameters needed for a BTC-UTC perpetual market. Create the market in `INITIALIZING` status and transition it to `ACTIVE` status after 3600 blocks.",
    "messages": [
      {
        "@type": "/dydxprotocol.prices.MsgCreateOracleMarket",
        "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky",
        "params": {
            "exchange_config_json": "{\"exchanges\":[{\"exchangeName\":\"Binance\",\"ticker\":\"BTCUSDT\",\"adjustByMarket\":\"USDT-USD\"},{\"exchangeName\":\"Bybit\",\"ticker\":\"BTCUSDT\",\"adjustByMarket\":\"USDT-USD\"},{\"exchangeName\":\"CoinbasePro\",\"ticker\":\"BTC-USD\"},{\"exchangeName\":\"Huobi\",\"ticker\":\"btcusdt\",\"adjustByMarket\":\"USDT-USD\"},{\"exchangeName\":\"Kraken\",\"ticker\":\"XXBTZUSD\"},{\"exchangeName\":\"Kucoin\",\"ticker\":\"BTC-USDT\",\"adjustByMarket\":\"USDT-USD\"},{\"exchangeName\":\"Mexc\",\"ticker\":\"BTC_USDT\",\"adjustByMarket\":\"USDT-USD\"},{\"exchangeName\":\"Okx\",\"ticker\":\"BTC-USDT\",\"adjustByMarket\":\"USDT-USD\"}]}",
            "exponent": -5,
            "id": 1001,
            "min_exchanges": 3,
            "min_price_change_ppm": 1000,
            "pair": "BTC-USD"
        }
      },
      {
        "@type": "/dydxprotocol.perpetuals.MsgCreatePerpetual",
        "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky",
        "params": {
            "atomic_resolution": -10,
            "default_funding_ppm": 0,
            "id": 1001,
            "liquidity_tier": 0,
            "market_id": 1001,
            "ticker": "BTC-USD"
        }
      },
      {
        "@type": "/dydxprotocol.clob.MsgCreateClobPair",
        "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky",
        "clob_pair": {
            "id": 1001,
            "perpetual_clob_metadata": {
              "perpetual_id": 1001
            },
            "quantum_conversion_exponent": -9,
            "status": "STATUS_INITIALIZING",
            "step_base_quantums": 1000000,
            "subticks_per_tick": 100000
        }
      },
      {
        "@type": "/dydxprotocol.delaymsg.MsgDelayMessage",
        "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky",
        "msg": {
            "@type": "/dydxprotocol.clob.MsgUpdateClobPair",
            "authority": "dydx1mkkvp26dngu6n8rmalaxyp3gwkjuzztq5zx6tr",
            "clob_pair": {
                "id": 1001,
                "perpetual_clob_metadata": {
                  "perpetual_id": 1001
                },
                "quantum_conversion_exponent": -9,
                "status": "STATUS_ACTIVE",
                "step_base_quantums": 1000000,
                "subticks_per_tick": 100000
            }
        },
        "delay_blocks" : 3600
      }
    ]
  }

Submitting an Onchain Proposal

Follow instructions here to submit an onchain proposal.