The joys of pricing Curve LP tokens

Matt Naus
Coinmonks
10 min readApr 12, 2022

--

One of the projects I am working on is Yearner.fi, a simple PWA app that aims to make it easy to track investments on the Yearn platform. One of the challenges I recently had to deal with, is reporting gains for Yearn vaults that take Curve LP tokens as investable assets.

When we try to determine the gains of an investment in a Yearn vault, we need to determine how much the value of an investor’s vault tokens has increased over a certain period of time (this can be for the entire investment period, or any other arbitrary period).

Fortunately for us, the smart contract code for each Yearn vault has a function named “pricePerShare”. As the name suggests, this function returns the price of a single vault token. However, the price is denominated in the vault’s underlying asset. This is no problem for vaults that accept regular crypto assets such as ETH, USDC or DAI since we can easily determine the price for these assets in USD or EUR and as such, express the price-per-share in any currency.

The same does not apply for vaults that take Curve LP tokens as the investable assets though. Curve LP tokens are not traded on major exchanges, hence getting price data for these tokens is more complicated compared to getting price data for crypto assets like ETH, USDC or DAI.

Curve LP tokens?

Curve is a Decentralized Exchange, originally designed to provide liquidity for stable coins. Curve’s main purpose is to make it easy and cheap to exchange one stable coin into another. For example, you will find pools that have two or more stable coins pegged to the same fiat currency. When you provide liquidity into one of these pools, you will receive Curve pool tokens in return, which entitle you to a portion of the trading fees in that pool.

The relationship between Curve and Yearn

Some Yearn vaults will let you deposit the above mentioned Curve pool tokens. A yield farming strategy will then be deployed to turn those Curve pool tokens into more Curve pool tokens. Exactly how Yearn accomplishes this is beyond the scope is this article (for more info regarding yield farming strategies, please have a look here), but it surely is magical!

Determining the value of Curve LP tokens

As we already determined, getting price data for Curve LP tokens is not straightforward, since these tokens are not traded on typical crypto exchanges. So we can’t simply go to CoinGecko and look up the price of these tokens.

We need to take a slightly different approach. If we can determine the total value of all assets deposited in the Curve pool, and determine the number of outstanding pool tokens, we can then determine the value of a single token by dividing the total value of the pool by the number of outstanding tokens.

Let’s look at an example to illustrate the above. I’ll be using the Curve tricrypto pool to illustrate the process. This pool contains three different crypto assets:

  1. USDT
  2. wBTC
  3. ETH

Each Curve pool has two separate smart contracts associated with it: a pool contract which facilitates the trading between assets in the pool and a token contract which issues pool tokens to those who provide liquidity (ie deposit assets) in the Curve pool.

Step 1: determine the value of the entire Curve pool

For this first step, we will need to take a closer look at the pool contract. Curve provides all the relevant data for each Curve pool on their website. When we open up the Curve page for the tricrypto pool, and scroll all the way to the bottom, we see that Curve provides Etherscan links for both the pool and token contracts.

When we click the “Pool contract” link in the footer, we’re taken to the Etherscan page for this contract. Amongst a ton useful data related to smart contracts and Ethereum wallets, transactions, etc Etherscan allows us to interact directly with parts of the smart contract. To get access to the smart contracts “read” functions (functions that only return data, but don’t change any blockchain data), we click the “Contract” button, followed by the “Read contract” button as shown in the image below.

Assets in the Curve pool

We’ll first want to know exactly which assets are in the pool. Specifically, we’ll want to know their smart contract addresses, so we can retrieve data for these assets through Etherscan.

The function we’ll use to retrieve the assets smart contract addresses is “coins”.

The “coins” function takes one argument/parameter, defined as i (which stands for index). Typically, these indexes start at 0, so to get the first asset in this Curve pool, we enter “0” as the parameter and click the “Query” button. The function will then return the smart contract address for the first asset; in our example that would be 0xD51a44d3FaE010294C616388b506AcdA1bfAAE46.

We can now click on the returned smart contract address which will open up a new browser tab with the Etherscan page for this smart contract. As you will see, the address is for the smart contract for USDT (Tether).

Next, we want to know exactly how much of this asset, Tether in this case, is located inside the Curve pool. To that end, we will interact with a “read” function named “balances”.

The “balances” function takes a single argument/parameter named address. In our example, this will be the smart contract address of the Curve pool. When we enter said address and click “Query”, the function will return a value that corresponds with the number of Tether tokens in the Curve tricrypto pool.

More about the “balances” (or “balanceOf”) function

The smart contract for USDT (Tether) is a so-called ERC20 token, which is a type of smart contract that follows a certain specification. Part of this specification is the “balances” function which allows us to figure out how much of the token is being held by a certain address (please note that this address can either be another smart contract or a “regular”, or Externally Owned Account, address). Unfortunately, we can not simply take the number returned by the “balances” function and assume this is the exact number of USDT tokens within the Curve pool. To get from the number returned by the function to the correct number we will need to determine where to place the decimal point. When looking over the “read” functions for the USDT contract, we’ll see another function named “decimals” which tells where to place the decimal point. In our example, the “decimals” function shows us the number “6”. Which means we can now take number returned by the “balances” function and move the decimal point 6 places to the left: 282231824397814 (as returned by the “balances” function) then becomes 282,231,824.397814.

So we now know that, at the time the screenshot was taken, the Curve tricrypto pool held 282,231,824.397814 (282.23 million) USDT tokens.

So far, so good. All that’s left is to determine the USD value of those tokens. Since we know USDT is a stable coin pegged to the USD, we could switch into lazy mode and simply assume 1 USDT = 1 USD. That’s one way to go, and you’d be right most of the time. However, there are no guarantees to whether or not USDT will always remain said peg. Therefor, to be sure, it is always best to check the USD value for the crypto asset on a major exchange or crypto price tracker. Using CoinGecko, we determine that, at the time of writing this article, 1 USDT is indeed 1.00 USD. Therefor, we now know that the USDT portion of the Curve tricrypto pool is worth a whopping $282,231,824.40 ($282.23 million).

We can follow the same process for the two remaining assets in the Curve pool: wBTC and wETH.

Back at the Etherscan page for the Curve pool smart contract, we again call the “coins” function, this time with the argument “1” which will return the smart contract address for Wrapped BTC (wBTC).

We then discover that the tricrypto pool holds a total of 7130.56588602 wBTC tokens (please note that the wBTC token contract uses a slightly different ERC20 version and as a result the balance function is called “balanceOf” instead of “balances”). At the time of writing, the wBTC price, as per CoinGecko, is $39,937.82. Multiplying 7130.56588602 by $39,937.82 equals $284,779,256.85 ($284.78 million) which is the total USD value of all the wBTC tokens in the Curve tricrypto pool.

That leaves us with the third and final asset in the pool; wETH. We again call the “coins” function in the Curve pool smart contract, this time with the argument “2”. We can then determine the total number of wETH tokens inside the Curve tricrypto pool which, at the time of writing, stands at 94745.353549728495212711 tokens. CoinGecko tells us that currently 1 wETH is worth $2,993.27. That bring us to a total USD value for all the wETH tokens in the Curve tricrypto pool of $283,598,424.42 ($283.60 million).

The total value of the Curve tricrypto pool

Now that we have the USD values of all three of the assets in the tricrypto pool, we get the total USD value of the pool by simply adding up the values of the individual assets:$282,231,824.40 + $284,779,256.85 + $283,598,424.42 = $850,609,505.67.

Step 2: determine the total number of issued pool tokens

Let’s briefly revisit the end goal: we are trying to determine the USD value of an individual Curve tricrypto pool token. We get there by dividing the USD value of the entire pool by the number of issued pool tokens. We have the former, now let’s get the latter.

Going back to the Curve page for the tricrypto pool, we click the link in the footer labeled “Token contract”. This will bring up another Etherscan page, this time for the smart contract that handles issuance and balances of the pool token for the tricrypto pool (these are the tokens you receive when depositing assets into the Curve pool).

We navigate to the contracts “read” function and look for a function named “totalSupply”. This function tells us the total number of issued pool tokens.

In our example, the total number of issued tokens equals 569975.96 (remember that we have to move the decimal point 18 places for this specific contract).

The pool’s token price, in USD

Alright. We now have the USD value of the entire pool and we have the total number of issued tokens.

As stated earlier, we divide the pool’s value in USD by the number of issued tokens to get to the value of a single token:

$850,609,505.67 / 569975.96 = $1,492.36

Hence, at the time of writing this article, the USD value of a single Curve tricrypto pool token equals $1,492.36.

Using the pool token value to determine gains in USD

When we try to figure out the gains for an investment in one of Yearn’s vaults, we use the smart contract’s function “pricePerShare” to determine the share price at two different points in time.

Since we also know how many Yearn vault tokens a specific investor held at both points in time, we can simply determine the value of their total investment at both points in time.

As we already established, since the “pricePerShare” function tells us the price denominated in the vault’s underlying asset, in our case Curve tricrypto pool tokens, this isn’t exactly helpful when we’d like to know the gains for an investment in fiat like USD or EUR.

But, since we know the fiat value of the underlying asset, ie the Curve tricrypto pool token, we can easily figure out the gains denominated in USD (or EUR or any other currency).

Let’s look at one final example: on the 1st of January I deposited 100 Curve tricrypto pool tokens into a Yearn vault and received Yearn vault tokens in return. On the 1st of February, I see that my Yearn vault tokens are now worth 102 Curve tricrypto pool tokens instead of the initial 100 I deposited into the vault. In other words, I have a (unrealized) gain of 2 Curve tricrypto pool tokens.

Since we know that 1 tricrypto pool token is worth $1,492.36, we also know that I have a (unrealized) gain of 2 x $1,492.36 = $2,984.72.

There we have it. Pricing Curve’s LP tokens like a pro, to determine the USD value of gains for an investment in a Yearn vault.

Join Coinmonks Telegram Channel and Youtube Channel learn about crypto trading and investing

Also, Read

--

--

Matt Naus
Coinmonks

Builder of interweb things, traveler of countries, drinker of whisky, co-founder of Groove.cm, DeFi & crypto bull