From 31bc00bf81e080f644855c7fd44e73ede6c36a3a Mon Sep 17 00:00:00 2001 From: RM Date: Wed, 25 Sep 2024 15:16:21 +0800 Subject: [PATCH] Add ethereum Equilibria --- src/api/stats/ethereum/getEquilibriaApys.js | 95 +++++++++++++++++++++ src/api/stats/ethereum/index.js | 2 + src/data/ethereum/convexPools.json | 19 ----- src/data/ethereum/pendlePools.json | 31 +++++++ 4 files changed, 128 insertions(+), 19 deletions(-) create mode 100644 src/api/stats/ethereum/getEquilibriaApys.js diff --git a/src/api/stats/ethereum/getEquilibriaApys.js b/src/api/stats/ethereum/getEquilibriaApys.js new file mode 100644 index 000000000..d45d26766 --- /dev/null +++ b/src/api/stats/ethereum/getEquilibriaApys.js @@ -0,0 +1,95 @@ +import { ETH_CHAIN_ID as chainId } from '../../../constants'; +import { fetchContract } from '../../rpc/client'; +import BigNumber from 'bignumber.js'; +import { fetchPrice } from '../../../utils/fetchPrice'; +import { parseAbi } from 'viem'; +import { getPendleApys } from '../common/getPendleBaseApys'; +import pools from '../../../data/ethereum/pendlePools.json'; +import { getApyBreakdown } from '../common/getApyBreakdownNew'; + +export async function getEquilibriaApys() { + const eqbPools = pools.filter(p => p.eqbGauge); + const eqbApys = await getPoolApys(chainId, eqbPools); + let { tradingApys, pendleApys } = await getPendleApys(chainId, pools); + return getApyBreakdown( + pools.map((p, i) => ({ + vaultId: p.name.replace('pendle-', 'pendle-eqb-'), + vault: eqbApys[p.address] || pendleApys[i], + trading: tradingApys[p.address.toLowerCase()], + })) + ); +} + +const PENDLE = '0x808507121B80c02388fAd14726482e061B8da827'; +const equilibriaAbi = parseAbi([ + 'function totalSupply() view returns (uint256)', + 'function rewards(address token) view returns (uint periodFinish, uint rewardRate)', + 'function expiry() view returns (uint)', +]); + +const getPoolApys = async (chainId, pools) => { + const apys = {}; + const totalSupplyCalls = [], + expiryCalls = [], + extraRewardInfo = [], + extraRewardsCalls = []; + pools.forEach(pool => { + expiryCalls.push(fetchContract(pool.address, equilibriaAbi, chainId).read.expiry()); + const rewardPool = fetchContract(pool.eqbGauge, equilibriaAbi, chainId); + totalSupplyCalls.push(rewardPool.read.totalSupply()); + extraRewardInfo.push({ pool: pool.name, token: PENDLE, oracle: 'tokens', oracleId: 'PENDLE' }); + extraRewardsCalls.push(rewardPool.read.rewards([PENDLE])); + pool.rewards?.forEach(extra => { + extraRewardInfo.push({ + pool: pool.name, + token: extra.token, + oracle: extra.oracle ?? 'tokens', + oracleId: extra.oracleId, + }); + extraRewardsCalls.push(rewardPool.read.rewards([extra.token])); + }); + }); + + const res = await Promise.all([ + Promise.all(totalSupplyCalls), + Promise.all(extraRewardsCalls), + Promise.all(expiryCalls), + ]); + + const poolInfo = res[0].map((_, i) => ({ + totalSupply: new BigNumber(res[0][i]), + expiry: new BigNumber(res[2][i]), + })); + const extras = extraRewardInfo.map((_, i) => ({ + ...extraRewardInfo[i], + rewardRate: new BigNumber(res[1][i]['1']), + periodFinish: new BigNumber(res[1][i]['0']), + })); + + for (let i = 0; i < pools.length; i++) { + const pool = pools[i]; + const info = poolInfo[i]; + + if (info.expiry < Date.now() / 1000) { + apys.push(new BigNumber(0)); + continue; + } + + const lpPrice = await fetchPrice({ oracle: 'lps', id: pool.name }); + const totalStakedInUsd = info.totalSupply.times(lpPrice).div('1e18'); + let yearlyRewardsInUsd = new BigNumber(0); + + for (const extra of extras.filter(e => e.pool === pool.name)) { + const price = await fetchPrice({ oracle: extra.oracle, id: extra.oracleId }); + if (extra.periodFinish < Date.now() / 1000) continue; + const extraRewardsInUsd = extra.rewardRate.times(31536000).times(price).div('1e18'); + yearlyRewardsInUsd = yearlyRewardsInUsd.plus(extraRewardsInUsd); + // console.log(pool.name, extra.oracleId, extraRewardsInUsd.div(totalStakedInUsd).valueOf()); + } + const apy = yearlyRewardsInUsd.div(totalStakedInUsd); + apys[pool.address] = apy; + + // console.log(pool.name, apy.valueOf(), yearlyRewardsInUsd.valueOf(), totalStakedInUsd.valueOf()); + } + return apys; +}; diff --git a/src/api/stats/ethereum/index.js b/src/api/stats/ethereum/index.js index 3c82c4764..d909db1f7 100644 --- a/src/api/stats/ethereum/index.js +++ b/src/api/stats/ethereum/index.js @@ -24,6 +24,7 @@ const { getbeQIApy } = require('./getbeQIApy'); const { getFxApys } = require('./getFxApys'); const { getPenpieApys } = require('./getPenpieApys'); const { getSkyApy } = require('./getSkyApy'); +const { getEquilibriaApys } = require('./getEquilibriaApys'); const getApys = [ getAcrossApys, @@ -48,6 +49,7 @@ const getApys = [ getVerseLpApys, getGammaApy, getPenpieApys, + getEquilibriaApys, getETHCompoundV3Apys, getEthSiloApys, getSkyApy, diff --git a/src/data/ethereum/convexPools.json b/src/data/ethereum/convexPools.json index 78696226d..fdcd2ec91 100644 --- a/src/data/ethereum/convexPools.json +++ b/src/data/ethereum/convexPools.json @@ -1688,25 +1688,6 @@ } ] }, - { - "name": "convex-frax", - "pool": "0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B", - "token": "0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B", - "rewardPool": "0xB900EF131301B307dB5eFcbed9DBb50A3e209B2e", - "tokens": [ - { - "oracle": "tokens", - "oracleId": "FRAX", - "decimals": "1e18" - }, - { - "basePool": "convex-3pool", - "oracle": "lps", - "oracleId": "convex-3pool", - "decimals": "1e18" - } - ] - }, { "name": "convex-fraxusdc", "pool": "0xDcEF968d416a41Cdac0ED8702fAC8128A64241A2", diff --git a/src/data/ethereum/pendlePools.json b/src/data/ethereum/pendlePools.json index ec9d4af4e..620aab77c 100644 --- a/src/data/ethereum/pendlePools.json +++ b/src/data/ethereum/pendlePools.json @@ -1,7 +1,38 @@ [ + { + "name": "pendle-solvbtc.bbn-26dec24", + "address": "0xeb4d3057738b9ed930f451be473c1ccc42988384", + "eqbGauge": "0x415d74E397168DA2d51360C82f8fbb16709C2fFF", + "oracle": "tokens", + "oracleId": "WBTC", + "decimals": "1e8", + "chainId": 1, + "beefyFee": 0.095 + }, + { + "name": "pendle-unibtc-26dec24", + "address": "0x40deae18c3ce932fdd5df1f44b54d8cf3902787b", + "eqbGauge": "0x126156B0D38149EDc01Eb2581F8c5d8506140920", + "oracle": "tokens", + "oracleId": "WBTC", + "decimals": "1e8", + "chainId": 1, + "beefyFee": 0.095 + }, + { + "name": "pendle-lbtc-26dec24", + "address": "0xCaE62858DB831272A03768f5844cbe1B40bB381f", + "eqbGauge": "0x08cef7aF62CDC92246515a81E87cC7DA633cC8B6", + "oracle": "tokens", + "oracleId": "WBTC", + "decimals": "1e8", + "chainId": 1, + "beefyFee": 0.095 + }, { "name": "pendle-ebtc-26dec24", "address": "0x36d3ca43ae7939645c306e26603ce16e39a89192", + "eqbGauge": "0xb9245b221A48a2e4843473E663b41BFE7a2E6c6f", "oracle": "tokens", "oracleId": "WBTC", "decimals": "1e8",