diff --git a/package.json b/package.json index dcd7ed30ab..354a5eb99e 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,8 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.33.0", - "@aave/math-utils": "1.33.0", + "@aave/contract-helpers": "1.33.1", + "@aave/math-utils": "1.33.1", "@bgd-labs/aave-address-book": "^4.17.1", "@emotion/cache": "11.10.3", "@emotion/react": "11.10.4", diff --git a/src/hooks/useIsContractAddress.ts b/src/hooks/useIsContractAddress.ts index 9af54a54fa..45d4db1b14 100644 --- a/src/hooks/useIsContractAddress.ts +++ b/src/hooks/useIsContractAddress.ts @@ -9,7 +9,7 @@ export const useIsContractAddress = (address: string, chainId?: number) => { return useQuery({ queryFn: () => provider.getCode(address), queryKey: ['isContractAddress', address], - enabled: true, + enabled: address !== '', staleTime: Infinity, select: (data) => data !== '0x', }); diff --git a/src/libs/web3-data-provider/Web3Provider.tsx b/src/libs/web3-data-provider/Web3Provider.tsx index 945121dbdb..26fe83287c 100644 --- a/src/libs/web3-data-provider/Web3Provider.tsx +++ b/src/libs/web3-data-provider/Web3Provider.tsx @@ -3,11 +3,13 @@ import { SignatureLike } from '@ethersproject/bytes'; import { JsonRpcProvider, TransactionResponse } from '@ethersproject/providers'; import { BigNumber, PopulatedTransaction, utils } from 'ethers'; import React, { ReactElement, useEffect, useState } from 'react'; +import { useIsContractAddress } from 'src/hooks/useIsContractAddress'; import { useRootStore } from 'src/store/root'; import { wagmiConfig } from 'src/ui-config/wagmiConfig'; import { hexToAscii } from 'src/utils/utils'; import { UserRejectedRequestError } from 'viem'; import { useAccount, useConnect, useSwitchChain, useWatchAsset } from 'wagmi'; +import { useShallow } from 'zustand/shallow'; import { Web3Context } from '../hooks/useWeb3Context'; import { getEthersProvider } from './adapters/EthersAdapter'; @@ -47,7 +49,9 @@ export const Web3ContextProvider: React.FC<{ children: ReactElement }> = ({ chil const [readOnlyModeAddress, setReadOnlyModeAddress] = useState(); const [switchNetworkError, setSwitchNetworkError] = useState(); - const setAccount = useRootStore((store) => store.setAccount); + const [setAccount, setConnectedAccountIsContract] = useRootStore( + useShallow((store) => [store.setAccount, store.setConnectedAccountIsContract]) + ); const account = address; const readOnlyMode = utils.isAddress(readOnlyModeAddress || ''); @@ -56,6 +60,8 @@ export const Web3ContextProvider: React.FC<{ children: ReactElement }> = ({ chil currentAccount = readOnlyModeAddress; } + const { data: isContractAddress } = useIsContractAddress(account || '', chainId); + useEffect(() => { if (didInit) { return; @@ -179,6 +185,17 @@ export const Web3ContextProvider: React.FC<{ children: ReactElement }> = ({ chil } }, [readOnlyModeAddress, setAccount]); + useEffect(() => { + if (!account) { + setConnectedAccountIsContract(false); + return; + } + + if (isContractAddress) { + setConnectedAccountIsContract(true); + } + }, [isContractAddress, setConnectedAccountIsContract, account]); + return ( { - const provider = get().jsonRpcProvider(chainId); + const { currentChainId, connectedAccountIsContract, jsonRpcProvider } = get(); + + const effectiveChainId = chainId ?? currentChainId; + + /** + * Trying to estimate gas on zkSync when connected with a smart contract address + * will fail. In that case, we'll just return the default value for all transactions. + * + * See here for more details: https://github.com/zkSync-Community-Hub/zksync-developers/discussions/144 + */ + if (effectiveChainId === ChainId.zksync && connectedAccountIsContract) { + return tx; + } + + const provider = jsonRpcProvider(chainId); const defaultGasLimit: BigNumber = tx.gasLimit ? tx.gasLimit : BigNumber.from('0'); delete tx.gasLimit; let estimatedGas = await provider.estimateGas(tx); diff --git a/src/store/walletSlice.ts b/src/store/walletSlice.ts index b6a1d6c26e..3beeb6a3bd 100644 --- a/src/store/walletSlice.ts +++ b/src/store/walletSlice.ts @@ -17,6 +17,8 @@ export interface WalletSlice { walletApprovalMethodPreference: ApprovalMethod; setWalletApprovalMethodPreference: (method: ApprovalMethod) => void; refreshWalletApprovalMethod: () => void; + connectedAccountIsContract: boolean; + setConnectedAccountIsContract: (isContract: boolean) => void; } const getWalletPreferences = () => { @@ -73,4 +75,8 @@ export const createWalletSlice: StateCreator< })); } }, + connectedAccountIsContract: false, + setConnectedAccountIsContract(isContract) { + set({ connectedAccountIsContract: isContract }); + }, }); diff --git a/yarn.lock b/yarn.lock index af1f536f75..16da6d5835 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,17 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.33.0": - version "1.33.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.33.0.tgz#d58f44c83737dfe3ab04b3776f1133064e08ebc6" - integrity sha512-hwOG+B6LYv8/oZIW3OYPZqr2OwEVYLWXO230h3LfUpG9P4+MhknZeyuJHRA7uGNpj2dpP/KYuLrYYfx4G9D0aQ== +"@aave/contract-helpers@1.33.1": + version "1.33.1" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.33.1.tgz#2156c179e802c40c137381d337c5f93ebee1abeb" + integrity sha512-Zu/zwJiX3k2xBRAlNfmIJMIo19YWVJAL2uRPHbvCVxOUgzlhVyglIF98FgcZ+4aLwcjvSAw10wnIzGgJcPTNVw== dependencies: isomorphic-unfetch "^3.1.0" -"@aave/math-utils@1.33.0": - version "1.33.0" - resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.33.0.tgz#2386f7353dfdc7bdd88079e4fd7351275b1cdbf6" - integrity sha512-guDUruuQTmp8QLUNRZJFxzu/VyJPs0Mieebk+tJDplVNq+TzaSZHU3YtAxp/u6tGw166v47ALFrt7yA/oaX1TA== +"@aave/math-utils@1.33.1": + version "1.33.1" + resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.33.1.tgz#1dddf06e48cca13251db94e2f24afb0aa1b270ed" + integrity sha512-+e7ThIRLxyrcLB507T3khdE6DqKn2vTR5hfnQd1rHetEzLObA6bKDElX7YEtGmuSzBwDTP4inpK2VtgiQAqIWQ== "@adobe/css-tools@^4.0.1": version "4.4.1"