mirror of
https://github.com/alexgo-io/DefiLlama-Adapters.git
synced 2026-01-12 16:53:02 +08:00
feat: add ultrayield and ultrayield-by-edge-capital adapters (#16758)
Co-authored-by: Artem Trifonov <artem@ultrayield.app>
This commit is contained in:
116
projects/ultrayield-by-edge-capital/index.js
Normal file
116
projects/ultrayield-by-edge-capital/index.js
Normal file
@@ -0,0 +1,116 @@
|
||||
// Сurator adapter that computes TVL for four vault types:
|
||||
// 1) ERC-4626 (totalAssets())
|
||||
// 2) MidasIssuance (supply)
|
||||
// 3) Boring (rate × supply via hook → accountant)
|
||||
// 4) Pre-deposit (same as MidasIssuance)
|
||||
|
||||
const { CONFIG } = require('./tvl.addresses.js');
|
||||
// ------------------------------- ABIs ---------------------------------------
|
||||
const ABI = {
|
||||
ERC4626: {
|
||||
asset: 'function asset() view returns (address)',
|
||||
totalAssets: 'function totalAssets() view returns (uint256)',
|
||||
},
|
||||
ERC20: {
|
||||
totalSupply: 'function totalSupply() view returns (uint256)',
|
||||
},
|
||||
// Boring Vault (through hook → accountant)
|
||||
BORING: {
|
||||
hook: 'function hook() view returns (address)',
|
||||
accountant: 'function accountant() view returns (address)',
|
||||
base: 'function base() view returns (address)',
|
||||
getRateSafe: 'function getRateSafe() view returns (uint256)',
|
||||
decimals: 'function decimals() view returns (uint8)',
|
||||
},
|
||||
}
|
||||
|
||||
// ---------------------------- TVL: ERC-4626 ---------------------------------
|
||||
async function getErc4626TVL(api, vaults) {
|
||||
if (!vaults?.length) return
|
||||
|
||||
const calls = vaults.map(v => v.toLowerCase());
|
||||
|
||||
const [assets, amounts] = await Promise.all([
|
||||
api.multiCall({abi: 'function asset() view returns (address)', calls: calls}),
|
||||
api.multiCall({abi: 'function totalAssets() view returns (uint256)', calls: calls})
|
||||
])
|
||||
|
||||
assets.forEach((asset, i) => {
|
||||
if (asset && amounts[i]) api.add(asset, amounts[i])
|
||||
})
|
||||
}
|
||||
|
||||
// --------------- TVL: Issuance-like via USD oracle (and Pre-deposit) --------
|
||||
// We compute: TVL = totalSupply(token)
|
||||
async function getIssuanceTokensTVL(api, items) {
|
||||
if (!items?.length) return
|
||||
|
||||
const supplies = await api.multiCall({
|
||||
abi: ABI.ERC20.totalSupply,
|
||||
calls: items,
|
||||
})
|
||||
|
||||
items.forEach((tokenAddress, i) => {
|
||||
if (supplies[i] != null) {
|
||||
api.add(tokenAddress.toLowerCase(), supplies[i])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ----------------------------- TVL: Boring ----------------------------------
|
||||
// For each boring vault:
|
||||
// vault -> hook() -> accountant()
|
||||
// accountant: base(), getRateSafe(), decimals() (rate scale)
|
||||
// vault token supply: totalSupply(vault)
|
||||
async function getBoringTVL(api, vaults) {
|
||||
if (!vaults?.length) return
|
||||
|
||||
for (const vault of vaults) {
|
||||
const hook = await api.call({target: vault, abi: 'function hook() view returns (address)'})
|
||||
const accountant = await api.call({target: hook, abi: 'function accountant() view returns (address)'})
|
||||
|
||||
const [asset, rate, supply, decimals] = await Promise.all([
|
||||
api.call({target: accountant, abi: 'function base() view returns (address)'}),
|
||||
api.call({target: accountant, abi: 'function getRateSafe() view returns (uint256)'}),
|
||||
api.call({target: vault, abi: 'erc20:totalSupply'}),
|
||||
api.call({target: accountant, abi: 'erc20:decimals'})
|
||||
])
|
||||
|
||||
if (asset && rate && supply) {
|
||||
const amount = BigInt(rate) * BigInt(supply) / (10n ** BigInt(decimals || 18))
|
||||
api.add(asset, amount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------ Orchestrator --------------------------------
|
||||
async function getTvl(api, chain) {
|
||||
const config = CONFIG[chain] || {}
|
||||
|
||||
await Promise.all([
|
||||
getErc4626TVL(api, config.erc4626),
|
||||
getIssuanceTokensTVL(api, config.issuance),
|
||||
getIssuanceTokensTVL(api, config.predeposit),
|
||||
getBoringTVL(api, config.boring)
|
||||
])
|
||||
}
|
||||
|
||||
// ------------------------------- Export -------------------------------------
|
||||
|
||||
const adapters = {
|
||||
timetravel: true,
|
||||
doublecounted: true,
|
||||
start: 0,
|
||||
methodology: 'TVL = sum of underlying balances: ERC-4626 via totalAssets(); Issuance/Pre-deposit via share totalSupply; Boring via accountant.getRate × vault.totalSupply.',
|
||||
}
|
||||
|
||||
Object.keys(CONFIG).forEach((chain) => {
|
||||
adapters[chain] = {
|
||||
tvl: async (api) => {
|
||||
await getTvl(api, chain)
|
||||
return api.getBalances()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = adapters
|
||||
67
projects/ultrayield-by-edge-capital/tvl.addresses.js
Normal file
67
projects/ultrayield-by-edge-capital/tvl.addresses.js
Normal file
@@ -0,0 +1,67 @@
|
||||
// Just addresses by chains. No ABI/logic here.
|
||||
// Format:
|
||||
// {
|
||||
// erc4626: [vaultAddr, ...],
|
||||
// issuanceTokens: [tokenAddr, ...],
|
||||
// predeposit: [tokenAddr, ...],
|
||||
// boring: [vaultAddr, ...],
|
||||
// }
|
||||
|
||||
const CONFIG = {
|
||||
ethereum: {
|
||||
erc4626: [
|
||||
'0x472425cc95be779126afa4aa17980210d299914f', // UltraYield BTC
|
||||
'0xc824a08db624942c5e5f330d56530cd1598859fd', // Kelp High Growth ETH
|
||||
'0x0562ae950276b24f3eae0d0a518dadb7ad2f8d66', // Morpho Edge UltraYield USDC
|
||||
'0x9a6340ce1282e01cb4ec9faae5fc5f4b60ca8839', // Mellow UltraYield x Edge x Allnodes
|
||||
'0x8ecc0b419dfe3ae197bc96f2a03636b5e1be91db', // Kelp sbUSD Vault
|
||||
'0xeaa3b922e9febca37d1c02d2142a59595094c605', // Upshift upEDGE Vault
|
||||
'0x59d675f75f973835b94d02b6d27b8539757dc65f', // Term UltraYield ETH
|
||||
'0x2be901715468c3c5393efa841525a713c583a8ec', // Term UltraYield USDC
|
||||
],
|
||||
issuance: [
|
||||
'0xbb51e2a15a9158ebe2b0ceb8678511e063ab7a55', // Midas - mEDGE
|
||||
'0x2a8c22e3b10036f3aef5875d04f8441d4188b656', // Midas - mBASIS
|
||||
'0x2fe058ccf29f123f9dd2aec0418aa66a877d8e50', // Plasma syrupUSD Pre-deposit Midas Vault
|
||||
'0x766255b53ae70fa39a18aa296f41fab17db6a810', // 0G USD Vault
|
||||
'0x513bd45be7643fe6c30c41cd4b327e8e341aaf9a', // 0G ETH Vault
|
||||
'0x48e284d0729eb1925066307072758d95dbbb49c4', // 0G BTC Vault
|
||||
],
|
||||
predeposit: [
|
||||
'0x699e04f98de2fc395a7dcbf36b48ec837a976490', // Turtle tacUSD
|
||||
],
|
||||
boring: [
|
||||
'0xbc0f3B23930fff9f4894914bD745ABAbA9588265', //EtherFi UltraYield Stablecoin vault
|
||||
]
|
||||
},
|
||||
hyperliquid: {
|
||||
erc4626: [
|
||||
'0xc061d38903b99ac12713b550c2cb44b221674f94', // Hyperbeat Ultra UBTC
|
||||
'0x96c6cbb6251ee1c257b2162ca0f39aa5fa44b1fb', // Hyperbeat Ultra HYPE
|
||||
],
|
||||
},
|
||||
plume_mainnet: {
|
||||
issuance: [
|
||||
'0x69020311836d29ba7d38c1d3578736fd3ded03ed', // Midas - mEDGE
|
||||
'0x0c78ca789e826fe339de61934896f5d170b66d78', // Midas - mBASIS
|
||||
],
|
||||
},
|
||||
base: {
|
||||
issuance: [
|
||||
'0x1c2757c1fef1038428b5bef062495ce94bbe92b2', // Midas - mBASIS
|
||||
],
|
||||
},
|
||||
etlk: {
|
||||
issuance: [
|
||||
'0x2247b5a46bb79421a314ab0f0b67ffd11dd37ee4', // Midas - mBASIS
|
||||
],
|
||||
},
|
||||
tac: {
|
||||
issuance: [
|
||||
'0x0e07999afff029894277c785857b4ca30ec07a5e', // Midas - mEDGE
|
||||
'0x06a317991f2f479a6213278b32d17a126fcab501', // Midas TacTON Vault
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = { CONFIG };
|
||||
56
projects/ultrayield/index.js
Normal file
56
projects/ultrayield/index.js
Normal file
@@ -0,0 +1,56 @@
|
||||
// Adapter that computes TVL for four vault types:
|
||||
// 1) ERC-4626 (totalAssets())
|
||||
|
||||
// ------------------------------- ABIs ---------------------------------------
|
||||
const ABI = {
|
||||
ERC4626: {
|
||||
asset: 'function asset() view returns (address)',
|
||||
totalAssets: 'function totalAssets() view returns (uint256)',
|
||||
},
|
||||
}
|
||||
|
||||
const { CONFIG } = require('./tvl.addresses.js');
|
||||
|
||||
// ---------------------------- TVL: ERC-4626 ---------------------------------
|
||||
async function getErc4626TVL(api, vaults) {
|
||||
if (!vaults?.length) return
|
||||
|
||||
const [assets, amounts] = await Promise.all([
|
||||
api.multiCall({abi: 'function asset() view returns (address)', calls: vaults}),
|
||||
api.multiCall({abi: 'function totalAssets() view returns (uint256)', calls: vaults})
|
||||
])
|
||||
|
||||
assets.forEach((asset, i) => {
|
||||
if (asset && amounts[i]) api.add(asset, amounts[i])
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------ Orchestrator --------------------------------
|
||||
async function getTvl(api, chain) {
|
||||
const config = CONFIG[chain] || {}
|
||||
|
||||
await Promise.all([
|
||||
getErc4626TVL(api, config.erc4626),
|
||||
])
|
||||
}
|
||||
|
||||
// ------------------------------- Export -------------------------------------
|
||||
|
||||
const adapters = {
|
||||
timetravel: true,
|
||||
doublecounted: true,
|
||||
start: 0,
|
||||
methodology: 'TVL = sum of underlying balances: ERC-4626 via totalAssets()',
|
||||
}
|
||||
|
||||
Object.keys(CONFIG).forEach((chain) => {
|
||||
adapters[chain] = {
|
||||
tvl: async (api) => {
|
||||
await getTvl(api, chain)
|
||||
return api.getBalances()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = adapters
|
||||
19
projects/ultrayield/tvl.addresses.js
Normal file
19
projects/ultrayield/tvl.addresses.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// Just addresses by chains. No ABI/logic here.
|
||||
// Format:
|
||||
// {
|
||||
// erc4626: [vaultAddr, ...],
|
||||
// issuanceTokens: [tokenAddr, ...],
|
||||
// predeposit: [tokenAddr, ...],
|
||||
// boring: [vaultAddr, ...],
|
||||
// }
|
||||
|
||||
const CONFIG = {
|
||||
ethereum: {
|
||||
erc4626: [
|
||||
'0x472425cc95be779126afa4aa17980210d299914f', // UltraYield BTC
|
||||
'0x8ecc0b419dfe3ae197bc96f2a03636b5e1be91db', // Kelp sbUSD Vault
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = { CONFIG };
|
||||
Reference in New Issue
Block a user