diff --git a/packages/account-sdk/src/interface/payment/utils/validation.test.ts b/packages/account-sdk/src/interface/payment/utils/validation.test.ts index 6f5bb576..c79707ae 100644 --- a/packages/account-sdk/src/interface/payment/utils/validation.test.ts +++ b/packages/account-sdk/src/interface/payment/utils/validation.test.ts @@ -20,6 +20,14 @@ describe('validateStringAmount', () => { ); }); + it('rejects malformed numeric strings that parseFloat would accept', () => { + const message = 'Invalid amount: must be a valid number'; + const malformed = ['1abc', '1.2.3', '1foo', '1e6', '1.', '.', '']; + for (const value of malformed) { + expect(() => validateStringAmount(value, 6)).toThrow(message); + } + }); + it('should reject non-string amounts', () => { expect(() => validateStringAmount(10 as any, 6)).toThrow('Invalid amount: must be a string'); }); diff --git a/packages/account-sdk/src/interface/payment/utils/validation.ts b/packages/account-sdk/src/interface/payment/utils/validation.ts index c6e2ad7f..018da0fe 100644 --- a/packages/account-sdk/src/interface/payment/utils/validation.ts +++ b/packages/account-sdk/src/interface/payment/utils/validation.ts @@ -11,13 +11,14 @@ export function validateStringAmount(amount: string, maxDecimals: number): void throw new Error('Invalid amount: must be a string'); } - const numAmount = parseFloat(amount); - - if (isNaN(numAmount)) { + // parseFloat is too lenient: it reads a leading numeric prefix and accepts values + // like "1abc", "1.2.3" or "1e6", which then fail later in parseUnits. Require a + // plain decimal string instead. + if (!/^-?\d+(\.\d+)?$/.test(amount)) { throw new Error('Invalid amount: must be a valid number'); } - if (numAmount <= 0) { + if (Number(amount) <= 0) { throw new Error('Invalid amount: must be greater than 0'); }