diff --git a/packages/core/src/lib/utils.spec.ts b/packages/core/src/lib/utils.spec.ts index 85efebea..9d2df311 100644 --- a/packages/core/src/lib/utils.spec.ts +++ b/packages/core/src/lib/utils.spec.ts @@ -1130,6 +1130,13 @@ describe('Helpers Utils Namespace', () => { precision: 10, }); expect(result5).toBe('1.5'); + + // Large values should not lose precision through JS number conversion + const result6 = PushChain.utils.helpers.formatUnits( + '123456789012345678901234567890', + { decimals: 18, precision: 6 } + ); + expect(result6).toBe('123456789012.345678'); }); it('should handle edge cases with precision', () => { diff --git a/packages/core/src/lib/utils.ts b/packages/core/src/lib/utils.ts index 81123c84..a65e3c5f 100644 --- a/packages/core/src/lib/utils.ts +++ b/packages/core/src/lib/utils.ts @@ -538,12 +538,20 @@ export class Utils { formatted = formatted + '.0'; } - // Apply precision if specified + // Apply precision if specified without converting through JS number, + // which would lose precision for large token values. if (precision !== undefined) { - const num = parseFloat(formatted); - const factor = Math.pow(10, precision); - const truncated = Math.floor(num * factor) / factor; - return truncated.toString(); + if (precision === 0) { + return formatted.split('.')[0]; + } + + const [integerPart, fractionalPart = ''] = formatted.split('.'); + const truncatedFraction = fractionalPart.slice(0, precision); + if (!truncatedFraction) { + return integerPart; + } + + return `${integerPart}.${truncatedFraction.replace(/0+$/, '')}`; } return formatted;