diff --git a/packages/contract-helpers/src/commons/gasStation.test.ts b/packages/contract-helpers/src/commons/gasStation.test.ts index 1f3368bc..903a9cb2 100644 --- a/packages/contract-helpers/src/commons/gasStation.test.ts +++ b/packages/contract-helpers/src/commons/gasStation.test.ts @@ -1,5 +1,6 @@ import { BigNumber, providers } from 'ethers'; import { estimateGas, estimateGasByNetwork } from './gasStation'; +import { ChainId } from './types'; describe('gasStation', () => { const provider: providers.Provider = new providers.JsonRpcProvider(); @@ -41,5 +42,33 @@ describe('gasStation', () => { const gas = await estimateGasByNetwork(tx, provider, 10); expect(gas).toEqual(BigNumber.from(110)); }); + it('Expects to return 350000 for zksync when connected with contract address', async () => { + jest + .spyOn(provider, 'getNetwork') + .mockImplementationOnce(async () => + Promise.resolve({ chainId: ChainId.zksync, name: 'zksync' }), + ); + + jest + .spyOn(provider, 'getCode') + .mockImplementationOnce(async () => Promise.resolve('0x1234')); + + const gas = await estimateGasByNetwork({ from: '0x123abc' }, provider); + expect(gas).toEqual(BigNumber.from(350000)); + }); + it('Expects to return default for zksync when connected with EOA', async () => { + jest + .spyOn(provider, 'getNetwork') + .mockImplementationOnce(async () => + Promise.resolve({ chainId: ChainId.zksync, name: 'zksync' }), + ); + + jest + .spyOn(provider, 'getCode') + .mockImplementationOnce(async () => Promise.resolve('0x')); + + const gas = await estimateGasByNetwork({ from: '0x123abc' }, provider); + expect(gas).toEqual(BigNumber.from(130)); + }); }); }); diff --git a/packages/contract-helpers/src/commons/gasStation.ts b/packages/contract-helpers/src/commons/gasStation.ts index 1bcaeb4e..c4632f55 100644 --- a/packages/contract-helpers/src/commons/gasStation.ts +++ b/packages/contract-helpers/src/commons/gasStation.ts @@ -21,8 +21,21 @@ export const estimateGasByNetwork = async ( provider: providers.Provider, gasSurplus?: number, ): Promise => { - const estimatedGas = await provider.estimateGas(tx); const providerNework: providers.Network = await provider.getNetwork(); + if (providerNework.chainId === ChainId.zksync && tx.from) { + /** + * Trying to estimate gas on zkSync when connected with a smart contract address + * will fail. In that case, we'll just return a default value for all transactions. + * + * See here for more details: https://github.com/zkSync-Community-Hub/zksync-developers/discussions/144 + */ + const data = await provider.getCode(tx.from); + if (data !== '0x') { + return BigNumber.from(350000); + } + } + + const estimatedGas = await provider.estimateGas(tx); if (providerNework.chainId === ChainId.polygon) { return estimatedGas.add(estimatedGas.mul(POLYGON_SURPLUS).div(100));