Skip to content

Commit badb631

Browse files
committed
fix: usd precision
1 parent 2447ed6 commit badb631

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

.changeset/giant-frogs-develop.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"fuels-wallet": patch
3+
---
4+
5+
fix: improve precision handling for USD conversion with really low rates (e.g. 0.0000007427)

packages/app/src/systems/Core/utils/convertToUsd.test.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DECIMAL_FUEL, bn } from 'fuels';
1+
import { DECIMAL_FUEL, DECIMAL_WEI, bn } from 'fuels';
22
import { convertToUsd } from './convertToUsd';
33

44
const MOCK_ETH_RATE = 2742.15;
@@ -56,6 +56,26 @@ describe('Convert to USD', () => {
5656
expect(value).toBe(24699091436.38);
5757
});
5858

59+
it('should be able to handle large amounts with high precision and regular rate', () => {
60+
const { formatted, value } = convertToUsd(
61+
bn('123456789999999999900000000000000001'),
62+
DECIMAL_WEI,
63+
MOCK_ETH_RATE
64+
);
65+
expect(formatted).toBe('$338,537,036,698,499,999,725.78');
66+
expect(value).toBe(338537036698500000000);
67+
});
68+
69+
it('should be able to handle large amounts with high precision decimal and low rate', () => {
70+
const { formatted, value } = convertToUsd(
71+
bn('123456789999999999900000000000000001'),
72+
DECIMAL_WEI,
73+
MOCK_REALLY_LOW_RATE
74+
);
75+
expect(formatted).toBe('$91,691,357,932.99');
76+
expect(value).toBe(91691357932.99);
77+
});
78+
5979
it('should be able to handle lower rates', () => {
6080
const { formatted, value } = convertToUsd(
6181
bn(100_000_000_000),

packages/app/src/systems/Core/utils/convertToUsd.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ function countDecimals(value: number): number {
1010

1111
// Handle scientific notation
1212
if (str.includes('e-')) {
13-
const [, exp] = str.split('e-');
14-
return Number(exp);
13+
const [nonExp, exp] = str.split('e-');
14+
const [, decimals] = nonExp.split('.');
15+
return Number(exp) + decimals.length;
1516
}
1617
return str.split('.')[1]?.length || 0;
1718
}
@@ -31,11 +32,11 @@ export function convertToUsd(
3132
const rateDecimals = countDecimals(rate);
3233
const targetPrecision = getTargetPrecision(rateDecimals, decimals);
3334

34-
// Convert the rate to a fixed-point integer (truncated to avoid rounding errors).
35-
// If the amount has more decimals than the rate, we need to add zeros to the rate.
36-
// If not, we don't need to do anything.
37-
const ratePrecision = 10 ** targetPrecision;
38-
const rateFixed = Math.trunc(rate * ratePrecision);
35+
// Get how many decimal places we need to apply to the rate to match the amount precision.
36+
// Usually the amount has more decimals than the rate, so we need to add zeros to the rate.
37+
const ratePrecision = Math.max(decimals - rateDecimals, 0);
38+
const rateUnits = bn.parseUnits(rate.toFixed(rateDecimals), rateDecimals);
39+
const rateFixed = rateUnits.mul(bn(10).pow(ratePrecision));
3940

4041
// Get how many decimal places we need to apply to the amount to match the rate precision.
4142
// Sometimes the rate has more decimals than the amount, so we need to add zeros to the amount.

0 commit comments

Comments
 (0)