Skip to content

Commit

Permalink
Merge branch 'DefiLlama:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
atozICT20 authored May 14, 2024
2 parents 7fea775 + fc2d6cf commit 3db2387
Show file tree
Hide file tree
Showing 124 changed files with 15,659 additions and 742 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dependencies": {
"@balancer-labs/sdk": "^1.1.5",
"@defillama/sdk": "^2.3.126",
"@defillama/sdk5": "npm:@defillama/sdk@^5.0.37",
"@defillama/sdk5": "npm:@defillama/sdk@^5.0.53",
"@types/jest": "^28.1.6",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.8.0",
Expand Down
3 changes: 2 additions & 1 deletion src/adaptors/aave-v3/abi.js

Large diffs are not rendered by default.

66 changes: 65 additions & 1 deletion src/adaptors/aave-v3/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { request, gql } = require('graphql-request');
const sdk = require('@defillama/sdk5');

const utils = require('../utils');
const { aTokenAbi } = require('./abi');
const { aTokenAbi, aaveStakedTokenDataProviderAbi } = require('./abi');
const poolAbi = require('./poolAbi');

const SECONDS_PER_YEAR = 31536000;
Expand Down Expand Up @@ -135,6 +135,67 @@ const queryMetis = gql`
}
`;

const stkGho = async () => {
const convertStakedTokenApy = (rawApy) => {
const rawApyStringified = rawApy.toString();
const lastTwoDigits = rawApyStringified.slice(-2);
const remainingDigits = rawApyStringified.slice(0, -2);
const result = `${remainingDigits}.${lastTwoDigits}`;
return Number(result);
};

const STKGHO = '0x1a88Df1cFe15Af22B3c4c783D4e6F7F9e0C1885d';
const stkGhoTokenOracle = '0x3f12643d3f6f874d39c2a4c9f2cd6f2dbac877fc';
const aaveStakedTokenDataProviderAddress =
'0xb12e82DF057BF16ecFa89D7D089dc7E5C1Dc057B';

const stkghoData = (
await sdk.api.abi.call({
target: aaveStakedTokenDataProviderAddress,
abi: aaveStakedTokenDataProviderAbi.find(
(m) => m.name === 'getStakedAssetData'
),
params: [STKGHO, stkGhoTokenOracle],
chain: 'ethereum',
})
).output;

const stkghoNativeApyRaw = stkghoData[6]; // 6th index of the tuple is the APY
const stkghoNativeApy = convertStakedTokenApy(stkghoNativeApyRaw);

const stkghoMeritApy = (
await superagent.get('https://apps.aavechan.com/api/merit/aprs')
).body.currentAPR.actionsAPR.stkgho;

const stkghoApy = stkghoNativeApy + stkghoMeritApy;

const stkghoSupply =
(
await sdk.api.abi.call({
target: STKGHO,
abi: 'erc20:totalSupply',
})
).output / 1e18;

const ghoPrice = (
await superagent.get(
`https://coins.llama.fi/prices/current/ethereum:${GHO}`
)
).body.coins[`ethereum:${GHO}`].price;

const pool = {
pool: `${STKGHO}-ethereum`.toLowerCase(),
chain: 'Ethereum',
project: 'aave-v3',
symbol: 'GHO',
tvlUsd: stkghoSupply * ghoPrice,
apy: stkghoApy,
url: 'https://app.aave.com/staking',
};

return pool;
};

const ethV3Pools = async () => {
const AaveProtocolDataProviderV3Mainnet =
'0x7B4EB56E7CD4b454BA8ff71E4518426369a138a3';
Expand Down Expand Up @@ -398,9 +459,12 @@ const apy = async () => {

const ethPools = await ethV3Pools();

const stkghoPool = await stkGho();

return pools
.flat()
.concat(ethPools)
.concat([stkghoPool])
.filter((p) => utils.keepFinite(p));
};

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ const getApy = async () => {

return {
...marketInfoToPool(chain, marketInfo, collateral, pricesObj),
project: 'abracadabra',
project: 'abracadabra-spell',
};
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ const getApy = async () => {
return {
pool: `${pool.stakingToken}-abracadabra`,
chain: utils.formatChain(chain),
project: 'abracadabra',
project: 'abracadabra-spell',
tvlUsd,
symbol,
apyReward,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ const cauldrons = require('./cauldrons');
const multiRewardFarms = require('./multi-reward-farms');
const farms = require('./farms');
const magicGlp = require('./magic-glp');
const utils = require('../utils');

const getApy = async () =>
[
const getApy = async () => {
const pools = [
...(await cauldrons()),
...(await farms()),
...(await magicGlp()),
...(await multiRewardFarms()),
].map((i) => ({ ...i, pool: i.pool.toLowerCase() }));

return utils.removeDuplicates(pools);
};

module.exports = {
timetravel: false,
apy: getApy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ const getApy = async () => {
return {
pool: `${magicGlpAddress}-magicglp-${chain}`,
chain: utils.formatChain(chain),
project: 'abracadabra',
project: 'abracadabra-spell',
symbol: utils.formatSymbol('magicGLP'),
tvlUsd:
(magicGlpTotalAssets[chain] / 10 ** glp.decimals) * glpPrice[chain],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const getApy = async () => {
return {
pool: `${address}-${chain}`,
chain: utils.formatChain(chain),
project: 'abracadabra',
project: 'abracadabra-spell',
tvlUsd: Number(tvlUsdChainFarms[address.toLowerCase()]),
symbol: symbol ?? utils.formatSymbol(symbols[stakingToken.toLowerCase()].output),
apyBase: stakingTokenYieldPool.apyBase,
Expand Down
3 changes: 2 additions & 1 deletion src/adaptors/acryptos/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const chainMapping = {
8453: 'base',
42161: 'arbitrum',
43114: 'avalanche',
59144: 'linea',
1666600000: 'harmony',
};

Expand Down Expand Up @@ -74,5 +75,5 @@ const main = async () => {
module.exports = {
timetravel: false,
apy: main,
url: 'https://app-v2.acryptos.com/#/BSC/vaults/all',
url: 'https://app.acryptos.com/',
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const getApy = async () => {
return {
pool: p,
chain: utils.formatChain('base'),
project: 'aerodrome',
project: 'aerodrome-v1',
symbol: utils.formatSymbol(s.split('-')[1]),
tvlUsd,
apyReward,
Expand Down
195 changes: 195 additions & 0 deletions src/adaptors/aloe/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
const sdk = require('@defillama/sdk5');
const { secondsInYear } = require('date-fns');
const ethers = require('ethers');
const { default: BigNumber } = require('bignumber.js');
const utils = require('../utils');
const superagent = require('superagent');
const { rewardTokens } = require('../sommelier/config');

const config = {
ethereum: { fromBlock: 18782116 },
optimism: { fromBlock: 113464669 },
base: { fromBlock: 7869252 },
arbitrum: { fromBlock: 159919891 },
linea: {
factory: '0x00000000333288eBA83426245D144B966Fd7e82E',
volatilityOracle: '0x00000000570385b76719a95Fdf27B9c7fB5Ff299',
lenderLens: '0xFc39498Edd3E18d5296E6584847f2580ad0e770B',
fromBlock: 3982456,
},
};

const ALOE_II_MAX_LEVERAGE = 1 / 200;
const ALOE_II_LIQUIDATION_INCENTIVE = 1 / 20;

function computeLTV(iv, nSigma) {
const ltv =
1 /
((1 + ALOE_II_MAX_LEVERAGE + ALOE_II_LIQUIDATION_INCENTIVE) *
Math.exp(iv * nSigma));
return Math.max(0.1, Math.min(ltv, 0.9));
}

async function getLTVs(chain, factory, volatilityOracle, uniswapPools) {
const parameters = await sdk.api2.abi.multiCall({
calls: uniswapPools.map((uniswapPool) => ({
target: factory,
params: [uniswapPool],
})),
abi: 'function getParameters(address uniswapPool) view returns (uint208 ante,uint8 nSigma,uint8 manipulationThresholdDivisor,uint32 pausedUntilTime)',
chain,
});

const consults = await sdk.api2.abi.multiCall({
calls: uniswapPools.map((uniswapPool) => ({
target: volatilityOracle,
params: [uniswapPool, '0x100000000'],
})),
abi: 'function consult(address pool,uint40 seed) view returns (uint56 metric,uint160 sqrtMeanPriceX96,uint256 iv)',
chain,
});

return parameters.map((p, i) =>
computeLTV(Number(consults[i].iv) / 1e12, Number(p.nSigma) / 10)
);
}

async function getPrices(chain, addresses) {
const priceKeys = [...new Set(addresses)].map(
(address) => `${chain}:${address}`
);
return (
await superagent.get(
`https://coins.llama.fi/prices/current/${priceKeys
.join(',')
.toLowerCase()}`
)
).body.coins;
}

async function getPoolsFor(chain) {
const {
factory = '0x000000009efdB26b970bCc0085E126C9dfc16ee8',
volatilityOracle = '0x0000000030d51e39a2dDDb5Db50F9d74a289DFc3',
lenderLens = '0x1f36838Ac6e3922dD26f1222d75af86185f2b798',
fromBlock,
} = config[chain];

const currentBlock = await sdk.api.util.getLatestBlock(chain);

const iface = new ethers.utils.Interface([
'event CreateMarket(address indexed pool, address lender0, address lender1)',
]);
const createMarketEvents = (
await sdk.api2.util.getLogs({
target: factory,
topic: '',
fromBlock,
toBlock: currentBlock.number,
keys: [],
topics: [iface.getEventTopic('CreateMarket')],
chain,
})
).output
.filter((ev) => !ev.removed)
.map((ev) => iface.parseLog(ev).args);

const lenders = createMarketEvents.flatMap((ev, idx) => [
{ address: ev.lender0, peer: ev.lender1, peerIdx: idx * 2 + 1 },
{ address: ev.lender1, peer: ev.lender0, peerIdx: idx * 2 },
]);

const uniswapPools = createMarketEvents.map((ev) => ev.pool);
const ltvs = await getLTVs(chain, factory, volatilityOracle, uniswapPools);

const basics = await sdk.api2.abi.multiCall({
calls: lenders.map((lender) => ({
target: lenderLens,
params: [lender.address],
})),
abi: 'function readBasics(address lender) view returns (address asset,uint256 interestRate,uint256 utilization,uint256 inventory,uint256 totalBorrows,uint256 totalSupply,uint8 reserveFactor,uint64 rewardsRate)',
chain,
});

const prices = await getPrices(
chain,
basics.map((info) => info.asset)
);

return basics
.map((info, i) => {
const reserveFraction = 1 / info.reserveFactor;
const userFraction = 1 - reserveFraction;

const aprBaseBorrow = new BigNumber(info.interestRate).times(
secondsInYear
);
const aprBaseLend = aprBaseBorrow
.times(info.utilization)
.times(userFraction)
.div('1e18');

const apyBaseBorrow =
utils.aprToApy(
aprBaseBorrow.div('1e7').toNumber() / 1e3,
secondsInYear
) / 100;
const apyBaseLend =
utils.aprToApy(aprBaseLend.div('1e7').toNumber() / 1e3, secondsInYear) /
100;

const priceKey = `${chain}:${info.asset}`.toLowerCase();
if (!(priceKey in prices)) {
return undefined;
}
const { decimals = 18, symbol, price } = prices[priceKey];

const totalSupply =
new BigNumber(info.inventory)
.times('1e8')
.div(`1e${decimals}`)
.toNumber() / 1e8;
const totalBorrow =
new BigNumber(info.totalBorrows)
.times('1e8')
.div(`1e${decimals}`)
.toNumber() / 1e8;
const tvl = totalSupply - totalBorrow;

const lender = lenders[i];
const peerAssetAddress = basics[lender.peerIdx].asset;
const peerPriceKey = `${chain}:${peerAssetAddress}`.toLowerCase();
const { symbol: peerSymbol } =
peerPriceKey in prices
? prices[peerPriceKey]
: { symbol: peerAssetAddress };

return {
pool: `${lender.address}-${chain}`.toLowerCase(),
chain,
project: 'aloe',
symbol: symbol.toUpperCase(),
tvlUsd: tvl * price,
apyBase: apyBaseLend * 100,
underlyingTokens: [info.asset],
poolMeta: `${peerSymbol.toUpperCase()}-pool`,
apyBaseBorrow: apyBaseBorrow * 100,
totalSupplyUsd: totalSupply * price,
totalBorrowUsd: totalBorrow * price,
ltv: ltvs[Math.floor(i / 2)],
};
})
.filter((pool) => pool !== undefined);
}

async function apy() {
return (
await Promise.all(Object.keys(config).map((chain) => getPoolsFor(chain)))
).flat();
}

module.exports = {
apy,
timetravel: false,
url: 'https://app.aloe.capital/markets',
};
Loading

0 comments on commit 3db2387

Please sign in to comment.