Skip to content
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

update #3

Merged
merged 42 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
83ef4d8
zerolend fix
slasher125 Nov 25, 2024
e74aeac
mantle staked eth rename
slasher125 Nov 25, 2024
7b7f779
zkswap fix
slasher125 Nov 26, 2024
5afa690
Aqua Patina APY adapter (#1597)
sponnet Nov 26, 2024
c2ed1ef
Feat: integrate morfi yield (#1614)
gWhy-j Nov 26, 2024
40dca74
Add xSTABLE2 pool (#1617)
spiehdid Nov 26, 2024
d6ca6af
Yel-Finance: Update potion addresses (#1618)
astroKo Nov 26, 2024
aeb2b67
Added endur to yield server (#1621)
0x-minato Nov 27, 2024
144fa2e
update exclusion
slasher125 Nov 27, 2024
8d64f03
Inverse: add sDOLA & sINV (#1620)
webmass Nov 28, 2024
36b29d0
compx rename
slasher125 Nov 29, 2024
21d126a
Osmosis fix (#1623)
slasher125 Nov 29, 2024
2979f8a
Added usdx-money to yield server (#1624)
brucelsoon Dec 3, 2024
60614d8
Corrected APY calculation (#1629)
Divljo31 Dec 3, 2024
00564a8
Add Kinetix Derivatives (#1625)
0xrmvdao Dec 3, 2024
5bae0f6
chore: Add Usual USD0++ in defillama yield server (#1627)
Magicking Dec 3, 2024
24634d1
Fix IPOR Fusion APY on 29.11.2024 (#1626)
rav-ipor Dec 3, 2024
7c54148
xexchange fix
slasher125 Dec 3, 2024
fa10a39
add pluto-so earn (#1622)
verzth Dec 3, 2024
72922ea
Fix Goat Protocol yields (#1630)
reikodoteth Dec 3, 2024
b240fd2
better headers
0xngmi Dec 3, 2024
695db16
revised avantis apy (#1631)
skords Dec 3, 2024
30f4bb0
Fix: base apy to reward apy (#1632)
Magicking Dec 3, 2024
93eea08
fix: list arbitrum vaults (#1633)
swan-of-bodom Dec 3, 2024
02b015c
resolv rename
slasher125 Dec 4, 2024
00aeeee
persistence fix
slasher125 Dec 4, 2024
d41dbbc
Added Ethena protocol (#1636)
Joro-Popov Dec 5, 2024
fc47233
Fix issues and add base, polygon, avalanche and fraxtal tracking (#1635)
Andreadinenno Dec 5, 2024
19eb639
add hyperdrive (#1637)
wakamex Dec 6, 2024
79faabf
feat(smardex): adds sUSDN staking pool (#1639)
estebgonza Dec 6, 2024
455f4b8
feat: kinetic yields (#1646)
EdgarRBL Dec 9, 2024
3149890
feat: added superlend for yield server (#1647)
priyam-anand Dec 9, 2024
ee3093e
spardex fix
slasher125 Dec 9, 2024
b67ac8f
zerolend fix
slasher125 Dec 9, 2024
786ba84
usdx money fix
slasher125 Dec 9, 2024
d26a5f1
update exclude list
slasher125 Dec 9, 2024
f3886cd
update exclusion list
slasher125 Dec 9, 2024
325cd30
remove pool
slasher125 Dec 10, 2024
5c615d0
Add xWETH2 (#1648)
spiehdid Dec 10, 2024
0b88a24
compound add missing market
slasher125 Dec 10, 2024
4ec00e2
superlend fix chain name
slasher125 Dec 11, 2024
d88849b
add bagful info (#1649)
Dec 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ jobs:
VENDOR_FINANCE: ${{ secrets.VENDOR_FINANCE }}
TRADERJOE: ${{ secrets.TRADERJOE }}
GRAPH_API_KEY: ${{ secrets.GRAPH_API_KEY }}
OSMOSIS_API_KEY: ${{ secrets.OSMOSIS_API_KEY}}
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,21 @@ A note on how to set apy related fields:
- if you are unsure/your data source doesn't contain a detailed breakdown, then provide an `apy` field indicating the total apy and omit the `apyBase` and `apyReward` fields (or set to null)
```

#### FAQ
### FAQ

> Why are some pools missing on DefiLlama which appear on my adapter?
#### Why are some pools missing on DefiLlama which appear on my adapter?

DefiLlama only displays pools with >10k TVL, so pools with less TVL than that will appear on the adapter but not on defillama

> I'm getting errors when running `npm install`
#### I'm getting errors when running `npm install`

Make sure you're running the command inside the `src/adaptors` folder, not in the project root folder.

> Why is X pool missing from https://defillama.com/yields/stablecoins ?
#### Why is X pool missing from https://defillama.com/yields/stablecoins ?

That page has stricter filters than other pages, only pools with >1M TVL and on audited protocols are included there.

#### Adapter module structure
### Adapter module structure

```js
module.exports = {
Expand Down
1 change: 1 addition & 0 deletions env.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ module.exports = {
GRAPH_API_KEY: process.env.GRAPH_API_KEY,
// DB
DATABASE_URL: process.env.DATABASE_URL,
OSMOSIS_API_KEY: process.env.OSMOSIS_API_KEY,
};
1 change: 1 addition & 0 deletions serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ functions:
SMARDEX_SUBGRAPH_API_KEY: ${file(./env.js):SMARDEX_SUBGRAPH_API_KEY}
VENDOR_FINANCE: ${file(./env.js):VENDOR_FINANCE}
TRADERJOE: ${file(./env.js):TRADERJOE}
OSMOSIS_API_KEY: ${file(./env.js):OSMOSIS_API_KEY}

# --- data enrichment
triggerEnrichment:
Expand Down
28 changes: 28 additions & 0 deletions src/adaptors/aqua-patina/abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"totalSupply": {
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "totalSupply",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
"ethPerAPEth": {
"inputs": [],
"name": "ethPerAPEth",
"outputs": [
{
"internalType": "uint256",
"name": "ethPerAPEth",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
}
54 changes: 54 additions & 0 deletions src/adaptors/aqua-patina/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const utils = require('../utils');
const sdk = require('@defillama/sdk');
const abi = require('./abi.json');
const axios = require('axios');

const APETH = '0xAaAaAAaBC6CBc3A1FD3a0fe0FDec43251C6562F5';
const ETH = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'


const getApy = async () => {
const apy = await utils.getData('https://wallet.aquapatina.com/api/apy_current');

tvl = await tvlUsd();

return [
{
pool: APETH,
chain: utils.formatChain('ethereum'),
project: 'aqua-patina',
symbol: utils.formatSymbol('APETH'),
tvlUsd: tvl,
apy: apy.data.apy,
},
];
};

async function tvlUsd() {

const supply = await sdk.api.abi.call({
target: APETH,
abi: abi['totalSupply'],
chain: 'ethereum'
});

const multiplier = await sdk.api.abi.call({
target: APETH,
abi: abi['ethPerAPEth'],
chain: 'ethereum'
});

const ethPrice = (
await axios.get('https://coins.llama.fi/prices/current/coingecko:ethereum')
).data.coins['coingecko:ethereum'].price;

let tvl = BigInt(supply.output) * BigInt(multiplier.output) / BigInt(1e18) / BigInt(1e18);

return Number(tvl) * ethPrice;
}

module.exports = {
timetravel: false,
apy: getApy,
url: 'https://aquapatina.eth/',
};
16 changes: 0 additions & 16 deletions src/adaptors/avantis/abiVaultManager.js

This file was deleted.

14 changes: 14 additions & 0 deletions src/adaptors/avantis/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
chunkArray: (array, size) => {
const result = [];
for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size));
}
return result;
},
calculateTrancheTotal: (transfers, trancheAddress) => {
return transfers
.filter((t) => t.to.toLowerCase() === trancheAddress.toLowerCase())
.reduce((acc, t) => acc + parseFloat((t.value / 1e6).toFixed(6)), 0);
},
};
164 changes: 121 additions & 43 deletions src/adaptors/avantis/index.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,152 @@
const utils = require('../utils');
const sdk = require('@defillama/sdk');
const abiVaultManager = require('./abiVaultManager');
const { request, gql } = require('graphql-request');
const { chunkArray, calculateTrancheTotal } = require('./helpers');
const { getBlocksByTime, getData } = require('../utils');

const ADDRESSES = {
base: {
AvantisJuniorTranche: '0x944766f715b51967E56aFdE5f0Aa76cEaCc9E7f9',
AvantisSeniorTranche: '0x83084cB182162473d6FEFfCd3Aa48BA55a7B66F7',
AvantisVaultManager: '0xe9fB8C70aF1b99F2Baaa07Aa926FCf3d237348DD',
USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
},
};

const API_BASE = 'https://api.avantisfi.com/v1/history/vaults/apr/';
const SUBGRAPH_URL =
'https://subgraph.satsuma-prod.com/052b6e8d4af9/avantis/avantis-mainnet/version/v0.1.9/api';

const main = async () => {
const [jrData, srData] = await Promise.all([
utils.getData(`${API_BASE}${ADDRESSES.base.AvantisJuniorTranche}/7`),
utils.getData(`${API_BASE}${ADDRESSES.base.AvantisSeniorTranche}/7`),
]);
const feeFetchCount = 10000;

if (jrData.success === false || srData.success === false) {
throw new Error('API response is not successful');
const feeDistributedQuery = gql`
query FeesDistributeds($first: Int!, $skip: Int!, $start: Int!, $end: Int!) {
feesDistributeds(
first: $first
skip: $skip
where: { timestamp_gte: $start, timestamp_lte: $end }
orderBy: timestamp
orderDirection: asc
) {
id
}
}
`;

const { averageApr: jrAverageApr, averageFee: jrAverageFee } = jrData;
const { averageApr: srAverageApr, averageFee: srAverageFee } = srData;
const vmToTrancheQuery = gql`
query VmToTrancheTransfers($transactionHashes: [String!]!, $to: [String!]!) {
vmtoTrancheTransfers(
where: { transactionHash_in: $transactionHashes, to_in: $to }
) {
value
to
}
}
`;

let [reserveRatio, profitMultiplier, jrTvl, srTvl] = await Promise.all([
sdk.api.abi.call({
target: ADDRESSES.base.AvantisVaultManager,
abi: abiVaultManager.find((m) => m.name === 'getReserveRatio'),
params: [0],
chain: 'base',
}),
sdk.api.abi.call({
target: ADDRESSES.base.AvantisVaultManager,
abi: abiVaultManager.find((m) => m.name === 'getProfitMultiplier'),
chain: 'base',
}),
const fetchFeeDistributedIds = async (timestamp, skip = 0) => {
const { feesDistributeds } = await request(
SUBGRAPH_URL,
feeDistributedQuery,
{
first: feeFetchCount,
skip: skip,
start: timestamp - 7 * 86400,
end: timestamp,
}
);

let ids = feesDistributeds.map((f) => f.id);

if (ids.length === feeFetchCount) {
ids = ids.concat(
await fetchFeeDistributedIds(timestamp, skip + feeFetchCount)
);
}

return ids;
};

const fetchTransfersForFeeDistributedIds = async (ids) => {
const chunkedIds = chunkArray(ids, 1000);

let totalJunior = 0;
let totalSenior = 0;

for (const chunk of chunkedIds) {
const { vmtoTrancheTransfers } = await request(
SUBGRAPH_URL,
vmToTrancheQuery,
{
transactionHashes: chunk,
to: [
ADDRESSES.base.AvantisJuniorTranche,
ADDRESSES.base.AvantisSeniorTranche,
],
}
);

totalJunior += calculateTrancheTotal(
vmtoTrancheTransfers,
ADDRESSES.base.AvantisJuniorTranche
);
totalSenior += calculateTrancheTotal(
vmtoTrancheTransfers,
ADDRESSES.base.AvantisSeniorTranche
);
}

return { totalJunior: totalJunior / 7, totalSenior: totalSenior / 7 };
};

// NOTE: OUR SUBGRAPH IS NOT CAUGHT UP TO DATE, SO WE ARE USING THE API FOR NOW
// -----------------------------------------------------------------------------
// We will reenable time travel once our subgraph is caught up
const main = async (timestamp = null) => {
// timestamp = timestamp ? parseInt(timestamp) : Math.floor(Date.now() / 1000);

// NOTE: OUR SUBGRAPH IS NOT CAUGHT UP TO DATE, SO WE ARE USING THE API FOR NOW
// -----------------------------------------------------------------------------
// Get total fees distributed for junior and senior tranches
// const feesDistributedIds = await fetchFeeDistributedIds(timestamp);
// const { totalJunior, totalSenior } = await fetchTransfersForFeeDistributedIds(
// feesDistributedIds
// );

// const [block] = await getBlocksByTime([timestamp], 'base');

const { meta } = await getData(
'https://api.avantisfi.com/v1/vault/returns-7-days'
);

// Get TVL for junior and senior tranches
let [juniorTvl, seniorTvl] = await Promise.all([
sdk.api.abi.call({
abi: 'erc20:balanceOf',
target: ADDRESSES.base.USDC,
params: [ADDRESSES.base.AvantisJuniorTranche],
chain: 'base',
// block: block,
}),
sdk.api.abi.call({
abi: 'erc20:balanceOf',
target: ADDRESSES.base.USDC,
params: [ADDRESSES.base.AvantisSeniorTranche],
chain: 'base',
// block: block,
}),
]);

jrTvl = jrTvl.output / 1e6;
srTvl = srTvl.output / 1e6;

const jrFeeSplit =
(parseFloat(profitMultiplier.output) * parseFloat(reserveRatio.output)) /
100;
juniorTvl = juniorTvl.output / 1e6;
seniorTvl = seniorTvl.output / 1e6;

let adjApyJr = 0,
adjApySr = 0;
// Calculate daily returns for junior and senior tranches
// const juniorDailyReturns = totalJunior / juniorTvl;
// const seniorDailyReturns = totalSenior / seniorTvl;
const juniorDailyReturns = meta.averageJrFees / juniorTvl;
const seniorDailyReturns = meta.averageSrFees / seniorTvl;

if (jrAverageApr > 0 && jrTvl > 0) {
adjApyJr = ((1 + jrAverageFee / jrTvl) ** 365 - 1) * jrFeeSplit;
}

if (srAverageApr > 0 && srTvl > 0) {
adjApySr = ((1 + srAverageFee / srTvl) ** 365 - 1) * (100 - jrFeeSplit);
}
// Calculate APY for junior and senior tranches
const juniorApy = (1 + juniorDailyReturns) ** 365 - 1;
const seniorApy = (1 + seniorDailyReturns) ** 365 - 1;

return [
{
Expand All @@ -77,8 +155,8 @@ const main = async () => {
project: 'avantis',
symbol: 'USDC',
poolMeta: 'junior',
tvlUsd: jrTvl,
apyBase: adjApyJr,
tvlUsd: juniorTvl,
apyBase: juniorApy * 100,
url: 'https://www.avantisfi.com/earn/junior',
},
{
Expand All @@ -87,8 +165,8 @@ const main = async () => {
project: 'avantis',
symbol: 'USDC',
poolMeta: 'senior',
tvlUsd: srTvl,
apyBase: adjApySr,
tvlUsd: seniorTvl,
apyBase: seniorApy * 100,
url: 'https://www.avantisfi.com/earn/senior',
},
];
Expand Down
Loading