-
Notifications
You must be signed in to change notification settings - Fork 826
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add blend pool yields * scale apr to percentage * specify pools to load to reduce rpc usage and filter for single asset with highest apr amongst pools * add pool id to poolMeta --------- Co-authored-by: Ryang-21 <[email protected]>
- Loading branch information
Showing
3 changed files
with
252 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
const { | ||
Pool, | ||
BackstopToken, | ||
Backstop, | ||
FixedMath, | ||
} = require('@blend-capital/blend-sdk'); | ||
const { getPrices, keepFinite, formatChain } = require('../utils'); | ||
|
||
const BACKSTOP_ID = 'CAO3AGAMZVRMHITL36EJ2VZQWKYRPWMQAPDQD5YEOF3GIF7T44U4JAL3'; | ||
const BLND_ID = 'CD25MNVTZDL4Y3XBCPCJXGXATV5WUHHOWMYFF4YBEGU5FCPGMYTVG5JY'; | ||
const BLEND_POOLS = [ | ||
'CDVQVKOY2YSXS2IC7KN6MNASSHPAO7UN2UR2ON4OI2SKMFJNVAMDX6DP', | ||
'CBP7NO6F7FRDHSOFQBT2L2UWYIZ2PU76JKVRYAQTG3KZSQLYAOKIF2WB', | ||
]; | ||
const NETWORK = { | ||
rpc: 'https://soroban-rpc.creit.tech/', | ||
passphrase: 'Public Global Stellar Network ; September 2015', | ||
}; | ||
|
||
const getApy = async (poolId, backstop) => { | ||
const pool = await Pool.load(NETWORK, poolId); | ||
// Skip pools that have been admin frozen - Pool is very likely to be broken | ||
if (pool.config.status === 4) return []; | ||
const prices = await getPrices(pool.config.reserveList, 'stellar'); | ||
let pools = []; | ||
for (const reserve of pool.reserves.values()) { | ||
const price = prices.pricesByAddress[reserve.assetId.toLowerCase()]; | ||
if (price) { | ||
let supplyEmissionsPerAsset = reserve.emissionsPerYearPerSuppliedAsset(); | ||
let borrowEmissionsPerAsset = reserve.emissionsPerYearPerBorrowedAsset(); | ||
let supplyEmissionsAPR = undefined; | ||
let borrowEmissionsAPR = undefined; | ||
// The backstop token is an 80/20 weighted lp token of blnd and usdc respectively | ||
// (Calculated using balancer spot equation) | ||
// @TODO replace with coingecko price after listing | ||
const usdcPerBlnd = | ||
FixedMath.toFloat(backstop.backstopToken.usdc, 7) / | ||
0.2 / | ||
(FixedMath.toFloat(backstop.backstopToken.blnd, 7) / 0.8); | ||
if (supplyEmissionsPerAsset > 0) { | ||
supplyEmissionsAPR = (supplyEmissionsPerAsset * usdcPerBlnd) / price; | ||
} | ||
if (borrowEmissionsPerAsset > 0) { | ||
borrowEmissionsAPR = (borrowEmissionsPerAsset * usdcPerBlnd) / price; | ||
} | ||
// Estimate borrow APY compoumded daily | ||
const borrowApy = (1 + reserve.borrowApr / 365) ** 365 - 1; | ||
let totalSupply = reserve.totalSupplyFloat() * price; | ||
let totalBorrow = reserve.totalLiabilitiesFloat() * price; | ||
|
||
const url = `https://mainnet.blend.capital/dashboard/?poolId=${poolId}`; | ||
|
||
pools.push({ | ||
pool: `${reserve.assetId}-stellar`.toLowerCase(), | ||
chain: formatChain('stellar'), | ||
project: 'blend-pools', | ||
symbol: reserve.tokenMetadata.symbol, | ||
tvlUsd: totalSupply - totalBorrow, | ||
// Supply is kept as APR to prevent overestimation of APY | ||
apyBase: reserve.supplyApr * 100, | ||
apyReward: supplyEmissionsAPR * 100, | ||
underlyingTokens: [reserve.assetId], | ||
rewardTokens: borrowEmissionsAPR || supplyEmissionsAPR ? [BLND_ID] : [], | ||
totalSupplyUsd: totalSupply, | ||
totalBorrowUsd: totalBorrow, | ||
apyBaseBorrow: borrowApy * 100, | ||
apyRewardBorrow: borrowEmissionsAPR * 100, | ||
ltv: totalBorrow / totalSupply, | ||
poolMeta: `Pool ID: ${pool.id}`, | ||
url, | ||
}); | ||
} | ||
} | ||
return pools; | ||
}; | ||
|
||
const apy = async () => { | ||
let backstop = await Backstop.load(NETWORK, BACKSTOP_ID); | ||
let pools = []; | ||
|
||
for (const poolId of BLEND_POOLS) { | ||
let poolApys = await getApy(poolId, backstop); | ||
for (const poolApy of poolApys) { | ||
if (poolApy) { | ||
let index = pools.findIndex((pool) => pool.pool == poolApy.pool); | ||
if (index !== -1) { | ||
if (poolApy.apyReward > pools[index].apyReward) { | ||
pools[index] = poolApy; | ||
} | ||
} else { | ||
pools.push(poolApy); | ||
} | ||
} | ||
} | ||
} | ||
return pools; | ||
}; | ||
|
||
module.exports = { | ||
apy, | ||
}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters