diff --git a/src/adapters/compound-v3/arbitrum/index.ts b/src/adapters/compound-v3/arbitrum/index.ts index 94f01ecc8..1e3bf391b 100644 --- a/src/adapters/compound-v3/arbitrum/index.ts +++ b/src/adapters/compound-v3/arbitrum/index.ts @@ -1,5 +1,5 @@ import { getAssetsContracts } from '@adapters/compound-v3/common/asset' -import { getCompLendBalances, getCompRewardBalances } from '@adapters/compound-v3/common/balance' +import { getCompLendBalances } from '@adapters/compound-v3/common/balance' import type { BalancesContext, BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' import { resolveBalances } from '@lib/balance' import { getSingleStakeBalances } from '@lib/stake' @@ -25,6 +25,7 @@ const USDC_e: Token = { const cUSDCv3_n: Contract = { chain: 'arbitrum', address: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', + token: USDC.address, underlyings: [USDC], } @@ -32,6 +33,7 @@ const cUSDCv3_n: Contract = { const cUSDCv3_b: Contract = { chain: 'arbitrum', address: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', + token: USDC_e.address, underlyings: [USDC_e], } @@ -41,21 +43,20 @@ const rewarder: Contract = { } export const getContracts = async (ctx: BaseContext) => { - const assets = await getAssetsContracts(ctx, [cUSDCv3_n, cUSDCv3_b]) + const compounders = await getAssetsContracts(ctx, [cUSDCv3_n, cUSDCv3_b]) return { - contracts: { compounders: [cUSDCv3_n, cUSDCv3_b], assets, rewarder }, + contracts: { compounders }, revalidate: 60 * 60, } } const compoundBalances = async (ctx: BalancesContext, compounders: Contract[], rewarder: Contract) => { - return Promise.all([getSingleStakeBalances(ctx, compounders), getCompRewardBalances(ctx, rewarder, compounders)]) + return Promise.all([getSingleStakeBalances(ctx, compounders), getCompLendBalances(ctx, compounders, rewarder)]) } export const getBalances: GetBalancesHandler = async (ctx, contracts) => { const balances = await resolveBalances(ctx, contracts, { - assets: (...args) => getCompLendBalances(...args, [cUSDCv3_n, cUSDCv3_b]), compounders: (...args) => compoundBalances(...args, rewarder), }) diff --git a/src/adapters/compound-v3/base/index.ts b/src/adapters/compound-v3/base/index.ts index d9bd4a6e7..8da78d80c 100644 --- a/src/adapters/compound-v3/base/index.ts +++ b/src/adapters/compound-v3/base/index.ts @@ -1,5 +1,5 @@ import { getAssetsContracts } from '@adapters/compound-v3/common/asset' -import { getCompLendBalances, getCompRewardBalances } from '@adapters/compound-v3/common/balance' +import { getCompLendBalances } from '@adapters/compound-v3/common/balance' import type { BalancesContext, BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' import { resolveBalances } from '@lib/balance' import { getSingleStakeBalances } from '@lib/stake' @@ -37,21 +37,20 @@ const rewarder: Contract = { } export const getContracts = async (ctx: BaseContext) => { - const assets = await getAssetsContracts(ctx, [cUSDbCv3, cWETHv3]) + const compounders = await getAssetsContracts(ctx, [cUSDbCv3, cWETHv3]) return { - contracts: { compounders: [cUSDbCv3, cWETHv3], assets, rewarder }, + contracts: { compounders }, revalidate: 60 * 60, } } const compoundBalances = async (ctx: BalancesContext, compounders: Contract[], rewarder: Contract) => { - return Promise.all([getSingleStakeBalances(ctx, compounders), getCompRewardBalances(ctx, rewarder, compounders)]) + return Promise.all([getSingleStakeBalances(ctx, compounders), getCompLendBalances(ctx, compounders, rewarder)]) } export const getBalances: GetBalancesHandler = async (ctx, contracts) => { const balances = await resolveBalances(ctx, contracts, { - assets: (...args) => getCompLendBalances(...args, [cUSDbCv3, cWETHv3]), compounders: (...args) => compoundBalances(...args, rewarder), }) diff --git a/src/adapters/compound-v3/common/asset.ts b/src/adapters/compound-v3/common/asset.ts index ae3974af0..32ec967d8 100644 --- a/src/adapters/compound-v3/common/asset.ts +++ b/src/adapters/compound-v3/common/asset.ts @@ -1,5 +1,6 @@ import type { BaseContext, Contract } from '@lib/adapter' -import { mapSuccessFilter, range } from '@lib/array' +import { mapMultiSuccessFilter, mapSuccessFilter, range } from '@lib/array' +import { abi as erc20Abi } from '@lib/erc20' import { multicall } from '@lib/multicall' const abi = { @@ -62,10 +63,36 @@ export async function getAssetsContracts(ctx: BaseContext, compounders: Contract abi: abi.getAssetInfo, }) - return mapSuccessFilter(assetsInfoRes, (res) => ({ + const rawAssets = mapSuccessFilter(assetsInfoRes, (res) => ({ chain: ctx.chain, address: res.output.asset, compounder: res.input.target, collateralFactor: res.output.borrowCollateralFactor, })) + + const [symbolRes, decimalsRes] = await Promise.all([ + multicall({ ctx, calls: rawAssets.map((asset) => ({ target: asset.address }) as const), abi: erc20Abi.symbol }), + multicall({ ctx, calls: rawAssets.map((asset) => ({ target: asset.address }) as const), abi: erc20Abi.decimals }), + ]) + + const assets: Contract[] = mapMultiSuccessFilter( + symbolRes.map((_, i) => [symbolRes[i], decimalsRes[i]]), + + (res, index) => { + const rawAsset = rawAssets[index] + const [{ output: symbol }, { output: decimals }] = res.inputOutputPairs + + return { + ...rawAsset, + decimals, + symbol, + } + }, + ) + + compounders.forEach((compounder) => { + compounder.assets = assets.filter((asset) => asset.compounder === compounder.address) + }) + + return compounders } diff --git a/src/adapters/compound-v3/common/balance.ts b/src/adapters/compound-v3/common/balance.ts index 6d1c92dbb..8cc31fece 100644 --- a/src/adapters/compound-v3/common/balance.ts +++ b/src/adapters/compound-v3/common/balance.ts @@ -55,10 +55,12 @@ const COMP: { [key: string]: `0x${string}` } = { export async function getCompLendBalances( ctx: BalancesContext, - assets: Contract[], compounders: Contract[], + rewarder: Contract, ): Promise { - const [userLendBalances, userBorrowBalances] = await Promise.all([ + const assets = compounders.flatMap((compounder) => compounder.assets) + + const [userLendBalances, userBorrowBalances, pendingCompRewards] = await Promise.all([ multicall({ ctx, calls: assets.map((asset) => ({ target: asset.compounder, params: [ctx.address, asset.address] }) as const), @@ -69,56 +71,36 @@ export async function getCompLendBalances( calls: compounders.map((compounder) => ({ target: compounder.address, params: [ctx.address] }) as const), abi: abi.borrowBalanceOf, }), + multicall({ + ctx, + calls: compounders.map( + (contract) => ({ target: rewarder.address, params: [contract.address, ctx.address] }) as const, + ), + abi: abi.getRewardOwed, + }), ]) const supplyBalance: Balance[] = mapSuccessFilter(userLendBalances, (res, index) => { + const asset = assets[index] as Balance const [balance, _reserved] = res.output - return { - chain: ctx.chain, - decimals: assets[index].decimals, - symbol: assets[index].symbol, - address: assets[index].address, + ...asset, amount: balance, - collateralFactor: assets[index].collateralFactor, category: 'lend', } }) const borrowBalance: Balance[] = mapSuccessFilter(userBorrowBalances, (res, index) => { const underlying = compounders[index].underlyings?.[0] as Contract - - if (!underlying) { - return null - } - + if (!underlying) return null return { - chain: ctx.chain, - decimals: underlying.decimals, - symbol: underlying.symbol, - address: underlying.address, + ...underlying, amount: res.output, category: 'borrow', } }).filter(isNotNullish) as Balance[] - return [...supplyBalance, ...borrowBalance] -} - -export async function getCompRewardBalances( - ctx: BalancesContext, - rewarder: Contract, - compounders: Contract[], -): Promise { - const pendingCompRewards = await multicall({ - ctx, - calls: compounders.map( - (contract) => ({ target: rewarder.address, params: [contract.address, ctx.address] }) as const, - ), - abi: abi.getRewardOwed, - }) - - return mapSuccessFilter(pendingCompRewards, (res) => ({ + const rewardBalance: Balance[] = mapSuccessFilter(pendingCompRewards, (res) => ({ chain: ctx.chain, address: COMP[ctx.chain], decimals: 18, @@ -126,4 +108,6 @@ export async function getCompRewardBalances( amount: res.output.owed, category: 'reward', })) + + return [...supplyBalance, ...borrowBalance, ...rewardBalance] } diff --git a/src/adapters/compound-v3/ethereum/index.ts b/src/adapters/compound-v3/ethereum/index.ts index 08cc1a988..0f0a0adc0 100644 --- a/src/adapters/compound-v3/ethereum/index.ts +++ b/src/adapters/compound-v3/ethereum/index.ts @@ -1,5 +1,5 @@ import { getAssetsContracts } from '@adapters/compound-v3/common/asset' -import { getCompLendBalances, getCompRewardBalances } from '@adapters/compound-v3/common/balance' +import { getCompLendBalances } from '@adapters/compound-v3/common/balance' import type { BalancesContext, BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' import { resolveBalances } from '@lib/balance' import { getSingleStakeBalances } from '@lib/stake' @@ -37,21 +37,20 @@ const rewarder: Contract = { } export const getContracts = async (ctx: BaseContext) => { - const assets = await getAssetsContracts(ctx, [cUSDCv3, cWETHv3]) + const compounders = await getAssetsContracts(ctx, [cUSDCv3, cWETHv3]) return { - contracts: { compounders: [cUSDCv3, cWETHv3], assets, rewarder }, + contracts: { compounders }, revalidate: 60 * 60, } } const compoundBalances = async (ctx: BalancesContext, compounders: Contract[], rewarder: Contract) => { - return Promise.all([getSingleStakeBalances(ctx, compounders), getCompRewardBalances(ctx, rewarder, compounders)]) + return Promise.all([getSingleStakeBalances(ctx, compounders), getCompLendBalances(ctx, compounders, rewarder)]) } export const getBalances: GetBalancesHandler = async (ctx, contracts) => { const balances = await resolveBalances(ctx, contracts, { - assets: (...args) => getCompLendBalances(...args, [cUSDCv3, cWETHv3]), compounders: (...args) => compoundBalances(...args, rewarder), }) diff --git a/src/adapters/compound-v3/polygon/index.ts b/src/adapters/compound-v3/polygon/index.ts index 59287b6fb..cb04b03a0 100644 --- a/src/adapters/compound-v3/polygon/index.ts +++ b/src/adapters/compound-v3/polygon/index.ts @@ -1,5 +1,5 @@ import { getAssetsContracts } from '@adapters/compound-v3/common/asset' -import { getCompLendBalances, getCompRewardBalances } from '@adapters/compound-v3/common/balance' +import { getCompLendBalances } from '@adapters/compound-v3/common/balance' import type { BalancesContext, BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' import { resolveBalances } from '@lib/balance' import { getSingleStakeBalances } from '@lib/stake' @@ -24,21 +24,20 @@ const rewarder: Contract = { } export const getContracts = async (ctx: BaseContext) => { - const assets = await getAssetsContracts(ctx, [cUSDCv3]) + const compounders = await getAssetsContracts(ctx, [cUSDCv3]) return { - contracts: { compounders: [cUSDCv3], assets, rewarder }, + contracts: { compounders }, revalidate: 60 * 60, } } const compoundBalances = async (ctx: BalancesContext, compounders: Contract[], rewarder: Contract) => { - return Promise.all([getSingleStakeBalances(ctx, compounders), getCompRewardBalances(ctx, rewarder, compounders)]) + return Promise.all([getSingleStakeBalances(ctx, compounders), getCompLendBalances(ctx, compounders, rewarder)]) } export const getBalances: GetBalancesHandler = async (ctx, contracts) => { const balances = await resolveBalances(ctx, contracts, { - assets: (...args) => getCompLendBalances(...args, [cUSDCv3]), compounders: (...args) => compoundBalances(...args, rewarder), })