DEX, AMM, and Strange Behaviour of Exchange Rates Explained in 5 Minutes

You might have noticed that when you exchange funds at Quipuswap, Uniswap, Pancake Swap and other DEX, the more the amount, the worse the rate. Why is this happening and can developers do anything about it?
Let’s take a look at how DEX operate, the principles of automatic market-making (AMM), and popular formulae to calculate the rate in a liquidity pool.
DEX and CEX: What’s the Difference?
Exchanges must gather liquidity in one place and automatically match opposing orders while calculating the market price of a trading pair. For that purpose, centralised exchanges (CEX) use an order book. It stores active limited orders like “I’ll sell 10 tez for $7 each” and “I’ll buy 50 tez for $6 each.”
- Alice buys 100 tez with the market price of $7.
- The exchange executes the transaction at the expense of the most profitable order, i.e. selling 10 tez for $7.
- The order’s liquidity is insufficient to close the deal.
- The exchange takes the next best thing, such as selling 200 tez for $7.10 each.
- Alice gets 100 tez at the average price of $7.09.
- The market price increases to $7.10.
This logic is built in the exchange core. Aside from sorting the orders, it checks the balances of traders, stores the history of transactions, and sends data to the trading interface.
Exchange cores are efficient but relatively big: an open-source implementation is about 330 kB, while commercial options like LSEG Millenium Exchange start at 2 MB. Meanwhile, the maximum volume of a Tezos smart contract is 32 kB, and 24 kB on Ethereum, so the core just can’t fit into a smart contract. That’s why DEX use another method to store liquidity and match orders, which is called AMM, or automatic market-making.
How AMM Works on DEXs
Just like CEX, DEX must store liquidity, match orders, and calculate the exchange rate. Storing each byte on a blockchain costs money: in Tezos, for example, storing 1 kB costs 0.25 tez. That’s why DEXs don’t record each order in a book but pool them all together. In fact, it’s two big orders to buy and sell. Therefore, a DEX executes orders at the expense of the pool.
As there is no order book, DEXs calculate the price from formulae, with X × Y = K (aka “constant product market maker”) being the most popular. X and Y stand for the number of tokens in the pool, and K is a constant. The value of K changes only when someone deposits or withdraws funds from the pool. K remains the same in the case of tokens’ exchange.
Trading with AMM works like this:
- There are 100 tez (X) and 700 kUSD (Y) in the pool. K is therefore 70 000, and the exchange rate is 1:7.
- Bob buys 10 tez for kUSD.
- АММ calculates how many kUSD are to be taken from Bob to retain K:
(100 − 10) × (700 + А) = 70 000
63 000 + 90А = 70 000
90А = 7000
А = 77.7 - Bob pays 77.7 kUSD and gets 10 tez.
- The pair’s exchange rate increases to $7.77.
The more tokens there are in the liquidity pool, the less the rate changes during the exchange. Still, it always does.
Can АММ Be More Efficient?
It can, but not for all use cases. Thus, exchanging stablecoins works better with X + Y = K.
- There are 100 uUSD and 700 kUSD in the pool, K equals 800.
- Bob buys 10 uUSD for kUSD.
- АММ calculates the price with the retention of K:
(100 − 10) + (700 + А) = 800
790 + A = 800
A = 10 - Bob sells 10 kUSD and buys 10 uUSD.
- The rate remains 1:1.
Developers and mathematicians have devised dozens of formulae for AMM. For example, that’s what a dynamic search for a weighted price with a built-in oracle looks like:
Complex formulae solve one problem but create another one. E.g., AMM for small transactions does not work well for big ones. An algorithm for concentrating liquidity around the existing price ties down its dynamics, and will be profitable for traders and unfavourable for liquidity providers. For that reason, most DEX devs remain faithful to the good old X × Y = K.
Subscribe and never miss updates from the world of Tezos:
- Telegram channel
- Twitter in Russian and Ukrainian
- Twitter in English
- YouTube channel
- hub at ForkLog