General-purpose AMMs and Options

Why general-purpose AMMs aren’t suited for options trading

Eri
Pods
Published in
16 min readJan 20, 2021

--

TL;DR

  • Options pricing depends on various factors (time to maturity and implied volatility, to name a few) and, in most cases, they tend to zero.
  • The price discovery mechanism of general-purpose AMMs (like Uniswap) normally relies on the volume of trades, assuming that in a liquid market the assets should be priced correctly by market forces. However, DeFi options markets are still nascent by the time of this post and options may not be updated as often, leaving the price outdated. Potentially generating a substantial impermanent loss for the liquidity providers of the option pool.
  • This post explores the math behind Uniswap v1 and concludes that using it as a venue of exchange for options tokens may not be the most adequate.

General-purpose AMM and Impermanent Loss

A general-purpose AMM, such as Uniswap v1 and v2, is one of the most important building blocks in DeFi. Its model is capable of combining price discovery and bootstrap any market in the world. It allows a market for even the most illiquid assets to exist and grow.

Its design carefully combines incentives to encourage different players to participate as sellers, buyers, and liquidity providers. In fact, the liquidity provider is a player that performs an important role in the system. It feels like an abstraction of the traditional market maker. The reason behind this similarity is that the AMM doesn’t require constant book management and orders filled but allows users to trade against their funds. Some may argue that those are not the same users nor perform the same business. But at the end of the day, both players (liquidity providers in Uniswap and market makers in traditional finance) bootstrap a market.

Currently, the liquidity provider has to add equal amounts in both sides of the pool as liquidity and in return expects to collect the fees of all the trading that happened in the pool and get their principal amount invested back.

Some users in DeFi have been reading or understanding the activity of providing liquidity as a “passive income investment” where one provides assets, holds the dollar amount of the funds, and receives a positive sum of fees for the initial investment. Although this might be true for pools of stable assets (DAI:USDC for instance) it is not entirely correct for pools with volatile assets (USDC:ETH for instance) in certain scenarios. There is a phenomenon known as impermanent loss.

Impermanent loss (IL) is the expression we use to refer to the negative return of adding liquidity to Uniswap on a volatile pair when compared to just holding both assets. It describes a situation where the profitability of the liquidity provider that was seeking passive income is negatively impacted. Impermanent loss is nonexistent or small in the scenario where the price scenario between the tokens added is back to the same ratio they were when the liquidity was initially added. But, in case the price conditions are different than what initially was, the withdrawal can be lower than the total amount provided when comparing to the scenario of just holding the assets.

That means that impermanent loss is only realized if the liquidity provider (LP) removes the liquidity in a price scenario different from the one initially used. If it doesn’t remove it and wait for a more opportunistic moment to withdraw, the loss won’t happen (impermanent loss). As a comparison, on traditional finance, one could think of this as a “selling a perpetual straddle” position. Perpetual because there is no expiration date on this position and the LP can hold it for as much time as they want.

Short Straddle payoff.

This means that the LP will profit from the fees during the period and not suffer from impermanent loss if, even with volatile markets, it removes liquidity at the same price level that it had when it entered.

Some could argue that they expect that the trading fees will cover their losses. It can happen but only to a certain extent, depending on how far the price is at the moment of the withdraw and how liquid and how many trades happened in the pool during the liquidity provision. So it’s fair to understand that the most profitable combination for liquidity providers is a pool in which the assets are not volatile and there are many trades per day. It is also important to take into consideration that the market defines the pricing of the asset and whenever the pricing of a token in Uniswap diverges from the market's price, arbitrageurs will take advantage of this arbitrage opportunity, trade in Uniswap and help guide Uniswap's prices closer to the token's market price.

TVL, volume of trades and fees generated in USDC:ETH pool in Uniswap source: https://info.uniswap.org/pair/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc

Simulating returns

To analyze returns from the liquidity provision activity on Uniswap v2 one should consider the following variables:

  1. Spot price of the pair in the moment of liquidity provision,
  2. Spot price of the pair in the withdrawal,
  3. Volume of trades in the pool,
  4. The volume of assets in the pool and consequently,
  5. The total fees originated from the trades to be distributed to the LPs

Let’s dig into this exercise starting with the mathematical formulas presented in Pintail's blog post which are essential to understand how the Uniswap's AMM work:

If you want to learn more about Impermanent loss details I recommend this post:
Uniswap: A Good Deal for Liquidity Providers?

Constant Product

The constant_product (k) factor is used as a way to price trades and maintain the balance of the value of both sides of the pool constant. When ignoring fees the factor is calculated as:

Formula 1: 
eth_liquidity_pool * token_liquidity_pool = constant_product

Pricing

Uniswap uses the following pricing formula to define how much each asset from the liquidity pool is valued at for trades:

Formula 2: 
eth_price = token_liquidity_pool / eth_liquidity_pool

Putting the formulas 1 and 2 together, we end up with the following:

Formula 3:
eth_liquidity_pool = sqrt(constant_product / eth_price)
Formula 4:
token_liquidity_pool = sqrt(constant_product * eth_price)

It’s is important to highlight that the product constant should be respected for the pricing of the assets for trades that happen until the moment another LP adds liquidity to the pool. When this happens, the constant_product is updated with the new pool balances and used for the pricing of the following trades. For example:

  • The initial pool starts with 100 ETH and 10,000 DAI. As so, the constant_product (k) = 100 * 10,000 = 1,000,000.
  • If 1 day later, John decided to add liquidity to the pool (and no trades happened in the pool) with 2 ETH and 2,000 DAI, the constant_product will need to be updated as there was an increase on both sides of the liquidity pool. As so, the new constant_product (k) that will be used for pricing the following trades will be: k = (100 + 2) * (10,000 + 2,000) = 102 * 12,000 = 1,224,000.

Considering that Uniswap's AMM requires that liquidity providers add a 50/50 proportion in terms of the value of each token, formula 2 determines that the pricing of the assets depends on the trading amount that happens in each pool. This means that in the case where no trades are happening in the pool (the only activity happening in the pool was liquidity provision), the eth_price would remain the same as at the moment of the creation of the pool. In other words, the price is updated only upon trading activity.

When adding liquidity, the pricing of the assets happen a bit differently from the pricing when wanting to buy 1 asset from the pool as we can see below:

Formula 5:
token_amount_to_provide = eth_amount_provided * (token_liquidity_pool / eth_liquidity_pool)

For example, let's suppose that Rob wants to add liquidity a pair of ETH:DAI to a pool. He wants to add 1 ETH, but how many DAI tokens will he have to provide? The current pool balance is 95 ETH and 10,529.49 DAI. Following the formula 5, he'll have to provide:

token_amount_to_provide = 1 * (10,529 / 95) = 110.87 DAI

After providing liquidity, the new pool balance would be:

  • 95 + 1 ETH = 96 ETH
  • 10,529 DAI + 110.87 DAI = 10,640.36 DAI
  • new k = 96 * 10,640.36 = 1,021,169.85

Liquidity Providers Shares

Another important concept that is essential to understand Uniswap's AMM and the difference between the initial position of tokens when getting in the pool and the exit position of tokens when removing liquidity is the LP tokens.

The LP tokens translate into how much each LP represents from the pool and, consequently, how much each LP will receive from the total fees generated in the pool.

Formula 6: LP tokens for the first liquidity provider
LP_tokens_amount = sqrt(eth_amount_provided * token_amount_provided) - 0.00000000000000001
Formula 7: LP tokens for the following liquidity providers
LP_tokens_amount = min((eth_amount_provided * total_LP_tokens / eth_liquidity_pool),(token_amount_provided * total_LP_tokens / token_liquidity_pool))

Impermanent Loss Scenario

Now that the key concepts were presented, let’s analyze a scenario where impermanent loss is realized by the liquidity provider.

Babi creates an ETH:DAI pool by adding 20k in total liquidity (100 ETH and 10,000 DAI). As the first liquidity provider, she receives a total of 1,000 LP shares, according to the formula 6:

Formula 6: LP tokens for the first liquidity provider
LP_tokens_amount = sqrt(eth_amount_provided * token_amount_provided) - 0.00000000000000001
  • LP_tokens_amount = sqrt (100 * 10,000) — 0.00000000000000001 = 1,000 LP shares

Let’s assume that after the creation of the pool, 9 trades happen as the following — n refers to each period after the pool creation:

Pool Status and Trades until n = 9

Consider the following transaction types:

  1. exact_output_x: when the user wants to buy 1 ETH for whatever price
  2. exact_output_y: when the user wants to buy 1 DAI using whatever amount of ETH
  3. exact_input_x: when the user wants to spend an exact amount of ETH to buy the equivalent in DAI
  4. exact_input_y: when the user wants to spend an exact amount of DAI to buy the equivalent in ETH
Transaction types of each trade.

The product constant (k) of 1,000,000 is the main guide for the pricing mechanism for the trades above. It calculates what should be the impact on each side of the pool so that this trade can happen and still maintain the constant product when ignoring fees. Now let’s calculate what’s the impact on each side of the pool after a trade happens:

Price discovery on transactions happening in the ETH:DAI pool

Let's dig into the trade that happens in n = 1:

  • Initial pool balance = 100 ETH and 10,000 DAI
  • Constant_product = 100 * 10,000 = 1,000,000
  • Type of the trade: exact_output_x → The trader wants to buy exactly 1 ETH (so he will be removing 1 ETH from the eth_liquidity_pool)
  • New eth_liquidity_pool = 100 — 1 = 99 ETH → Now that we have this new ETH pool balance, what is the new DAI pool balance as there will be an influx of DAI tokens in the pool?
  • New DAI_liquidity_pool = constant_product / new eth_pool_balance = 1,000,000 / 99 = 10,101.01
  • From the influx of DAI in the pool, we can assume the following formula:
Formula 8:
eth_price = (DAI_liquidity_pool at the end of n=1 — DAI_liquidity_pool at the previous period) / ETH bought
  • eth_price = (10,101.01–10,000)/1 = 101.01 → So the price the ETH was bought by the trader in the n=1 trade was 101.01.
  • Final pool balance: 99 ETH and 10.101.01 DAI

We can below what were the prices that happened in Uniswap's AMM, considering the constant_product of 1,000,000 and the new pool balances after the trades. We can also visualize the price with the 0.3% fee that is charged for each trade:

ETH pricing in DAI + Fees generated during trades

The final pool overview after the trades happened is:

Final view of the pool after trades happened

Now let’s assume that Tom (user10_Add_1ETH) wants to add 1 ETH in liquidity at the moment n= 10. As the AMM requires that the LPs provide a pair of tokens with the same value on each side, Tom has to provide an amount of DAI that is worth the same as 1 ETH, and this price is taken from the formula 5, presented previously:

Formula 5:
token_amount_to_provide = eth_amount_provided * (token_liquidity_pool / eth_liquidity_pool)

So Tom has to provide, together with 1 ETH:

  • DAI_amount_to_provide = 1 * (10,529 / 95) = 110.87 DAI

As the new liquidity provider got into the pool, the constant_product needs to be updated for the pricing of the following trades until the moment a new LP gets in the pool:

  • new k = 96 * 10,640 = 1,021,170

Right after Tom, 7 other LPs provide liquidity in the pool, following the pricing provided by the AMM from the formula 5, and receive the respective LP shares according to the formula 7 as follows:

Formula 5:
token_amount_to_provide = eth_amount_provided * (token_liquidity_pool / eth_liquidity_pool)
Formula 7: LP tokens for the following liquidity providers
LP_tokens_amount = min((eth_amount_provided * total_LP_tokens / eth_liquidity_pool),(token_amount_provided * total_LP_tokens / token_liquidity_pool))
Liquidity providers' initial position, LP shares and their impact in the pools

Let’s first take into consideration the following given information to facilitate the impermanent loss analysis:

  • Tom's initial position when getting in the pool was: 1 ETH and 110.87 DAI
  • Tom (user10_Add_1ETH) decides to remove their tokens out of the pool at any moment after n = 17
  • Tom’s representativity in the pool is: Tom LP tokens / total_LP_tokens = 10.53/1,284.30 = 0.008199 = 0.82%
  • No additional liquidity providers got in the pool after n = 17, only trades happened
  • As ETH:DAI pool has a big volume of trades, we can consider that Uniswap's pricing mechanism reflects the real pricing in the market as arbitrageurs would be constantly correcting the price by taking advantage of arbitrage opportunities
  • time period (n) stands for each period where the price is updated in the AMM

Let's compare what happens to his funds as price is updated when he holds the assets in his wallet and removes liquidity from the pool:

HODL position
Final position after removing liquidity

Now let's compare what is the difference between each situation above:

Comparative view between HODL x Providing liquidity

Taking the formula of impermanent loss or divergence_loss from Pintail’s blogpost and applying to this case, we have:

Formula 9:
divergence_loss = 2 * sqrt(price_ratio) / (1+price_ratio) — 1

What we can get as a conclusion from the simulation above is that there is indeed a loss when providing liquidity when compared to holding the tokens in the wallet. This happens as the pool balances change and the price of each token changes as it gets updated as trades happen in the pool.

It is important to highlight that the LP provider removes the equivalent of what he represents out of the pool. In this case, Tom removes 0.8% of the current pools at the moment he decided to remove liquidity. As the pool at the moment, Tom wants to remove liquidity might be different from the scenario he got in, his final position differs from his initial position of tokens balance.

This phenomenon can also be observed in the graph below by plotting the price changes:

Impermanent loss along price changes — Source: https://pintail.medium.com/uniswap-a-good-deal-for-liquidity-providers-104c0b6816f2

Fees impact

Uniswap distributes 0.3% of all trades to the LPs according to their participation in the pool. Consequently, the more trades happen in the pool, the more passive income the LPs get. Which is distributed accordingly to the proportion each LP represents of the pool as presented previously.

As we can see, the impermanent loss happens as Uniswap’s AMM functions in a way to maintain the product of the two liquidity pools, which is called constant_product, the same as it was before the trade (excluding fees) — we can say that the AMM is a vintage scale that makes sure both sides weight the same in terms of value (a 50%/50% proportion).

It is important to highlight that the token prices in Uniswap are updated along with the trades that happen in the pools, which relies a lot on the capability of arbitrageurs to find profitable arbitrage opportunities when comparing Uniswap prices to other exchanges. As so, we can say that the pricing of Uniswap’s AMM is defined solely by the trades that happen in the pools.

Although this model may have a really good fit with non-volatile assets and highly voluminous trading pools, it may not be true for all kinds of assets.

What happens to options?

Options pools

In a DeFi option (in this case specifically Pods options) a user has to lock 100% in collateral and mint the option token. The option token represents the right for the buyer and the obligation for the seller. But, since the seller locked the collateral upfront there is not much to be enforced, the smart contract holds the obligation.

After minting the option, a user can choose to sell them or to provide liquidity to the pool. As Uniswap is a decentralized protocol that can have a pool of any pair of assets started by anyone, users could sell the options tokens directly in the Uniswap pool for each series. By doing so, the user is:

a) assuming that the options market for that specific options series is the most liquid it can be and, therefore, the price of the AMM is correct by pure arbitrage forces and represents a fair, updated price.

or

b) arbitrating the pool price, if the pool is mispricing the options and there is an opportunity to close the gap.

Unfortunately, DeFi is only starting and DeFi options are also just starting. This means that not necessarily the DeFi options market is capable of correcting Uniswap’s price at all times. This means that if a pool stays for a long time without trades, there will be a big arbitrage opportunity. While this may the really good for traders it may not be as good for the liquidity providers.

But how would someone know that an option price is mispriced?

Pricing options

There are several models for pricing options in traditional finance and the most widely know is called Black-Scholes.

The Black-Scholes formula is as follows:

where:

Black-Scholes is a mathematical model for pricing an option contract and this model assumes, among other things, that the asset’s volatility remains constant over the option’s life (which is not applicable — especially in crypto). The formula applies only to European options (and to American calls on non-dividend paying assets).

All methods are trying, to some extent, to calculate what is the probability the option will expire in-the-money and if it does, what would that value be at present time. To calculate such theoretical price authors incorporate factors like underlying asset spot price, time to expiration, implied volatility, risk-free rate, and strike price. Those factors also known as greeks have a different impact on the option price.

At expiration

The time to maturity of the option that is also called the option’s time value is also an important factor that affects pricing when using the Black-Scholes model.

The closer the option is from the expiration date, its intrinsic value tends to amplify, which means that if an option is in-the-money closer to its expiration date, the more valuable it is as the probability of the option to be exercised and be profitable is high, which makes the option to be priced more expensively. The same logic happens when the option is out-of-money close to its expiration date: the probability of the option being exercised is low, which means that its value is close to worthlessness (zero). You can see more details about this concept below:

Source: https://www.investopedia.com/articles/optioninvestor/02/021302.asp

At expiration, options prices are either in-the-money or out-of-the-money. Most of the time, options end up out-of-the-money and, therefore, at expiration the options are valued at zero.

This means that if a user providers liquidity to an options pool and they end up out-of-the-money, users could withdraw a bigger proportion of options tokens than ETH. At that time, the options tokens may be valued at zero. Options that they did not “mint” and there is no collateral to withdraw from them. When thinking about the impermanent loss, in this case, we’d have to consider that one of the assets of the pair is worthless by expiration.

What would happen with an option price in Uniswap if it’s not possible to input none of those factors on it’s pricing?

Options trading in General Purpose AMMs

Each trader treats the greeks and formulas as it seems fit. But most of them have some way of calculating the option price that can account for all the factors that impact an option price. Traders would likely find ways to arbitrage open opportunities but liquidity providers ultimately could result in losses for allocating their capital to potential mispriced trades.

For this reason, using a model like Uniswap for pricing options may not be the best alternative for liquidity providers.

In future posts, we’ll explore other possibilities that might be more suited to options.

Before you go

If you enjoy discussing topics like this, make sure you join our discord and share your thoughts with us!

Thank you for reading! 🤓

About Pods

Pods is a decentralized non-custodial options protocol. Users can create options and trade them through an Options AMM on the Ethereum Blockchain. Pods is the easiest way to hedge crypto in DeFi.

We invite you to take the first step in your new mission: start testing the app on app.pods.finance

Join the Pods community

app | website | documentation | blog | twitter | youtube | telegram | discord

--

--