This document contains the formulas used to calculate the APY for Pendle markets.
In this document, we takes the market `0x107a2e3cd2bb9a32b9ee2e4d51143149f8367eba` on mainnet as an example.
[TOC]
# **Variables**
| name | Description |
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| $market$ | [0x107a2e3cd2bb9a32b9ee2e4d51143149f8367eba](https://etherscan.io/address/0x107a2e3cd2bb9a32b9ee2e4d51143149f8367eba) |
| $sy$ | [0xC4ed348c56223C5953939e932E315F9d72Cd83fF](https://etherscan.io/address/0xC4ed348c56223C5953939e932E315F9d72Cd83fF) |
| $lpPriceUsd$ | price of the lp token in terms of USD |
| $syPriceUsd$ | price of the sy token in terms of USD |
| $pendlePriceUSD$ | price of the Pendle token in terms of USD |
| $totalVotedLastEpoch$ | total of vePendle voted for the pool in the last epoch |
| $duration$ | the interval that we use to calculate the APY. For example, $duration=7$ means we calculate the APY based on data of the last 7 days. In our system, we use 7 days as the default duration! |
| $syIndex$ | the current index of the SY token, can be taken from [exchangeRate function](https://etherscan.io/address/0xC4ed348c56223C5953939e932E315F9d72Cd83fF#readContract#F9) of the sy contract |
| $prevSyIndex$ | the $syIndex$ at $duration$ days ago. |
| $yearsToExpiry$ | the number of years until the expiry of the market. |
| $daysToExpiry$ | the number of days until the expiry of the market. |
# Underlying APY
$underlyingApy = underlyingInterestApy + underlyingRewardApr$
$underlyingApy$ comes in two part, below are how to calculate each of them
## **UnderlyingInterestApy**
$interestMultiple = \frac{syIndex}{prevSyIndex}$
$underlyingInterestApy = interestMultiple^{\frac{365}{days}} - 1$
- Explanation:
- $UnderlyingInterestApy$ estimates the current APY for the **interest** of the underlying protocol of the SY token. **Interest** = returns in the underlying asset, and it’s auto-compounding by default.
- In this formula, we are taking the historical APY for the last 7 days, to extrapolate into the returns for the year.
## **UnderlyingRewardApr**
- For each reward token:
- $prevRewardIndex =$ $rewardIndex$ at $duration$ days ago
- $dailyRewardPerSy = \frac{rewardIndex - prevRewardIndex}{days}$
- $dailyRewardYield = dailyRewardPerSy * \frac{rewardPrice}{syPrice}$
- $tokenRewardApr = dailyRewardYield \times 365$
- $underlyingRewardApr = \sum tokenRewardApr$
- Explanation:
- $underlyingRewardApr$ estimates the current APr for the **rewards** of the underlying protocol of the SY token. **Rewards** = returns in the reward token, and it’s not auto-compounding by default.
- In this formula, we are taking the historical rewards rate for the last 7 days, to extrapolate into the returns for the year.
- Each reward token has its own reward rate, so they have their own APR. We sum them up to get the total APR for all reward tokens.
# **impliedAPY**
$apy = e^{lnImpliedYield} - 1$
- $lnImpliedYield$ can be read from [readState](https://etherscan.io/address/0x107a2e3cd2bb9a32b9ee2e4d51143149f8367eba#readContract#F18) function of the market contract. Do remember to scale it by 1e18.
# **SwapFeeApy & voterApr**
Define:
- `explicitSwapFee` is total explicit swap fee (in terms of SY) gotten from the last `durations` days
- `implicitSwapFee` is total implicit swap fee (in terms of SY) gotten from the last `duration` days
## SwapFeeApy
$swapFeeApy$ is the APY that LP holders will get from the swap fees of the pool.
$poolValue = lpPriceUsd * totalSupply$
$swapFeeForLpHolder = explicitSwapFee * 20\% + implicitSwapFee$
$swapFeeRateForLpHolder = \frac{swapFeeForLpHolder * syPriceUsd}{poolValue}$
$swapFeeApy = (1 + swapFeeRateForLpHolder)^\frac{{365}}{durations} - 1$
- Explanation:
- LP Holder will received 20% from explicit swap fee, and 100% from the implicit swap fee
- $swapFeeRateForLpHolder$ is the rate of swap fee that LP holder will get in terms of USD, then we interpolate it to get the $swapFeeApy$
## VoterApr
$VoterApr$ is the APR that vePendle voters will get from voting for the pool.
$swapFeeForVoter = explicitSwapFee * 80\%$
$swapFeeRateForVoter = \frac{swapFeeForVoter \ \times \ syPriceUsd}{PendlePriceUSD \ \times \ totalVotedLastEpoch}$
$voterApr = swapFeeRateForVoter \times \frac{365}{durationInDays}$
- Explanation:
- Voter will received 80% from explicit swap fee of the pool
# longYieldApy
$interestReturns = (1+underlyingInterestApy)^{yearsToExpiry} - 1$
$rewardsReturns = underlyingRewardApy * yearsToExpiry$
$ytReturns = interestReturns + rewardsReturns$
$ytReturnsAfterFee = holdYtReturns \times 97\%$
$longYieldApy=\frac{ytReturnsAfterFee}{ytPriceInAsset}^{\frac{1}{yearsToExpiry}}-1$
- Explanation:
- $interestReturns$:
- interest returns, in terms of accounting asset, for holding 1 YT from now until expiry
- $rewardsReturns$:
- rewards returns, in terms of accounting asset, for holding 1 YT from now until expiry
- $ytReturnsAfterFee$:
- we charge 3% on YT yield, so we need to scale it down by 97%
- $longYieldApy$:
- This is the APY if we buy YT today, and hold it all the way to expiry, assuming the underlying APY will stay the same. This can be negative (if the returns from YT is less than YT price)
- Starting with $ytPriceInAsset$, we got back $ytReturnsWithFee$ after $yearsToExpiry$.Then we just need to scale it to one year to get the APY
# effectiveImpliedApy
Effective Implied APY is the APY based on the actual rate that the user used to swap.
To calculate $effectiveImpliedApy$, we need to get the $ptExchangeRate$: how much PT you can get from 1 underlying.
There are 3 type of swaps:
- PT <-> any token except YT
- YT <-> any token except PT
- PT <-> YT
Each of them has different way to calculate the $ptExchangeRate$
## PT <-> any token
- $underlying$: input/output token amount in terms of the underlying token
- $ptAmount$: PT input/output amount
$$ptExchangeRate = \frac{ptAmount}{underlying}$$
## YT <-> any token
- $ytAmount$: YT intput/output amount
$$ptExchangeRate = \frac{1}{1 - \frac{underlying}{ytAmount}}$$
## PT <-> YT
$$ptExchangeRate = 1 + \frac{ptAmount}{ytAmount}$$
From $ptExchangeRate$ you can calculate the effectiveImpliedApy as follow:
$$effectiveImpliedApy = ptExchangeRate^{\frac{365}{daysToExpiry}} - 1$$