WorkflowCredmark Logo

Computing LP Fees for Uniswap v2

Fees from Liquidity Providing

Kunlun Yang

2023/02/21

As a veteran DeFi protocol, Uniswap v2 did a great deal to introduce the world to the idea of incentivized liquidity provisioning on decentralized exchanges. Liquidity in this context refers to a pair of tokens that are added to a pool so users can swap one of those tokens for the other.

While Uniswap v3 has overtaken much of v2’s market share, v2 remains active. It is still active on Uniswap and was forked to create SushiSwap and other decentralized exchanges (DEXes). Liquidity providers (LPs) still like v2 pools because of their simplicity. Some tokens only have v2-style pools.

LPs are rewarded for providing liquidity. Swaps generate fees that are shared pro rata amongst the LPs. Unfortunately, these fees are simply added to the LP’s position (which changes as tokens are swapped). This is called “impermanent loss.” The LP’s withdrawable amount changes with the price in the pool. which is only realized during withdrawal. Hence, the fees for V2 are not directly separatable. LPs may want to distinguish between the two in order to track their performance, or they may need to report them separately to a tax authority.

In this blog post, we propose a method for computing an LP’s fees.

The Lifecycle of a v2 LP Position

  1. The LP deposits tokens.
  2. The LP receives newly-minted LP tokens. The number of LP tokens is determined by the ratio between the newly added liquidity and the current pool’s liquidity.
  3. For every transaction, 0.25-0.30% of the trade value is given to the LPs of the pool, pro rata. This fee, however, is not set aside. It is added to the LPs’ liquidity.
  4. When LPs redeem their LP tokens, they receive a portion of the pool proportional to the LP tokens in existence at that time.

The Calculation of Fees

v2 is a constant product market maker (CPMM). It uses the product L of the amount of two tokens as the invariant for exchange. L is also a measure of liquidity.

For a v2 pool with two tokens, a pool of reserve (X , Y) has a total liquidity of

(1) The pool’s price ratio is also related to the reserve (X , Y)

(2) When adding liquidity, the added token (x , y) is approximately, if not exactly, in proportion to the pool’s reserve (X , Y) at a specific block number. The approximation is due to the fact that a swap transaction that changes the reserve can take place in the same block as a transaction to add liquidity.

(3) The deposit tokens represents the below amount of liquidity L in the pool for the LP.

(4) The LP can withdraw tokens in the below amount based on the liquidity L added earlier, and the current ratio. The difference between the values, calculated using the current prices, in (x₁ , y₁) and (x , y) is the impermanent loss. We need to note that the liquidity for the LP is not tracked by the pool; instead, we obtain it by (4).

(5) The amount (x₁ , y₁) does not count when the fee is calculated. The amount the LP receives depends on the number of LP tokens redeemed.

Remember that when depositing tokens, the LP receives a number of new LP tokens proportional to the existing liquidity in the pool.

which is equivalent to...

(6) We combine (7) with (3) to take into account the possibility of the pool’s reserve changing in the block in which the liquidity is added. At this point we resolve the ambiguity (approximation) in (3) and select the minimum values for x and y. This gives us the number of LP tokens sent back to the LP.

(7) When redeeming tokens, the LP gets a fraction of the reserve which is determined by the ratio of LP tokens redeemed to the total number of LP tokens. This amount is inclusive of the transaction fees.

(8) If we then exclude the value that would have been withdrawn without a fee (see impermanent loss calculation (5), we are left with the fee itself.

Example

Let’s consider the case below.

  • pool 0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc of USDC-WETH.
  • User 0x18196A32F99bD5feeAfd6bD6b55a63A0EeEf23a6 made 5 deposits and 1 withdrawal in full. We have a transaction balance table for the LP tokens.

The table below shows the LP tokens being minted and sent to the user, and finally the user redeeming the LP tokens.

Each row represents a transaction for which we can calculate the following fields:

  • token0_lp / token1_lp: the amount of USDC and WETH available to withdraw using formula (8) from the total balance of LP tokens belonging to the user.
  • in_out_amount0 / in_out_amount1: the amount of USDC and WETH in the current transaction.
  • token0_lp_current / token1_lp_current: the amount of USDC and WETH that is available to withdraw (excluding fee) using formulas (4) to obtain liquidity with token0_lp, and token1_lp from the previous row, and formula (5) which takes into account the change in token prices, which is reflected in the pool’s token ratio.
  • token0_fee / token1_fee: we apply formula (9) to the above result. This is the fee accumulated between the block numbers in the previous row and the current row.
    • token0_fee = token0_lp - in_out_amount0 - token0_lp_current
    • token1_fee = token1_lp - in_out_amount1 - token1_lp_current

Using this method, we only need to fetch LP token balances to derive information about the tokens added to the pool. We can therefore avoid fetching more detailed transaction data about these underlying tokens. We want to do this for two reasons:

  1. LP tokens can be swapped among users, likely close to a fair price that is inclusive of the fee. There is no funding token transaction for a user who buys an LP token. In our method, we count the fee for the buyer of the LP tokens from the time of receipt.
  2. The funding/redeeming transactions can be confused with swap transactions. Locating only the transactions for LP token simplifies the data preparation.

The result shows that we can restore the actual amount of funding tokens in close approximation.

  • Row 1: 51.00296534 / 0.04110695973 closely match with 51.000288 / 0.04110911 https://etherscan.io/tx/0x04bc2b59ebec879a6b9b93be11dcf9707e1fae389639ca15227cdcc9f75f7634
  • Row 2: 47.283594 / 0.03903517202 exactly match with https://etherscan.io/tx/0x2411f4a563db5a3c737f03bc29371ab3d6c79c68d174d73bd7e912c81f2455dc
  • Row 3: 50 / 0.04133739832 exactly match with https://etherscan.io/tx/0xc5093125f5417c52de95ad268f22f54d404295b08b17e5089100c916ee9b2b4d
  • Row 4: 45 / 0.03713664447 exactly match with https://etherscan.io/tx/0xbcd49c3006e544aa5c0b1e9df53a827ae9e739109c92f98957a5902e83eb9bfc
  • Row 5: 99.99994258 / 0.07826888671 closely matches with 100 / 0.0782688416 https://etherscan.io/tx/0xdbad8b3233cdeaeff7e79e18a15c6931d4d22afda016e44e287538d86fe67bd6
  • Row 6: -297.2393642 / -0.2343857018 exactly matches with https://etherscan.io/tx/0xb308f679cfb5d6e5918ad4091a5403676c0909aedc897b23b8a37de52b64df77

The total fee for this LP is the sum of fees from all block ranges, USDC 0.428541381 and WETH 0.00034724257, for a total investment of $600 worth of USDC-WETH.

Summary

In this blog post, we described our method to calculate the current fee due a Uniswap v2 LP –including an LP who bought LP tokens from another party – at any point in time. We do this without requiring information about the original token deposits.

This output can be generated by running the model uniswap-v2.lp-fee-history by calling the script below:

credmark-dev run uniswap-v2.lp-fee-history -i '{"pool": "0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc", "lp": "0x18196A32F99bD5feeAfd6bD6b55a63A0EeEf23a6"}' -j -b 16495331

The last row is added by the model in order to show the block number at which the model ran. It is not a transaction record.

About Credmark

Credmark runs a financial modeling platform powered by reliable on-chain data. We curate and manages DeFi data making it available via API and the Snowflake Marketplace around the globe and across industries.

Our community of quants, developers, and modelers actively build models for the DeFi community by leveraging our data API and tools. Join the growing community and together we will advance the next-generation financial system.

copy to clipboard

Sign up for our newsletter for the latest product updates, partnerships, and more.

Ready to get started?

Sign up for our free Token API

Get the latest news

Footer

Credmark logo
DiscordDiscord iconTwitterTelegramTelegram iconYoutubeYouTube iconGitHub

© 2023 Credmark Labs, Inc. All rights reserved.

Products

  • All Products
  • Token API
  • Portfolio API
  • DeFi API
  • Raw Data

Documentation

  • Token API Reference
  • Portfolio API Reference
  • DeFi API Reference
  • Transformation Reference
  • Framework Reference

Resources

  • FAQ
  • Blog
  • Reports
  • Media

About

  • Careers
  • About us
  • Community

Support

  • Status
  • Contact us