mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Fix BigNumber issues (#9860)
* Document where we need BigNumber-related changes * Fix 1 unit test * Debug progress * Add required values for each upstream usage of getBigNumber * Switch to base 10 * Address feedback
This commit is contained in:
parent
ed27c359c6
commit
67303b7865
@ -80,6 +80,8 @@ export default class TokenInput extends PureComponent {
|
|||||||
|
|
||||||
const multiplier = Math.pow(10, Number(decimals || 0))
|
const multiplier = Math.pow(10, Number(decimals || 0))
|
||||||
const hexValue = multiplyCurrencies(decimalValue || 0, multiplier, {
|
const hexValue = multiplyCurrencies(decimalValue || 0, multiplier, {
|
||||||
|
multiplicandBase: 10,
|
||||||
|
multiplierBase: 10,
|
||||||
toNumericBase: 'hex',
|
toNumericBase: 'hex',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -39,19 +39,23 @@ export function getHexGasTotal({ gasLimit, gasPrice }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function addEth(...args) {
|
export function addEth(...args) {
|
||||||
return args.reduce((acc, base) => {
|
return args.reduce((acc, ethAmount) => {
|
||||||
return addCurrencies(acc, base, {
|
return addCurrencies(acc, ethAmount, {
|
||||||
toNumericBase: 'dec',
|
toNumericBase: 'dec',
|
||||||
numberOfDecimals: 6,
|
numberOfDecimals: 6,
|
||||||
|
aBase: 10,
|
||||||
|
bBase: 10,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addFiat(...args) {
|
export function addFiat(...args) {
|
||||||
return args.reduce((acc, base) => {
|
return args.reduce((acc, fiatAmount) => {
|
||||||
return addCurrencies(acc, base, {
|
return addCurrencies(acc, fiatAmount, {
|
||||||
toNumericBase: 'dec',
|
toNumericBase: 'dec',
|
||||||
numberOfDecimals: 2,
|
numberOfDecimals: 2,
|
||||||
|
aBase: 10,
|
||||||
|
bBase: 10,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,11 @@ const baseChange = {
|
|||||||
BN: (n) => new BN(n.toString(16)),
|
BN: (n) => new BN(n.toString(16)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utility function for checking base types
|
||||||
|
const isValidBase = (base) => {
|
||||||
|
return Number.isInteger(base) && base > 1
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the base type of numeric value
|
* Defines the base type of numeric value
|
||||||
* @typedef {('hex' | 'dec' | 'BN')} NumericBase
|
* @typedef {('hex' | 'dec' | 'BN')} NumericBase
|
||||||
@ -162,6 +167,10 @@ const conversionUtil = (
|
|||||||
})
|
})
|
||||||
|
|
||||||
const getBigNumber = (value, base) => {
|
const getBigNumber = (value, base) => {
|
||||||
|
if (!isValidBase(base)) {
|
||||||
|
throw new Error('Must specificy valid base')
|
||||||
|
}
|
||||||
|
|
||||||
// We don't include 'number' here, because BigNumber will throw if passed
|
// We don't include 'number' here, because BigNumber will throw if passed
|
||||||
// a number primitive it considers unsafe.
|
// a number primitive it considers unsafe.
|
||||||
if (typeof value === 'string' || value instanceof BigNumber) {
|
if (typeof value === 'string' || value instanceof BigNumber) {
|
||||||
@ -173,6 +182,11 @@ const getBigNumber = (value, base) => {
|
|||||||
|
|
||||||
const addCurrencies = (a, b, options = {}) => {
|
const addCurrencies = (a, b, options = {}) => {
|
||||||
const { aBase, bBase, ...conversionOptions } = options
|
const { aBase, bBase, ...conversionOptions } = options
|
||||||
|
|
||||||
|
if (!isValidBase(aBase) || !isValidBase(bBase)) {
|
||||||
|
throw new Error('Must specify valid aBase and bBase')
|
||||||
|
}
|
||||||
|
|
||||||
const value = getBigNumber(a, aBase).add(getBigNumber(b, bBase))
|
const value = getBigNumber(a, aBase).add(getBigNumber(b, bBase))
|
||||||
|
|
||||||
return converter({
|
return converter({
|
||||||
@ -183,6 +197,11 @@ const addCurrencies = (a, b, options = {}) => {
|
|||||||
|
|
||||||
const subtractCurrencies = (a, b, options = {}) => {
|
const subtractCurrencies = (a, b, options = {}) => {
|
||||||
const { aBase, bBase, ...conversionOptions } = options
|
const { aBase, bBase, ...conversionOptions } = options
|
||||||
|
|
||||||
|
if (!isValidBase(aBase) || !isValidBase(bBase)) {
|
||||||
|
throw new Error('Must specify valid aBase and bBase')
|
||||||
|
}
|
||||||
|
|
||||||
const value = getBigNumber(a, aBase).minus(getBigNumber(b, bBase))
|
const value = getBigNumber(a, aBase).minus(getBigNumber(b, bBase))
|
||||||
|
|
||||||
return converter({
|
return converter({
|
||||||
@ -194,6 +213,10 @@ const subtractCurrencies = (a, b, options = {}) => {
|
|||||||
const multiplyCurrencies = (a, b, options = {}) => {
|
const multiplyCurrencies = (a, b, options = {}) => {
|
||||||
const { multiplicandBase, multiplierBase, ...conversionOptions } = options
|
const { multiplicandBase, multiplierBase, ...conversionOptions } = options
|
||||||
|
|
||||||
|
if (!isValidBase(multiplicandBase) || !isValidBase(multiplierBase)) {
|
||||||
|
throw new Error('Must specify valid multiplicandBase and multiplierBase')
|
||||||
|
}
|
||||||
|
|
||||||
const value = getBigNumber(a, multiplicandBase).times(
|
const value = getBigNumber(a, multiplicandBase).times(
|
||||||
getBigNumber(b, multiplierBase),
|
getBigNumber(b, multiplierBase),
|
||||||
)
|
)
|
||||||
|
@ -5,17 +5,26 @@ import { addCurrencies, conversionUtil } from './conversion-util'
|
|||||||
describe('conversion utils', function () {
|
describe('conversion utils', function () {
|
||||||
describe('addCurrencies()', function () {
|
describe('addCurrencies()', function () {
|
||||||
it('add whole numbers', function () {
|
it('add whole numbers', function () {
|
||||||
const result = addCurrencies(3, 9)
|
const result = addCurrencies(3, 9, {
|
||||||
|
aBase: 10,
|
||||||
|
bBase: 10,
|
||||||
|
})
|
||||||
assert.equal(result.toNumber(), 12)
|
assert.equal(result.toNumber(), 12)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('add decimals', function () {
|
it('add decimals', function () {
|
||||||
const result = addCurrencies(1.3, 1.9)
|
const result = addCurrencies(1.3, 1.9, {
|
||||||
|
aBase: 10,
|
||||||
|
bBase: 10,
|
||||||
|
})
|
||||||
assert.equal(result.toNumber(), 3.2)
|
assert.equal(result.toNumber(), 3.2)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('add repeating decimals', function () {
|
it('add repeating decimals', function () {
|
||||||
const result = addCurrencies(1 / 3, 1 / 9)
|
const result = addCurrencies(1 / 3, 1 / 9, {
|
||||||
|
aBase: 10,
|
||||||
|
bBase: 10,
|
||||||
|
})
|
||||||
assert.equal(result.toNumber(), 0.4444444444444444)
|
assert.equal(result.toNumber(), 0.4444444444444444)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -217,6 +217,10 @@ export function getTokenFiatAmount(
|
|||||||
const currentTokenToFiatRate = multiplyCurrencies(
|
const currentTokenToFiatRate = multiplyCurrencies(
|
||||||
contractExchangeRate,
|
contractExchangeRate,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
|
{
|
||||||
|
multiplicandBase: 10,
|
||||||
|
multiplierBase: 10,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
const currentTokenInFiat = conversionUtil(tokenAmount, {
|
const currentTokenInFiat = conversionUtil(tokenAmount, {
|
||||||
fromNumericBase: 'dec',
|
fromNumericBase: 'dec',
|
||||||
|
@ -152,9 +152,11 @@ export async function isSmartContractAddress(address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function sumHexes(...args) {
|
export function sumHexes(...args) {
|
||||||
const total = args.reduce((acc, base) => {
|
const total = args.reduce((acc, hexAmount) => {
|
||||||
return addCurrencies(acc, base, {
|
return addCurrencies(acc, hexAmount, {
|
||||||
toNumericBase: 'hex',
|
toNumericBase: 'hex',
|
||||||
|
aBase: 16,
|
||||||
|
bBase: 16,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -12,8 +12,11 @@ export function calcMaxAmount({ balance, gasTotal, sendToken, tokenBalance }) {
|
|||||||
? multiplyCurrencies(tokenBalance, multiplier, {
|
? multiplyCurrencies(tokenBalance, multiplier, {
|
||||||
toNumericBase: 'hex',
|
toNumericBase: 'hex',
|
||||||
multiplicandBase: 16,
|
multiplicandBase: 16,
|
||||||
|
multiplierBase: 10,
|
||||||
})
|
})
|
||||||
: subtractCurrencies(addHexPrefix(balance), addHexPrefix(gasTotal), {
|
: subtractCurrencies(addHexPrefix(balance), addHexPrefix(gasTotal), {
|
||||||
toNumericBase: 'hex',
|
toNumericBase: 'hex',
|
||||||
|
aBase: 16,
|
||||||
|
bBase: 16,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user