diff --git a/src/helpers/lib/formatBN.js b/src/helpers/lib/formatBN.js index 74d16a1..6330be7 100644 --- a/src/helpers/lib/formatBN.js +++ b/src/helpers/lib/formatBN.js @@ -4,18 +4,25 @@ export const tenPow = x => ( (new BN(10)).pow(new BN(x)) ) -export const formatBN = (amount, base, precision) => { +export const formatBN = (amount, base, precision, fixed = false) => { // Inspired by: https://github.com/ethjs/ethjs-unit/blob/35d870eae1c32c652da88837a71e252a63a83ebb/src/index.js#L83 const baseLength = base.toString().length const whole = amount.div(base).toString() let fraction = amount.mod(base).toString() const zeros = '0'.repeat(Math.max(0, baseLength - fraction.length - 1)) - fraction = `${zeros}${fraction}`.replace(/0+$/, '').slice(0, precision) - if (fraction === '' || parseInt(fraction, 10) === 0) { + fraction = `${zeros}${fraction}` + + if (!fixed) fraction = fraction.replace(/0+$/, '') + + const slicedFraction = fraction.slice(0, precision) + + if (!fixed && (slicedFraction === '' || parseInt(slicedFraction, 10) === 0)) { return whole } - return `${whole}.${fraction}` + const prefix = (new BN(slicedFraction).eq(new BN(fraction)) || !fixed) ? '' : '~' + + return `${prefix}${whole}.${slicedFraction}` } diff --git a/src/helpers/tokenAmount.js b/src/helpers/tokenAmount.js index d8866f6..4b60a43 100644 --- a/src/helpers/tokenAmount.js +++ b/src/helpers/tokenAmount.js @@ -10,11 +10,12 @@ export default (eth) => * @param {string} tokenAddress The address of the token * @param {*} amount The absolute amount for the token quantity (wei) * @param {bool} showSymbol Whether the token symbol will be printed after the amount - * @param {*} [precision=2] The number of decimal places to format to + * @param {*} precision The number of decimal places to format to. If set, the precision is always enforced. * @return {Promise} */ - async (tokenAddress, amount, showSymbol = true, precision = 2) => { + async (tokenAddress, amount, showSymbol = true, precision) => { const amountBn = new BN(amount) + const fixed = !!precision let decimals let symbol @@ -40,7 +41,9 @@ export default (eth) => } } - const formattedAmount = formatBN(amountBn, tenPow(decimals), Number(precision)) + precision = precision || decimals + + const formattedAmount = formatBN(amountBn, tenPow(decimals), Number(precision), fixed) return { type: 'string', diff --git a/test/examples/examples.js b/test/examples/examples.js index 28e829a..2a5347c 100644 --- a/test/examples/examples.js +++ b/test/examples/examples.js @@ -110,15 +110,15 @@ const helperCases = [ [{ source: 'Balance: `@tokenAmount(token, balance, false, 5)` ANT', bindings: { token: address('0x960b236A07cf122663c4303350609A66A7B288C0'), balance: int('647413054595780000000000') } - }, 'Balance: 647413.05459 ANT'], + }, 'Balance: ~647413.05459 ANT'], [{ source: 'Balance: `@tokenAmount(token, balance, false, 5)` ANT (non-checksummed)', bindings: { token: address('0x960b236a07cf122663c4303350609a66a7b288c0'), balance: int('647413054595780000000000') } - }, 'Balance: 647413.05459 ANT (non-checksummed)'], + }, 'Balance: ~647413.05459 ANT (non-checksummed)'], [{ source: 'Balance: `@tokenAmount(token, balance)`', bindings: { token: address(ETH), balance: int('647413054595780000000000') } - }, 'Balance: 647413.05 ETH'], + }, 'Balance: 647413.05459578 ETH'], [{ source: 'Balance: `@tokenAmount(token, balance)`', bindings: { token: address('0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7'), balance: int('10') } @@ -127,6 +127,22 @@ const helperCases = [ source: 'Balance: `@tokenAmount(token, balance)`', bindings: { token: address('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'), balance: int('10000000000000000000') } }, 'Balance: 10 DAI'], + [{ + source: 'Balance: `@tokenAmount(token, balance)`', + bindings: { token: address('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'), balance: int('1000000000000000') } + }, 'Balance: 0.001 DAI'], + [{ + source: 'Balance: `@tokenAmount(token, balance)`', + bindings: { token: address('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'), balance: int('1') } + }, 'Balance: 0.000000000000000001 DAI'], + [{ + source: 'Balance: `@tokenAmount(token, balance, true, 3)`', + bindings: { token: address('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'), balance: int('1000000000000000001') } + }, 'Balance: ~1.000 DAI'], + [{ + source: 'Balance: `@tokenAmount(token, balance)`', + bindings: { token: address('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'), balance: int('1000000000000000001') } + }, 'Balance: 1.000000000000000001 DAI'], [{ source: 'Balance: `@tokenAmount(self.token(): address, balance)`', bindings: { balance: int('10000000000000000000') },