Liquidity Pool Mechanics
How Does A Liquidity Pool Actually Work?
We talked about liquidity pools and their importance to the function of Automated Market Makers on DEXs in this article, but we felt it was important to give you a deep dive into liquidity pool mechanics in its own separate article.
At Pontem, we’re aware that this emerging technology is complicated, and if you’re new to the space it can feel hard to know where to start. If you use our decentralized exchange, Liquidswap, or pretty much any other DEX on the market, you’re going to end up using a liquidity pool at some point. They are super important to the DeFi ecosystem, as they are what make decentralized exchanges competitive with centralized.
But just like any new emerging financial technology, there are risks and you could end up losing most, if not all, of your money. But the good news about liquidity pools is: you can minimize that risk by learning how they operate!
What is a Liquidity Pool?
A liquidity pool is, essentially, a decentralized, peer-to-peer market for a pair of digital assets. When DeFi infrastructure was relatively new, developers needed to tackle the problem of liquid markets for digital assets without a centralized entity providing the market. It needed to be a market that was supplied by the same people using the market.
Say you want to buy an altcoin with your ETH. Where do you go to do that? Normally, a centralized exchange. You deposit or purchase your ETH into a hot wallet whose private key is owned by the exchange. You must put your faith in the exchange to handle your funds correctly, and as we’ve seen with the recent FTX Exchange collapse, those institutions don’t always do that.
With the invention of the liquidity pool, DeFi finally had a way to compete with centralized exchanges. Liquidity pools gave users the ability to exchange two assets, and the opportunity to earn money helping others do that as well.
In a liquidity pool, users of the exchange deposit an asset pair in an equal amount into a pool. This pool is used to provide liquid exchanges to other users who wish to exchange an asset pair. In exchange for providing this service, liquidity pool providers receive a portion of the trading fees relative to how much they provided to the pool, as well as other specialty tokens called liquidity tokens that can be reinvested on the platform.
Why are Liquidity Pools Important to DeFi?
Liquidity pools are important to DeFi because they are the basis for how decentralized exchanges (DEXs) run. In order for DeFi to become a viable alternative to the traditional financial system, one of the fundamental structures it must have is a way for users to exchange different assets. Liquidity pools are the easiest way for DEXs to provide that service for users.
Liquidity pools lock funds in smart contracts, meaning that you can always see where your funds are at a given time. The draw of liquidity pools and DEXs is that they are not owned by a certain entity, you have custody over your own assets the entire time. If you are someone who doesn’t want to trust a centralized institution with your assets, you can trust the smart contracts that show exactly where your money is.
How Liquidity Pools Work
A lot of DEX users don’t really understand the mechanics of liquidity pools. Pontem’s support team keeps getting questions along the lines of, “Why did my swap execute at such a bad price?” or, “Why is the price on Liquidswap different from Binance?”
Most of the questions and frustrations can be avoided if you take the time to dig into the math - which is what we’ll do in this section.
The Constant Product Formula
Typically, a liquidity pool is made up of two different digital assets that are part of a specific trading pair. Some examples of this are APT/WETH, ETH/USDT, and APT/USDT. Built into the smart contract algorithm of the pool is a mathematical formula to carefully regulate the assets’ relative prices. The most commonly used formula is:
Where X is the amount of one asset in the trading pair, Y is the amount of the other asset in the trading pair, and k is a constant. This ensures that the total liquidity in the pool remains constant over the course of each swap, while allowing the price ratio to fluctuate depending on the ratio of the assets in the pool.
We’re gonna throw some algebra your way, so just bear with us here! This formula is responsible for calculating the actual price of a swap. Every swap increases the reserve of one token, and decreases the reserve of the other, but the value of k remains constant over the course of the swap.
With that in mind, we can write a formula to show how the reserves would change. The user who makes the swap adds some amount of token X to the pool (we’ll call this amount ΔX) and receives some Y tokens in return. We’ll call the amount that leaves the pool ΔY. Since k remains constant, we get:
And if we rearrange the formula, we can solve for ΔY and get the change in price using the formula:
Now that we’ve thrown a bunch of letters at you, let’s take a look at a real example so that we can really understand the formula in action.
Starting Liquidity And Price
Say Bob is creating a pool and depositing 400 CARROT and 100 USDT to start. The starting value of k is determined when the pool is created and depends on how much initial liquidity the first provider deposits. We’ll get:
The starting price will be 4 CARROT for 1 USDT. The initial amounts of X and Y determine the starting price, so Bob should be careful to deposit the assets in such ratios as to ensure the desired initial price.
How To Calculate Swap Price
Now imagine that Alice wants to buy some CARROT from the pool and is ready to spend 10 USDT. Remember that the k value must remain 40,000. How many CARROT will she receive? Let’s plug the numbers into the formula:
(100 USDT+10 USDT)*(400-ΔCARROT)= 40,000
ΔCARROT=(400*10)/(100+10)=4000/110=36.3636. Alice will get around 36.36 CARROT in return for her 10 USDT.
Note that when she fills the swap form, she will see the current swap price (4 CARROT per 1 USDT), but the actual price of her swap will be different. Actual swap price: 36.3636/10 = 3.63636 CARROT for 1 USDT. In other words, instead of 0.25 USDT, 1 CARROT is now 0.275 USDT: 0.275/0.25.
The price impact is 10%, which is a lot. That’s because Alice added a lot of USDT to the pool relative to what was already there. It’s crucial to understand that the larger the trade relative to the pool liquidity, the bigger the price adjustment.
What If The Reserves Are Very Low?
The power of the x*y=k formula is that it can accommodate a swap of any size, even when there is little liquidity. The price impact can be very high, though, but it’s not a bad thing. The formula discourages users from making large swaps that unbalance the pool.
For example, imagine there are 400 CARROT and 100 USDT in the pool, and Alice decide to spend 500 USDT buying CARROT.
(100 USDT+500 USDT)*(400-ΔCARROT)= 40,000
Actual swap price: 333.3333/500 = 0.66 CARROT for 1 USDT.
Instead of the initial 0.25 USDT, Alice paid 1.5 USDT for each CARROT! If she didn’t understand how DEX liquidity pools work and didn’t check the reserves, she probably expected to receive 500/0.25=2,000 CARROT. Instead, Alice was in for a nasty surprise.
When Does k Change?
The value of k remains constant only within a single swap’s frame of reference. Within the frame of reference of the whole pool over time, though, k changes constantly, every time liquidity is added or removed from a pool.
- Swapping fees. Most DEXes change between 0.15% and 0.30% on each swap (in addition to the gas fee charged by the blockchain). These fees are the reward for the liquidity providers who deposit funds in the pool and make swaps possible.
Collected fees are added to the pool balance and remain there until a liquidity provider claims them. Whenever a fee is charged, the protocol treats it as a liquidity event, and the value of k changes just a tiny bit.
Calculations get a bit complex here, especially when you swap one token for another, rather than for the blockchain’s native coin (ETH, APT, BNB etc.). Check out the Uniswap documentation for the exact formulas: fees in uncorrelated pools on Liquidswap work the same way.
- Liquidity providers adding funds. When you add liquidity to a pool, you increase the reserves of both tokens. You’ll need to add an equivalent amount of both at the current exchange rate, so that the price will remain the same.
Example: there are 400 CARROT and 100 USDT in reserve, and the price is 0.25 CARROT for 1 USDT. If you want to deposit 100 CARROT, you’ll also need to add 100*0.25=25 USDT. The new k value will be:
You’ll now own 20% of all the liquidity in the pool, so you’ll get 20% of all the fees. If another liquidity provider joins or leaves, your share of the overall reserves will change, and so will your fee reward.
A Real-Life Example From Liquidswap
Once you understand how the formula affects price, you can see certain conditions in the system that don’t make trading favorable. Low liquidity and price are the main ones.
Compare these three APT-USDT pools on Liquidswap. They feature USDT bridged using different protocols: LayerZero, Wormhole, and Celer. The LayerZero USDT pool is the most liquid, with over $30,000 USDT. A 10 APT swap will move the price by 0.38%, which is acceptable.
The Wormhole USDT-APT pool has much shallower liquidity: only $3,700 USDC. Swapping 10 APT will result in a 3% change in price - and it won’t be in your favor. Also, note the price difference: 11.2 USDT for 1 APT in the Wormhole pool and 11.58 USDT in the LayerZero pool.
Finally, the least liquid of the three is the Celer USDT pool, with just 6 USDT in reserves.
Here, the current price is just 0.57 USDT for 1 APT, and swapping 10 APT will move the price by a whopping 94.39%. In such cases, Liquidswap will give you a red warning.
You may think that nobody would accept such a swap. And yet, we’ve had actual cases on Liquidswap where users lost money swapping into low-liquidity pools and then complained about it in the Telegram chat. There’s nothing we can do in such situations: the system works exactly as it’s supposed to. Users simply need to exercise caution.
In this example, the user failed to understand that with x*y=k, there is no such thing as “not enough USDT”. There’s always enough - it’s all about the price impact.
What happens if the DEX price becomes different from the price on centralized exchanges?
Let’s say that CARROT is also listed on a centralized exchange like KuCoin and its price is 0.25 USDT. What will happen now that the DEX price has increased to 0.275 USDT?
Such a discrepancy creates an arbitrage opportunity. Traders will buy CARROT on the CEX for 0.25 USDT, send it to a decentralized wallet, and sell it on the DEX for 0.275 USDT for a quick 10% profit (minus the transfer & exchange fees). This will increase the CARROT reserves in the pool and diminish the reserve of USDT, driving the price towards the external market value.
The same will happen if Bob (the pool creator) miscalculates the initial liquidity and ends up with a starting price that’s different from the external market price. For example, if he deposits just 300 CARROT and 100 USDT, the pool’s initial CARROT price will be 100/300=0.3333… USDT. Arbitrage traders will very quickly notice the opportunity, buy CARROT at 0.25 USDT on KuCoin and sell it into the pool for a profit. The price will go down to the KuCoin level and Bob will experience so-called impermanent loss.
Note that arbitrage traders (and bots) don’t necessarily watch all the pools on all DEXes. If a certain trading pair exists only on a couple of DEXes (such as Celer USDT-APT, for example), and reserves are low, the price can remain detached from the external market for a long time.
While the x*y=k formula works well for most pools, stablecoins pose a challenge because of high slippage. Stablecoins should always trade 1:1, meaning that they should always be the same price. But if someone makes a large swap, especially in a pool with low liquidity, a token’s price can be significantly affected. You can see how this poses a problem when the price of a token should always remain the same.
Along with stablecoins, pairs like BTC/WBTC and ETH/WETH also face a similar problem because their relative prices are correlated. As a solution, Solidly (a DEX on Fantom built by Andre Cronje) introduced a different formula:
x^3*y + x*y^3 = k
Liquidswap adopted the same formula for swaps between correlated assets. It allows us to keep slippage minimal, even for large transactions. You’ll find more details here.
Example: let’s assume that a pool contains 100 USDT and 100 USDC. If the pool uses the x*y=k formula, k=100*100=10,000, and the relative price is 1 USDT for 1 USDC - as it should be for stablecoins. Alice swaps 30 USDT for USDC, the result would be:
ΔUSDC=(100*30)/(100+30)=3000/130=23.077. Alice will get only 23.077 USDC in return for her 30 USDT. This isn’t the result you want to see for a stablecoin pair.
Now let’s see what happens if we use x^3*y + x*y^3 = k.
k=(100^3)*100 + 100*(100^3)=100,000,000+100,000,000=200,000,000 (that’s 200 million).
(100 USDT+30 USDT)^3*(new USDC value)+(100 USDT+30 USDT)*(new USDC value^3)=200,000,000
2,197,000*(new USDC value)+130*(new USDC value^3)=200,000,000
To simplify the equation, let’s write it down as 130x^3+2,197,000x-200,000,000=0.
We will leave the mechanics of solving this cubic equation out - you can refresh your algebra here or use an online calculator.
As you may know, every cubic equation can have up to three real solutions, but out of the three roots in this example the only usable one is 70.39332. That’s how much USDC will be left in the pool after the swap - therefore, Alice received (100-70.39332)=29.60668 USDC.
There’s still some price impact because the swap was large relative to the pool balance, but the result is much closer to the 30 USDT that Alice swapped.
By the way, the swapping fees in correlated pools on Liquidswap is just 0.04% - yet another reason to try Liquidswap on Aptos.
How Liquidity Pools Can Be Dangerous
We’ve already examined the danger of swapping into low-liquidity pools, but there are other risks, too.
Slippage is when an order is executed at a price different from the price at which it was placed. Sometimes, you will place an order for one price, and in the time between placing the order and execution, the price changes due to some other transaction that happens in between. Users who forget to check their slippage settings can incur huge losses.
A live example of this is from Twitter, where user BowTiedPickle told the story of one unlucky user who paid $2,080,468.85 to receive only $0.05 USDT. The user used the KyberSwap aggregation router to exchange 3CRV (DAI/USDC/USDT) LP tokens into USDT and didn’t set their slippage. The 3CRV/SUDC pool that was used ended up only containing about $2 in liquidity and hadn’t been used for 251 days.
2 million 3CRV flood the pool, and remember x*y must always equal the constant k, so the huge imbalance causes the price of the 3CRV to drop drastically and the trade is executed leaving the user with about 5 cents worth of USDC. With the pool being crazy imbalanced, a simple MEV bot was able to come through and restore the balance, netting itself over $2 million in profit.
This is an extreme case, but it just highlights how important it is to understand the formula and how it impacts price.
The second way liquidity pools can be dangerous is impermanent loss (IL), which occurs when the price ratio of the combined assets fluctuates, as they tend to do. If you deposit an asset at a certain price, and the price then decreases, the depositor incurs a loss if they withdraw their funds before the ratio has time to correct the loss.
The loss is called impermanent because until you withdraw your funds, the price ratio could change in your favor and you could end up without a loss at all. But in reality, once you withdraw the funds from a pool, the loss becomes quite permanent.
Tips to Stay Safe in Liquidity Pools
So now that you understand the formula and how it affects price a little better, we want to leave you with a few simple tips to avoid losing a lot of your money in a liquidity pool.
- Don’t use a pool with low liquidity
A pool with low liquidity means the pool generally does not have a high Total Value Locked (TVL), or it has a highly unequal amount of assets. The more liquidity available in a pool, the better the swap price you’ll get, especially with large orders. This is because the x*y=k formula in a large pool does not have to adjust as drastically for trades.
The USDC Wormhole - WETH Wormhole pool has only $23 in reserves - clearly not a pool to swap into! Conversely, the USDC Wormhole - APT liquidity pool has over $1 million locked in it, meaning you can make larger trades without much price impact.
- Don’t execute a large trade in an illiquid pool
If you must use a pool with low liquidity, don’t execute a large trade. Either your order will not execute due to there being too much slippage, or you will end up paying a lot of money for assets barely worth anything. This is a common occurrence in small pools of altcoins.
- Check your slippage!
The very real example we used in this article is a great example for why you should always set your slippage. Most liquidity pools allow you to set a percentage of slippage that you would allow and if any more slippage were to occur, your order will not execute. Making sure to complete this simple step will help you avoid incredibly costly mistakes.
On Liquidswap, maximum slippage is set to 0.50% by default, meaning that a swap will succeed if the execution price differs from the original price accepted by the user by no more than 0.50% in either direction. If the difference is greater, the swap will fail.
You can change the slippage in the settings (the gear icon), but be careful. Setting it too low increases the risk of failure (and you will lose the gas fee), but setting it too high can make you vulnerable to frontrunning bots.
- Turn on the front running protection whenever you swap.
Simply click on the little red lock icon next to the gear icon on Liquidswap and toggle the switch to On. Note that this great feature is available only for Pontem Wallet.
Understanding how DeFi liquidity pools work can mean the difference between successful swapping and losing lots of money. As you study and experiment with Liquidswap, do give Pontem a follow on Twitter, Discord, and Telegram - we have many exciting new features coming!
Pontem is a product studio building foundational dApps and development tools for Aptos using the visionary Move coding language and Move VM. Together with the Aptos team, Pontem is creating an ecosystem for the first billion blockchain users across the globe.
Pontem’s products include:
- Pontem Wallet: the first Aptos wallet to integrate native dApps, now with 250,000+ installs );
- Liquidswap: a DEX with 150,000+ unique users and up to $1M in daily volume;
- ByteBabel: the first Solidity to Move bytecode transpiler;
- Move Code Playground: the first browser code editor for Move, and more.