From 8c4287f2cdd1690ed2e07410a322659e4f17f2d3 Mon Sep 17 00:00:00 2001 From: Denis Davidyuk Date: Thu, 11 Apr 2024 12:36:26 +1000 Subject: [PATCH] fix(contract): detect if ACI doesn't match called contract --- src/contract/Contract.ts | 3 +++ test/integration/contract-aci.ts | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/contract/Contract.ts b/src/contract/Contract.ts index 7e4bf8eb45..8f41f3e34e 100644 --- a/src/contract/Contract.ts +++ b/src/contract/Contract.ts @@ -171,6 +171,9 @@ class Contract { break; case 'error': message = decode(returnValue).toString(); + if (/Expected \d+ arguments, got \d+/.test(message)) { + throw new ContractError(`ACI doesn't match called contract. Error provided by node: ${message}`); + } break; default: throw new InternalError(`Unknown return type: ${returnType}`); diff --git a/test/integration/contract-aci.ts b/test/integration/contract-aci.ts index a357ccca0d..2223715127 100644 --- a/test/integration/contract-aci.ts +++ b/test/integration/contract-aci.ts @@ -19,6 +19,7 @@ import { NoSuchContractFunctionError, ConsensusProtocolVersion, InvalidTxError, + ContractError, } from '../../src'; import { getSdk } from '.'; import { @@ -362,6 +363,18 @@ describe('Contract instance', () => { expect((await contract.intFn(3)).decodedResult).to.be.equal(3n); }); + it('fails if aci doesn\'t match called contract', async () => { + const aci = structuredClone(testContractAci); + const fn = aci.at(-1)?.contract?.functions.find(({ name }) => name === 'intFn'); + assertNotNull(fn); + fn.arguments.push(fn.arguments[0]); + const contract = await aeSdk.initializeContract<{ + intFn: (a: InputNumber, b: InputNumber) => bigint; + }>({ aci, address: testContract.$options.address }); + await expect(contract.intFn(3, 2)).to.be + .rejectedWith(ContractError, 'ACI doesn\'t match called contract. Error provided by node: Expected 1 arguments, got 2'); + }); + it('deploys and calls by bytecode and aci', async () => { const contract = await aeSdk.initializeContract( { bytecode: testContractBytecode, aci: testContractAci },