Understanding how a Constant Product Automated Market Maker works

oliver · April 9, 2024

Constant Product Automated Market Makers are a pretty novel idea of how you can trade assets (like :poop: for :gem: and vice versa). We’ll take a brief look at what they do.

Introduction

Assume there exists assets (Ai)i(A_i)_i. We are wondering how a computer program could facilitate a trustworthy trading infrastructure for these assets.

Classically assets are traded on something akin to a stock-exchange: Traders submit (buy or sell) orders to the exchange. When orders match, the exchange enforces their execution. In this scenario, liquidity is a potential problem: The market price of an asset could be something like the last successfully executed trade, but nobody assures you that you can always buy or sell to anything close to that market price: There needs to be a second party willing to trade.

In practice, this problem is solved by market makers who are very good at pricing assets and at risk management. They make money by accepting all sorts of trade at something slightly worse than the market price, but you have the convenience of getting your orders fulfilled almost instantaneously. Assets however are only attractive for market makers if there is enough supply and demand of those assets in question – otherwise, they might have to hold assets for a very long time, which isn’t their business model (they don’t want to have long positions, they make money on trades).

Liquidity pools are a different approach in decentralised finance. The idea is the following: You have a couple of assets lying around you don’t particularly need. You hand your assets to a trustworthy party, the liquidity pool, who promises that:

  1. You can always withdraw assets that are as valuable as the assets you put it, but they might not be the same amounts per asset.
  2. You will be compensated for this inconvenience.

The liquidity pool then acts as both a trading platform and a market maker. Satisfying the second requirement is easy: Just charge a fee for every trade and reimburse the liquidity provider. The first of course is much harder and more interesting. It depends on the pricing model of the liquidity pool.

The Obvious Scam

You can use liquidity pools to sell :poop: for :gem: like this:

  1. Create 3*10^6 units of an asset :poop: which is to 100% in your possession. It is :poop: and has no value to you.
  2. You create a liquidity pool. You pretend that you value your 3*10^6 units of :poop: at 150 :gem:
  3. As you are the only one who can issue (or create) :poop:, there will be at most 3*10^6 units of :poop: in the liquidity pool. If some poor sucker starts trading, they will have to buy :poop: for :gem: from you.
  4. If you’re satisfied with the amount of :gem: in the pool, you close the pool. You get back whatever :poop: did not sell and all them sweet, sweet :gem:

This is exactly what happened with TruAmpl. The three most important TX are these:

  1. The creator provides the liquidity pool: 3*10^6 TMPL for 150 ETH
  2. Some poor sucker buys 19k TMPL for 1 ETH
  3. Some poor sucker buys 38k TMPL for 2 ETH
  4. The creator removes liquidity: 2.9*10^6 TMPL and 154 ETH get transferred to their wallet.

(Numbers don’t add up perfectly because there were more transactions).

This all happened within 37 minutes. The cost of creating that token was around 0.1 ETH (plus time, plus marketing).

The code of the contract for TruAmpl is charmingly straightforward (i.e., it is as short as possible to keep costs low). However, it does include a lovely comment at the beginning:

We have Eliminated the Fixed target price and introduced floating/balancing price target depending upon the current price of TMPL, so that whenever the price go higher the floating target price shifts itself and tries to manage the risk of fall back thus maintaining quilibrium.

We also have changed the rebase structure in a way such that network participants gets consistent rebase irrespective of price manipulation so anyone can buy at a certain price at his comfort level without fearing of falling price back to $1 which makes it super powerful. Here the price will readjust itself according to formula which relies on supply demand of token and is not pegged to base price of $1. Rebase is between 0.5% to 1% per 0.1$ gain hence it helps to nullify the decrease in demand there by fluctuating the target price and maintaining the gains and liquidity

I think we can safely assume that development time took less than an hour.

How is this different from an IPO?

At a glance, you might wonder how this is different from any other initial price offering (or for that matter, just standing in the street and offering to sell :poop: to whoever might want it at a ridiculously inflated price).

The issue is the price adjustment. For this, we need to get a bit more specific.

Constant Product Automated Market Maker

A possible solution to price two assets A,BA, B might be the following: A potential liquidity provider has lots of AA and BB lying around. They price them in such a way that 1A1A is as valuable as pBpB. He gives the Liquidity Pool multiples of these, i.e., he puts nAnA and npBnpB into the pool. For simplicity say n=1n=1.

Assume these are the only assets in the pool, so we have 11 unit of AA and pp units of BB. Let’s say a trader wants to buy xx units of AA and pay with some BB. How many p(x)p(x) units of BB does he need to provide? A Constant Product Market Maker imposes that the product of the amounts of the two assets in the liquidity pool has to be constant.

In our example, this means that (1x)(p+p(x))=1p, (1-x)\cdot(p+p(x)) = 1\cdot p, so p(x)=px1x.p(x) = p\frac{x}{1-x}. Notice that x/(1x)>1x/(1-x) > -1 if x<1x<1, so for all x<1x<1 this gives a well-defined transaction.

What does our liquidity provider think of this trade? For our liquidity provider, 1A1A is as valuable as pBpB, so when at the start they provided 1A1A and pBpB to the liquidity pool, this was worth 2pB2pB for them. Now the liquidity provider would value the liquidity pool at (in BB) p(1x)+(p+xp1x)=px22x+21x p(1-x) + (p+\frac{xp}{1-x}) = p \frac{x^2-2x+2}{1-x}

Reasonable amounts for xx are anything in (,1)(-\infty, 1) (the trader can’t buy more than 1A1A, because that’s all there is in the pool, but he can sell as much as he wants).

We quickly check that the lowest possible value of x22x+21x\frac{x^2-2x+2}{1-x} on (,1)(-\infty, 1) is 22, which we attain for x=0x=0 – so if any non-zero trade occurs, the liquidity pool becomes more valuable for the liquidity provider.

Trading pools and the above scam

Let’s the AA contained in the liquidity pool is all the AA there exists. Then as long as the liquidity provider provides liquidity, traders know they can sell back xx amount of AA for at least pxpx amount of BB (minus fees, which we can ignore). This makes this scenario much more predictable than a stock IPO where nobody assures that you can sell back your stock to the emitter.

The same process however also limits price corrections. Imagine an IPO for :poop: It would start with an absurd price and maybe some trader would buy it. But if the order book stays somewhat empty, the trader would put a sell order at a somewhat lower price than the IPO – we see a price correction.

In the liquidity pool, this doesn’t happen. If you buy :poop: and think you’ve paid too much for it (because you start to realise it’s :poop:), then you can still sell it at an inflated price back to the liquidity pool for as long as it exists. The price can never get worse than the initial offering, as nobody can buy (or borrow) AA somewhere else to drain the pool of :gem: There is no incentive to open a second liquidity pool of :poop: and :gem: with a more realistic price.

Twitter, Facebook