One of the killer features of smart-contract enabled blockchain is Decentralized Finance which has a variety of applications, including exchanging (or swapping) tokens one for another in a decentralized, trustless way.
To enable this swap mechanism, a protocol creates a “liquidity pool” which contains deposits for 2 tokens / cryptocurrencies (sometimes more) and uses these reserves to process the swaps.
Behind the scene, the math that allows this is the use of invariants: “An invariant function is a total function on S that takes the same value before and after execution of the loop body”.
One such function is the constant product function. With X the amount of token A in a pool, and Y the amount of token B in that same pool we get the following:
X * Y = K
The main point here is that no matter the amount of tokens being swapped, the multiplication of the amount of token A and token B owned by the pool should always be equal to K.
Let’s see a quick example: a user wants to swap 10 token A and get a certain amount of tokens B in return. Let’s assume for simplicity that there are 100 token A in the pool and 100 token B in the pool.
Considering that K should not change, this gives us the following:
// First compute K K = 100 * 100 = 10000 // we are swapping 10 token A for token B // and K should not change after this transformation // so how much token B should we get? We need to compute the new pool balance of token B after this swap // We'll write the change in supply of token B with the name delta_b K = 10000 = (X + 10) * (Y + delta_b) (100 + 10) * (100 + delta_b) = 10000 100 + delta_b = 10000 / (100 + 10) 100 + delta_b = 10000 / 110 delta_b = 10000 / 110 - 100 delta_b = -9.090909
We can see here that to satisfy the invariant K = X * Y after the swap, the supply of token B in the pool must diminish by 9.09. This means that the user will get around 9.09 units of token B in exchange for his 10 token A. Pretty simple, right?
The intent behind this constant product formula is to allow swapping from one token to another, but it also makes it expensive to bring the pool out of balance.
The beauty of it is that this formula also enables us to price tokens: if we were to consider the absence of slippage, then we can say that the price of token A, quoted in token B, is pool_amount_token_b / pool_amount_token_a.
Let’s see what the price is like in our example, and how much slippage this operation entailed:
// From the initial condition of 100 tokens on each side: price_x_init = pool_amount_token_b / pool_amount_token_a price_x_init = 100 / 100 price_x_init = 1 // now let's check our situation after the swap price_x_final = (100 - 9.09) / (100 + 10) price_x_final = 90.91 / 110 price_x_final = 0.82 // We can now calculate the slippage: slippage = price_x_final / price_x_init - 1.0 slippage = 0.82 / 1.0 - 1.0 slippage = -0.18
As expected since the amount of token B in the pool has fallen while the amount of token A has risen, the price of token A has decreased.
This swap has therefore had an impact of 18% of the price of X, so quite high slippage! This pool had quite a low supply so such a high slippage is to be expected. Usually there are also protocol fees to consider, as protocols reward people to deposit their tokens in the pool, so it’s important to keep an eye out for slippage and fees.