Skip to content

Commit

Permalink
feat: optimize getAddressesBalances to minimize RPC calls
Browse files Browse the repository at this point in the history
  • Loading branch information
NandyBa committed Jan 1, 2025
1 parent b56b8e2 commit ea9d1da
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 33 deletions.
12 changes: 10 additions & 2 deletions src/hooks/useREG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,20 @@ const getREG = async (
ERC20ABI,
GnosisRpcProvider,
)
const availableBalance = await getAddressesBalances(
let availableBalance = await getAddressesBalances(
REG_ContractAddress,
addressList,
providers,
GnosisRpcProvider,
)

if (includeETH) {
availableBalance += await getAddressesBalances(
REG_ContractAddress,
addressList,
EthereumRpcProvider,
)
}

const regVaultAbiGetUserGlobalStateOnly =
getRegVaultAbiGetUserGlobalStateOnly()

Expand Down
3 changes: 1 addition & 2 deletions src/hooks/useREGVotingPower.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const getRegVotingPower = async (
addressList: string[],
): Promise<REGVotingPowertoken> => {
const { GnosisRpcProvider } = await initializeProviders()
const providers = [GnosisRpcProvider]
const RegVotingPowerContract = new Contract(
RegVotingPower_Gnosis_ContractAddress,
ERC20ABI,
Expand All @@ -29,7 +28,7 @@ const getRegVotingPower = async (
const totalAmount = await getAddressesBalances(
RegVotingPower_Gnosis_ContractAddress,
addressList,
providers,
GnosisRpcProvider,
)

const contractRegVotePowerTotalSupply =
Expand Down
3 changes: 1 addition & 2 deletions src/hooks/useRWA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ const getRWA = async (
): Promise<RWARealtoken> => {
const { GnosisRpcProvider /* , EthereumRpcProvider */ } =
await initializeProviders()
const providers = [GnosisRpcProvider]

const contractRwa_Gnosis = new Contract(
RWA_ContractAddress,
Expand All @@ -52,7 +51,7 @@ const getRWA = async (
const totalAmount = await getAddressesBalances(
RWA_ContractAddress,
addressList,
providers,
GnosisRpcProvider,
)
const RwaContractTotalSupply = await contractRwa_Gnosis.totalSupply()
const totalTokens = Number(RwaContractTotalSupply) / 10 ** RWAtokenDecimals
Expand Down
60 changes: 33 additions & 27 deletions src/utils/blockchain/erc20Infos.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { AaveV3Ethereum, AaveV3Gnosis } from '@bgd-labs/aave-address-book'

import { Contract, JsonRpcProvider } from 'ethers'

import { getErc20AbiBalanceOfOnly } from 'src/utils/blockchain/ERC20'

import { batchCallOneContractOneFunctionMultipleParams } from './contract'
import { WalletBalanceProviderABI } from './abi/WalletBalanceProviderABI'

const getAddressesBalances = async (
contractAddress: string,
addressList: string[],
providers: JsonRpcProvider[],
provider: JsonRpcProvider,
consoleWarnOnError = false,
) => {
let totalAmount = 0
Expand All @@ -20,38 +22,42 @@ const getAddressesBalances = async (
consoleWarnOnError && console.error('Invalid address list')
return totalAmount
}
if (!providers?.length) {
if (!provider) {
consoleWarnOnError && console.error('Invalid providers')
return totalAmount
}
const erc20AbiBalanceOfOnly = getErc20AbiBalanceOfOnly()
if (!erc20AbiBalanceOfOnly) {
throw new Error('balanceOf ABI not found')
}
const balancesPromises = providers.map((provider: JsonRpcProvider) => {
const Erc20BalanceContract = new Contract(
contractAddress,
erc20AbiBalanceOfOnly,
provider,
)
const balances = batchCallOneContractOneFunctionMultipleParams(
Erc20BalanceContract,
'balanceOf',
addressList.map((address: string) => [address as unknown as object]),
)
return balances
})

const balancesArray = await Promise.all(balancesPromises.flat())
const balances = balancesArray.flat()
// Sum all valid balances
balances.forEach((balance: object | null | undefined) => {
try {
if (balance) {
totalAmount += Number(balance)
}
} catch (error) {}
})

let walletBalanceProviderAddress
switch (provider._network.chainId) {
case 100n:
walletBalanceProviderAddress = AaveV3Gnosis.WALLET_BALANCE_PROVIDER
break
case 1n:
walletBalanceProviderAddress = AaveV3Ethereum.WALLET_BALANCE_PROVIDER
break
default:
consoleWarnOnError && console.error('Invalid provider')
return totalAmount
}

const balanceWalletProviderContract = new Contract(
walletBalanceProviderAddress,
WalletBalanceProviderABI,
provider,
)

const balances = await balanceWalletProviderContract.batchBalanceOf(
addressList,
[contractAddress],
)
totalAmount = balances.reduce(
(acc: number, b: bigint) => acc + Number(b),
0,
)
return totalAmount
} catch (error) {
console.warn('Failed to get balances', error)
Expand Down

0 comments on commit ea9d1da

Please sign in to comment.