# Part 1 — The Evolution of Decentralized Exchanges

--

This is the first installment in a two part series exploring the evolution of Decentralized Exchanges. The first part covers the mechanics of constant product and concentrated liquidity Decentralized Exchanges. The second part focuses on Carbon and the innovation it provides to this changing landscape.

# Introduction

Today we want to do a deep dive on the topic of concentrated liquidity (Uniswap V3) and get an understanding of the mechanics behind this liquidity provisioning method. In order to do that we need to look at the motivation for concentrated liquidity and what brought us here. We will start with a brief overview of Constant Product Automated Market Makers.

# Starter: Constant Product

The early implementations of Decentralized exchanges all use a CPAMM (constant product automated market making) pricing scheme. Under this scheme a liquidity pair is created from two tokens ( e.g. `X`

and `Y`

) and arranged using smart contracts such that liquidity providers (LPs) need to contribute tokens `X`

and `Y`

. The ratio of `X/Y`

or `Y/X`

is the implicit marginal price of token `X`

measured in token `Y`

and token `Y`

measured in token `X`

respectively. If token `X`

is a USD stable coin token such as `USDC`

and token `Y`

is another token (we will call this token `RSK`

for this example), assuming a pool contains `6 USDC`

and `2 RSK`

tokens results in:

`X/Y = 6 USDC/2 RSK = 3 USDC/RSK`

`Y/X = 2 RSK/6 USDC = .33 RSK/USDC`

The above exchange rates are equivalent but express using a different base value (numeraire).

All swaps under a CPAMM is governed by the constant product function (`X * Y = K`

). Following our previous example with `6 USDC`

and `2 RSK`

tokens and plugging this into our function, our `K`

value is equal to `12`

.

In practice, what this means is that anyone trying to trade in this pool by adding `USDC`

and removing `RSK`

tokens or the opposite (adding `RSK`

and removing `USDC`

) must abide by the constant product formula such that the constant `K`

is always maintained. A few trading examples are shown below that illustrates this behavior:

`Start: 6 USDC and 2 RSK, K = 12`

`Trade 1: Remove 3 USDC, Add 2 RSK`

`Result: 3 USDC and 4 RSK, K = 12`

`Start: 3 USDC and 4 RSK, K = 12`

`Trade 2: Remove 1 USDC, Add 2 RSK`

`Result: 2 USDC and 6 RSK, K = 12`

`Start: 2 USDC and 6 RSK, K = 12`

`Trade 3: Add 4 USDC, remove 4 RSK`

`Result: 6 USDC and 2 RSK, K = 12`

Some key observations about the above:

- The token that is being traded out becomes more expensive and this is intuitive because it is becoming scarcer. This can be seen with the initial state before trade one which had a marginal price of
`6 USDC / 2 RSK = 3 USDC/RSK`

but later after trade two, the new marginal price is equivalent to`2 USDC / 6 RSK = .33 USDC/RSK`

. Meaning that every`RSK`

token that gets traded in, returns less`USDC`

tokens. If the above continues, the`USDC/RSK`

rate will continue to decrease while at the same time the quantity of`USDC`

tokens diminishes. An important property of CPAMM is that liquidity pools can never be 100% depleted of either token. This means that liquidity exists across the entire price range zero to infinity. - The trades that are made can be reversed and therefore return the liquidity pool to its initial token quantities and exchange rates. This can be seen with trade number three which reverses the previous two trades and returns the liquidity pool to its original state. This property of constant product AMMs is what we call symmetrical liquidity as the buying and selling of tokens happen on the same bonding curve and is governed by the CPAMM function. In stark contrast, Carbon allows for asymmetrical liquidity such that you have two distinct bonding curves that are used for selling each asset.
- In reality, trading fees are collected when a trade is made and all of it (or a portion) is returned to the LP. For our example, we have opted to neglect trading fees in order to make the examples easier to follow.

From the above, we can see that the property of deploying liquidity across the entire price range (0 and infinity) allows for liquidity to exist at every price point and while this is useful, it might also not be optimal for certain use cases. Mainly, this applies for trading pairs where the assets are “liked” and trade for the majority of time between a very close exchange rate (little to no volatility). These “liked” assets such as stable coin pairs (`USDC/DAI, DAI/USDT`

) and liquid derivatives for staking tokens (`ETH/stETH, ETH/rETH`

) fall under this category.

# First Evolution: Concentrated Liquidity

The need for allocating liquidity within a custom price range arose from the observation that the vast majority of liquidity in constant product pools went unutilized. For example, the Uniswap V2 `DAI/USDC`

pair utilizes ~0.50% of the total available capital for trading between $0.99 and $1.011. Another way to view this is that 99.5% of the liquidity went unutilized. A profit motivated LP might want to provide his liquidity in a tight range knowing that most trades occur between certain price points and therefore earn a higher amount of trading fees.

A large innovation that led to concentrated liquidity was being able to slice the price range between 0 and infinity into small evenly distributed ticks. From an LP perspective, each position (an LP can have multiple positions) in a Uniswap V3 liquidity pair is its own price range. Each price range can have an amount of tokens contributed by LPs and is finite as the reserves can run out.

A price range is represented by a tick(s) which defines a lower and upper boundary. Each tick in a trading pair has an index that corresponds to a certain price. We can use a numbered horizontal line with evenly spaced out intervals (tick indexes) to have a visual representation of this system:

When visualizing a non infinite price curve, we arrive at a curve whose boundaries terminate on each axis. In such a curve, it is possible to deplete all of token `Y`

as we move from point `a`

to `b`

. Similarly, it is possible to deplete all of token `X`

as we move from point `b`

to point `a`

. In either scenario, we can be left entirely with a single token and at this point the curve (represents a price range) is no longer active.

Once the liquidity at an interval is consumed, the next adjacent tick becomes active. An LP whose price range resides in a non active tick does not have their liquidity utilized and therefore does not earn fees. If the price in the future retraces, the liquidity becomes active again and LPs in range start earning fees.

Any liquidity position whose range is contributing to the newly active tick starts earning fees. It is important to note that if a trade crosses a tick boundary, this will increase the cost of such a transaction.

An LP can allocate his capital across multiple ticks and therefore multiple price curves. It is possible for each tick to have different liquidity depth based on LP contributions

Even though there are multiple price curves for a trading pair representing different price ranges, when trading against a trading pair they are all aggregated together. A trader therefore has access to use all the overlapping price curves available at a specific price point when trading against the pool.

From a trader perspective, having liquidity concentrated results in a better outcome for their trades. This doesn’t take into account just in time liquidity providers that might also swoop in to fill an order at the detriment (they earn less in fees) of current LPs and benefit of the trader in the current tick. One can conclude that capital can be more efficiently allocated if it can be adjusted to be provided at certain price points via liquidity concentration.

It is important to understand liquidity provisioning in Uniswap V3 as later on it will be used as a comparison between Carbon. Depending on the price range where liquidity is contributed, an LP might have to provide either one or both tokens in the trading pair.

The first scenario in which the price range overlaps the current price for the trading pair means that an LP will need to provide both tokens. In this scenario, if the current price falls in the midpoint of your price range then contributing liquidity is similar to a Uniswap V2 pool. An LP will have to provide an equal value of both tokens to the Uniswap V3 pool.

An example is the following:

`Current Price = $20`

`Price Range = $18-$22`

The above example shows that the current price of `$20`

is the midpoint of the `$18-$22`

range and `$2`

away from either boundary.

If the current price falls in the price range but is not the midpoint then an LP will still have to supply both tokens but not in equal value.

An example is the following

`Current Price = $19`

`Price Range = $18-$22`

The above example shows that the current price of `$19`

is `$1`

away from the `$18`

boundary and `$3`

away from the `$22`

boundary.

If the current price falls outside the price range then an LP will only have to supply a single token. Assume that a liquidity pool has `6 USDC`

and `2 RSK`

tokens for a `K`

value of `12`

(`X * Y = K`

). The current marginal price of `RSK`

is `3 USDC/RSK`

`2 RSK * 6 USDC = 12`

`6 USDC/2 RSK = 3 USDC/RSK`

An LP might decide to provide some USDC liquidity in the range of `0.33–1.33 USDC/RSK`

. This means that this is lower than the current price of `3 USDC/RSK`

and in order for the liquidity to be in range, the price of `RSK`

needs to drop. This means that this would required an addition of `RSK`

tokens and a removal of `USDC`

from the pool:

`Start: 2 RSK * 6 USDC = 12`

`Swap: Add 1 RSK, Remove 2 USDC`

`Result: 3 RSK * 4 USDC = 12`

`Marginal Price: 4 USDC / 3 RSK = 1.33 USDC/RSK`

`Start: 2 RSK * 6 USDC = 12`

`Swap: Add 4 RSK, Remove 4 USDC`

`Result: 6 RSK * 2 USDC = 12`

`Marginal Price: 2 USDC / 6 RSK = .33 USDC/RSK`

As the price of `RSK`

drops to `1.33 USDC/RSK`

, the `USDC`

that we provided within this range is slowly converted to `RSK`

until our `USDC`

is depleted once the price goes down below `.33 USDC/RSK`

. If the price of `RSK`

increases and retraces, then our `RSK`

tokens will slowly get converted to `USDC`

until all our `RSK`

is swapped.

The example of providing single sided liquidity at a higher price range than the current price is up to the reader.

When it comes to concentrated liquidity, a few observations can be made:

- The token of higher value always gets swapped for the token of lesser value. Depending on the concentration of liquidity this could mean concentrated impermanent loss.
- If you are no longer in range, then you are no longer earning any trading fees. An LP might be required to withdraw their liquidity and recreate their position in order to be in range again. This incurs extra cost to the LP and is costly to automate.
- Trades are reversible if the price retraces and from an LP perspective would require constant monitoring in order to remove liquidity once your order is filled.

# Conclusion

Now that we have a foundational understanding of constant product and concentrated liquidity AMMs the next step is to explore the innovation that Carbon brings to this landscape. In the second part of this series we are looking to do an in depth deep dive into Carbon and the mechanics behind it.

## Additional Resources

- Visit us on carbondefi.xyz
- Read the litepaper, whitepaper, and patent filing
- View and simulate strategies using the Carbon simulator, Binder, and Python module.
- Follow Carbon on Twitter
- Subscribe to the Carbon Medium
- Join the Carbon community on Discord
- Participate in Carbon Governance

**Carbon. A decentralized protocol for asymmetric liquidity and trading.**