Looking Closer at UniV4 Orders
I have been thinking about what kind of orders UniV4 could potentially unlock. I say potentially, since I am not sure it is possible to build a correct accounting for any of them with UniV4, but intuitively it seems plausible.
First, the possible order dimensions that could be created with UniV4 hooks:
a) One-time order vs many-times order
b) One direction vs two directions. Meaning the order can be executed with the price approaching the liquidity range from both directions
c) Maker vs Taker. Meaning that the order is a counterparty for the token demand coming from the pool swap(), or it adds to it
So each type of order can be identified by the (a, b, c) tuple per the above dimensions. For example, we can express a one time order with two directions and type maker as (1, 2, 1).
Let's see the categories that these order types facilitate.
(a, b, 1) Category: Limit Orders
The (a, b, 1) category represents limit orders. In this case liquidity is added to the book for Takers in market orders.
(2, 2, 1) : Standard LP Order
Since a=2 and b=2, they can be traded multiple times and in both directions. Considering c=1, they are counterparties for spot traders, i.e. the ones trading through swap() function.
This is the core mechanism that defines "stable" liquidity on Uniswap-like pools.
Trading on a Uniswap-like pool preserves liquidity, considered an invariant, producing the well-known hyperbolic bonding curve $xy = k$.
The $k$ preserved quantity here is just liquidity squared - so $k=L^2$.
Uniswap V3 range orders, aka “concentrated liquidity”, are just a specific instance of this category.
(1, 2, 1): LOB
This category represents standard LOB (limit order book) orders that are one-time, meaning that when fully executed they disappear from the book.
In Uniswap V3-like pools, considering $P$ pool price and $(P_{a}, P_{b})$, the price range of the limit order, aka "concentrated liquidity", is naturally:
- A bid if $P_{b} < P$ (since it is on the left side of the book, concerning the pool price)
- And, an ask if $P_{a} > P$ (since it is on the right side of the book, concerning the pool price)
Example
Let's assume on a ETH/USDC Pool with $P=1000$ that we have such a limit order consisting of:
Range: $(P_{a}, P_{b})=(900, 900 + \epsilon)$. The Uniswap V3 price space has a min. granularity which is $10^{-4}$ (i.e. 1 bip in the log price space) and each pool can have a custom tick spacing which is defined at pool creation and can't be changed. So let's call $\epsilon$ the min. bucket size for this pool.
Amount: 200 USDC. Since we are on bid size of the book, we can only place quote token (i.e. no ETH possible for this kind of orders).
When the pool price enters this range (i.e. $P_{a} < P < P_{b}$) the USDC reserves are converted in ETH as the bids are filled (so the order buys ETH). And when $P < P_{a}$, the reserves of this order will be all in ETH.
So far, it is like a standard LP order - similar to (2,2,1) - but the main difference is:
- For the standard LP order, when $P$ moves back, crosses $P_{a}$, and moves toward $P_{b}$, the reserves are converted back from ETH to USDC
- For this category of order instead, the fact that $P$ crosses $P_{a}$ from the left again does not cause any swap, since this is a one-time order
(1, 1, 1)
This is a tricky subcategory since it depends on the specific direction set.
In case of a bid (i.e. with $P_{b} < P$) then:
- If the execution direction is set right to left, it is equivalent to (1,2,1) above
- If the execution direction is set left to right, they are actually ask orders for a future pool price - i.e. when $P(t) < P_{a}$
This is the same for the other case.
(x, y, 2) Category: Market Orders
They work the opposite of (x,y,1) orders, as they are assimilable to the swap flow and they consume the liquidity provided by the category of orders above.
(1, 1, 2) and (1, 2, 2)
They are similar to the (1,b,1) category, with the difference that they need to be market orders. And so, it is like programming them to be executed at a certain price.
A simple example is a stop-loss order - it is programmed to be executed as a market order when the condition of the pool price reaching a certain figure is verified.
(2, 2, 2)
Inverse LP Order - it is like having both a stop loss and buy at set on a given price.
(2, 1, x)
This does not apply. Since in a one-directional order, all the reserves are converted into the other tokens the first time it is executed. Even if the price traverses the order again, there are more tokens to swap.
Extensibility
While we walked through some potential high level order types, UniV4 also allows for custom pricing logic, which when paired with the flexibility of different order types will unlock even more use cases. We’re excited to see what people come up with as it gets rolled out.