From c7c25fc417ebf46c473f232c6b5f1f9345f199e0 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 19 Jun 2024 15:40:22 +0100 Subject: [PATCH] feat: tx trade ordering (#2231) * feat: Order trade transactions within a block --- protocol/0001-MKTF-market_framework.md | 3 +- protocol/0028-GOVE-governance.md | 3 ++ .../0093-TRTO-trading_transaction_ordering.md | 47 +++++++++++++++++++ protocol/features.json | 24 ++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 protocol/0093-TRTO-trading_transaction_ordering.md diff --git a/protocol/0001-MKTF-market_framework.md b/protocol/0001-MKTF-market_framework.md index 6579c5bcd..3d32d838a 100644 --- a/protocol/0001-MKTF-market_framework.md +++ b/protocol/0001-MKTF-market_framework.md @@ -33,7 +33,8 @@ Data: - If this is negative e.g. -3 this means that the smallest order and position is of size 1000. - Accepted values are `-6,...,-1,0,1,2,...,6`. - **Tick size**: the minimum change in quote price for the market. Order prices and offsets for pegged orders must be given as an exact multiple of the tick size. For example if the tick size is 0.02 USD. then a price of 100.02 USD is acceptable and a price of 100.03 USD is not. The tick size of a market can be updated through governance. Note, the tick size should be specified in terms of the market decimals, e.g. for a scaled tick size of `0.02` (USDT) in a market using `5` decimal places, the tick size would be set to `2000`. -- **Liquidation strategy**: A field specifying the liquidation strategy for the market. Please refer to [0012-POSR-position_resolution](./0012-POSR-position_resolution.md#managing-networks-position) for supported strategies. +- **Liquidation strategy**: A field specifying the liquidation strategy for the market. Please refer to [0012-POSR-position_resolution](./0012-POSR-position_resolution.md#managing-networks-position) for supported strategies. +- **Transaction Prioritisation**: A boolean, whether to enable [transaction prioritisation](./0092-TRTO-trading_transaction_ordering.md). Note: it is agreed that initially the integer representation of the full precision of both order and positions can be required to fit into an int64, so this means that the largest position/order size possible reduces by a factor of ten for every extra decimal place used. This also means that, for instance, it would not be possible to create a `BTCUSD` market that allows order/position sizes equivalent to 1 sat. diff --git a/protocol/0028-GOVE-governance.md b/protocol/0028-GOVE-governance.md index bedf799e1..b609255e1 100644 --- a/protocol/0028-GOVE-governance.md +++ b/protocol/0028-GOVE-governance.md @@ -579,6 +579,8 @@ APIs should also exist for clients to: - A market proposal with position decimal places not in `{-6,...,-1,0,1,2,...,6}` gets rejected. (0028-GOVE-062) For product spot: (0028-GOVE-075) - A market proposal with a tick size less than or equal to `0` gets rejected (0028-GOVE-180). - At enactment, a market change proposal updating the tick size leaves in place all orders where the quoted price is not an exact multiple of `10^-mdp` (where `mdp` is the market decimal places) (0028-GOVE-182). +- At enactment, a market with `Transaction Prioritisation` enabled will have transactions re-prioritised as defined in [transaction prioritisation](./0092-TRTO-trading_transaction_ordering.md) (0028-GOVE-192). +- At enactment, a market with `Transaction Prioritisation` disabled will not have transactions re-prioritised (0028-GOVE-193). #### Market change proposals @@ -623,6 +625,7 @@ APIs should also exist for clients to: - A market change proposal specifying a new tick size less than or equal to `0` gets rejected (0028-GOVE-184). - At enactment, a market change proposal updating the tick size cancels all pegged orders where their offset is no longer an exact integer multiple of the tick size (0028-GOVE-183). - A market LP with ELS > 0 can vote on a market change proposal even if the key doesn't meet the `governance.proposal.updateMarket.minVoterBalance` for governance token. (0028-GOVE-185). +- An amendment to a market to enable or disable `Transaction Prioritisation` will have that effect immediately upon enactment. (0028-GOVE-194) #### Network parameter change proposals diff --git a/protocol/0093-TRTO-trading_transaction_ordering.md b/protocol/0093-TRTO-trading_transaction_ordering.md new file mode 100644 index 000000000..e72eeb86e --- /dev/null +++ b/protocol/0093-TRTO-trading_transaction_ordering.md @@ -0,0 +1,47 @@ +# Trading Transaction Ordering + +In order for an exchange to offer competitive prices for parties arriving and wishing to trade immediately, others have to be willing to place limit orders on the book which will remain there and wait for an incoming order to match with it. These are required for a limit order book to exist (as implied by the name) but expose the party placing the initial limit order to a range of risks, as often the reason these orders will eventually trade is because the price has become unfavourable to the party who placed the order, but they either have not realised or have not had a chance to cancel the order yet. This is often referred to as "toxic flow". Whilst another party obviously gains from this transaction, it is generally acknowledged that the higher a given venue's proportion of toxic flow to more balanced flow, the wider market makers will end up quoting to avoid being the victim of this. This issue is particularly present when considering a decentralised exchange with a publicly available mempool and higher latency than a centralised exchange, both giving potential toxic flow a significant edge. As such, exchange and transaction designs which allow for the reduction of this without unfairly impacting other parties using the network may allow for the exchange as a whole to provide traders with better prices than otherwise. This specification covers one such proposed methodology, comprising of a specified ordering of order executions on a given market. + +## Execution Ordering + +Trading transactions (those which create, update or remove orders of any type on any market) should be executed in a specific way once included in a block. This ordering is per-market (inter-market ordering is unspecified). The functionality can be enabled/disabled at a per-market level through market governance. When disabled for a given market, all transactions are sorted as normal with no delays applied. + +Chiefly, when enabled all transactions which would cancel an order or create post-only orders should be executed first before transactions which could create trades, within which all cancellations should be executed prior to post-only orders. The ordering of the transactions in this way means that, at the time of each block being created, all parties who are contributing to creating an order book have an opportunity to update their prices prior to anyone who would capitalise on temporary stale prices, regardless of which transaction reached the validator's pre-block transaction pool first. This ordering can still be seen to be a "fair" transaction ordering, as parties cannot take actions which would cause a trade, but only take action to avoid trading at a price they no longer desire (or indeed to improve a price prior to trade-creating transactions' arrival). + +Furthermore, transactions which can cause a trade by acting aggressively, such as non-post-only orders and amends, will be delayed by a number of blocks, governed by a network parameter `market.aggressiveOrderBlockDelay`, prior to execution. This results in the pattern where: + + 1. Prior to block N, post only order A and market order B arrive to the chain, these are both included in block N. + 1. When block N is executed, order A takes effect. + 1. Prior to block N + 1, post only order C then market order D and finally a cancellation of order A arrive to the chain, these are both included in block N + 1. + 1. When block N + 1 is executed, the cancellation of order A first takes effect, then the post-only order C, then finally market order B. + 1. When block N + 2 is executed, market order D takes effect + +## Batch Transactions + +Batch transactions, as they contain different order types, must be handled slightly differently. In the initial version, they will remain to be executed as one unit. When determining execution position, the protocol will inspect the components of the batch transaction. If the transaction contains any order creation messages which are not post-only, or any order amends at all, the entire batch will be delayed as if it were a transaction which could create trades (as some component of it could). If the batch contains exclusively cancellations and/or post-only limit orders then it will be executed in the expedited head-of-block mode specified above. Batches will still be executed all at once as specified, in the order cancellations -> amendments -> creations. The total ordering of executions when including batches should be: + + 1. Standalone Cancellations + 1. Batches (containing both cancellations and order creations) + 1. Standalone Creations + +## Acceptance criteria + +- A batch transaction including only cancellations and/or post-only limit orders is executed at the top of the block alongside standalone post-only limit orders and cancellations. (0093-TRTO-001) +- A batch transaction including either a non-post-only order or an amendment is delayed by one block and then executed after the expedited transactions in that later block. (0093-TRTO-002) +- Cancellation transactions always occur before: + - Market orders (0093-TRTO-003) + - Non post-only limit orders (0093-TRTO-004) + - Order Amends (0093-TRTO-005) + - post-only limit orders (0093-TRTO-013) +- Post-only transactions always occur before: + - Market orders (0093-TRTO-006) + - Non post-only limit orders (0093-TRTO-007) + - Order Amends (0093-TRTO-008) +- Potentially aggressive orders take effect on the market exactly one block after they are included in a block (i.e for an order which is included in block N it hits the market in block N+1). This is true for: + - Market orders (0093-TRTO-009) + - Non post-only limit orders (0093-TRTO-010) + - Order Amends (0093-TRTO-011) +- An expedited batch transaction is executed after cancellations but before standalone post-only creations (0093-TRTO-012) +- The transaction ordering functionality can be enabled/disabled on a per-market level (0093-TRTO-015) +- With two active markets, with one having transaction ordering enabled and one disabled, transactions are correctly sorted/delayed on the market with it enabled whilst the other has transactions executed in arrival order. (0093-TRTO-014) +- When `market.aggressiveOrderBlockDelay` is set to `1` aggressive orders are delayed by a single block on eligible markets. If it is amended via governance to `5` then all aggressive orders after enactment of this change will be delayed by `5` blocks instead. (0093-TRTO-016) diff --git a/protocol/features.json b/protocol/features.json index e25f5ff3d..daebd7d8b 100644 --- a/protocol/features.json +++ b/protocol/features.json @@ -725,6 +725,30 @@ "milestone": "colosseo_II", "acs": ["0028-GOVE-188", "0028-GOVE-189", "0028-GOVE-190", "0028-GOVE-191"] }, + "Transaction Ordering": { + "milestone": "colosseo_II", + "acs": [ + "0093-TRTO-001", + "0093-TRTO-002", + "0093-TRTO-003", + "0093-TRTO-004", + "0093-TRTO-005", + "0093-TRTO-006", + "0093-TRTO-007", + "0093-TRTO-008", + "0093-TRTO-009", + "0093-TRTO-010", + "0093-TRTO-011", + "0093-TRTO-012", + "0093-TRTO-013", + "0093-TRTO-014", + "0093-TRTO-015", + "0093-TRTO-016", + "0028-GOVE-192", + "0028-GOVE-194", + "0028-GOVE-193" + ] + }, "Spot AMM": { "milestone": "genbu_temple", "acs": [