Front-running, Griefing and the Perils of Virtual Settlement (Part 2) | by Will Warren | 0x Blog

image

This post is a continuation of part 1, which provided an introduction to blockchain race conditions, front-running, the 0x protocol specification and presented two ways that 0x protocol may be used to implement a decentralized exchange that eliminates front-running and trade collisions by setting the 0x order schema’s taker parameter to an externally owned account (EOA).

There are a variety of ways that 0x protocol may be used that eliminate front-running and trade collisions, each with unique trade offs. The solutions presented in part 1 do so at the expense of networked liquidity, a unique property of 0x protocol that is described below. In this post, we will discuss ways 0x protocol may be used that prevent front-running and trade collisions while preserving networked liquidity by setting the 0x order schema’s taker parameter to a smart contract address.

Networked Liquidity

Networked liquidity refers to the seamless flow of orders through a network of interconnected exchanges, marketplaces and dApps. The interconnections act as a source of network effects, the phenomenon where a product or service gains additional utility as more people use it. Network effects are particularly important in marketplaces. Exchanges exist to aggregate buyers and sellers in one place — creating a pool of liquidity and, by extension, a more functional market. Networked liquidity allows for the same sort of aggregation, while remaining decentralized.

Orders can flow between relayers that implement the standard relayer API, allowing order book aggregation for relayers that are looking to add depth to their book as a bootstrapping technique or for groups of relayers that opt into some sort of fee sharing arrangement (see ZEIP12, this and this).

Orders can flow from relayers through dApps to their end users, providing end users the ability to frictionlessly acquire application-specific tokens or to make payments in any arbitrary token from directly within the dApp. We refer to this concept as token abstraction; you can learn more about token abstraction from our devcon 3 presentation.

Traders and dApp users can access all of these streams of order flow from a single standard wallet. No trading accounts. No need to put custody in the hands of a third party. No need to scatter one’s digital assets across multiple smart contracts. No deposits or withdrawals. This becomes increasingly useful as more types of digital assets and associated relayers enter the network.

Review

To summarize the key points that we have discussed up until now:

  1. There are valuable advantages to networked liquidity.
  2. Networked liquidity can be achieved if each relayer in the network uses the open order book strategy discussed in part 1, but open order books are vulnerable to trade collisions and front-running.
  3. Solutions presented in part 1 eliminate front-running and trade collisions by setting the 0x order schema’s taker parameter to an EOA. In assigning each order to a specific counter party, there can be no free flow of orders and therefore no networked liquidity.
  4. We need a way to keep orders open so they can be filled by anyone, but we simultaneously need to bring structure to these disparate streams of order flow to prevent trade collisions and front-running.

The good news is that 0x protocol is designed in a modular way such that we can create novel solutions that sit one layer above 0x’s system of smart contracts. This will ultimately require us to set the 0x order schema’s taker parameter to a smart contract address. Let’s now take a look at how these smart contract interactions can work.

Chaining Smart Contracts Together

By setting the 0x order schema’s taker parameter to a smart contract address, we can force orders to be funneled through an arbitrarily complex pipeline of logic. This allows us to develop interesting smart contract systems on top of 0x while maintaining a clean separation between the respective bodies of code.

In the above diagram, 0x protocol’s Exchange smart contract is represented as a grey rectangle. The order shown on the left side of the figure will only be executed by the Exchange contract if it is passed in by the smart contract specified as the taker, which can be any arbitrary smart contract.

Some interesting things we can do:

  • Funnel orders through a contract that implements fee sharing for relayers that pool liquidity or for dApps that pull liquidity from relayers.
  • Funnel orders through a contract that allows a network of “wranglers” to liquidate a trader’s margin position if it falls below its collateral requirement, per the rate provided by a trusted price oracle. This could potentially be useful for projects like dYdX or Lendroid.
  • Funnel orders through a contract that requires the Ethereum addresses for each trader to be registered to a specific white list. A relayer that specializes in securities tokens could use this approach to ensure all traders accessing their order book have gone through a rigorous KYC/AML process. Even more interesting, one could outsource curation of the white list to an independent institution that specializes in compliance using something like Harbor or Polymath. This could allow any relayer to ensure security tokens are only accessible to accredited/KYC’d individuals but without the relayer having access to any sensitive data regarding the identity behind each Ethereum address.
  • Funnel orders through a contract that implements LoopRing like behavior where “ring miners” submit batches of matched orders to the blockchain and receive a portion of the fee or a spread.
  • Funnel orders through a contract that eliminates front-running and trade collisions by enforcing rules around trade execution, which we will explore in more detail below.

Note: while one can implement the above systems using version 1 of 0x protocol, the current smart contract architecture is designed such that these layer 2 contracts must (1) have access to msg.sender’s tokens and (2) forward trade proceeds to msg.sender after a trade is completed. ZEIP2 or ZEIP18 will simplify these types of contract interactions by decoupling msg.sender from taker, making it easier to create modular smart contract systems on top of 0x protocol.

Note: For an example of an interesting smart contract that plugs into 0x, check out the contract that we used for the ZRX token sale and explanatory diagram. TL;DR this contract executed the “Genesis Trade” which was just a huge sell order for 50% of the total supply of ZRX tokens, but divvied up equally across all ~12,000 people that registered to participate in our token sale.

Commit-Reveal Schemes

Commit-reveal schemes are proposed as a solution for front-running. In this section we will describe how commit-reveal schemes work conceptually and how one may be implemented on top of 0x protocol using the smart contract chaining approach discussed above.

In general, commit-reveal schemes are used to prevent information leakage in situations where there are multiple parties involved in a transaction and one party’s decision, if made public, might impact the decisions or behaviors of others. Blind auctions and blind votes are examples of commit-reveal schemes.

In the context of decentralized exchange, a commit-reveal scheme may be layered on top of a 0x-based open order book by breaking the process of entering into a trade into two steps:

  1. After identifying an attractive order, the taker financially commits to filling that order by sending a transaction to the blockchain, but the important part about the first transaction is that it does not reveal the taker’s intent to outside observers.
  2. Once the first transaction has been mined, the taker sends a second transaction to the blockchain that contains the full details of the order they would like to fill along with a secret that proves that they financially committed to this particular order in step 1. If the secret is valid, then the order is filled.

The commit-reveal process and associated smart contract interactions are shown in the diagram below. Note that the relayer is hosting an open order book, but each order within the order book specifies a Commit-Reveal contract as the taker.

Pros:

  • Eliminates front-running from traders and miners.
  • Networked liquidity remains feasible.
  • Does not add centralization to the system.

Cons:

  • Does not prevent accidental collisions: multiple traders can still commit to the same order. In fact, the time delay between the commit and reveal transactions make collisions more likely to occur.
  • Two Ethereum transactions are required for each trade, increasing the average gas cost to >220k gas/trade versus an open order book which is ~140k gas/trade.
  • The time delay between commit and reveal transactions degrades the UX.
  • The process of generating an order is different than the process of consuming an order, which could lead to a confusing UX.

While the commit-reveal scheme presented above eliminates front-running and preserves networked liquidity, it is vulnerable to trade collisions. Once significant volume is flowing through a liquidity network structured this way, it is likely that collisions will occur frequently. Further, the asynchronous nature of commit-reveal schemes leads to a variety of failure modes that must be dealt with in smart contract code, increasing the contract’s complexity and attack surface. What happens to the taker’s security deposit if the maker cancels their order during the time between the commit and reveal? What we really need is a way to achieve consensus on the ordering of trades when there are numerous streams of order flow.

Trade Execution Coordinators

Centralized cryptocurrency exchanges are responsible for four things: custody, liquidity aggregation, trade execution and settlement. In the decentralized model, the Ethereum blockchain takes care of custody via decentralized consensus, 0x relayers are responsible for liquidity aggregation, 0x protocol is responsible for trade settlement, but 0x protocol does not define a process for trade execution.

In the open order book model, trade execution defaults to blockchain consensus which would be first-come-first-serve in an ideal world but is asynchronous and gameable in practice.

In the order matching model, liquidity aggregation and trade execution are bundled together by a matcher. While an honest matcher will execute trades according to price-time priority, there are no technical constraints that enforce this behavior, only social incentives such as loss of reputation and associated damage to business.

Conceptually, a Trade Execution Coordinator (TEC) is what you get when you unbundle the entity responsible for trade execution from the entity responsible for liquidity aggregation. A TEC can be centralized— a process managed by a single person — or decentralized. Regardless, a good TEC will do the following:

  • ensure trades are executed according to price-time priority,
  • be able to serve numerous relayers simultaneously,
  • operate securely and transparently,
  • remain highly available, censorship resistant and invulnerable to griefing.

A TEC with these properties can bring structure to disparate streams of order flow and allow us to fully realize the benefits of networked liquidity while eliminating front-running and trade collisions. So how can we take steps towards this vision?

Centralized, Trusted TEC

The simplest model for a TEC is a Trade Execution smart contract that requires a coordinator’s cryptographic signature before funneling any order onto the Exchange contract for settlement. In this model, relayers use an open order book strategy but each order’s taker parameter is set to the Trade Execution smart contract. Takers must go to the coordinator and acquire a cryptographic signature before injecting the order and associated signature into the Trade Execution contract. It follows that the coordinator is responsible for eliminating collisions and front-running by enforcing price-time priority over trade execution.

The TEC can be an individual relayer that coordinates trade execution for their own liquidity pool or an independent third party that offers this service for numerous relayers. Regardless of who the coordinator is, relying on an individual entity is centralizing and requires trust.

Pros:

  • Eliminates front-running from traders and miners.
  • Eliminates trade collisions.
  • Networked liquidity remains feasible.
  • Makers can cancel orders without creating an on-chain transaction if they trust the TEC to honor a “soft cancel.”

Neutral:

  • Gas costs are paid by the taker.
  • Coordinators can censor traders (from the perspective of other traders, having the coordinator blacklist griefers could be considered a good thing).

Cons:

  • Centralized point of failure.
  • Requires trust as coordinators can abuse their power by favoring certain traders or front-running.
  • The process of generating an order is different than the process of consuming an order, which could lead to a confusing UX.
  • Gas consumption per trade increases to ~170k gas versus the open order book model which consumes ~140k gas.

Centralized, Trustless TEC

Is there a way that we can eliminate the need to trust a centralized TEC? Perhaps. Some potential approaches for eliminating trust could include:

  • Obscuring trade information from a coordinator so it doesn’t know specific details about the order it is signing, but it does know whether or not it has signed the same order in the past. Without order details it is challenging to behave dishonestly. This could potentially be done by sending a hash of an order to the coordinator.
  • Rely on trusted hardware (Intel SGX?). One could potentially audit a hardware TEC in real-time to ensure that it is behaving honestly.

Ultimately, we would prefer a decentralized solution not only to eliminate trust but to eliminate single points of failure.

Decentralized TEC

The problem of achieving consensus on the ordering of trades is the same as the double-spend problem. A fully decentralized and trustless solution to this problem will look a lot like a blockchain. While we don’t want a centralized and trusted TEC, we don’t necessarily need a fully decentralized and trustless TEC.

Fortunately, there are a variety of ways that a semi-decentralized TEC could be structured and numerous avenues of research worth exploring. Promising directions could include delegating trade execution to a quorum of ecosystem stakeholders using multi-party signature schemes via

or using Schnorr signatures. Another interesting building block is the random beacon, which could allow the quorum to be randomly selected from a pool of stakeholders.

Concluding Thoughts

The goal for this post was to communicate the extensibility of 0x protocol’s system of smart contracts and how this design allows us to experiment with novel solutions for front-running and trade collisions. We have a solid foundation to build upon and many promising avenues of research to explore. Networked liquidity is a topic that deserves its own post, but I hope that the concept and potential benefits have been communicated through the brief introduction provided above. In part 3 we will discuss greifing — ways that a malicious actor can intentionally disrupt markets — along with mitigation strategies. Part 3 will also cover order book hygiene: basic steps that relayers should take to ensure their order book is devoid of stale orders and in sync with the blockchain state.