refactor default aave helper

This commit is contained in:
g1nt0ki
2025-11-09 14:04:31 +01:00
parent aa7388b22a
commit f831b30021
4 changed files with 124 additions and 115 deletions

View File

@@ -10,22 +10,16 @@ const methodologies = require('../helper/methodologies');
const addressesProviderRegistryETH = "0x52D306e36E3B6B02c153d0266ff0f85d18BCD413";
function ethereum(borrowed) {
return async (api)=> {
return async (api) => {
const balances = api.getBalances()
const { block } = api
// V2 TVLs
if (block >= 11360925) {
const [v2Atokens, v2ReserveTokens, dataHelper] = await getV2Reserves(block, addressesProviderRegistryETH, 'ethereum')
if(borrowed){
await getBorrowed(balances, block, "ethereum", v2ReserveTokens, dataHelper, id=>id);
} else {
await getTvl(balances, block, 'ethereum', v2Atokens, v2ReserveTokens, id => id);
}
}
if (block >= 11998773) {
await ammMarket(api, borrowed)
const [v2Atokens, v2ReserveTokens, dataHelper] = await getV2Reserves(api, addressesProviderRegistryETH)
if (borrowed) {
await getBorrowed(balances, api.block, "ethereum", v2ReserveTokens, dataHelper);
} else {
await getTvl(balances, api.block, 'ethereum', v2Atokens, v2ReserveTokens);
}
await ammMarket(api, borrowed)
return balances;
}
@@ -39,7 +33,7 @@ async function stakingBalancerTvl(api) {
const aaveStakingContract = "0x4da27a545c0c5b758a6ba100e3a049001de870f5";
function v2(chain, v2Registry){
function v2(chain, v2Registry) {
const section = borrowed => sdk.util.sumChainTvls([
aaveChainTvl(chain, v2Registry, undefined, undefined, borrowed),
])
@@ -50,7 +44,7 @@ function v2(chain, v2Registry){
}
module.exports = {
methodology: methodologies.lendingMarket,
methodology: methodologies.lendingMarket,
ethereum: {
staking: staking(aaveStakingContract, aaveTokenAddress),
pool2: stakingBalancerTvl,
@@ -59,13 +53,13 @@ module.exports = {
},
avax: v2("avax", "0x4235E22d9C3f28DCDA82b58276cb6370B01265C2"),
polygon: v2("polygon", "0x3ac4e9aa29940770aeC38fe853a4bbabb2dA9C19"),
hallmarks:[
//[1618419730, "Start MATIC V2 Rewards"],
[1619470313, "Start Ethereum V2 Rewards"],
[1633377983, "Start AVAX V2 Rewards"],
[1635339600, "Potential xSUSHI attack found"],
[1651881600, "UST depeg"],
[1654822801, "stETH depeg"],
],
hallmarks: [
//[1618419730, "Start MATIC V2 Rewards"],
[1619470313, "Start Ethereum V2 Rewards"],
[1633377983, "Start AVAX V2 Rewards"],
[1635339600, "Potential xSUSHI attack found"],
[1651881600, "UST depeg"],
[1654822801, "stETH depeg"],
],
};
// node test.js projects/aave/index.js

View File

@@ -7,74 +7,89 @@ const { getChainTransform, getFixBalances, } = require('../helper/portedTokens')
const { sumTokens2, } = require('../helper/unwrapLPs');
const methodologies = require('./methodologies');
async function getV2Reserves(block, addressesProviderRegistry, chain, dataHelperAddress, abis = {}) {
async function getV2Reserves(api, addressesProviderRegistry, dataHelperAddress, { abis = {}, v3 } = {}) {
let validProtocolDataHelpers
const _abi = {
getAddressesProvidersList: abi.getAddressesProvidersList,
getAddress: abi.getAddress,
getReservesList: abi.getReservesList,
getReserveData: v3 ? abi.getReserveDataV3 : abi.getReserveData,
}
if (abis)
Object.entries(abis).forEach(([k, v]) => _abi[k] = v)
if (dataHelperAddress === undefined) {
const addressesProviders = (
await sdk.api.abi.call({
target: addressesProviderRegistry,
abi: abi["getAddressesProvidersList"],
block,
chain
})
).output;
const addressesProviders = await api.call({ target: addressesProviderRegistry, abi: _abi.getAddressesProvidersList, })
const protocolDataHelpers = (
await sdk.api.abi.multiCall({
calls: addressesProviders.map((provider) => ({
target: provider,
params: "0x0100000000000000000000000000000000000000000000000000000000000000",
})),
abi: abi["getAddress"],
block,
chain
})
).output;
validProtocolDataHelpers = protocolDataHelpers.filter(
(helper) =>
helper.output !== ADDRESSES.null
).map(p => p.output);
const protocolDataHelpers = await api.multiCall({
calls: addressesProviders.map((provider) => ({
target: provider,
params: "0x0100000000000000000000000000000000000000000000000000000000000000",
})),
abi: _abi.getAddress,
})
validProtocolDataHelpers = protocolDataHelpers.filter((helper) => helper !== ADDRESSES.null)
if (!validProtocolDataHelpers.length) {
console.log('No valid protocol data helpers found for', api.chain, addressesProviders)
const lendingPools = await api.multiCall({ calls: addressesProviders, abi: 'address:getLendingPool', })
const aTokenAddresses = []
const reserveAddresses = []
const borrowedAmounts = []
for (const lendingPool of lendingPools) {
const reserves = await api.call({ target: lendingPool, abi: _abi.getReservesList, })
const reserveData = await api.multiCall({ calls: reserves, abi: _abi.getReserveData, target: lendingPool, })
reserves.forEach((reserve, i) => {
reserveAddresses.push(reserve)
aTokenAddresses.push(reserveData[i].aTokenAddress)
})
if (v3) {
const supplyVariable = await api.multiCall({ abi: 'erc20:totalSupply', calls: reserveData.map(i => i.variableDebtTokenAddress), })
const supplyStable = await api.multiCall({ abi: 'erc20:totalSupply', calls: reserveData.map(i => i.stableDebtTokenAddress), })
reserveData.forEach((_, idx) => {
let value = +supplyVariable[idx] + +supplyStable[idx]
borrowedAmounts.push(value)
})
} else {
reserveData.forEach((data) => {
borrowedAmounts.push(+data.totalVariableDebt + +data.totalStableDebt)
})
}
}
return [aTokenAddresses, reserveAddresses, undefined, borrowedAmounts]
}
} else {
validProtocolDataHelpers = dataHelperAddress
}
const aTokenMarketData = (
await sdk.api.abi.multiCall({
calls: validProtocolDataHelpers.map((dataHelper) => ({
target: dataHelper,
})),
abi: abis.getAllATokens || abi["getAllATokens"],
block,
chain
})
).output;
const aTokenMarketData = await api.multiCall({ calls: validProtocolDataHelpers, abi: abis.getAllATokens || abi["getAllATokens"], })
let aTokenAddresses = [];
aTokenMarketData.map((aTokensData) => {
aTokenAddresses = [
...aTokenAddresses,
...aTokensData.output.map((aToken) => aToken[1]),
...aTokensData.map((aToken) => aToken[1]),
];
});
const underlyingAddressesData = (
await sdk.api.abi.multiCall({
calls: aTokenAddresses.map((aToken) => ({
target: aToken,
})),
abi: abi["getUnderlying"],
block,
chain
})
).output;
const reserveAddresses = underlyingAddressesData.map((reserveData) => reserveData.output);
const underlyingAddressesData = await api.multiCall({ calls: aTokenAddresses, abi: abi["getUnderlying"], })
const reserveAddresses = underlyingAddressesData
return [aTokenAddresses, reserveAddresses, validProtocolDataHelpers[0]]
}
async function getTvl(balances, block, chain, v2Atokens, v2ReserveTokens, transformAddress) {
if (!transformAddress) transformAddress = id => id
const balanceOfUnderlying = await sdk.api.abi.multiCall({
calls: v2Atokens.map((aToken, index) => ({
target: v2ReserveTokens[index],
@@ -87,7 +102,14 @@ async function getTvl(balances, block, chain, v2Atokens, v2ReserveTokens, transf
sdk.util.sumMultiBalanceOf(balances, balanceOfUnderlying, true, transformAddress)
}
async function getBorrowed(balances, block, chain, v2ReserveTokens, dataHelper, transformAddress, v3 = false) {
async function getBorrowed(balances, block, chain, v2ReserveTokens, dataHelper, transformAddress, v3 = false, { borrowedAmounts } = {}) {
if (!transformAddress) transformAddress = id => id
if (borrowedAmounts) {
borrowedAmounts.forEach((amount, idx) => {
sdk.util.sumSingleBalance(balances, transformAddress(v2ReserveTokens[idx]), amount)
})
return balances
}
const reserveData = await sdk.api.abi.multiCall({
calls: v2ReserveTokens.map((token) => ({
target: dataHelper,
@@ -109,9 +131,9 @@ function aaveChainTvl(_chain, addressesProviderRegistry, transformAddressRaw, da
const chain = api.chain
const block = api.block
const balances = {}
const { transformAddress, fixBalances, v2Atokens, v2ReserveTokens, dataHelper, updateBalances } = await getData({ oracle, chain, block, addressesProviderRegistry, dataHelperAddresses, transformAddressRaw, abis, })
const { transformAddress, fixBalances, v2Atokens, v2ReserveTokens, dataHelper, updateBalances, borrowedAmounts, } = await getData({ api, oracle, chain, block, addressesProviderRegistry, dataHelperAddresses, transformAddressRaw, abis, v3, })
if (borrowed) {
await getBorrowed(balances, block, chain, v2ReserveTokens, dataHelper, transformAddress, v3);
await getBorrowed(balances, block, chain, v2ReserveTokens, dataHelper, transformAddress, v3, { borrowedAmounts, });
} else {
await getTvl(balances, block, chain, v2Atokens, v2ReserveTokens, transformAddress);
}
@@ -145,47 +167,39 @@ module.exports = {
aaveV3Export,
}
const cachedData = {}
async function getData({ oracle, chain, block, addressesProviderRegistry, dataHelperAddresses, transformAddressRaw, abis, api, v3 }) {
async function getData({ oracle, chain, block, addressesProviderRegistry, dataHelperAddresses, transformAddressRaw, abis, }) {
let dataHelperAddressesStr
if (dataHelperAddresses && dataHelperAddresses.length) dataHelperAddressesStr = dataHelperAddresses.join(',')
const key = `${chain}-${block}-${addressesProviderRegistry}-${dataHelperAddresses}-${oracle}`
if (!cachedData[key]) cachedData[key] = _getData()
return cachedData[key]
if (!api)
api = new sdk.ChainApi({ chain, block })
async function _getData() {
sdk.log('get aava metadata:', key)
const transformAddress = transformAddressRaw || getChainTransform(chain)
const fixBalances = getFixBalances(chain)
const [v2Atokens, v2ReserveTokens, dataHelper, borrowedAmounts,] = await getV2Reserves(api, addressesProviderRegistry, dataHelperAddresses, { abis, v3, })
let updateBalances
const transformAddress = transformAddressRaw || getChainTransform(chain)
const fixBalances = getFixBalances(chain)
const [v2Atokens, v2ReserveTokens, dataHelper] = await getV2Reserves(block, addressesProviderRegistry, chain, dataHelperAddresses, abis)
let updateBalances
if (oracle) {
const params = { chain, block, target: oracle, }
const [
baseCurrency, baseCurrencyUnit, prices,
] = await Promise.all([
sdk.api2.abi.call({ ...params, abi: oracleAbis.BASE_CURRENCY, }),
sdk.api2.abi.call({ ...params, abi: oracleAbis.BASE_CURRENCY_UNIT, }),
sdk.api2.abi.call({ ...params, abi: oracleAbis.getAssetsPrices, params: [v2ReserveTokens], }),
])
if (oracle) {
const params = { chain, block, target: oracle, }
const [
baseCurrency, baseCurrencyUnit, prices,
] = await Promise.all([
sdk.api2.abi.call({ ...params, abi: oracleAbis.BASE_CURRENCY, }),
sdk.api2.abi.call({ ...params, abi: oracleAbis.BASE_CURRENCY_UNIT, }),
sdk.api2.abi.call({ ...params, abi: oracleAbis.getAssetsPrices, params: [v2ReserveTokens], }),
])
const baseToken = transformAddress(baseCurrency)
updateBalances = balances => {
v2ReserveTokens.map(i => `${chain}:${i.toLowerCase()}`).forEach((token, i) => {
if (!balances[token]) return;
const balance = balances[token] * prices[i] / baseCurrencyUnit
delete balances[token]
sdk.util.sumSingleBalance(balances, baseToken, balance)
})
return balances
}
const baseToken = transformAddress(baseCurrency)
updateBalances = balances => {
v2ReserveTokens.map(i => `${chain}:${i.toLowerCase()}`).forEach((token, i) => {
if (!balances[token]) return;
const balance = balances[token] * prices[i] / baseCurrencyUnit
delete balances[token]
sdk.util.sumSingleBalance(balances, baseToken, balance)
})
return balances
}
return { transformAddress, fixBalances, v2Atokens, v2ReserveTokens, dataHelper, updateBalances, }
}
return { transformAddress, fixBalances, v2Atokens, v2ReserveTokens, dataHelper, updateBalances, borrowedAmounts, }
}
const oracleAbis = {

View File

@@ -13,5 +13,6 @@
"getReserveDataV2": "function getReserveData(address asset) view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp)",
"getBPool": "address:bPool",
"getHelperReserveData": "function getReserveData(address asset) view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp)",
"getReserveTotalBorrows": "function getReserveTotalBorrows(address _reserve) view returns (uint256)"
"getReserveTotalBorrows": "function getReserveTotalBorrows(address _reserve) view returns (uint256)",
"getReserveDataV3": "function getReserveData(address asset) view returns (((uint256 data) configuration, uint128 liquidityIndex, uint128 variableBorrowIndex, uint128 currentLiquidityRate, uint128 currentVariableBorrowRate, uint128 currentStableBorrowRate, uint40 lastUpdateTimestamp, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint8 id))"
}

View File

@@ -11,7 +11,7 @@ const coreMarkets = {
pool2: staking("0x76ba3eC5f5adBf1C58c91e86502232317EeA72dE", "0x32df62dc3aed2cd6224193052ce665dc18165841"),
},
bsc: {
...aaveExports(undefined, '0x1e8323a513e099322aa435d172f1e7836fc620a5'),
...aaveExports(undefined, '0x1e8323a513e099322aa435d172f1e7836fc620a5', undefined, undefined, { v3: true }),
// balancer pool is not unwrapped properly, so we use staking and rely on price api instead
pool2: sumTokensExport({ owner: '0x4fd9f7c5ca0829a656561486bada018505dfcb5e', tokens: ['0x346575fc7f07e6994d76199e41d13dc1575322e1'], useDefaultCoreAssets: true, })
},
@@ -72,7 +72,7 @@ Object.keys(rizMarketsConfig).forEach(chain => {
module.exports = mergeExports([rizMarketExports, coreMarkets])
module.exports.hallmarks = [
// [1704178500, "flash loan exploit"],
// ['2024-10-16', 'Multisig was compromised'],
]
// module.exports.hallmarks = [
// // [1704178500, "flash loan exploit"],
// // ['2024-10-16', 'Multisig was compromised'],
// ]