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

Moveflow #11229

Closed
wants to merge 5 commits into from
Closed

Moveflow #11229

Show file tree
Hide file tree
Changes from 3 commits
Commits
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
14 changes: 14 additions & 0 deletions projects/blend-finance/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

const { aaveExports } = require('../helper/blend')
const methodologies = require('../helper/methodologies')
const { mergeExports } = require('../helper/utils')

const mainMarket = {
bevm: aaveExports('bevm', '0x26fb0b1eef8822f8F71a385d2839b6a654cA186a', undefined, ['0x3Eb2Dd6c395B8E6E3ab843858480aC60e9D0f3Bc'], {v3: true}),
}

const innovativeMarket = {
}

module.exports = mergeExports(mainMarket, innovativeMarket)
module.exports.methodology = methodologies.lendingMarket
17 changes: 17 additions & 0 deletions projects/helper/abis/blend.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"getTotalDebt": "function getTotalDebt(address asset) view returns (uint256)",
"getReservesList": "address[]:getReservesList",
"getAMMReserveData": "function getReserveData(address asset) view returns (tuple(tuple(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))",
"getCurrentTokens": "address[]:getCurrentTokens",
"getReserveData": "function getReserveData(address _reserve) view returns (uint256 totalLiquidity, uint256 availableLiquidity, uint256 totalBorrowsStable, uint256 totalBorrowsVariable, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 utilizationRate, uint256 liquidityIndex, uint256 variableBorrowIndex, address aTokenAddress, uint40 lastUpdateTimestamp)",
"getReserveConfigurationData": "function getReserveConfigurationData(address _reserve) view returns (uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, address interestRateStrategyAddress, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive)",
"getReserves": "address[]:getReserves",
"getAddressesProvidersList": "address[]:getAddressesProvidersList",
"getAddress": "function getAddress(bytes32 id) view returns (address)",
"getAllBTokens": "function getAllBTokens() view returns (tuple(string symbol, address tokenAddress)[])",
"getUnderlying": "address:UNDERLYING_ASSET_ADDRESS",
"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)"
}
299 changes: 299 additions & 0 deletions projects/helper/blend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
const { getLogs } = require('./cache/getLogs')
const ADDRESSES = require('./coreAssets.json')
const sdk = require('@defillama/sdk');
const { default: BigNumber } = require('bignumber.js');
const abi = require('./abis/blend.json');
const { getChainTransform, getFixBalancesSync, } = require('../helper/portedTokens')
const { sumTokens2 } = require('../helper/unwrapLPs');
const methodologies = require('./methodologies');

async function getV2Reserves(block, addressesProviderRegistry, chain, dataHelperAddress, abis = {}) {
let validProtocolDataHelpers
if (dataHelperAddress === undefined) {
const addressesProviders = (
await sdk.api.abi.call({
target: addressesProviderRegistry,
abi: abi["getAddressesProvidersList"],
block,
chain
})
).output;

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);
} else {
validProtocolDataHelpers = dataHelperAddress
}

console.log({validProtocolDataHelpers});
console.log({sdk});
console.log({block});
console.log({chain});


const aTokenMarketData = (
await sdk.api.abi.multiCall({
calls: validProtocolDataHelpers.map((dataHelper) => ({
target: dataHelper,
})),
abi: abis.getAllBTokens || abi["getAllBTokens"],
block,
chain
})
).output;

let aTokenAddresses = [];
aTokenMarketData.map((aTokensData) => {
aTokenAddresses = [
...aTokenAddresses,
...aTokensData.output.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);

return [aTokenAddresses, reserveAddresses, validProtocolDataHelpers[0]]
}

async function getTvl(balances, block, chain, v2Atokens, v2ReserveTokens, transformAddress) {
const balanceOfUnderlying = await sdk.api.abi.multiCall({
calls: v2Atokens.map((aToken, index) => ({
target: v2ReserveTokens[index],
params: aToken,
})),
abi: "erc20:balanceOf",
block,
chain
});
sdk.util.sumMultiBalanceOf(balances, balanceOfUnderlying, true, transformAddress)
}

async function getBorrowed(balances, block, chain, v2ReserveTokens, dataHelper, transformAddress, v3 = false) {
const reserveData = await sdk.api.abi.multiCall({
calls: v2ReserveTokens.map((token) => ({
target: dataHelper,
params: [token],
})),
abi: v3 ? abi.getTotalDebt : abi.getHelperReserveData,
block,
chain
});

reserveData.output.forEach((data, idx) => {
const quantity = v3 ? data.output : BigNumber(data.output.totalVariableDebt).plus(data.output.totalStableDebt).toFixed(0)
sdk.util.sumSingleBalance(balances, transformAddress(data.input.params[0]), quantity)
})
}

function aaveChainTvl(_chain, addressesProviderRegistry, transformAddressRaw, dataHelperAddresses, borrowed, v3 = false, { abis = {}, oracle, blacklistedTokens = [], hasV2LPs = false, } = {}) {
return async (api) => {
console.log("api.chain",api.chain);


const chain = api.chain
const block = api.block
const balances = {}
console.log({oracle, chain, block, addressesProviderRegistry, dataHelperAddresses, transformAddressRaw, abis,});

const { transformAddress, fixBalances, v2Atokens, v2ReserveTokens, dataHelper, updateBalances } = await getData({ oracle, chain, block, addressesProviderRegistry, dataHelperAddresses, transformAddressRaw, abis, })
console.log({balances, block, chain, v2Atokens, v2ReserveTokens, transformAddress});

if (borrowed) {
await getBorrowed(balances, block, chain, v2ReserveTokens, dataHelper, transformAddress, v3);
} else {
await getTvl(balances, block, chain, v2Atokens, v2ReserveTokens, transformAddress);
}
if (updateBalances) updateBalances(balances)
fixBalances(balances)
Object.keys(balances).forEach((key) => {
if (!blacklistedTokens.length) return;
if (blacklistedTokens.some(i => new RegExp(i, 'gi').test(key))) {
delete balances[key]
}
})
if (hasV2LPs) await sumTokens2({ block, resolveLP: true, balances, chain, })
return balances
}
}
function aaveExports(_chain, addressesProviderRegistry, transform = undefined, dataHelpers = undefined, { oracle, abis, v3 = false, blacklistedTokens = [], hasV2LPs = false, } = {}) {
return {
tvl: aaveChainTvl(_chain, addressesProviderRegistry, transform, dataHelpers, false, v3, { oracle, abis, blacklistedTokens, hasV2LPs, }),
borrowed: aaveChainTvl(_chain, addressesProviderRegistry, transform, dataHelpers, true, v3, { oracle, abis, hasV2LPs, blacklistedTokens, })
}
}

module.exports = {
methodology: methodologies.lendingMarket,
aaveChainTvl,
getV2Reserves,
getTvl,
aaveExports,
getBorrowed,
aaveV2Export,
}

const cachedData = {}

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}`
console.log({key});

if (!cachedData[key]) cachedData[key] = _getData()

return cachedData[key]

async function _getData() {
sdk.log('get aava metadata:', key)

const transformAddress = transformAddressRaw || await getChainTransform(chain)
const fixBalances = await getFixBalancesSync(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], }),
])

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, }
}
}

const oracleAbis = {
BASE_CURRENCY: "address:BASE_CURRENCY",
BASE_CURRENCY_UNIT: "uint256:BASE_CURRENCY_UNIT",
getAssetsPrices: "function getAssetsPrices(address[] assets) view returns (uint256[])",
}

function aaveV2Export(registry, { useOracle = false, baseCurrency, baseCurrencyUnit, abis = {}, fromBlock, blacklistedTokens = [] } = {}) {

async function tvl(api) {
const data = await getReservesData(api)
const tokensAndOwners = data.map(i => ([i.underlying, i.aTokenAddress]))
if (!useOracle)
return sumTokens2({ tokensAndOwners, api, blacklistedTokens })
const balances = {}
const res = await api.multiCall({ abi: 'erc20:balanceOf', calls: tokensAndOwners.map(i => ({ target: i[0], params: i[1] })) })
res.forEach((v, i) => {
sdk.util.sumSingleBalance(balances, data[i].currency, v * data[i].price, api.chain)
})
return balances
}

async function borrowed(api) {
const balances = {}
const data = await getReservesData(api)
const supplyVariable = await api.multiCall({
abi: 'erc20:totalSupply',
calls: data.map(i => i.variableDebtTokenAddress),
})
const supplyStable = await api.multiCall({
abi: 'erc20:totalSupply',
calls: data.map(i => i.stableDebtTokenAddress),
})
data.forEach((i, idx) => {
let value = +supplyVariable[idx] + +supplyStable[idx]
if (useOracle) {
sdk.util.sumSingleBalance(balances, i.currency, value * i.price, api.chain)
} else {
sdk.util.sumSingleBalance(balances, i.underlying, value, api.chain)
}
})
return balances
}

async function getReservesData(api) {
if (fromBlock) return getReservesDataFromBlock(api)
const tokens = await api.call({ abi: abiv2.getReservesList, target: registry })
const data = await api.multiCall({ abi: abis.getReserveData ?? abiv2.getReserveData, calls: tokens, target: registry, })
data.forEach((v, i) => v.underlying = tokens[i])
if (useOracle) {
let currency = baseCurrency
let unit = baseCurrencyUnit

const addressProvider = await api.call({ abi: abiv2.getAddressesProvider, target: registry })
const oracle = await api.call({ abi: abiv2.getPriceOracle, target: addressProvider })

if (!currency) currency = await api.call({ abi: abiv2.BASE_CURRENCY, target: oracle })
if (!unit) unit = await api.call({ abi: abiv2.BASE_CURRENCY_UNIT, target: oracle })

const decimals = await api.multiCall({ abi: 'erc20:decimals', calls: tokens })
// const currencyDecimal = await api.call({ abi: 'erc20:decimals', target: currency })
const currencyDecimal = 18
const prices = await api.call({ abi: abiv2.getAssetsPrices, target: oracle, params: [tokens] })
prices.forEach((v, i) => {
data[i].price = (v / unit )/ (10 ** (decimals[i] - currencyDecimal))
data[i].currency = currency
})
}
return data
}

async function getReservesDataFromBlock(api) {
const logs = await getLogs({
api,
target: registry,
topics: ['0x3a0ca721fc364424566385a1aa271ed508cc2c0949c2272575fb3013a163a45f'],
fromBlock,
eventAbi: 'event ReserveInitialized (address indexed underlying, address indexed aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress)',
onlyArgs: true,
})
return logs
}

const abiv2 = {
getReservesList: "address[]:getReservesList",
getAddressesProvider: "address:getAddressesProvider",
BASE_CURRENCY: "address:BASE_CURRENCY",
BASE_CURRENCY_UNIT: "uint256:BASE_CURRENCY_UNIT",
getPriceOracle: "address:getPriceOracle",
getAssetsPrices: "function getAssetsPrices(address[]) view returns (uint256[])",
getReserveData: "function getReserveData(address asset) view returns (tuple(tuple(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))",
}

return { tvl, borrowed, }
}
6 changes: 5 additions & 1 deletion projects/helper/coreAssets.json
Original file line number Diff line number Diff line change
Expand Up @@ -1730,7 +1730,11 @@
"WETH": "0x7526B5318Cbe690FBd3eC8DD7ad122f4F1b1d76F"
},
"bevm": {
"WBTC": "0xB5136FEba197f5fF4B765E5b50c74db717796dcD"
"WBTC": "0xB5136FEba197f5fF4B765E5b50c74db717796dcD",
"SAT": "0xF2692468666E459D87052f68aE474E36C1a34fbB",
"USDT": "0xa67ed736649f2958a35fd249a584151056b4b745",
"USDC": "0x915247bf09471922e2c6da6f69fc9114708e8a26",
"ETH": "0x948def74953a18ebd854a5b015f63b0910be58cc"
},
"degen": {
"WDEGEN": "0xeb54dacb4c2ccb64f8074eceea33b5ebb38e5387"
Expand Down
46 changes: 46 additions & 0 deletions projects/moveflow/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const ADDRESSES = require('../helper/coreAssets.json')
const sdk = require("@defillama/sdk");
const { staking } = require("../helper/staking");
const { sumTokensAndLPsSharedOwners } = require("../helper/unwrapLPs");
const { request, gql } = require("graphql-request");
const { getBlock } = require('../helper/http')
const { transformBalances } = require("../helper/portedTokens");

const graphUrl = 'https://main-api.flow.movefuns.xyz/'
const graphQuery = gql`
query ExampleQuery {
tvl {
coin_type
lock_amount
}
}`
async function getTokenAmount() {
const data = await request(
graphUrl,
graphQuery,
{},
{
"x-auth-info":"123"
}
);
console.log("data.tvl",data.tvl);
return data.tvl
}

async function aptosTvl(api) {
const coinContainers = await getTokenAmount();

coinContainers.map((item)=>{
api.add(item.coin_type, parseInt(item.lock_amount));
})
}




module.exports = {
aptos: {
tvl: aptosTvl,
},

};
Loading