Borrow Rate
Explanation of the Interest Rate charged to Traders
The GammaPool calculates an interest rate index charged to borrowers that depends on the utilization rate of the GammaPool's funds and the swap fees accrued. The interest rate calculation aims to pay the same yield LPs earn in the CFMM plus a spread, up until an optimal utilization rate of the GammaPool is reached. In addition the interest rate calculation is capped at a maximum rate of 1500% APY.
The formula for the update of this index (accFeeIndex) is as follows
adjCFMM_Yield = CFMM_Yield * (1 + spread)
lastFeeIndex = min{1 + apy1500, max{1 +
adjCFMM_Yield, adjBorrowRate}}
the apy1500 is the 1500% APY equivalent yield for the time period the calculation is run through. The CFMM_Yield is the yield of the CFMM over the time period of the calculation, while the spread is an additional amount added to the CFMM Yield that is based on the utilization rate. The adjBorrowRate is the deannualized floor borrow rate at any time, based on the utilization rate of the GammaPool
Utilization Rate
The utilization rate of the pool is calculated as follows
utilizationRate = (liquidityInvariantBorrowed) / (liquidityInvarantBorrowed + liquidityInvariantInGammaPool)
Liquidity invariant refers to the invariant used by the CFMM (e.g. geometric mean of reserve assets in UniswapV2).
Linear Kinked Rate Model
The linear kinked rate model (AAVE's interest rate model) is used to calculate the floor borrow rate of the GammaPool. It works as follows
When Utilization Rate <= Optimal Utilization Rate
borrowRate = baseRate + utilizationRate * slope1 / optimalUtilRate
When Utilization Rate > Optimal Utilization Rate
utilizationRateDifference = utilizationRate - optimalUtilRate
variableRate = utilizationRateDifference * slope2 / (1 - optimalUtiliRate)
borrowRate = baseRate + slope1 + variableRate
The formula above increases the borrow rate as the utilization rate increases at a constant rate of slope1 up until the optimal utilization rate. Past the optimal utilization rate the borrow rate increases at the significantly faster rate of slope2 as the utilization rate increases.
The base rate is the lowest possible rate of the pool.
Parameters: utilizationRate - how much of the pool’s funds have been borrowed out
optimalUtilRate - rate after which borrow rate increases at slope2 rate.
slope1 - rate at which borrow rate increases when utilizationRate <= optimalUtilRate
slope2 - rate at which borrow rate increases when utilizationRate > optimalUtilRate
baseRate - minimum/starting rate charged by the GammaPool
Before accruing the borrow rate, the rate is deannualized according to how much time has passed in terms of blocks since the last update.
adjBorrowRate = (currentBlockNum - lastBlockNum) * borrowRate / blocksPerYear
CFMM Yield
The CFMM yield is tracked by checking the growth of the liquidity invariant in the GammaPool.
CFMM_Yield = (cfmmInvariant1 / cfmmInvariant0) * (cfmmTotalSupply0 / cfmmTotalSupply1) - 1
In the above formula the cfmmInvariant1 refers to the invariant in the CFMM (e.g. the geometric mean of the reserve assets) in the current update and cfmmInvariant0 refers to the invariant in the cfmm at time previous update.
cfmmTotalSupply1 refers to the total supply of CFMM LP tokens in the current update while cfmmTotalSupply0 is the the total supply of CFMM LP tokens in the previous update.
Leveraged CFMM Yield
The liquidity borrowed out of GammaSwap can be greater than the liquidity in GammaSwap if there is additional liquidity in the underlying AMM. When that happens the GammaSwap platform is leveraged.
Note this is Liquidity not TVL. You can never borrow more liquidity from the pool than the TVL available. All positions in GammaSwap are always fully collateralized. This is to ensure accurate yields in the platform.
Borrowed Liquidity > Liquidity in CFMM
The effects of leverage can leverage the CFMM yield charged to liquidity borrowers in GammaSwap by the leverage factor.
Leverage Factor = BorrowedLiquidity / LiquidityInCFMM
If the leverage factor is substantially large it can have an unrealistic interest rate charged to the borrowers. Say there's only $1 of liquidity left in the AMM and $1 million borrowed in GammaSwap. $1 in fees in the AMM is 100% fee yield but borrowers should not be charged $1M for that.
Deleveveraged CFMM Yield
To avoid an excessively leveraged CFMM fee yield we cap the leverage of the yield according to the following formula
maxLeverage = 1 / (1 - optimalUtilRate)
Therefore when the leverage factor of the cfmmYield is greater than the maxLeverage, we deleverage the cfmmYield and releverage it to the maxLeverage calculated above.
Deleveraged_CFMM_Yield = [(cfmmInvariant1 / cfmmInvariant0) * (cfmmTotalSupply0 / cfmmTotalSupply1) - 1] * (cfmmInvariant0 / cfmmInvariant0 + borrowedInvariant)
In the above formula borrowedInvariant refers to BorrowedLiquidity in the previous formula and cfmmInvariant refers to liquidity in the CFMM. The 0 and 1 index refer to the last and current measure respectively. Therefore the above formula is simply deleveraging the CFMM Yield by the “Leverage Factor”.
We then releverage the yield according to the maxLeverage
Releveraged_CFMM_Yield = Deleveraged_CFMM_Yield * maxLeverage
This process only happens the the utilization rate is greater than the optimal utilization rate, since the optimal utilization rate determines the max leverage factor
Rationale for Deleveraging CFMM Yield
Since different token pairs have different risk characteristics we try to rely mostly on the swap fees as a measure of the adequate yield to compensate for volatility to let market forces determine what should be the proper yield for different token pairs.
The main purpose of deleveraging the platform is as a countermeasure against attack vectors where most of the liquidity is borrowed out of the platform to overstate the CFMM yield.
Spread
A spread is added to the borrow rate that will be charged to liquidity borrowers. The spread is calculated as
spread = BorrowRate * 10
The borrow rate here refers to the borrow rate calculated in the section about the linear kinked rate model. Therefore, this spread depends on the utilization and optimal utilization rate. As the utilization rate increases the spread added to the interest rate charged to liquidtiy borrowers increases.
Final Short Liquidity Rate
Final Short Liquidity Rate
For example, if the rate that will be charged to liquidity borrowers is 10%, that is the CFMM_Yield is 10%, and the spread is 20%, then the final rate calculated is as follows
adjCFMM_Yield = CFMM_Yield * (1 + spread) = 10% * (1 + 20%) = 12%
A spread of 20% means the BorrowRate was 2%. Therefore the final calculation for the interest charged is as follows (assuming a full year passed since the last update and therefore the charge is for a full year)
GammaSwapBorrowRate = min{1 + apy1500, max{adjCFMM_Yield, adjBorrowRate}}
GammaSwapBorrowRate = min{1 + 1500%, max{12%, 2%}}
In reality this numbers are not annualized, instead their numbers corresponding to the period that passed since the last calculation is used. For example
apy1500 = (currentBlock - lastBlockUpdate) * 1500% / blocksPerYear
adjBorrowRate
= (currentBlock - lastBlockUpdate) * BorrowRate / blocksPerYear
Lending/LP Rate
From the formula above, based on the utilization rate we can calculate the lending rate, or yield earned by LPs in Gammaswap, as follows
GammaSwapLendingRate = CFMM_Yield * (1 - utilizationRate) + utilizationRate * GammaSwapBorrowRate
Since whenever the utilization rate is less than the optimal utilization rate, the GammaSwapBorrowRate is usually the CFMM_Yield plus a spread, the GammaSwapLendingRate and GammaSwapBorrowRate tend to be very close to each other.
There may be some substantial deviations whenever there are swap fees in a short period of time that when measured by the GammaPool they exceed the deannualized 1500% APY cap. In those cases the GammaPool may undeperform the AMM.
Also, if the CFMM_Yield is very large, e.g. over 100 APY, a the spread can be substantial since it's added as a percentage of the CFMM_Yield. For example if the spread is 20% and the CFMM_Yield is 200 APY, then the spread is 40 APY, for a total GammaSwapBorrowRate of 240 APY vs a GammaSwapBorrowRate of 200 APY. When the CFMM_Yield is small, e.g. 5 APY, a 20% spread ends up being only an additional 1% point per year.
Interest Rate Index
Since the GammaPool must charge all liquidity borrowers the same rate at any given time, it must keep track of an internal accrued interest rate index.
The interest rate index does not concern itself with the current yield in the CFMM, only with the yield charged to liquidity borrowers, therefore at every update of the GammaPool contract’s state, it uses the lastFeeIndex calculated above to compound with every udpate and update the accrued fee index, which is the internal index of the GammaPool
accFeeIndex = accFeeIndex * lastFeeIndex
The more often the GammaPool’s state is updated the more the interest rate approaches a continuous compounding interest rate.
Loan Accrued Interest Rate Update
The accrued index is then used to update a liquidity loan as follows
loanLiquidity = loanLiquidity * accFeeIndex / loanRateIndex
Each loan keeps a loanRateIndex that is used to measure how much interest has accrued on the loan since the last update. After the update the loanRateIndex is set to the current accFeeIndex to be ready for the next update.
loanRateIndex = accFeeIndex
“loanLiquidity” is the debt in liquidity invariant terms of the liquidity loan. This field keeps track of the initial liquidity debt plus all interest accrued on the loan by compounding with the accFeeIndex.
“loanRateIndex” is the accFeeIndex in the previous update or time the loan was created. After the update the loan’s rateIndex is updated to the current accFeeIndex to be ready for the next update.
Fee Distribution
100% of all CFMM Yield charged to borrowers is paid to the LPs as part of the Supply APY calculation.
20% of the additional yield on top of the CFMM_Yield that is charged to borrowers is paid as protocol revenue to the DAO. This is 2o% of the spread added on top of the CFMM_Yield or 20% of the portion that exceeds the CFMM_Yield whenever the pool's utilization rate is above the optimal utilization rate.
In addition to generating protocol revenue the 20% number serves as a counter measure to attackers of the GammaPool trying to profit from excessively leveraging the CFMM_yield.
Last updated