diff --git a/packages/target-ethers-v5/src/codegen/index.ts b/packages/target-ethers-v5/src/codegen/index.ts index 239e1a488..6f1a98007 100644 --- a/packages/target-ethers-v5/src/codegen/index.ts +++ b/packages/target-ethers-v5/src/codegen/index.ts @@ -240,6 +240,23 @@ export function codegenAbstractContractFactory(contract: Contract, abi: any): st ` } +// Earlier versions of the vyper compiler included the 'gas' estimates as a member +// in the vyper-generated abi object. +// This breaks the typechain auto-generation code, since gas is a number and not stringified. +// Further, even if it were stringified, the gas estimates are generally incorrect. +// So the 'gas' member is manually removed from the abi in the generated typechain. +function stringifyAbi(abi: any): string { + if (typeof abi === 'object') { + const abiNoGas = abi.map((element: any) => { + const { gas: _, ...withoutGas } = element + return withoutGas + }) + return JSON.stringify(abiNoGas, null, 2) + } + + return JSON.stringify(abi, null, 2) +} + function codegenCommonContractFactory(contract: Contract, abi: any): { header: string; body: string } { const imports: Set = new Set([contract.name, contract.name + 'Interface']) @@ -257,7 +274,7 @@ function codegenCommonContractFactory(contract: Contract, abi: any): { header: s const header = ` import type { ${[...imports.values()].join(', ')} } from "${contractTypesImportPath}"; - const _abi = ${JSON.stringify(abi, null, 2)}; + const _abi = ${stringifyAbi(abi)}; `.trim() const body = ` diff --git a/packages/target-ethers-v5/test/generation.test.ts b/packages/target-ethers-v5/test/generation.test.ts index ad1467674..8c94f1ab4 100644 --- a/packages/target-ethers-v5/test/generation.test.ts +++ b/packages/target-ethers-v5/test/generation.test.ts @@ -37,6 +37,35 @@ describe('Ethers generation edge cases', () => { expect(source).toEqual(expect.stringMatching(/export class TestContract__factory extends ContractFactory \{/)) expect(source).toEqual(expect.stringMatching(/static linkBytecode\(/)) }) + + it('should exclude gas field from ABI', () => { + const abi = [ + { + stateMutability: 'view', + type: 'function', + name: 'foo', + inputs: [ + { + name: 'bar', + type: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + }, + ], + gas: 3135, + }, + ] + + const source = codegenContractFactory(DEFAULT_FLAGS, emptyContract, abi, { + bytecode: '{{BYTECODE}}', + }) + + expect(source).not.toEqual(expect.stringMatching(/"gas":/)) + }) }) describe(generateEventFilters.name, () => {