Every day, thousands of people use a decentralized exchange (DEX) for the first time. However, the idiosyncrasies of a public blockchain routinely catch newcomers off-guard, even those familiar with trading on more traditional venues. As a result, traders bleed money to arbitrageurs and frontrunners, leading to worse-than-necessary execution.
At a high level, we can break down the costs of each trade into several parts:
1. Price impact
2. Broker or trading fees
3. Slippage
4. Transaction fees of the underlying blockchain
This article on automated market-makers (AMMs) will serve as an intro to the series and discuss the first and most crucial cost: price impact. You will learn:
- how AMMs like Uniswap V2, Sushiswap, and Balancer determine the prices they quote
- and how to minimize the price impact of your trade using a few simple strategies.
What are liquidity pools?
Most DEXs consist of many liquidity pools that represent different trading pairs, like ETH/WBTC. Instead of matching buyers and sellers in an order book, these liquidity pools act as an automated market maker.
A liquidity pool is a smart contract that holds reserves of two or more tokens and allows anyone to deposit and withdraw funds from them, but only according to very specific rules.
One such rule is the constant product formula x*y = k, where x and y are the reserves of two tokens, A and B. In order to withdraw some amount of token A, one must deposit a proportional amount of token B to maintain the constant k before fees.
How does an AMM determine its price?
From the constant product formula, it follows that the price of that token A is simply price_token_A = reserve_token_B/ reserve_token_A.
Pricing Curve
Chart 1: Different AMM formulas result in different pricing curves. When a hypothetical Uniswap v2 liquidity pool has 15 Y-tokens, it will only pay 0.1 X-tokens for the marginal Y-token. But when it has only 2.5 Y-token, it will pay 4.0 X-tokens. Other pricing curves are designed to concentrate more liquidity around a certain price (e.g. 1.0 for stablecoins). Source: Curve Whitepaper
To look at a real-world example, at the time of writing there are 236 WBTC and 3,020 ETH in Uniswap's ETH/WBTC pool. This reserve ratio implies that ETH's market price at the time of writing is 236 / 3,020 = 0.0781 WBTC.
Crucially, the AMM does not update this price as other markets move around it. The market price only moves as the reserve ratio of the tokens in the pool changes, which happens when someone trades against it.
To explore an example, what happens if the price on Binance falls to 0.078? That implies Uniswap LPs are currently buying ETH at a premium, creating an arbitrage opportunity. As a result, arbitrageurs buy the "cheap" ETH on Binance and sell it on Uniswap for an immediate profit. They keep doing this until the next unit of Uniswap ETH only pays 0.0781 WBTC - same as on Binance - and they can no longer profit by selling more. In our example above, this point is reached after selling 58 ETH to the pool (ignoring fees and gas for simplicity).
As a result, even though AMMs don't update their price based on incoming real-world information, traders can still expect the price quoted by an AMM to closely track the global market price because of continuous arbitrage.
What is Price Impact?
While we learned how to compute the current market price from the ratio of two token reserves, this market price only shows the price the AMM wants for the marginal token. However, in practice, a trader will often buy or sell many tokens at once, with every token costing more than the previous one. This difference between the current market price and the expected fill price is called price impact. Price impact is a function of
- the size of your trade relative to the size of the liquidity pool, as well as
- the trading rule being used (e.g. constant product formula).
Chart 2: Comparing the average fill price (left y-axis) and price impact (right y-axis) for different order sizes (x-axis). Both factors increase with order size. The larger the order size relative to the pool, the further above the market price will the trade get filled.
Chart 3: Comparing the average fill price (left y-axis) and price impact (right y-axis) of a 10 WBTC sell order on different pool sizes on Uniswap v2 (x-axis). The pool size is the total value of the pool including the reserves of both assets. The orders represent 0.19%, 1.85%, and 18.52% of the pool respectively. So a good rule of thumb is that the price impact of your order is about twice the size of your order relative to the pool.
How can Price Impact be minimized?
As we alluded to earlier, price impact can represent a large share of a trade's overall execution cost. Here are some simple strategies to minimize it:
1. Find the deepest market: So far, we established that price impact is a function of trade size relative to the size of the pool or market. It follows then that we want to find the pool that has the most liquidity in the price range we care about, which is where we get filled closest to the market price. A token's depth table on Coingecko is a good starting point to analyze this.
Chart 4: Trading pairs for UNI, sorted by liquidity within 2% of the .market price. Note the difference in spread between Uniswap and Bitfinex.
2. Look outside of DeFi: While this is a post on AMMs, we won't pretend you can always get the best execution on-chain. In fact, since the AMMs discussed spreading their liquidity across a continuous range of prices, they often have little liquidity concentrated around the current market price. This is a known problem that many DEXs are trying to solve, for example, Uniswap V3 will allow market makers to place their liquidity concentrated around the current market price, making prices more competitive to CEXs as a result. When a trade moves the price on a DEX and the same token trades in other markets, an arbitrage opportunity is created. As discussed, arbitrageurs will "backrun" the trade (i.e. insert their own transaction immediately after). and move the price back to the global market price. It's easy to see why the existence of such an arbitrage is itself proof of an execution mistake, as the trader is donating capital to the arbitrageur. This begs the question: should you execute an on-chain trade with more than a 2-3% price impact if other markets exist?
3. Mind the trading fees: AMMs have a trading fee of 0.3%, which translates to a spread of 0.6% between the best buy order and the best sell order. Within this range, the AMM does not quote any prices. In other words, even the most liquid AMM trade has an implicit 0.3% price impact. Minimizing the impact of fees is extremely important, especially for trades that have very little price impact on a CEX, so a CEX might be the better execution venue outright. (For comparison, the same trade would have a 0.1% fee on Binance and 0.07% on FTX). That said, there are other reasons to pay more for DEX access, including retaining full custody or avoiding an onboarding, KYC, or deposit process. However, even in those cases, traders should be aware that their higher execution prices include an implicit decentralization or instant liquidity premium.
4. Spread out trades: First, it's possible to split one trade into several smaller trades over time. This is especially relevant for traders who prefer to trade on a DEX in spite of other liquid markets existing outside DeFi. In that case, you can e.g buy in 20% increments and let arbitrageurs revert the price after every trade. These five orders together will cause a lower price impact than a single large order, but with the added tradeoff of higher gas costs and execution time. The larger the trade, the better this strategy is, as the fixed cost of gas decreases relative to the benefit of marginally better execution. This strategy also works when assets are mean reverting, e.g. stablecoins.
5. The direct route is not always the cheapest: Not every trade has a direct token pair, and even if it does, it may be cheaper to use a bridge currency instead. For example, while tokens A:B might have a direct pair, it is often cheaper to trade A => ETH => B, if these pairs are sufficiently more liquid. Aggregators are very useful in that regard, even if you just use them to look at their router suggestions.
6. Use DEX aggregators: Finally, you can use a DEX aggregator like 1inch, Match, or Paraswap. Aggregators are the DeFi equivalent of smart order routing and work because AMMs will sell the first token at a cheaper price than the tenth token. Whenever a token trades in multiple pools, aggregators will buy the token across all pools in order to minimize the price impact on each one of them. Instead of spreading the trade over time in a single market, this order executes at once, spread over many possible markets. Aggregators also command substantially higher gas costs than a single trade, similar to splitting trades manually.
Chart 5: The optimal strategy to buy 10, 50, 100, and 200 AAVE with ETH. The larger the trade, the more exchanges are added to the route to avoid moving any individual pool too much.
Outlook
In the second part of this series, we will focus entirely on slippage. Almost all AMM trades are subject to frontrunning, causing them to be filled at the maximum slippage the trader is willing to accept. This is a unique "feature" of trading on a public blockchain that cannot be avoided with how decentralized exchanges work today. The cost can only be shifted around, leading us to formulate "The Sandwich Trilemma".
Notes
1. Other forms of DEXs based on a central-limit order book (such as Serum) or batch auctions (such as Gnosis) are not in the scope of this article.
2. Fees slightly increase the k every trade.
Author: Hasu.
Comments
Post a Comment