From d0a1a32bc64b9c9bc513abbe2ee67e7edb094b1d Mon Sep 17 00:00:00 2001 From: janniks Date: Tue, 2 Jan 2024 17:20:57 +0100 Subject: [PATCH] fix: add error throwing on too large fungible post-condition --- packages/transactions/src/postcondition.ts | 14 +++++----- packages/transactions/src/types.ts | 5 +++- packages/transactions/tests/builder.test.ts | 30 +++++++++++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/packages/transactions/src/postcondition.ts b/packages/transactions/src/postcondition.ts index 7886cc1c..caf44876 100644 --- a/packages/transactions/src/postcondition.ts +++ b/packages/transactions/src/postcondition.ts @@ -1,23 +1,21 @@ import { IntegerType, intToBigInt } from '@stacks/common'; +import { ClarityValue } from './clarity'; import { - PostConditionType, FungibleConditionCode, NonFungibleConditionCode, + PostConditionType, StacksMessageType, } from './constants'; - import { AssetInfo, - PostConditionPrincipal, - parseAssetInfoString, - parsePrincipalString, - STXPostCondition, FungiblePostCondition, NonFungiblePostCondition, + PostConditionPrincipal, + STXPostCondition, + parseAssetInfoString, + parsePrincipalString, } from './postcondition-types'; -import { ClarityValue } from './clarity'; - export function createSTXPostCondition( principal: string | PostConditionPrincipal, conditionCode: FungibleConditionCode, diff --git a/packages/transactions/src/types.ts b/packages/transactions/src/types.ts index ad178242..62773edc 100644 --- a/packages/transactions/src/types.ts +++ b/packages/transactions/src/types.ts @@ -42,7 +42,7 @@ import { createLPString, } from './postcondition-types'; import { Payload, deserializePayload, serializePayload } from './payload'; -import { DeserializationError } from './errors'; +import { DeserializationError, SerializationError } from './errors'; import { deserializeTransactionAuthField, deserializeMessageSignature, @@ -379,6 +379,9 @@ export function serializePostCondition(postCondition: PostCondition): Uint8Array postCondition.conditionType === PostConditionType.STX || postCondition.conditionType === PostConditionType.Fungible ) { + // SIP-005: Maximal length of amount is 8 bytes + if (postCondition.amount > BigInt('0xffffffffffffffff')) + throw new SerializationError('The post-condition amount may not be larger than 8 bytes'); bytesArray.push(intToBytes(postCondition.amount, false, 8)); } diff --git a/packages/transactions/tests/builder.test.ts b/packages/transactions/tests/builder.test.ts index dd06161a..a9aa1864 100644 --- a/packages/transactions/tests/builder.test.ts +++ b/packages/transactions/tests/builder.test.ts @@ -84,6 +84,11 @@ import { createTransactionAuthField } from '../src/signature'; import { TransactionSigner } from '../src/signer'; import { deserializeTransaction, StacksTransaction } from '../src/transaction'; import { cloneDeep } from '../src/utils'; +import { + createFungiblePostCondition, + createSTXPostCondition, + serializePostCondition, +} from '../src'; function setSignature( unsignedTransaction: StacksTransaction, @@ -2157,3 +2162,28 @@ test('Get contract map entry - no match', async () => { expect(result).toEqual(mockResult); expect(result.type).toBe(ClarityType.OptionalNone); }); + +test('Post-conditions with amount larger than 8 bytes throw an error', () => { + const amount = BigInt('0xffffffffffffffff') + 1n; + + const stxPc = createSTXPostCondition( + 'SP34EBMKMRR6SXX65GRKJ1FHEXV7AGHJ2D8ASQ5M3', + FungibleConditionCode.Equal, + amount + ); + + const fungiblePc = createFungiblePostCondition( + 'SP34EBMKMRR6SXX65GRKJ1FHEXV7AGHJ2D8ASQ5M3', + FungibleConditionCode.Equal, + amount, + 'SP34EBMKMRR6SXX65GRKJ1FHEXV7AGHJ2D8ASQ5M3.token::frank' + ); + + expect(() => { + serializePostCondition(stxPc); + }).toThrowError('The post-condition amount may not be larger than 8 bytes'); + + expect(() => { + serializePostCondition(fungiblePc); + }).toThrowError('The post-condition amount may not be larger than 8 bytes'); +});