Just In Time AMM Protocol
A Novel AMM Protocol Design for Hyper-Efficient Decentralised Cross Chain Swaps on Chainflip
The JIT AMM was introduced to the protocol design on the 28Feb22
Link to that post can be found below 👇
Chainflip’s AMM design differs substantially from industry standards due to limitations introduced by the nature of cross-chain transfers. The Chainflip AMM protocol has several distinguishing features which radically alter the optimal liquidity provider strategy and offer significant capital efficiency and pricing accuracy advantages for users. We call this style of AMM a “JIT (Just In Time ) AMM.” There are very few examples of similar trading products in use today.
An open-source python model of the JIT AMM is avalaible on the Chainflip GitHub right now: https://github.com/chainflip-io/chainflip-jit-amm-python
- The JIT AMM is implemented directly on the State Chain in the 'pools' pallet. Written in Rust, it's a substrate rewrite of the Uniswap v3 design on Ethereum with several changes and additions running in a custom execution envrinment.
- Range orders work as they normally do in Uniswap v3. Liqudity remains deployed until the LP submits an extrinsic which removes it from the pool and returns the remaining funds and fees to their 'free' balance.
- Limit orders are layered on top of the existing range order system. Limit orders are fully consumed by swaps, and the resulting funds are returned directly to the LP's 'free' balance.
- Swaps will take all of the liquidity from both limit and range orders in each price 'tick' before moving on to the next. Limit orders are consumed before range orders in each price tick.
- As soon as a sufficient witness threshold for a swap deposit is reached, the event which triggers the swap is automatically executed, and the block producing validator must execute the swaps for the block to be valid.
- Incoming swaps are bundled per direction. If multiple buy or sell swaps appear in a block, the pools pallet will treat those buys or sells as a single larger buy or sell swap to be executed in one step. This is to prevent frontrunning and to make JIT quoting simpler to calculate for LPs.
- No limit orders are executed against each other, as would be the case in a traditional matching engine. This means it is possible to have a buy order at a price higher than than the lowest sell, and vice versa. This eliminates some potential MEV posibilites.
Uniswap V3 Introduced the concept of range orders into the AMM world, which brought about a number of improvements to the capital efficiency and user experience of many of Uniswap’s most popular pools. Chainflip, as a cross-chain product, does not share the same execution environment assumptions as typical AMMs. Unlike in a single chain environment, Chainflip must address the following issues:
- The protocol must wait several blocks to confirm external chain deposits, due to the risk of chain reorganisations external to Chainflip. As a decentralised and programmatic system, there is no way to manually reorder transactions if this occurs, and so several block confirmations are often needed to operate safely. Given that there is a non-trivial delay to confirm incoming swap deposits, and they are on public chains, all market participants will know the swaps that will be executed before they occur.
- Furthermore, the confirmation times would also cause pricing and arbitrage to be significantly delayed using normal rules, resulting in prolonged price differences compared to market index prices.
One major advantage to traditional AMMs is that as Chainflip runs in its own independent execution environment, much of the swap execution can be automated and executed by the validator network without complex user interactions.
The core concept that drives the JIT AMM design is to flip frontrunning on it’s head. Instead of users being front run by MEV seeking bots, the protocol naturally incentivises liquidity providers to front run each other to the benefit of the user. Several months after first publishing our protocol design of a JIT AMM, MEV seekers spotted examples of this in action on Uniswap v3. For trades of a large enough size, there are opportunities to front-run other LPs even on the expensive Ethereum blockchain, proving the viability of this strategy in the wild. JIT liquidity provision has risen from 3% of all Uniswap volume to well over half as at the time of writing (22 Feb 2023).
As long as a few Market Makers compete with each other for the trades, this protocol design should ensure that users performing swaps are always getting market pricing or better than market pricing at the time of swap execution, with low fees and minimal slippage, and that capital efficiency in this protocol should far exceed all other existing AMM designs depending on the level of competition between Market Makers.
Let’s trace the path of a typical swap to examine how this works in practice. For this example, our hypothetical user will swap USDC (ERC20) for BTC (Native), and Market Makers A, B, and C will compete to win the liquidity fee from the trade. There is a 25bps liquidity fee on this pool.
- The user (BTC buyer) generates a quote which creates a unique deposit address associated with their destination address and swap intentions for BTC. The user initiates the swap by depositing 10,000 USDC.
- The Ethereum blockchain includes the USDC deposit in the next block. The Market Makers spot that the deposit has occurred and track other upcoming USDC deposits. Although it will take several Ethereum blocks for the transaction to be witnessed and executed on the Chainflip State Chain, the Market Makers can track the Ethereum txes using provided pre-witnessing tools.
- Chainflip requires 4 Ethereum blocks to consider a deposit transaction ‘final.’ It is therefore estimated that the swap will be executed in 8 Chainflip State Chain blocks (around 48 seconds). Market Makers now must include any state chain limit order or range order updates in those 8 blocks to compete for the trade.
- By having additional capital float on other exchanges like Coinbase, Binance, and so on, Market Makers can use risk model calculations to determine their best possible price for the trade. Using this calculation, they update their range orders and move their USDC in the USDC-BTC pool right up to that price. In this case, Market Maker A creates a limit order of $10,000 USDC at $23,934 per BTC, whereas Market Maker B moves their $10,000 of USDC to $23,938 per BTC.
- The swap deposit reaches the witness threshold and the swap is executed. As the pool price (from the last trade) is $23,920, the range orders consume $1000 of the swap value before the pool price matches the highest limit order, in this case Market Maker B's $23,934 bid, which fills the rest of the buy swap.
- Market Maker B, having just bought $9,000 of BTC, goes ahead and sells $9,000 of BTC at $23,980 on other markets. If managed correctly, the Market Maker just pulled in a nice little profit and did so by taking on a mere 6 seconds of price risk. These opportunities occur every time a swap is executed.
- The Chainflip Validator network now sends the swapped BTC funds to the user, straight to their native BTC wallet address they provided at the start.
- Market Maker B might now make some withdrawals or deposits to their LP position to rebalance their portfolio to prepare to capture future opportunities, while Market Makers A and C are ready to take opportunities in batches in the immediate future. The next one is just 1 Ethereum block away.
This swap flow relies on Market Makers executing behaviour which is nearly identical to that of typical software driven OTC desks, but in an open and competitive environment. This strategy can easily be integrated into typical market making strategies as a method of generating trade flow without needing to build or expand a customer base.
In reality, it would likely be rare that a single liquidity provider takes 100% of the liquidity fee in big swaps, but rather one or two Market Makers taking the large majority of a given trade with smaller amounts filled by an assortment of other liquidity providers using range orders. In any case, the Market Makers will always know what trades they (and everyone else) just executed and will follow the same steps and principles. Furthermore, in the wider Chainflip protocol design, it is intended to have dozens of these pools operating simultaneously, all moving at slightly different speeds on the basis of the block and confirmation times of each chain. A BTC to ETH swap for example would not be facilitated in a single swap. Instead, a user’s funds would automatically be routed through two pools, BTC-USDC and then USDC-ETH, which would involve two swaps that both follow the same rules as described above, just done with a single block between the two swaps.
Due to this arrangement, Market Makers must not only track future deposits into the pool in question, but also the expected path of deposits into other pools that will ultimately be routed into the pool in question in order to accurately predict batches. Routing everything through USD does mean that users will be exposed to USD for a short window of time while they wait for their swaps to be routed, which may not be desirable in some circumstances, but is assessed to be a worthwhile tradeoff in order to minimise liquidity fragmentation, which would arguably be worse for users under normal market conditions. If particular routes within the protocol become popular enough, direct asset-to-asset pools (such as ETH-BTC) can be added through protocol upgrades to allow users to avoid this price exposure.
Lastly, with all market making strategies, there are degrees of complexity. Advanced risk and prediction modelling would certainly give competing Market Makers an edge over one another to offer better prices and turn a greater profit while still winning good trades.
Using this swap flow has some other non-trivial benefits for users. Firstly, by grouping trades by block, frontrunning traders becomes nonsensical, as all traders in the swap get the same price.
Furthermore, for a good majority of trades in normal market conditions, this liquidity strategy should totally neutralise effective slippage for the bulk of users.
There are however some tradeoffs which we must accept to achieve this. Namely, this protocol can not give users certainty about the ultimate outcome of their swap ahead of time. Until all order updates are in, a final slippage/pricing calculation can not be made. This is exacerbated in multi-swap trade routes.
However, with the development of risk models and prediction models displayed on trade estimation tools on user front ends, it will be relatively straightforward to inform the users about the likely outcome of their trades given the intended size, current market state, and historical data. This is also true on existing DEXes where MEV significantly alters the predicted outcome by just looking at the pool state alone.
On top of this, if a pool ever becomes very imbalanced because of large trades in one direction in a short window of time, users who are relying on the JIT model for accurate pricing might end up suffering. This is because all of the Market Makers would have been cleaned out on one side, and large amounts of passive liquidity are not generally expected to be prevalent on JIT AMMs to mitigate this problem. Market Makers also have to wait longer to rebalance a portfolio than normal AMMs, as there is an additional lag to confirm deposits and process withdrawals than other on-chain AMMs. That being said, rebalancing wouldn't take any longer than on a typical centralised exchange.
This could be mitigated again by displaying a warning to users when generating quotes if the front-end detects a current imbalance or significant deviation in the relevant pools from index prices. Better yet, automated systems can be implemented which delay the execution of swaps until the system has been rebalanced.
The TVL of the pools in a JIT AMM can not be compared to a typical liquidity pool, as the TVL of a pool actually represents as much as half of the maximum practical trade size - a kind of capital efficiency that pushes at the extremes of what is possible. If all LPs are executing an active strategy, a pool with popular assets that has a TVL of $10m could in theory tolerate a trade batch of up to around $3.5m - $4m in one direction with very little deviation (<0.2%) from global index pricing in most cases (depending on the trade pair and global liquidity state across all markets, which you can look up here: cryptosor.info). This kind of capital efficiency can not be replicated effectively on any normal AMM. This price impact estimation is based on observing typical instantaneous liquidity on major pairs using tools such as
However, it is not possible to have greater than 100% capital efficiency. Large deposits that exceed or heavily exhaust the available liquidity in the pool change the underlying game theory, and incentivise the Market Makers to collude rather than compete. If Market Makers know that they can’t fill the order, and also know that the other Market Makers can’t fill the order, Market Makers stand to gain much more if they all shift their orders away from the market price to effectively buy the incoming deposit at a fraction of the global market price.
This isn’t too different to what happens when liquidity pools on other AMMs accept huge deposits with non linear slippage, where exceeding the effective liquidity of the pool progressively degrades the effective price. However, because the Market Makers on the JIT AMM have time to respond to incoming deposits, there is greater room for exploitation. It only makes sense for the Market Makers to play this new game if liquidity on one side will definitely be exhausted in a given trade, but the consequences for the trader in this case are no worse than if they had used a typical AMM dominated by MEV strategies.
Another potential feature that would help avoid exhausting liquidity pools and incentivising predatory LP behaviour is to break up extremely large swaps automatically. By splitting large deposits into chunks and executing them over time, arbitrageurs and Market Makers would have more time to handle the trade. This is similar to how most OTC desks handle large orders on the backend in any case. The depositor should theoretically get similar prices as if they had used an OTC desk if this deposit splitting feature is implemented effectively. At this stage, we don’t plan to implement this feature early on, but if proven to be important in the wild, a protocol upgrade can occur.
The Chainflip AMM protocol is an implementation of a potentially new class of AMM called a “Just In Time AMM” (JIT AMM), which is a decentralised method of getting users close to market prices at all times in spite of the unique challenges faced by a multichain AMM like Chainflip. It is also a way to give free trade flow to market makers who can integrate the AMM into their existing flow sources.