Skip to content

Commit

Permalink
refactor: decouple getPools function
Browse files Browse the repository at this point in the history
  • Loading branch information
therealemjy committed Dec 17, 2024
1 parent f12a609 commit 1a9ca79
Show file tree
Hide file tree
Showing 13 changed files with 327 additions and 291 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ const userIsolatedCollateralizedVTokenAddresses = [
'0xee543d5de2dbb5b07675fc72831a2f1812428393',
];

const userCollateralizedVTokenAddresses = [
const userCollateralVTokenAddresses = [
...userLegacyCollateralizedVTokenAddresses,
...userIsolatedCollateralizedVTokenAddresses,
];

const vTokenBalancesAllMock = async (vTokenAddresses: string[]) =>
vTokenAddresses.map(vTokenAddress => {
const isUserCollateral = userCollateralizedVTokenAddresses.some(
const isUserCollateral = userCollateralVTokenAddresses.some(
a => a.toLowerCase() === vTokenAddress.toLowerCase(),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1075,15 +1075,6 @@ exports[`useGetPools > does not fetch Prime distributions if user is not Prime 1
"userSupplyBalanceCents": "199992566000000",
},
],
"primeVTokenAddresses": [
"0xD5C4C2e2facBEB59D0216D0595d63FcDc6F9A1a7",
"0xb7526572FFE56AB9D7489838Bf2E18e3323b441A",
"0x08e0A5575De71037aE36AbfAfb516595fE68e5e4",
"0x74469281310195A04840Daf6EdF576F559a3dE80",
"0x3338988d0beb4419Acb8fE624218754053362D06",
"0x2197d02cC9cd1ad51317A0a85A656a0c82383A7c",
"0x712774CBFFCBD60e9825871CcEFF2F917442b2c3",
],
}
`;

Expand Down Expand Up @@ -2282,15 +2273,6 @@ exports[`useGetPools > fetches and formats Prime distributions and Prime distrib
"userSupplyBalanceCents": "199992566000000",
},
],
"primeVTokenAddresses": [
"0xD5C4C2e2facBEB59D0216D0595d63FcDc6F9A1a7",
"0xb7526572FFE56AB9D7489838Bf2E18e3323b441A",
"0x08e0A5575De71037aE36AbfAfb516595fE68e5e4",
"0x74469281310195A04840Daf6EdF576F559a3dE80",
"0x3338988d0beb4419Acb8fE624218754053362D06",
"0x2197d02cC9cd1ad51317A0a85A656a0c82383A7c",
"0x712774CBFFCBD60e9825871CcEFF2F917442b2c3",
],
}
`;

Expand Down Expand Up @@ -3309,14 +3291,5 @@ exports[`useGetPools > filters out Prime simulations that are 0 1`] = `
"userSupplyBalanceCents": "199992566000000",
},
],
"primeVTokenAddresses": [
"0xD5C4C2e2facBEB59D0216D0595d63FcDc6F9A1a7",
"0xb7526572FFE56AB9D7489838Bf2E18e3323b441A",
"0x08e0A5575De71037aE36AbfAfb516595fE68e5e4",
"0x74469281310195A04840Daf6EdF576F559a3dE80",
"0x3338988d0beb4419Acb8fE624218754053362D06",
"0x2197d02cC9cd1ad51317A0a85A656a0c82383A7c",
"0x712774CBFFCBD60e9825871CcEFF2F917442b2c3",
],
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,6 @@ exports[`useGetPools > returns pools in the correct format 1`] = `
"userSupplyBalanceCents": "0",
},
],
"primeVTokenAddresses": [],
}
`;

Expand Down Expand Up @@ -1790,7 +1789,6 @@ exports[`useGetPools > returns pools with time based reward rates in the correct
"userSupplyBalanceCents": "0",
},
],
"primeVTokenAddresses": [],
}
`;

Expand Down Expand Up @@ -2687,6 +2685,5 @@ exports[`useGetPools > returns pools with user data in the correct format 1`] =
"userSupplyBalanceCents": "199992566000000",
},
],
"primeVTokenAddresses": [],
}
`;
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type BigNumber from 'bignumber.js';

import type { AssetDistribution, PrimeApy, Token } from 'types';
import type { AssetDistribution, Token } from 'types';
import { calculateDailyTokenRate } from 'utilities/calculateDailyTokenRate';
import findTokenByAddress from 'utilities/findTokenByAddress';
import formatRewardDistribution from 'utilities/formatRewardDistribution';

import type { ApiRewardDistributor } from 'clients/api/queries/useGetPools/getPools/getApiPools';
import { convertPriceMantissaToDollars } from 'utilities';
import type { PrimeApy } from '../../../types';
import { isDistributingRewards } from './isDistributingRewards';

export type FormatDistributionsInput = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import BigNumber from 'bignumber.js';
import { NATIVE_TOKEN_ADDRESS } from 'constants/address';
import { COMPOUND_DECIMALS } from 'constants/compoundMantissa';
import type { PoolLens } from 'libs/contracts';
import type { Asset, ChainId, Pool, PrimeApy, Token, TokenBalance, VToken } from 'types';
import type { Asset, ChainId, Pool, Token, TokenBalance, VToken } from 'types';
import {
areAddressesEqual,
areTokensEqual,
Expand All @@ -16,7 +16,7 @@ import {
getDisabledTokenActions,
isPoolIsolated,
} from 'utilities';
import type { MarketParticipantsCounts } from '../../types';
import type { MarketParticipantsCounts, PrimeApy } from '../../types';
import type { ApiPool } from '../getApiPools';
import { formatDistributions } from './formatDistributions';

Expand All @@ -26,19 +26,19 @@ export const formatOutput = ({
tokens,
currentBlockNumber,
isolatedPoolParticipantsCountMap,
primeApyMap,
userPrimeApyMap,
userVTokenBalances = [],
userTokenBalances = [],
userCollateralizedVTokenAddresses = [],
userCollateralVTokenAddresses = [],
userVaiBorrowBalanceMantissa,
}: {
chainId: ChainId;
tokens: Token[];
currentBlockNumber: number;
apiPools: ApiPool[];
primeApyMap: Map<string, PrimeApy>;
isolatedPoolParticipantsCountMap: Map<string, MarketParticipantsCounts>;
userCollateralizedVTokenAddresses?: string[];
isolatedPoolParticipantsCountMap?: Map<string, MarketParticipantsCounts>;
userPrimeApyMap?: Map<string, PrimeApy>;
userCollateralVTokenAddresses?: string[];
userVTokenBalances?: Awaited<ReturnType<PoolLens['callStatic']['vTokenBalancesAll']>>;
userTokenBalances?: TokenBalance[];
userVaiBorrowBalanceMantissa?: BigNumber;
Expand Down Expand Up @@ -139,7 +139,7 @@ export const formatOutput = ({
blocksPerDay,
underlyingToken: vToken.underlyingToken,
underlyingTokenPriceDollars: tokenPriceDollars,
primeApy: primeApyMap.get(vToken.address),
primeApy: userPrimeApyMap?.get(vToken.address),
tokens,
supplyBalanceTokens,
borrowBalanceTokens,
Expand Down Expand Up @@ -187,7 +187,7 @@ export const formatOutput = ({
const userBorrowBalanceCents = userBorrowBalanceTokens.multipliedBy(tokenPriceCents);
const userWalletBalanceCents = userWalletBalanceTokens.multipliedBy(tokenPriceCents);

const isCollateralOfUser = !!userCollateralizedVTokenAddresses.some(address =>
const isCollateralOfUser = !!userCollateralVTokenAddresses.some(address =>
areAddressesEqual(address, vToken.address),
);

Expand All @@ -201,11 +201,11 @@ export const formatOutput = ({
}

const supplierCount = isIsolated
? isolatedPoolParticipantsCountMap.get(vToken.address.toLowerCase())?.supplierCount ?? 0
? isolatedPoolParticipantsCountMap?.get(vToken.address.toLowerCase())?.supplierCount ?? 0
: market.supplierCount;

const borrowerCount = isIsolated
? isolatedPoolParticipantsCountMap.get(vToken.address.toLowerCase())?.borrowerCount ?? 0
? isolatedPoolParticipantsCountMap?.get(vToken.address.toLowerCase())?.borrowerCount ?? 0
: market.borrowerCount;

const asset: Asset = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getIsolatedPoolParticipantsCount } from 'clients/subgraph';
import type { ChainId } from 'types';
import type { MarketParticipantsCounts } from '../../types';

export const getIsolatedPoolParticipantCounts = async ({ chainId }: { chainId: ChainId }) => {
const isolatedPoolParticipantsCount = await getIsolatedPoolParticipantsCount({ chainId });

const isolatedPoolParticipantsCountMap = new Map<string, MarketParticipantsCounts>();
(isolatedPoolParticipantsCount?.pools || []).forEach(pool =>
pool.markets.forEach(market => {
isolatedPoolParticipantsCountMap.set(market.id.toLowerCase(), {
borrowerCount: +market.borrowerCount,
supplierCount: +market.supplierCount,
});
}),
);

return { isolatedPoolParticipantsCountMap };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
type IsolatedPoolComptroller,
type LegacyPoolComptroller,
getIsolatedPoolComptrollerContract,
} from 'libs/contracts';
import type { Provider } from 'libs/wallet';
import type { ChainId } from 'types';
import { isPoolIsolated } from 'utilities';
import type { ApiPool } from '../getApiPools';

export const getUserCollateralAddresses = async ({
accountAddress,
apiPools,
chainId,
provider,
legacyPoolComptrollerContract,
}: {
accountAddress: string;
apiPools: ApiPool[];
chainId: ChainId;
provider: Provider;
legacyPoolComptrollerContract?: LegacyPoolComptroller;
}) => {
const getAssetsInPromises: ReturnType<IsolatedPoolComptroller['getAssetsIn']>[] = [];

apiPools.forEach(pool => {
const isIsolated = isPoolIsolated({
chainId,
comptrollerAddress: pool.address,
});

if (!isIsolated) {
return;
}

const comptrollerContract = getIsolatedPoolComptrollerContract({
signerOrProvider: provider,
address: pool.address,
});

if (accountAddress) {
getAssetsInPromises.push(comptrollerContract.getAssetsIn(accountAddress));
}
});

if (accountAddress && legacyPoolComptrollerContract) {
getAssetsInPromises.push(legacyPoolComptrollerContract.getAssetsIn(accountAddress));
}

const results = await Promise.all(getAssetsInPromises);

return { userCollateralAddresses: results.flat() };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Prime } from 'libs/contracts';
import { convertAprBipsToApy } from 'utilities';
import type { PrimeApy } from '../../types';

export const getUserPrimeApys = async ({
primeContract,
accountAddress,
primeVTokenAddresses,
}: { primeContract: Prime; accountAddress: string; primeVTokenAddresses: string[] }) => {
const primeAprs = await Promise.all(
primeVTokenAddresses.map(primeVTokenAddress =>
primeContract.calculateAPR(primeVTokenAddress, accountAddress),
),
);

const userPrimeApyMap = new Map<string, PrimeApy>();
primeAprs.forEach((primeApr, index) => {
const apys: PrimeApy = {
borrowApy: convertAprBipsToApy({ aprBips: primeApr.borrowAPR.toString() || '0' }),
supplyApy: convertAprBipsToApy({ aprBips: primeApr.supplyAPR.toString() || '0' }),
};

userPrimeApyMap.set(primeVTokenAddresses[index], apys);
});

return { userPrimeApyMap };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { getTokenBalances } from 'clients/api';
import { NATIVE_TOKEN_ADDRESS } from 'constants/address';
import type { PoolLens, VenusLens } from 'libs/contracts';
import type { Provider } from 'libs/wallet';
import type { ChainId, Token } from 'types';
import { findTokenByAddress, isPoolIsolated } from 'utilities';
import type { ApiPool } from '../getApiPools';

export const getUserTokenBalances = async ({
accountAddress,
apiPools,
chainId,
tokens,
provider,
poolLensContract,
venusLensContract,
}: {
accountAddress: string;
apiPools: ApiPool[];
chainId: ChainId;
tokens: Token[];
provider: Provider;
poolLensContract: PoolLens;
venusLensContract?: VenusLens;
}) => {
// Extract token records and addresses
const [legacyPoolVTokenAddresses, isolatedPoolsVTokenAddresses, underlyingTokens] =
apiPools.reduce<[string[], string[], Token[]]>(
(acc, pool) => {
const newLegacyPoolVTokenAddresses: string[] = [];
const newIsolatedPoolsVTokenAddresses: string[] = [];
const newUnderlyingTokens: Token[] = [];
const newUnderlyingTokenAddresses: string[] = [];

pool.markets.forEach(market => {
const isIsolated = isPoolIsolated({
chainId,
comptrollerAddress: pool.address,
});

// VToken addresses are unique
if (isIsolated) {
newIsolatedPoolsVTokenAddresses.push(market.address.toLowerCase());
} else {
newLegacyPoolVTokenAddresses.push(market.address.toLowerCase());
}

const underlyingToken = findTokenByAddress({
address: market.underlyingAddress || NATIVE_TOKEN_ADDRESS,
tokens,
});

if (
underlyingToken &&
!newUnderlyingTokenAddresses.includes(underlyingToken.address.toLowerCase())
) {
newUnderlyingTokens.push(underlyingToken);
newUnderlyingTokenAddresses.push(underlyingToken.address.toLowerCase());
}
});

return [
acc[0].concat(newLegacyPoolVTokenAddresses),
acc[1].concat(newIsolatedPoolsVTokenAddresses),
acc[2].concat(newUnderlyingTokens),
];
},
[[], [], []],
);

const [userIsolatedPoolVTokenBalances, userLegacyPoolVTokenBalances, userTokenBalances] =
await Promise.all([
accountAddress
? poolLensContract.callStatic.vTokenBalancesAll(
isolatedPoolsVTokenAddresses,
accountAddress,
)
: undefined,
accountAddress && venusLensContract
? venusLensContract.callStatic.vTokenBalancesAll(legacyPoolVTokenAddresses, accountAddress)
: undefined,
accountAddress
? getTokenBalances({
accountAddress,
tokens: underlyingTokens,
provider,
})
: undefined,
]);

return {
userIsolatedPoolVTokenBalances,
userLegacyPoolVTokenBalances,
userTokenBalances,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import BigNumber from 'bignumber.js';
import type { VaiController } from 'libs/contracts';

export const getUserVaiBorrowBalance = async ({
accountAddress,
vaiControllerContract,
}: { accountAddress: string; vaiControllerContract?: VaiController }) => {
const [_accrueVaiInterest, vaiRepayAmountMantissa] = await Promise.all([
// Call (statically) accrueVAIInterest to calculate past accrued interests before fetching all
// interests. Since multicall will batch these requests, the call to accrueVAIInterest and
// getVAIRepayAmount will happen in the same request (thus making the accrual possible)
vaiControllerContract ? vaiControllerContract.callStatic.accrueVAIInterest() : undefined,
vaiControllerContract ? vaiControllerContract.getVAIRepayAmount(accountAddress) : undefined,
]);

const userVaiBorrowBalanceMantissa = vaiRepayAmountMantissa
? new BigNumber(vaiRepayAmountMantissa.toString())
: undefined;

return { userVaiBorrowBalanceMantissa };
};
Loading

0 comments on commit 1a9ca79

Please sign in to comment.