Skip to content

Commit

Permalink
Precision from contract (#78)
Browse files Browse the repository at this point in the history
* Test cases for new precision for @tokenAmount #77

* Implement new @tokenAmount logic. Fixes #77
  • Loading branch information
schmidsi authored and izqui committed Sep 18, 2019
1 parent d49ddba commit 35a446d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 10 deletions.
15 changes: 11 additions & 4 deletions src/helpers/lib/formatBN.js
Expand Up @@ -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}`
}
9 changes: 6 additions & 3 deletions src/helpers/tokenAmount.js
Expand Up @@ -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<radspec/evaluator/TypedValue>}
*/
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
Expand All @@ -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',
Expand Down
22 changes: 19 additions & 3 deletions test/examples/examples.js
Expand Up @@ -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') }
Expand All @@ -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') },
Expand Down

0 comments on commit 35a446d

Please sign in to comment.