-
Notifications
You must be signed in to change notification settings - Fork 1.1k
aihedge-finance: add APY adapter for AIHedge vaults #2840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| const sdk = require('@defillama/sdk'); | ||
| const utils = require('../utils'); | ||
|
|
||
| const VAULTS = [ | ||
| { | ||
| address: '0x469201fA49DB171C0F95371533C2D3Ad5aE60400', | ||
| underlying: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC | ||
| symbol: 'USDC', | ||
| }, | ||
| ]; | ||
|
|
||
| const CHAIN = 'ethereum'; | ||
|
|
||
| const convertToAssetsAbi = | ||
| 'function convertToAssets(uint256 shares) external view returns (uint256)'; | ||
|
|
||
| const SHARE_UNIT = (10n ** 6n).toString(); | ||
| const DAY = 24 * 3600; | ||
|
|
||
| async function apy() { | ||
| const timestamp = Math.floor(Date.now() / 1000); | ||
|
|
||
| const [{ height: blockNow }, { height: blockPrev }] = await Promise.all([ | ||
| utils.getPriceApiData(`/block/${CHAIN}/${timestamp}`), | ||
| utils.getPriceApiData(`/block/${CHAIN}/${timestamp - DAY}`), | ||
| ]); | ||
|
|
||
| const addresses = VAULTS.map((v) => v.address); | ||
| const calls = addresses.map((target) => ({ target })); | ||
| const shareCalls = addresses.map((target) => ({ | ||
| target, | ||
| params: [SHARE_UNIT], | ||
| })); | ||
|
|
||
| const [decimals, totalAssets, rateNow, ratePrev] = await Promise.all([ | ||
| sdk.api.abi.multiCall({ abi: 'erc20:decimals', calls, chain: CHAIN }), | ||
| sdk.api.abi.multiCall({ | ||
| abi: 'uint:totalAssets', | ||
| calls, | ||
| chain: CHAIN, | ||
| block: blockNow, | ||
| }), | ||
| sdk.api.abi.multiCall({ | ||
| abi: convertToAssetsAbi, | ||
| calls: shareCalls, | ||
| chain: CHAIN, | ||
| block: blockNow, | ||
| }), | ||
| sdk.api.abi.multiCall({ | ||
| abi: convertToAssetsAbi, | ||
| calls: shareCalls, | ||
| chain: CHAIN, | ||
| block: blockPrev, | ||
| }), | ||
| ]); | ||
|
|
||
| const underlyings = VAULTS.map((v) => v.underlying); | ||
| const { pricesByAddress } = await utils.getPrices(underlyings, CHAIN); | ||
|
|
||
| const pools = VAULTS.map((vault, i) => { | ||
| const dec = Number(decimals.output[i].output); | ||
| const total = Number(totalAssets.output[i].output); | ||
| const rNow = Number(rateNow.output[i].output); | ||
| const rPrev = Number(ratePrev.output[i].output); | ||
| const price = pricesByAddress[vault.underlying.toLowerCase()] || 0; | ||
|
|
||
| const tvlUsd = (total / 10 ** dec) * price; | ||
|
Comment on lines
+65
to
+67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Do not report a missing price as zero TVL. A missing price becomes Suggested guard- const price = pricesByAddress[vault.underlying.toLowerCase()] || 0;
+ const price = Number(pricesByAddress[vault.underlying.toLowerCase()]);
+ if (!Number.isFinite(price) || price <= 0) return null;
...
- return pools.filter(utils.keepFinite);
+ return pools.filter(Boolean).filter(utils.keepFinite);Also applies to: 86-86 🤖 Prompt for AI Agents |
||
|
|
||
| let apyBase = 0; | ||
| if (rPrev > 0 && rNow > 0) { | ||
| apyBase = ((rNow / rPrev) ** 365 - 1) * 100; | ||
| } | ||
|
|
||
| return { | ||
| pool: `${vault.address}-${CHAIN}`.toLowerCase(), | ||
| chain: utils.formatChain(CHAIN), | ||
| project: 'aihedge-finance', | ||
| symbol: vault.symbol, | ||
| tvlUsd, | ||
| apyBase, | ||
| underlyingTokens: [vault.underlying], | ||
| url: `https://dapp.aihedge.finance/#/yield/1/${vault.address}`, | ||
| }; | ||
| }); | ||
|
|
||
| return pools.filter(utils.keepFinite); | ||
| } | ||
|
|
||
| module.exports = { | ||
| timetravel: true, | ||
| apy, | ||
| url: 'https://dapp.aihedge.finance', | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 50379
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 3606
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 10317
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 22054
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 237
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 10698
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 10268
🏁 Script executed:
Repository: DefiLlama/yield-server
Length of output: 5587
Honor the timetravel contract
apy()readsDate.now(), so historical backfills still use the live 24h window. Thread the requested timestamp through this adaptor (and align the price lookups to the same time), or settimetravel: false.🤖 Prompt for AI Agents