diff --git a/package.json b/package.json index 65fb65c1..ea33093d 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "dependencies": { "@apollo/client": "^3.9.5", + "@bgd-labs/aave-address-book": "^4.7.3", "@mantine/core": "^7.5.3", "@mantine/dates": "^7.5.3", "@mantine/form": "^7.5.3", diff --git a/src/hooks/useREG.ts b/src/hooks/useREG.ts index 0a83161d..1c627690 100644 --- a/src/hooks/useREG.ts +++ b/src/hooks/useREG.ts @@ -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() diff --git a/src/hooks/useREGVotingPower.ts b/src/hooks/useREGVotingPower.ts index 5af3af1a..5fe7da94 100644 --- a/src/hooks/useREGVotingPower.ts +++ b/src/hooks/useREGVotingPower.ts @@ -20,7 +20,6 @@ const getRegVotingPower = async ( addressList: string[], ): Promise => { const { GnosisRpcProvider } = await initializeProviders() - const providers = [GnosisRpcProvider] const RegVotingPowerContract = new Contract( RegVotingPower_Gnosis_ContractAddress, ERC20ABI, @@ -29,7 +28,7 @@ const getRegVotingPower = async ( const totalAmount = await getAddressesBalances( RegVotingPower_Gnosis_ContractAddress, addressList, - providers, + GnosisRpcProvider, ) const contractRegVotePowerTotalSupply = diff --git a/src/hooks/useRWA.ts b/src/hooks/useRWA.ts index 88cf8606..7121f009 100644 --- a/src/hooks/useRWA.ts +++ b/src/hooks/useRWA.ts @@ -42,7 +42,6 @@ const getRWA = async ( ): Promise => { const { GnosisRpcProvider /* , EthereumRpcProvider */ } = await initializeProviders() - const providers = [GnosisRpcProvider] const contractRwa_Gnosis = new Contract( RWA_ContractAddress, @@ -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 diff --git a/src/repositories/RpcProvider.ts b/src/repositories/RpcProvider.ts index ded4082d..628fb7b4 100644 --- a/src/repositories/RpcProvider.ts +++ b/src/repositories/RpcProvider.ts @@ -6,7 +6,7 @@ import { ZeroAddress, } from 'ethers' -import { getErc20AbiBalanceOfOnly } from 'src/utils/blockchain/ERC20' +import { ERC20ABI } from 'src/utils/blockchain/abi/ERC20ABI' import { REG_ContractAddress } from 'src/utils/blockchain/consts/otherTokens' import { batchCallOneContractOneFunctionMultipleParams } from 'src/utils/blockchain/contract' import { wait } from 'src/utils/general' @@ -80,18 +80,10 @@ async function testRpcThresholds( if (concurrentRequestsMin > concurrentRequestsMax) { throw new Error('concurrentMin cannot be greater than concurrentMax') } - const erc20AbiBalanceOfOnly = getErc20AbiBalanceOfOnly() - if (!erc20AbiBalanceOfOnly) { - throw new Error('balanceOf ABI not found') - } // Create a dummy array of addresses filled with 'ZeroAddress' for fetching balances const batchAddressesArray = Array(requestsBatchSize).fill([ZeroAddress]) - const contract = new Contract( - REG_ContractAddress, - erc20AbiBalanceOfOnly, - provider, - ) + const contract = new Contract(REG_ContractAddress, ERC20ABI, provider) // Loop from max to min concurrent requests for ( let currentThresold = concurrentRequestsMax; diff --git a/src/utils/blockchain/ERC20.ts b/src/utils/blockchain/ERC20.ts index e4dde0cb..c799cdd9 100644 --- a/src/utils/blockchain/ERC20.ts +++ b/src/utils/blockchain/ERC20.ts @@ -44,11 +44,3 @@ export const ERC20 = { isTransferEvent, parseTransferEvent, } - -export const getErc20AbiBalanceOfOnly = (): object[] | null => { - const Erc20AbiBalanceOfOnly = ERC20ABI.find((abi) => abi.name === 'balanceOf') - if (!Erc20AbiBalanceOfOnly) { - throw new Error('balanceOf not found in ERC20 ABI') - } - return [Erc20AbiBalanceOfOnly] -} diff --git a/src/utils/blockchain/abi/WalletBalanceProviderABI.ts b/src/utils/blockchain/abi/WalletBalanceProviderABI.ts new file mode 100644 index 00000000..048a4963 --- /dev/null +++ b/src/utils/blockchain/abi/WalletBalanceProviderABI.ts @@ -0,0 +1,36 @@ +export const WalletBalanceProviderABI = [ + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'address', name: 'token', type: 'address' }, + ], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'users', type: 'address[]' }, + { internalType: 'address[]', name: 'tokens', type: 'address[]' }, + ], + name: 'batchBalanceOf', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'provider', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserWalletBalances', + outputs: [ + { internalType: 'address[]', name: '', type: 'address[]' }, + { internalType: 'uint256[]', name: '', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { stateMutability: 'payable', type: 'receive' }, +] diff --git a/src/utils/blockchain/erc20Infos.ts b/src/utils/blockchain/erc20Infos.ts index 4072610a..32b0ffef 100644 --- a/src/utils/blockchain/erc20Infos.ts +++ b/src/utils/blockchain/erc20Infos.ts @@ -1,13 +1,13 @@ -import { Contract, JsonRpcProvider } from 'ethers' +import { AaveV3Ethereum, AaveV3Gnosis } from '@bgd-labs/aave-address-book' -import { getErc20AbiBalanceOfOnly } from 'src/utils/blockchain/ERC20' +import { Contract, JsonRpcProvider } from 'ethers' -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 @@ -20,38 +20,38 @@ 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') + + 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 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) {} - }) + 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) diff --git a/yarn.lock b/yarn.lock index 8d2a5ab7..53d58580 100644 --- a/yarn.lock +++ b/yarn.lock @@ -264,6 +264,11 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@bgd-labs/aave-address-book@^4.7.3": + version "4.7.3" + resolved "https://registry.yarnpkg.com/@bgd-labs/aave-address-book/-/aave-address-book-4.7.3.tgz#8a2ca1ca3b2e67474c0b07ea8e681a1400f3bc5b" + integrity sha512-4/QS5hLcjKuHAfdOAgaxSWVvi6RKu/U5ZHyndptvvKcNmzcC60tczN3NALCqWNXCBmzFY5e6cg82KsZJqVEjOQ== + "@coinbase/wallet-sdk@^3.6.5": version "3.7.2" resolved "https://registry.npmjs.org/@coinbase/wallet-sdk/-/wallet-sdk-3.7.2.tgz"