From ad64968aabc47bf268bad22d407efca98ff9d986 Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Wed, 4 Sep 2024 18:15:19 +0200 Subject: [PATCH] Fix exponential str bug (#1766) --- .../components/ibc/ibc-in/asset-utils.test.ts | 47 +++++++++++++++---- .../src/components/ibc/ibc-in/asset-utils.tsx | 7 ++- packages/types/src/lo-hi.ts | 6 ++- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/apps/minifront/src/components/ibc/ibc-in/asset-utils.test.ts b/apps/minifront/src/components/ibc/ibc-in/asset-utils.test.ts index d3b5c828d9..57d57b6413 100644 --- a/apps/minifront/src/components/ibc/ibc-in/asset-utils.test.ts +++ b/apps/minifront/src/components/ibc/ibc-in/asset-utils.test.ts @@ -1,7 +1,11 @@ import { describe, expect, test } from 'vitest'; import { fromDisplayAmount, toDisplayAmount } from './asset-utils'; +import { bigNumConfig } from '@penumbra-zone/types/lo-hi'; +import { BigNumber } from 'bignumber.js'; -const asset = { +BigNumber.config(bigNumConfig); + +const osmoMetadata = { denom_units: [ { denom: 'osmo', exponent: 6 }, { denom: 'uosmo', exponent: 0 }, @@ -12,49 +16,67 @@ const asset = { symbol: 'OSMO', }; +const usdyMetadata = { + denom_units: [ + { + denom: 'ausdy', + exponent: 0, + aliases: ['attousdy'], + }, + { + denom: 'usdy', + exponent: 18, + }, + ], + base: 'ausdy', + display: 'usdy', + name: 'Ondo US Dollar Yield', + symbol: 'USDY', +}; + describe('toDisplayAmount', () => { test('converts uosmo to osmo correctly', () => { - expect(toDisplayAmount(asset, { denom: 'uosmo', amount: '41000000' })).toEqual('41'); + expect(toDisplayAmount(osmoMetadata, { denom: 'uosmo', amount: '41000000' })).toEqual('41'); }); test('high precision conversion from uosmo to osmo', () => { - expect(toDisplayAmount(asset, { denom: 'uosmo', amount: '123456789012345' })).toEqual( + expect(toDisplayAmount(osmoMetadata, { denom: 'uosmo', amount: '123456789012345' })).toEqual( '123456789.012345', ); }); test('coin denom not found in asset denom_units', () => { - expect(toDisplayAmount(asset, { denom: 'xosmo', amount: '1000000' })).toEqual('1000000'); + expect(toDisplayAmount(osmoMetadata, { denom: 'xosmo', amount: '1000000' })).toEqual('1000000'); }); test('zero amount conversion from uosmo to osmo', () => { - expect(toDisplayAmount(asset, { denom: 'uosmo', amount: '0' })).toEqual('0'); + expect(toDisplayAmount(osmoMetadata, { denom: 'uosmo', amount: '0' })).toEqual('0'); }); }); describe('fromDisplayAmount', () => { test('converts osmo to uosmo correctly for a whole number', () => { - const result = fromDisplayAmount(asset, 'osmo', '1'); + const result = fromDisplayAmount(osmoMetadata, 'osmo', '1'); expect(result).toEqual({ denom: 'uosmo', amount: '1000000' }); }); test('converts osmo to uosmo correctly for a decimal number', () => { - const result = fromDisplayAmount(asset, 'osmo', '0.5'); + const result = fromDisplayAmount(osmoMetadata, 'osmo', '0.5'); expect(result).toEqual({ denom: 'uosmo', amount: '500000' }); }); test('handles large numbers', () => { - const result = fromDisplayAmount(asset, 'osmo', '123456'); + const result = fromDisplayAmount(osmoMetadata, 'osmo', '123456'); expect(result).toEqual({ denom: 'uosmo', amount: '123456000000' }); }); test('converts when display amount is zero', () => { - const result = fromDisplayAmount(asset, 'osmo', '0'); + const result = fromDisplayAmount(osmoMetadata, 'osmo', '0'); expect(result).toEqual({ denom: 'uosmo', amount: '0' }); }); test('returns input amount if display exponent is undefined', () => { - const result = fromDisplayAmount(asset, 'xosmo', '100'); + const result = fromDisplayAmount(osmoMetadata, 'xosmo', '100'); expect(result).toEqual({ denom: 'xosmo', amount: '100' }); }); @@ -69,4 +91,9 @@ describe('fromDisplayAmount', () => { const result = fromDisplayAmount(noExponentForBase, 'osmo', '100'); expect(result).toEqual({ denom: 'uosmo', amount: '100000000' }); }); + + test('should work with very large numbers', () => { + const result = fromDisplayAmount(usdyMetadata, 'usdy', '112'); + expect(result).toEqual({ denom: 'ausdy', amount: '112000000000000000000' }); + }); }); diff --git a/apps/minifront/src/components/ibc/ibc-in/asset-utils.tsx b/apps/minifront/src/components/ibc/ibc-in/asset-utils.tsx index 55ca574410..2b5f835e50 100644 --- a/apps/minifront/src/components/ibc/ibc-in/asset-utils.tsx +++ b/apps/minifront/src/components/ibc/ibc-in/asset-utils.tsx @@ -5,6 +5,7 @@ import { BigNumber } from 'bignumber.js'; import { AssetDenomUnit } from '@chain-registry/types/assets'; import { CosmosAssetBalance } from './hooks.ts'; import { ChainRegistryClient } from '@penumbra-labs/registry'; +import { bigNumConfig } from '@penumbra-zone/types/lo-hi'; // Searches for corresponding denom in asset registry and returns the metadata export const augmentToAsset = (denom: string, chainName: string): Asset => { @@ -52,7 +53,11 @@ export const fromDisplayAmount = ( const baseExponent = getExponent(asset.denom_units, asset.base) ?? 0; const exponentDifference = displayExponent - baseExponent; - const amount = new BigNumber(displayAmount).shiftedBy(exponentDifference).toString(); + + // Overriding repo default and setting a very high threshold to avoid exponential notation + const CustomBigNumber = BigNumber.clone({ ...bigNumConfig, EXPONENTIAL_AT: [-1e9, 1e9] }); + + const amount = new CustomBigNumber(displayAmount).shiftedBy(exponentDifference).toString(); return { denom: asset.base, amount }; }; diff --git a/packages/types/src/lo-hi.ts b/packages/types/src/lo-hi.ts index ea59cd58ff..bf4c51ecd7 100644 --- a/packages/types/src/lo-hi.ts +++ b/packages/types/src/lo-hi.ts @@ -2,13 +2,15 @@ import { BigNumber } from 'bignumber.js'; -BigNumber.config({ +export const bigNumConfig: BigNumber.Config = { EXPONENTIAL_AT: [-20, 20], FORMAT: { decimalSeparator: '.', groupSeparator: '', }, -}); +}; + +BigNumber.config(bigNumConfig); /** * In protobufs, it's common to split a single u128 into two u64's.