From e92cffeb90696e45d42d66557d364b6a3698ac26 Mon Sep 17 00:00:00 2001 From: spider-g <8703289+spider-g@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:24:41 -0300 Subject: [PATCH 1/3] APY adapter for avUSD, avBTC and avETH --- src/adaptors/avant-protocol/index.js | 154 +++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/adaptors/avant-protocol/index.js diff --git a/src/adaptors/avant-protocol/index.js b/src/adaptors/avant-protocol/index.js new file mode 100644 index 0000000000..102513c8c2 --- /dev/null +++ b/src/adaptors/avant-protocol/index.js @@ -0,0 +1,154 @@ +const sdk = require('@defillama/sdk') +const axios = require('axios') +const utils = require('../utils') + +// Avalanche tokens + +const avUSD = '0x24dE8771bC5DdB3362Db529Fc3358F2df3A0E346' +const savUSD = '0x06d47F3fb376649c3A9Dafe069B3D6E35572219E' // Staked avUSD (ERC-4626) + +const avBTC = '0xfd2c2A98009d0cBed715882036e43d26C4289053' +const savBTC = '0x649342c6bff544d82DF1B2bA3C93e0C22cDeBa84' // Staked avBTC (ERC-4626) + +// Ethereum tokens + +const avETH = '0x9469470C9878bf3d6d0604831d9A3A366156f7EE' +const savETH = '0xDA06eE2dACF9245Aa80072a4407deBDea0D7e341' // Staked avETH (ERC-4626) +const wETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' + +const abi = { + convertToAssets: { "inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function" }, + totalAssets: { "inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"" ,"type":"uint256"}],"stateMutability":"view","type":"function" }, +} + +const DAY = 86_400 +const SCALE = BigInt(1e18) +const SHARES = BigInt(1e18) + +async function getBlockAtTimestamp(chain, ts) { + const { data } = await axios.get(`https://coins.llama.fi/block/${chain}/${ts}`) + return { block: data.height || data.number, ts: data.timestamp || ts } +} + +async function readShareToAssetRatio(chain, blockNumber, vault) { + const { output } = await sdk.api.abi.call({ + target: vault, + abi: abi.convertToAssets, + params: [SHARES.toString()], + chain, + block: blockNumber, + }) + return BigInt(output) +} + +function ratioToDaily(rNow, rPrev, secondsBigOrNum) { + if (rPrev === 0n || rNow === 0n) return 0 + const qFP = (rNow * SCALE) / rPrev + const q = Number(qFP) / Number(SCALE) + if (!(q > 0) || !isFinite(q)) return 0 + const seconds = Number(secondsBigOrNum) || 1 + const exp = DAY / seconds + return Math.pow(q, exp) - 1 +} + +async function computeApyBase(chain, vault) { + const nowTs = Math.floor(Date.now() / 1e3) + const WEEK = 7 * DAY + + const [{ block: bNow, ts: tNow }, { block: bPast, ts: tPast }] = await Promise.all([ + getBlockAtTimestamp(chain, nowTs), + getBlockAtTimestamp(chain, nowTs - WEEK), + ]) + + const [rNow, rPast] = await Promise.all([ + readShareToAssetRatio(chain, bNow, vault), + readShareToAssetRatio(chain, bPast, vault) + ]) + if (rNow === 0n || rPast === 0n || rNow === rPast) return 0 + + const daily = ratioToDaily(rNow, rPast, Math.max(1, tNow - tPast)) + if (!daily) return 0 + + const aprBase = daily * 365 * 100 + return utils.aprToApy(aprBase, 365) // number +} + +async function getPrice(chain, token, tokenSubstitute) { + async function _getPrice(chain, tokenAddress) { + const priceKey = `${chain}:${tokenAddress}` + const { data } = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + price = data.coins?.[priceKey]?.price ?? 0 + return price + } + const price = await _getPrice(chain, token) + if (price) { + return price + } else if (tokenSubstitute) { + return await _getPrice(chain, tokenSubstitute) + } + return 1 +} + +async function getData(chain, vault, underlying, underlyingSubstitute = undefined) { + const { output: totalAssetsBn } = await sdk.api.abi.call({ + target: vault, + abi: abi.totalAssets, + chain, + }) + + const price = await getPrice(chain, underlying, underlyingSubstitute) + const tvlUsd = (Number(totalAssetsBn) / 1e18) * price + const apyBase = await computeApyBase(chain, vault) + + return { tvlUsd, apyBase } +} + +async function apy() { + const [savUSDData, savBTCData, savETHData] = await Promise.all([ + getData('avax', savUSD, avUSD), + getData('avax', savBTC, avBTC), + getData('ethereum', savETH, avETH, wETH) + ]) + + return [ + { + pool: `${savUSD}-avax`, + chain: 'avax', + project: 'avant-protocol', + symbol: 'savUSD', + tvlUsd: savUSDData.tvlUsd, + apyBase: savUSDData.apyBase, + underlyingTokens: [avUSD], + poolMeta: 'ERC-4626: savUSD → avUSD', + url: 'https://www.avantprotocol.com', + }, + { + pool: `${savBTC}-avax`, + chain: 'avax', + project: 'avant-protocol', + symbol: 'savBTC', + tvlUsd: savBTCData.tvlUsd, + apyBase: savBTCData.apyBase, + underlyingTokens: [avBTC], + poolMeta: 'ERC-4626: savBTC → avBTC', + url: 'https://www.avantprotocol.com', + }, + { + pool: `${savETH}-ethereum`, + chain: 'ethereum', + project: 'avant-protocol', + symbol: 'savETH', + tvlUsd: savETHData.tvlUsd, + apyBase: savETHData.apyBase, + underlyingTokens: [avETH], + poolMeta: 'ERC-4626: savETH → avETH', + url: 'https://www.avantprotocol.com', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.avantprotocol.com', +} From a68f34cc0d08625862fd0ca77b65fba32dd3230e Mon Sep 17 00:00:00 2001 From: spider-g <8703289+spider-g@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:01:38 -0300 Subject: [PATCH 2/3] fix project slugs --- src/adaptors/avant-protocol/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/adaptors/avant-protocol/index.js b/src/adaptors/avant-protocol/index.js index 102513c8c2..bb7826ddec 100644 --- a/src/adaptors/avant-protocol/index.js +++ b/src/adaptors/avant-protocol/index.js @@ -114,7 +114,7 @@ async function apy() { { pool: `${savUSD}-avax`, chain: 'avax', - project: 'avant-protocol', + project: 'avant-avusd', symbol: 'savUSD', tvlUsd: savUSDData.tvlUsd, apyBase: savUSDData.apyBase, @@ -125,7 +125,7 @@ async function apy() { { pool: `${savBTC}-avax`, chain: 'avax', - project: 'avant-protocol', + project: 'avant-avbtc', symbol: 'savBTC', tvlUsd: savBTCData.tvlUsd, apyBase: savBTCData.apyBase, @@ -136,7 +136,7 @@ async function apy() { { pool: `${savETH}-ethereum`, chain: 'ethereum', - project: 'avant-protocol', + project: 'avant-aveth', symbol: 'savETH', tvlUsd: savETHData.tvlUsd, apyBase: savETHData.apyBase, From add6efeee5cfd91c10bce288ef767721bc076333 Mon Sep 17 00:00:00 2001 From: spider-g <8703289+spider-g@users.noreply.github.com> Date: Thu, 23 Oct 2025 12:52:37 -0300 Subject: [PATCH 3/3] split adapters according to protocol slug --- src/adaptors/avant-avbtc/index.js | 29 ++++++++ src/adaptors/avant-aveth/index.js | 30 +++++++++ .../index.js => avant-aveth/shared.js} | 66 +------------------ src/adaptors/avant-avusd/index.js | 29 ++++++++ 4 files changed, 91 insertions(+), 63 deletions(-) create mode 100644 src/adaptors/avant-avbtc/index.js create mode 100644 src/adaptors/avant-aveth/index.js rename src/adaptors/{avant-protocol/index.js => avant-aveth/shared.js} (61%) create mode 100644 src/adaptors/avant-avusd/index.js diff --git a/src/adaptors/avant-avbtc/index.js b/src/adaptors/avant-avbtc/index.js new file mode 100644 index 0000000000..762c8e4e2d --- /dev/null +++ b/src/adaptors/avant-avbtc/index.js @@ -0,0 +1,29 @@ +const { getData } = require('../avant-aveth/shared') + +// Avalanche tokens +const avBTC = '0xfd2c2A98009d0cBed715882036e43d26C4289053' +const savBTC = '0x649342c6bff544d82DF1B2bA3C93e0C22cDeBa84' // Staked avBTC (ERC-4626) + +async function apy() { + const savBTCData = await getData('avax', savBTC, avBTC) + + return [ + { + pool: `${savBTC}-avax`, + chain: 'avax', + project: 'avant-avbtc', + symbol: 'savBTC', + tvlUsd: savBTCData.tvlUsd, + apyBase: savBTCData.apyBase, + underlyingTokens: [avBTC], + poolMeta: 'ERC-4626: savBTC → avBTC', + url: 'https://www.avantprotocol.com', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.avantprotocol.com', +} diff --git a/src/adaptors/avant-aveth/index.js b/src/adaptors/avant-aveth/index.js new file mode 100644 index 0000000000..89bfbbc123 --- /dev/null +++ b/src/adaptors/avant-aveth/index.js @@ -0,0 +1,30 @@ +const { getData } = require('./shared') + +// Ethereum tokens +const avETH = '0x9469470C9878bf3d6d0604831d9A3A366156f7EE' +const savETH = '0xDA06eE2dACF9245Aa80072a4407deBDea0D7e341' // Staked avETH (ERC-4626) +const wETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' + +async function apy() { + const savETHData = await getData('ethereum', savETH, avETH, wETH) + + return [ + { + pool: `${savETH}-ethereum`, + chain: 'ethereum', + project: 'avant-aveth', + symbol: 'savETH', + tvlUsd: savETHData.tvlUsd, + apyBase: savETHData.apyBase, + underlyingTokens: [avETH], + poolMeta: 'ERC-4626: savETH → avETH', + url: 'https://www.avantprotocol.com', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.avantprotocol.com', +} diff --git a/src/adaptors/avant-protocol/index.js b/src/adaptors/avant-aveth/shared.js similarity index 61% rename from src/adaptors/avant-protocol/index.js rename to src/adaptors/avant-aveth/shared.js index bb7826ddec..6659d7cb4b 100644 --- a/src/adaptors/avant-protocol/index.js +++ b/src/adaptors/avant-aveth/shared.js @@ -2,20 +2,6 @@ const sdk = require('@defillama/sdk') const axios = require('axios') const utils = require('../utils') -// Avalanche tokens - -const avUSD = '0x24dE8771bC5DdB3362Db529Fc3358F2df3A0E346' -const savUSD = '0x06d47F3fb376649c3A9Dafe069B3D6E35572219E' // Staked avUSD (ERC-4626) - -const avBTC = '0xfd2c2A98009d0cBed715882036e43d26C4289053' -const savBTC = '0x649342c6bff544d82DF1B2bA3C93e0C22cDeBa84' // Staked avBTC (ERC-4626) - -// Ethereum tokens - -const avETH = '0x9469470C9878bf3d6d0604831d9A3A366156f7EE' -const savETH = '0xDA06eE2dACF9245Aa80072a4407deBDea0D7e341' // Staked avETH (ERC-4626) -const wETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' - const abi = { convertToAssets: { "inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function" }, totalAssets: { "inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"" ,"type":"uint256"}],"stateMutability":"view","type":"function" }, @@ -33,7 +19,7 @@ async function getBlockAtTimestamp(chain, ts) { async function readShareToAssetRatio(chain, blockNumber, vault) { const { output } = await sdk.api.abi.call({ target: vault, - abi: abi.convertToAssets, + abi: abi.convertToAssets, params: [SHARES.toString()], chain, block: blockNumber, @@ -61,7 +47,7 @@ async function computeApyBase(chain, vault) { ]) const [rNow, rPast] = await Promise.all([ - readShareToAssetRatio(chain, bNow, vault), + readShareToAssetRatio(chain, bNow, vault), readShareToAssetRatio(chain, bPast, vault) ]) if (rNow === 0n || rPast === 0n || rNow === rPast) return 0 @@ -103,52 +89,6 @@ async function getData(chain, vault, underlying, underlyingSubstitute = undefine return { tvlUsd, apyBase } } -async function apy() { - const [savUSDData, savBTCData, savETHData] = await Promise.all([ - getData('avax', savUSD, avUSD), - getData('avax', savBTC, avBTC), - getData('ethereum', savETH, avETH, wETH) - ]) - - return [ - { - pool: `${savUSD}-avax`, - chain: 'avax', - project: 'avant-avusd', - symbol: 'savUSD', - tvlUsd: savUSDData.tvlUsd, - apyBase: savUSDData.apyBase, - underlyingTokens: [avUSD], - poolMeta: 'ERC-4626: savUSD → avUSD', - url: 'https://www.avantprotocol.com', - }, - { - pool: `${savBTC}-avax`, - chain: 'avax', - project: 'avant-avbtc', - symbol: 'savBTC', - tvlUsd: savBTCData.tvlUsd, - apyBase: savBTCData.apyBase, - underlyingTokens: [avBTC], - poolMeta: 'ERC-4626: savBTC → avBTC', - url: 'https://www.avantprotocol.com', - }, - { - pool: `${savETH}-ethereum`, - chain: 'ethereum', - project: 'avant-aveth', - symbol: 'savETH', - tvlUsd: savETHData.tvlUsd, - apyBase: savETHData.apyBase, - underlyingTokens: [avETH], - poolMeta: 'ERC-4626: savETH → avETH', - url: 'https://www.avantprotocol.com', - }, - ] -} - module.exports = { - timetravel: false, - apy, - url: 'https://www.avantprotocol.com', + getData, } diff --git a/src/adaptors/avant-avusd/index.js b/src/adaptors/avant-avusd/index.js new file mode 100644 index 0000000000..39b9a1417b --- /dev/null +++ b/src/adaptors/avant-avusd/index.js @@ -0,0 +1,29 @@ +const { getData } = require('../avant-aveth/shared') + +// Avalanche tokens +const avUSD = '0x24dE8771bC5DdB3362Db529Fc3358F2df3A0E346' +const savUSD = '0x06d47F3fb376649c3A9Dafe069B3D6E35572219E' // Staked avUSD (ERC-4626) + +async function apy() { + const savUSDData = await getData('avax', savUSD, avUSD) + + return [ + { + pool: `${savUSD}-avax`, + chain: 'avax', + project: 'avant-avusd', + symbol: 'savUSD', + tvlUsd: savUSDData.tvlUsd, + apyBase: savUSDData.apyBase, + underlyingTokens: [avUSD], + poolMeta: 'ERC-4626: savUSD → avUSD', + url: 'https://www.avantprotocol.com', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.avantprotocol.com', +}