From e49b7a8c80cc7944fad517a595fa2af3a458f555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nandy=20B=C3=A2?= Date: Wed, 1 Jan 2025 23:41:08 +0100 Subject: [PATCH 1/6] feat: add address book lib --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index 65fb65c..ea33093 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/yarn.lock b/yarn.lock index 8d2a5ab..53d5858 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" From 5eb3c4a54ec263a0540ceaee2e9511d8edd29ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nandy=20B=C3=A2?= Date: Wed, 1 Jan 2025 23:45:37 +0100 Subject: [PATCH 2/6] feat: add aave core lib --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index ea33093..97531db 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "clean:build": "npm run clean:cache && npm run build" }, "dependencies": { + "@aave/core-v3": "^1.19.3", "@apollo/client": "^3.9.5", "@bgd-labs/aave-address-book": "^4.7.3", "@mantine/core": "^7.5.3", diff --git a/yarn.lock b/yarn.lock index 53d5858..05fabe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== +"@aave/core-v3@^1.19.3": + version "1.19.3" + resolved "https://registry.yarnpkg.com/@aave/core-v3/-/core-v3-1.19.3.tgz#513e886b37a8d84d9821a4041dceb5f014919669" + integrity sha512-Xr7+VcoU5b4mPwM4IUCnskw3lciwrnL4Xloyad8GOddYeixnri2lZYobNmErm1LwE50vqjI0O+9QGNKY2TDkeQ== + "@adraffy/ens-normalize@1.10.0": version "1.10.0" resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz" From b56b8e2e38e50fa5f677518ebc27eaa183fe727a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nandy=20B=C3=A2?= Date: Thu, 2 Jan 2025 00:24:51 +0100 Subject: [PATCH 3/6] feat: add wallet balance provider provider ABI --- .../abi/WalletBalanceProviderABI.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/utils/blockchain/abi/WalletBalanceProviderABI.ts diff --git a/src/utils/blockchain/abi/WalletBalanceProviderABI.ts b/src/utils/blockchain/abi/WalletBalanceProviderABI.ts new file mode 100644 index 0000000..048a496 --- /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' }, +] From ea9d1da9e146b039f943f9c9ac6af0e12c4f75cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nandy=20B=C3=A2?= Date: Thu, 2 Jan 2025 00:26:56 +0100 Subject: [PATCH 4/6] feat: optimize getAddressesBalances to minimize RPC calls --- src/hooks/useREG.ts | 12 +++++- src/hooks/useREGVotingPower.ts | 3 +- src/hooks/useRWA.ts | 3 +- src/utils/blockchain/erc20Infos.ts | 60 ++++++++++++++++-------------- 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/hooks/useREG.ts b/src/hooks/useREG.ts index 0a83161..1c62769 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 5af3af1..5fe7da9 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 88cf860..7121f00 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/utils/blockchain/erc20Infos.ts b/src/utils/blockchain/erc20Infos.ts index 4072610..a6d47f9 100644 --- a/src/utils/blockchain/erc20Infos.ts +++ b/src/utils/blockchain/erc20Infos.ts @@ -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 @@ -20,7 +22,7 @@ const getAddressesBalances = async ( consoleWarnOnError && console.error('Invalid address list') return totalAmount } - if (!providers?.length) { + if (!provider) { consoleWarnOnError && console.error('Invalid providers') return totalAmount } @@ -28,30 +30,34 @@ const getAddressesBalances = async ( 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) From 0922d7ef3a1cdc2575e49da2ee17b4ddc682fdc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nandy=20B=C3=A2?= Date: Thu, 2 Jan 2025 00:35:29 +0100 Subject: [PATCH 5/6] fix: remove un-used lib --- package.json | 1 - yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/package.json b/package.json index 97531db..ea33093 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "clean:build": "npm run clean:cache && npm run build" }, "dependencies": { - "@aave/core-v3": "^1.19.3", "@apollo/client": "^3.9.5", "@bgd-labs/aave-address-book": "^4.7.3", "@mantine/core": "^7.5.3", diff --git a/yarn.lock b/yarn.lock index 05fabe7..53d5858 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,11 +7,6 @@ resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@aave/core-v3@^1.19.3": - version "1.19.3" - resolved "https://registry.yarnpkg.com/@aave/core-v3/-/core-v3-1.19.3.tgz#513e886b37a8d84d9821a4041dceb5f014919669" - integrity sha512-Xr7+VcoU5b4mPwM4IUCnskw3lciwrnL4Xloyad8GOddYeixnri2lZYobNmErm1LwE50vqjI0O+9QGNKY2TDkeQ== - "@adraffy/ens-normalize@1.10.0": version "1.10.0" resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz" From 4eaf297d8eff00babe3573dd67b67f978cd0ea8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nandy=20B=C3=A2?= Date: Thu, 2 Jan 2025 00:41:47 +0100 Subject: [PATCH 6/6] fix: erc20 abi --- src/repositories/RpcProvider.ts | 12 ++---------- src/utils/blockchain/ERC20.ts | 8 -------- src/utils/blockchain/erc20Infos.ts | 6 ------ 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/repositories/RpcProvider.ts b/src/repositories/RpcProvider.ts index ded4082..628fb7b 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 e4dde0c..c799cdd 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/erc20Infos.ts b/src/utils/blockchain/erc20Infos.ts index a6d47f9..32b0ffe 100644 --- a/src/utils/blockchain/erc20Infos.ts +++ b/src/utils/blockchain/erc20Infos.ts @@ -2,8 +2,6 @@ import { AaveV3Ethereum, AaveV3Gnosis } from '@bgd-labs/aave-address-book' import { Contract, JsonRpcProvider } from 'ethers' -import { getErc20AbiBalanceOfOnly } from 'src/utils/blockchain/ERC20' - import { WalletBalanceProviderABI } from './abi/WalletBalanceProviderABI' const getAddressesBalances = async ( @@ -26,10 +24,6 @@ const getAddressesBalances = async ( 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) {