From 3ff12d70e9a07d2efb35afde6577d95a8f77a0f5 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Tue, 24 Jan 2023 08:44:49 -0600 Subject: [PATCH] Replace usages of conversion util in rest of UI folder in favor of Numeric (#17334) --- shared/modules/Numeric.ts | 3 +- .../confirm-transaction.duck.js | 7 +- ui/ducks/send/helpers.js | 31 ++--- ui/ducks/send/send.js | 123 +++++++++++------- ui/ducks/swaps/swaps.js | 19 ++- ui/helpers/utils/confirm-tx.util.js | 100 +++++--------- ui/helpers/utils/confirm-tx.util.test.js | 30 ----- ui/helpers/utils/gas.js | 40 ++---- ui/helpers/utils/gas.test.js | 12 -- ui/helpers/utils/token-util.js | 33 ++--- ui/helpers/utils/util.js | 9 +- ui/hooks/gasFeeInput/test-utils.js | 29 +---- ui/hooks/gasFeeInput/useGasFeeErrors.js | 22 +--- .../gasFeeInput/useTransactionFunctions.js | 8 +- ui/hooks/useCurrencyDisplay.js | 19 ++- ui/hooks/useIncrementedGasFees.js | 4 +- .../confirm-decrypt-message.component.js | 18 +-- ...confirm-encryption-public-key.component.js | 18 +-- .../confirm-transaction-base.component.js | 2 +- ui/pages/send/send.constants.js | 34 ++--- ui/pages/send/send.utils.js | 96 ++++---------- ui/pages/send/send.utils.test.js | 81 ++---------- ui/selectors/custom-gas.js | 91 +++++-------- 23 files changed, 290 insertions(+), 539 deletions(-) diff --git a/shared/modules/Numeric.ts b/shared/modules/Numeric.ts index b8149f601..6525ab325 100644 --- a/shared/modules/Numeric.ts +++ b/shared/modules/Numeric.ts @@ -278,7 +278,8 @@ export class Numeric { this.value = bnToBigNumber(value); } else if ( isNullOrUndefined(value) || - (typeof value === 'number' && isNaN(value)) + (typeof value === 'number' && isNaN(value)) || + (typeof value === 'string' && value === '') ) { // There are parts of the codebase that call this method without a value, // or with a 'NaN' (which is probably a bug somewhere in our tests?). diff --git a/ui/ducks/confirm-transaction/confirm-transaction.duck.js b/ui/ducks/confirm-transaction/confirm-transaction.duck.js index bb846a204..a8a9ba007 100644 --- a/ui/ducks/confirm-transaction/confirm-transaction.duck.js +++ b/ui/ducks/confirm-transaction/confirm-transaction.duck.js @@ -13,8 +13,8 @@ import { } from '../../helpers/utils/confirm-tx.util'; import { - conversionUtil, getValueFromWeiHex, + hexToDecimal, sumHexes, } from '../../../shared/modules/conversion.utils'; import { getAveragePriceEstimateInHexWEI } from '../../selectors/custom-gas'; @@ -293,10 +293,7 @@ export function setTransactionToConfirm(transactionId) { } if (txParams.nonce) { - const nonce = conversionUtil(txParams.nonce, { - fromNumericBase: 'hex', - toNumericBase: 'dec', - }); + const nonce = hexToDecimal(txParams.nonce); dispatch(updateNonce(nonce)); } diff --git a/ui/ducks/send/helpers.js b/ui/ducks/send/helpers.js index d0497c892..a414a7f2b 100644 --- a/ui/ducks/send/helpers.js +++ b/ui/ducks/send/helpers.js @@ -1,5 +1,6 @@ import { addHexPrefix } from 'ethereumjs-util'; import abi from 'human-standard-token-abi'; +import BigNumber from 'bignumber.js'; import { GAS_LIMITS, MIN_GAS_LIMIT_HEX } from '../../../shared/constants/gas'; import { calcTokenAmount } from '../../../shared/lib/transactions-controller-utils'; import { CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP } from '../../../shared/constants/network'; @@ -8,11 +9,6 @@ import { TransactionEnvelopeType, } from '../../../shared/constants/transaction'; import { readAddressAsContract } from '../../../shared/modules/contract-utils'; -import { - conversionUtil, - multiplyCurrencies, -} from '../../../shared/modules/conversion.utils'; -import { ETH, GWEI } from '../../helpers/constants/common'; import { addGasBuffer, generateERC20TransferData, @@ -21,6 +17,7 @@ import { } from '../../pages/send/send.utils'; import { getGasPriceInHexWei } from '../../selectors'; import { estimateGas } from '../../store/actions'; +import { Numeric } from '../../../shared/modules/Numeric'; export async function estimateGasLimitForSend({ selectedAddress, @@ -109,15 +106,10 @@ export async function estimateGasLimitForSend({ if (!isSimpleSendOnNonStandardNetwork) { // If we do not yet have a gasLimit, we must call into our background // process to get an estimate for gasLimit based on known parameters. - - paramsForGasEstimate.gas = addHexPrefix( - multiplyCurrencies(blockGasLimit, 0.95, { - multiplicandBase: 16, - multiplierBase: 10, - roundDown: '0', - toNumericBase: 'hex', - }), - ); + paramsForGasEstimate.gas = new Numeric(blockGasLimit, 16) + .times(new Numeric(0.95, 10)) + .round(0, BigNumber.ROUND_DOWN) + .toPrefixedHexString(); } // The buffer multipler reduces transaction failures by ensuring that the @@ -268,14 +260,9 @@ export function generateTransactionParams(sendState) { * @returns {string} */ export function getRoundedGasPrice(gasPriceEstimate) { - const gasPriceInDecGwei = conversionUtil(gasPriceEstimate, { - numberOfDecimals: 9, - toDenomination: GWEI, - fromNumericBase: 'dec', - toNumericBase: 'dec', - fromCurrency: ETH, - fromDenomination: GWEI, - }); + const gasPriceInDecGwei = new Numeric(gasPriceEstimate, 10) + .round(9) + .toString(); const gasPriceAsNumber = Number(gasPriceInDecGwei); return getGasPriceInHexWei(gasPriceAsNumber); } diff --git a/ui/ducks/send/send.js b/ui/ducks/send/send.js index d17cbc61e..491e6e42a 100644 --- a/ui/ducks/send/send.js +++ b/ui/ducks/send/send.js @@ -4,12 +4,8 @@ import { addHexPrefix } from 'ethereumjs-util'; import { debounce } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; import { - conversionGreaterThan, - conversionUtil, + decimalToHex, getValueFromWeiHex, - multiplyCurrencies, - subtractCurrencies, - sumHexes, } from '../../../shared/modules/conversion.utils'; import { GAS_ESTIMATE_TYPES, GAS_LIMITS } from '../../../shared/constants/gas'; import { @@ -109,6 +105,7 @@ import { calcGasTotal, calcTokenAmount, } from '../../../shared/lib/transactions-controller-utils'; +import { Numeric } from '../../../shared/modules/Numeric'; import { estimateGasLimitForSend, generateTransactionParams, @@ -902,31 +899,21 @@ const slice = createSlice({ let amount = '0x0'; if (draftTransaction.asset.type === AssetType.token) { const decimals = draftTransaction.asset.details?.decimals ?? 0; + const multiplier = Math.pow(10, Number(decimals)); - amount = multiplyCurrencies( - draftTransaction.asset.balance, - multiplier, - { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 10, - }, - ); + amount = new Numeric(draftTransaction.asset.balance, 16) + .times(multiplier, 10) + .toString(); } else { - const _gasTotal = sumHexes( + const _gasTotal = new Numeric( draftTransaction.gas.gasTotal || '0x0', - state.gasTotalForLayer1 || '0x0', - ); - amount = subtractCurrencies( - addHexPrefix(draftTransaction.asset.balance), - addHexPrefix(_gasTotal), - { - toNumericBase: 'hex', - aBase: 16, - bBase: 16, - }, - ); + 16, + ).add(new Numeric(state.gasTotalForLayer1 || '0x0', 16)); + + amount = new Numeric(draftTransaction.asset.balance, 16) + .minus(_gasTotal) + .toString(); } slice.caseReducers.updateSendAmount(state, { payload: amount, @@ -1266,6 +1253,9 @@ const slice = createSlice({ validateAmountField: (state) => { const draftTransaction = state.draftTransactions[state.currentTransactionUUID]; + + const amountValue = new Numeric(draftTransaction.amount.value, 16); + switch (true) { // set error to INSUFFICIENT_FUNDS_FOR_GAS_ERROR if the account balance is lower // than the total price of the transaction inclusive of gas fees. @@ -1289,10 +1279,7 @@ const slice = createSlice({ break; // if the amount is negative, set error to NEGATIVE_ETH_ERROR // TODO: change this to NEGATIVE_ERROR and remove the currency bias. - case conversionGreaterThan( - { value: 0, fromNumericBase: 'dec' }, - { value: draftTransaction.amount.value, fromNumericBase: 'hex' }, - ): + case amountValue.isNegative(): draftTransaction.amount.error = NEGATIVE_ETH_ERROR; break; // If none of the above are true, set error to null @@ -1407,28 +1394,81 @@ const slice = createSlice({ validateSendState: (state) => { const draftTransaction = state.draftTransactions[state.currentTransactionUUID]; + slice.caseReducers.addHistoryEntry(state, { + payload: 'Begin validating send state', + }); if (draftTransaction) { switch (true) { case Boolean(draftTransaction.amount.error): + slice.caseReducers.addHistoryEntry(state, { + payload: `Amount is in error ${draftTransaction.amount.error}`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case Boolean(draftTransaction.gas.error): + slice.caseReducers.addHistoryEntry(state, { + payload: `Gas is in error ${draftTransaction.gas.error}`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case Boolean(draftTransaction.asset.error): + slice.caseReducers.addHistoryEntry(state, { + payload: `Asset is in error ${draftTransaction.asset.error}`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case draftTransaction.asset.type === AssetType.token && draftTransaction.asset.details === null: + slice.caseReducers.addHistoryEntry(state, { + payload: `Asset is TOKEN and token details is null`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case state.stage === SEND_STAGES.ADD_RECIPIENT: + slice.caseReducers.addHistoryEntry(state, { + payload: `Form is invalid because stage is ADD_RECIPIENT`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case state.stage === SEND_STAGES.INACTIVE: + slice.caseReducers.addHistoryEntry(state, { + payload: `Form is invalid because stage is INACTIVE`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case state.gasEstimateIsLoading: + slice.caseReducers.addHistoryEntry(state, { + payload: `Form is invalid because gasEstimateIsLoading`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case new BigNumber(draftTransaction.gas.gasLimit, 16).lessThan( new BigNumber(state.gasLimitMinimum), ): + slice.caseReducers.addHistoryEntry(state, { + payload: `Form is invalid because ${draftTransaction.gas.gasLimit} is lessThan ${state.gasLimitMinimum}`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; break; case draftTransaction.recipient.warning === 'loading': + slice.caseReducers.addHistoryEntry(state, { + payload: `Form is invalid because recipient warning is loading`, + }); + draftTransaction.status = SEND_STATUSES.INVALID; + break; case draftTransaction.recipient.warning === KNOWN_RECIPIENT_ADDRESS_WARNING && draftTransaction.recipient.recipientWarningAcknowledged === false: + slice.caseReducers.addHistoryEntry(state, { + payload: `Form is invalid because recipient warning not acknolwedged`, + }); draftTransaction.status = SEND_STATUSES.INVALID; break; default: + slice.caseReducers.addHistoryEntry(state, { + payload: `Form is valid`, + }); draftTransaction.status = SEND_STATUSES.VALID; } } @@ -1730,13 +1770,7 @@ export function editExistingTransaction(assetType, transactionId) { const address = getTokenAddressParam(tokenData); const nickname = getAddressBookEntryOrAccountName(state, address) ?? ''; - const tokenAmountInHex = addHexPrefix( - conversionUtil(tokenAmountInDec, { - fromNumericBase: 'dec', - toNumericBase: 'hex', - }), - ); - + const tokenAmountInHex = addHexPrefix(decimalToHex(tokenAmountInDec)); await dispatch( actions.addNewDraft({ ...draftTransactionInitialState, @@ -1936,14 +1970,13 @@ export function updateSendAmount(amount) { 10, Number(draftTransaction.asset.details?.decimals || 0), ); - const decimalValueString = conversionUtil(addHexPrefix(amount), { - fromNumericBase: 'hex', - toNumericBase: 'dec', - toCurrency: draftTransaction.asset.details?.symbol, - conversionRate: multiplier, - invertConversionRate: true, - }); - + const decimalValueString = new Numeric(addHexPrefix(amount), 16) + .toBase(10) + .applyConversionRate( + draftTransaction.asset.details?.symbol ? multiplier : 1, + true, + ) + .toString(); logAmount = `${Number(decimalValueString) ? decimalValueString : ''} ${ draftTransaction.asset.details?.symbol }`; diff --git a/ui/ducks/swaps/swaps.js b/ui/ducks/swaps/swaps.js index 1e9fb41bc..3f469e01a 100644 --- a/ui/ducks/swaps/swaps.js +++ b/ui/ducks/swaps/swaps.js @@ -53,7 +53,6 @@ import { } from '../../pages/swaps/swaps.util'; import { addHexes, - conversionLessThan, decGWEIToHexWEI, decimalToHex, getValueFromWeiHex, @@ -91,6 +90,8 @@ import { calcGasTotal, calcTokenAmount, } from '../../../shared/lib/transactions-controller-utils'; +import { EtherDenomination } from '../../../shared/constants/common'; +import { Numeric } from '../../../shared/modules/Numeric'; export const GAS_PRICES_LOADING_STATES = { INITIAL: 'INITIAL', @@ -289,15 +290,13 @@ export function shouldShowCustomPriceTooLowWarning(state) { return false; } - const customPriceRisksSwapFailure = conversionLessThan( - { - value: customGasPrice, - fromNumericBase: 'hex', - fromDenomination: 'WEI', - toDenomination: 'GWEI', - }, - { value: average, fromNumericBase: 'dec' }, - ); + const customPriceRisksSwapFailure = new Numeric( + customGasPrice, + 16, + EtherDenomination.WEI, + ) + .toDenomination(EtherDenomination.GWEI) + .greaterThan(average, 10); return customPriceRisksSwapFailure; } diff --git a/ui/helpers/utils/confirm-tx.util.js b/ui/helpers/utils/confirm-tx.util.js index 315cbcc55..fd2c70649 100644 --- a/ui/helpers/utils/confirm-tx.util.js +++ b/ui/helpers/utils/confirm-tx.util.js @@ -1,63 +1,31 @@ import currencyFormatter from 'currency-formatter'; import currencies from 'currency-formatter/currencies'; import BigNumber from 'bignumber.js'; -import { addHexPrefix } from '../../../app/scripts/lib/util'; import { unconfirmedTransactionsCountSelector } from '../../selectors'; -import { - conversionUtil, - addCurrencies, - multiplyCurrencies, - conversionGreaterThan, -} from '../../../shared/modules/conversion.utils'; +import { Numeric } from '../../../shared/modules/Numeric'; +import { EtherDenomination } from '../../../shared/constants/common'; -export function increaseLastGasPrice(lastGasPrice) { - return addHexPrefix( - multiplyCurrencies(lastGasPrice || '0x0', 1.1, { - multiplicandBase: 16, - multiplierBase: 10, - toNumericBase: 'hex', - }), - ); +export function getHexGasTotal({ gasLimit = '0x0', gasPrice = '0x0' }) { + return new Numeric(gasLimit, 16) + .times(new Numeric(gasPrice, 16)) + .toPrefixedHexString(); } -export function hexGreaterThan(a, b) { - return conversionGreaterThan( - { value: a, fromNumericBase: 'hex' }, - { value: b, fromNumericBase: 'hex' }, - ); +export function addEth(firstValue, ...otherValues) { + return otherValues + .reduce((numericAcc, ethAmount) => { + return numericAcc.add(new Numeric(ethAmount, 10)).round(6); + }, new Numeric(firstValue, 10)) + .toString(); } -export function getHexGasTotal({ gasLimit, gasPrice }) { - return addHexPrefix( - multiplyCurrencies(gasLimit || '0x0', gasPrice || '0x0', { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 16, - }), - ); -} - -export function addEth(...args) { - return args.reduce((acc, ethAmount) => { - return addCurrencies(acc, ethAmount, { - toNumericBase: 'dec', - numberOfDecimals: 6, - aBase: 10, - bBase: 10, - }); - }); -} - -export function addFiat(...args) { - return args.reduce((acc, fiatAmount) => { - return addCurrencies(acc, fiatAmount, { - toNumericBase: 'dec', - numberOfDecimals: 2, - aBase: 10, - bBase: 10, - }); - }); +export function addFiat(firstValue, ...otherValues) { + return otherValues + .reduce((numericAcc, fiatAmount) => { + return numericAcc.add(new Numeric(fiatAmount, 10)).round(2); + }, new Numeric(firstValue, 10)) + .toString(); } export function getTransactionFee({ @@ -67,15 +35,14 @@ export function getTransactionFee({ conversionRate, numberOfDecimals, }) { - return conversionUtil(value, { - fromNumericBase: 'BN', - toNumericBase: 'dec', - fromDenomination: 'WEI', - fromCurrency, - toCurrency, - numberOfDecimals, - conversionRate, - }); + let fee = new Numeric(value, 16, EtherDenomination.WEI) + .toDenomination(EtherDenomination.ETH) + .toBase(10); + + if (fromCurrency !== toCurrency && conversionRate) { + fee = fee.applyConversionRate(conversionRate); + } + return fee.round(numberOfDecimals).toString(); } export function formatCurrency(value, currencyCode) { @@ -98,14 +65,13 @@ export function convertTokenToFiat({ }) { const totalExchangeRate = conversionRate * contractExchangeRate; - return conversionUtil(value, { - fromNumericBase: 'dec', - toNumericBase: 'dec', - fromCurrency, - toCurrency, - numberOfDecimals: 2, - conversionRate: totalExchangeRate, - }); + let tokenInFiat = new Numeric(value, 10); + + if (fromCurrency !== toCurrency && totalExchangeRate) { + tokenInFiat = tokenInFiat.applyConversionRate(totalExchangeRate); + } + + return tokenInFiat.round(2).toString(); } export function hasUnconfirmedTransactions(state) { diff --git a/ui/helpers/utils/confirm-tx.util.test.js b/ui/helpers/utils/confirm-tx.util.test.js index d0f4971a8..5389164c9 100644 --- a/ui/helpers/utils/confirm-tx.util.test.js +++ b/ui/helpers/utils/confirm-tx.util.test.js @@ -2,36 +2,6 @@ import { GAS_LIMITS } from '../../../shared/constants/gas'; import * as utils from './confirm-tx.util'; describe('Confirm Transaction utils', () => { - describe('increaseLastGasPrice', () => { - it('should increase the gasPrice by 10%', () => { - const increasedGasPrice = utils.increaseLastGasPrice('0xa'); - expect(increasedGasPrice).toStrictEqual('0xb'); - }); - - it('should prefix the result with 0x', () => { - const increasedGasPrice = utils.increaseLastGasPrice('a'); - expect(increasedGasPrice).toStrictEqual('0xb'); - }); - }); - - describe('hexGreaterThan', () => { - it('should return true if the first value is greater than the second value', () => { - expect(utils.hexGreaterThan('0xb', '0xa')).toStrictEqual(true); - }); - - it('should return false if the first value is less than the second value', () => { - expect(utils.hexGreaterThan('0xa', '0xb')).toStrictEqual(false); - }); - - it('should return false if the first value is equal to the second value', () => { - expect(utils.hexGreaterThan('0xa', '0xa')).toStrictEqual(false); - }); - - it('should correctly compare prefixed and non-prefixed hex values', () => { - expect(utils.hexGreaterThan('0xb', 'a')).toStrictEqual(true); - }); - }); - describe('getHexGasTotal', () => { it('should multiply the hex gasLimit and hex gasPrice values together', () => { expect( diff --git a/ui/helpers/utils/gas.js b/ui/helpers/utils/gas.js index 0355a3449..1aa19cafc 100644 --- a/ui/helpers/utils/gas.js +++ b/ui/helpers/utils/gas.js @@ -1,20 +1,19 @@ import { constant, times, uniq, zip } from 'lodash'; import BigNumber from 'bignumber.js'; -import { addHexPrefix } from 'ethereumjs-util'; import { GAS_RECOMMENDATIONS, EDIT_GAS_MODES, } from '../../../shared/constants/gas'; -import { - hexWEIToDecGWEI, - multiplyCurrencies, -} from '../../../shared/modules/conversion.utils'; +import { hexWEIToDecGWEI } from '../../../shared/modules/conversion.utils'; +import { Numeric } from '../../../shared/modules/Numeric'; import { bnGreaterThan, isNullish, roundToDecimalPlacesRemovingExtraZeroes, } from './util'; +const TEN_PERCENT_NUMERIC = new Numeric(1.1, 10); + export const gasEstimateGreaterThanGasUsedPlusTenPercent = ( gasUsed, gasFeeEstimates, @@ -30,29 +29,6 @@ export const gasEstimateGreaterThanGasUsedPlusTenPercent = ( return bnGreaterThan(maxFeePerGasFromEstimate, maxFeePerGasInTransaction); }; -/** - * Simple helper to save on duplication to multiply the supplied wei hex string - * by 1.10 to get bare minimum new gas fee. - * - * @param {string | undefined} hexStringValue - hex value in wei to be incremented - * @param conversionOptions - * @returns {string | undefined} hex value in WEI 10% higher than the param. - */ -export function addTenPercent(hexStringValue, conversionOptions = {}) { - if (hexStringValue === undefined) { - return undefined; - } - return addHexPrefix( - multiplyCurrencies(hexStringValue, 1.1, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 10, - numberOfDecimals: 0, - ...conversionOptions, - }), - ); -} - /** * Simple helper to save on duplication to multiply the supplied wei hex string * by 1.10 to get bare minimum new gas fee. @@ -61,7 +37,13 @@ export function addTenPercent(hexStringValue, conversionOptions = {}) { * @returns {string | undefined} hex value in WEI 10% higher than the param. */ export function addTenPercentAndRound(hexStringValue) { - return addTenPercent(hexStringValue, { numberOfDecimals: 0 }); + if (hexStringValue === undefined) { + return undefined; + } + return new Numeric(hexStringValue, 16) + .times(TEN_PERCENT_NUMERIC) + .round(0) + .toPrefixedHexString(); } export function isMetamaskSuggestedGasEstimate(estimate) { diff --git a/ui/helpers/utils/gas.test.js b/ui/helpers/utils/gas.test.js index cf197afb7..177206a22 100644 --- a/ui/helpers/utils/gas.test.js +++ b/ui/helpers/utils/gas.test.js @@ -1,7 +1,6 @@ import { PRIORITY_LEVELS } from '../../../shared/constants/gas'; import { - addTenPercent, gasEstimateGreaterThanGasUsedPlusTenPercent, formatGasFeeOrFeeRange, } from './gas'; @@ -38,17 +37,6 @@ describe('Gas utils', () => { }); }); - describe('addTenPercent', () => { - it('should add 10% to hex value passed', () => { - const result = addTenPercent('0x59682f00'); - expect(result).toStrictEqual('0x62590080'); - }); - it('should return undefined if undefined value is passed', () => { - const result = addTenPercent(undefined); - expect(result).toBeUndefined(); - }); - }); - describe('formatGasFeeOrFeeRange', () => { describe('given a singular fee', () => { it('should return a string "X GWEI" where X is the fee rounded to the given precision', () => { diff --git a/ui/helpers/utils/token-util.js b/ui/helpers/utils/token-util.js index 04e63db9c..863cb5f76 100644 --- a/ui/helpers/utils/token-util.js +++ b/ui/helpers/utils/token-util.js @@ -1,14 +1,11 @@ import log from 'loglevel'; -import { - conversionUtil, - multiplyCurrencies, -} from '../../../shared/modules/conversion.utils'; import { getTokenStandardAndDetails } from '../../store/actions'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; import { parseStandardTokenTransactionData } from '../../../shared/modules/transaction.utils'; import { TokenStandard } from '../../../shared/constants/transaction'; import { getTokenValueParam } from '../../../shared/lib/metamask-controller-utils'; import { calcTokenAmount } from '../../../shared/lib/transactions-controller-utils'; +import { Numeric } from '../../../shared/modules/Numeric'; import * as util from './util'; import { formatCurrency } from './confirm-tx.util'; @@ -189,21 +186,19 @@ export function getTokenFiatAmount( return undefined; } - const currentTokenToFiatRate = multiplyCurrencies( - contractExchangeRate, - conversionRate, - { - multiplicandBase: 10, - multiplierBase: 10, - }, - ); - const currentTokenInFiat = conversionUtil(tokenAmount, { - fromNumericBase: 'dec', - fromCurrency: tokenSymbol, - toCurrency: currentCurrency.toUpperCase(), - numberOfDecimals: 2, - conversionRate: currentTokenToFiatRate, - }); + const currentTokenToFiatRate = new Numeric(contractExchangeRate, 10) + .times(new Numeric(conversionRate, 10)) + .toString(); + + let currentTokenInFiat = new Numeric(tokenAmount, 10); + + if (tokenSymbol !== currentCurrency.toUpperCase() && currentTokenToFiatRate) { + currentTokenInFiat = currentTokenInFiat.applyConversionRate( + currentTokenToFiatRate, + ); + } + + currentTokenInFiat = currentTokenInFiat.round(2).toString(); let result; if (hideCurrencySymbol) { result = formatCurrency(currentTokenInFiat, currentCurrency); diff --git a/ui/helpers/utils/util.js b/ui/helpers/utils/util.js index e470f69b0..85850630d 100644 --- a/ui/helpers/utils/util.js +++ b/ui/helpers/utils/util.js @@ -15,7 +15,7 @@ import { TRUNCATED_NAME_CHAR_LIMIT, TRUNCATED_ADDRESS_END_CHARS, } from '../../../shared/constants/labels'; -import { toBigNumber } from '../../../shared/modules/conversion.utils'; +import { Numeric } from '../../../shared/modules/Numeric'; // formatData :: ( date: ) -> String export function formatDate(date, format = "M/d/y 'at' T") { @@ -485,9 +485,10 @@ export function roundToDecimalPlacesRemovingExtraZeroes( if (numberish === undefined || numberish === null) { return ''; } - return toBigNumber - .dec(toBigNumber.dec(numberish).toFixed(numberOfDecimalPlaces)) - .toNumber(); + return new Numeric( + new Numeric(numberish, 10).toFixed(numberOfDecimalPlaces), + 10, + ).toNumber(); } /** diff --git a/ui/hooks/gasFeeInput/test-utils.js b/ui/hooks/gasFeeInput/test-utils.js index 949600092..4ceb2ac53 100644 --- a/ui/hooks/gasFeeInput/test-utils.js +++ b/ui/hooks/gasFeeInput/test-utils.js @@ -1,10 +1,6 @@ import { useSelector } from 'react-redux'; import { GAS_ESTIMATE_TYPES } from '../../../shared/constants/gas'; -import { - conversionUtil, - multiplyCurrencies, -} from '../../../shared/modules/conversion.utils'; import { getConversionRate, getNativeCurrency, @@ -26,6 +22,8 @@ import { getCustomMaxFeePerGas, getCustomMaxPriorityFeePerGas, } from '../../ducks/swaps/swaps'; +import { Numeric } from '../../../shared/modules/Numeric'; +import { EtherDenomination } from '../../../shared/constants/common'; // Why this number? // 20 gwei * 21000 gasLimit = 420,000 gwei @@ -148,30 +146,15 @@ export const generateUseSelectorRouter = return undefined; }; -export function getTotalCostInETH(gwei, gasLimit) { - return multiplyCurrencies(gwei, gasLimit, { - fromDenomination: 'GWEI', - toDenomination: 'ETH', - multiplicandBase: 10, - multiplierBase: 10, - }); -} - export function convertFromHexToFiat(value) { - const val = conversionUtil(value, { - fromNumericBase: 'hex', - toNumericBase: 'dec', - fromDenomination: 'WEI', - }); + const val = new Numeric(value, 16).toBase(10).toString(); return `$${(val * MOCK_ETH_USD_CONVERSION_RATE).toFixed(2)}`; } export function convertFromHexToETH(value) { - const val = conversionUtil(value, { - fromNumericBase: 'hex', - toNumericBase: 'dec', - fromDenomination: 'WEI', - }); + const val = new Numeric(value, 16, EtherDenomination.WEI) + .toBase(10) + .toDenomination(EtherDenomination.ETH); return `${val} ETH`; } diff --git a/ui/hooks/gasFeeInput/useGasFeeErrors.js b/ui/hooks/gasFeeInput/useGasFeeErrors.js index 49771b837..6a8ba2d5c 100644 --- a/ui/hooks/gasFeeInput/useGasFeeErrors.js +++ b/ui/hooks/gasFeeInput/useGasFeeErrors.js @@ -1,11 +1,6 @@ import { useMemo } from 'react'; import { shallowEqual, useSelector } from 'react-redux'; import { GAS_ESTIMATE_TYPES, GAS_LIMITS } from '../../../shared/constants/gas'; -import { - conversionLessThan, - conversionGreaterThan, - addHexes, -} from '../../../shared/modules/conversion.utils'; import { checkNetworkAndAccountSupports1559, getSelectedAccount, @@ -13,13 +8,13 @@ import { import { isLegacyTransaction } from '../../helpers/utils/transactions.util'; import { bnGreaterThan, bnLessThan } from '../../helpers/utils/util'; import { GAS_FORM_ERRORS } from '../../helpers/constants/gas'; +import { Numeric } from '../../../shared/modules/Numeric'; const HIGH_FEE_WARNING_MULTIPLIER = 1.5; const validateGasLimit = (gasLimit, minimumGasLimit) => { - const gasLimitTooLow = conversionLessThan( - { value: gasLimit, fromNumericBase: 'dec' }, - { value: minimumGasLimit || GAS_LIMITS.SIMPLE, fromNumericBase: 'hex' }, + const gasLimitTooLow = new Numeric(gasLimit, 10).lessThan( + new Numeric(minimumGasLimit || GAS_LIMITS.SIMPLE, 16), ); if (gasLimitTooLow) { @@ -139,15 +134,12 @@ const hasBalanceError = (minimumCostInHexWei, transaction, ethBalance) => { if (minimumCostInHexWei === undefined || ethBalance === undefined) { return false; } - const minimumTxCostInHexWei = addHexes( - minimumCostInHexWei, - transaction?.txParams?.value || '0x0', + const minimumTxCostInHexWei = new Numeric(minimumCostInHexWei, 16).add( + new Numeric(transaction?.txParams?.value || '0x0', 16), ); + const ethBalanceInHexWei = new Numeric(ethBalance, 16); - return conversionGreaterThan( - { value: minimumTxCostInHexWei, fromNumericBase: 'hex' }, - { value: ethBalance, fromNumericBase: 'hex' }, - ); + return minimumTxCostInHexWei.greaterThan(ethBalanceInHexWei); }; /** diff --git a/ui/hooks/gasFeeInput/useTransactionFunctions.js b/ui/hooks/gasFeeInput/useTransactionFunctions.js index 15af059f6..9158a8329 100644 --- a/ui/hooks/gasFeeInput/useTransactionFunctions.js +++ b/ui/hooks/gasFeeInput/useTransactionFunctions.js @@ -2,10 +2,6 @@ import { useCallback } from 'react'; import { useDispatch } from 'react-redux'; import { EDIT_GAS_MODES, PRIORITY_LEVELS } from '../../../shared/constants/gas'; -import { - decGWEIToHexWEI, - decimalToHex, -} from '../../../shared/modules/conversion.utils'; import { addTenPercentAndRound, editGasModeIsSpeedUpOrCancel, @@ -18,6 +14,10 @@ import { updateSwapsUserFeeLevel, updateTransactionGasFees, } from '../../store/actions'; +import { + decGWEIToHexWEI, + decimalToHex, +} from '../../../shared/modules/conversion.utils'; /** * @typedef {object} TransactionFunctionsReturnType diff --git a/ui/hooks/useCurrencyDisplay.js b/ui/hooks/useCurrencyDisplay.js index eb675428b..2963f53eb 100644 --- a/ui/hooks/useCurrencyDisplay.js +++ b/ui/hooks/useCurrencyDisplay.js @@ -7,11 +7,10 @@ import { getNativeCurrency, } from '../ducks/metamask/metamask'; -import { - conversionUtil, - getValueFromWeiHex, -} from '../../shared/modules/conversion.utils'; +import { getValueFromWeiHex } from '../../shared/modules/conversion.utils'; import { TEST_NETWORK_TICKER_MAP } from '../../shared/constants/network'; +import { Numeric } from '../../shared/modules/Numeric'; +import { EtherDenomination } from '../../shared/constants/common'; /** * Defines the shape of the options parameter for useCurrencyDisplay @@ -61,13 +60,11 @@ export function useCurrencyDisplay( currency === nativeCurrency || (!isUserPreferredCurrency && !nativeCurrency) ) { - return conversionUtil(inputValue, { - fromNumericBase: 'hex', - toNumericBase: 'dec', - fromDenomination: 'WEI', - numberOfDecimals: numberOfDecimals || 2, - toDenomination: denomination, - }); + return new Numeric(inputValue, 16, EtherDenomination.WEI) + .toDenomination(denomination || EtherDenomination.ETH) + .round(numberOfDecimals || 2) + .toBase(10) + .toString(); } else if (isUserPreferredCurrency && conversionRate) { return formatCurrency( getValueFromWeiHex({ diff --git a/ui/hooks/useIncrementedGasFees.js b/ui/hooks/useIncrementedGasFees.js index 14e58391b..e85c7362b 100644 --- a/ui/hooks/useIncrementedGasFees.js +++ b/ui/hooks/useIncrementedGasFees.js @@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js'; import { useMemo } from 'react'; import { decGWEIToHexWEI } from '../../shared/modules/conversion.utils'; import { isEIP1559Transaction } from '../../shared/modules/transaction.utils'; -import { addTenPercent } from '../helpers/utils/gas'; +import { addTenPercentAndRound } from '../helpers/utils/gas'; import { useGasFeeEstimates } from './useGasFeeEstimates'; /** @@ -15,7 +15,7 @@ import { useGasFeeEstimates } from './useGasFeeEstimates'; * @returns {string} hexWei value of the higher of the two inputs. */ function getHighestIncrementedFee(originalFee, currentEstimate) { - const buffedOriginalHexWei = addTenPercent(originalFee); + const buffedOriginalHexWei = addTenPercentAndRound(originalFee); const currentEstimateHexWei = decGWEIToHexWEI(currentEstimate); return new BigNumber(buffedOriginalHexWei, 16).greaterThan( diff --git a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js index f30576674..ed12e9e81 100644 --- a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js +++ b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js @@ -11,7 +11,8 @@ import { PageContainerFooter } from '../../components/ui/page-container'; import { EVENT } from '../../../shared/constants/metametrics'; import { SECOND } from '../../../shared/constants/time'; -import { conversionUtil } from '../../../shared/modules/conversion.utils'; +import { Numeric } from '../../../shared/modules/Numeric'; +import { EtherDenomination } from '../../../shared/constants/common'; export default class ConfirmDecryptMessage extends Component { static contextTypes = { @@ -98,13 +99,14 @@ export default class ConfirmDecryptMessage extends Component { } = this.state; const { t } = this.context; - const nativeCurrencyBalance = conversionUtil(balance, { - fromNumericBase: 'hex', - toNumericBase: 'dec', - fromDenomination: 'WEI', - numberOfDecimals: 6, - conversionRate, - }); + const nativeCurrencyBalance = new Numeric( + balance, + 16, + EtherDenomination.WEI, + ) + .applyConversionRate(conversionRate) + .round(6) + .toBase(10); return (
diff --git a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js index acf4328b3..205f2d0cc 100644 --- a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js +++ b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js @@ -6,8 +6,9 @@ import Identicon from '../../components/ui/identicon'; import { PageContainerFooter } from '../../components/ui/page-container'; import { EVENT } from '../../../shared/constants/metametrics'; -import { conversionUtil } from '../../../shared/modules/conversion.utils'; import SiteOrigin from '../../components/ui/site-origin'; +import { Numeric } from '../../../shared/modules/Numeric'; +import { EtherDenomination } from '../../../shared/constants/common'; export default class ConfirmEncryptionPublicKey extends Component { static contextTypes = { @@ -74,13 +75,14 @@ export default class ConfirmEncryptionPublicKey extends Component { } = this.props; const { t } = this.context; - const nativeCurrencyBalance = conversionUtil(balance, { - fromNumericBase: 'hex', - toNumericBase: 'dec', - fromDenomination: 'WEI', - numberOfDecimals: 6, - conversionRate, - }); + const nativeCurrencyBalance = new Numeric( + balance, + 16, + EtherDenomination.WEI, + ) + .applyConversionRate(conversionRate) + .round(6) + .toBase(10); return (
diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 19eaf03c5..ecbe550d0 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -67,12 +67,12 @@ import { CHAIN_ID_TO_NETWORK_ID_MAP, ///: END:ONLY_INCLUDE_IN } from '../../../shared/constants/network'; -import TransactionAlerts from '../../components/app/transaction-alerts'; import { addHexes, hexToDecimal, hexWEIToDecGWEI, } from '../../../shared/modules/conversion.utils'; +import TransactionAlerts from '../../components/app/transaction-alerts'; const renderHeartBeatIfNotInTest = () => process.env.IN_TEST ? null : ; diff --git a/ui/pages/send/send.constants.js b/ui/pages/send/send.constants.js index 38acb8081..a93828ddd 100644 --- a/ui/pages/send/send.constants.js +++ b/ui/pages/send/send.constants.js @@ -1,31 +1,25 @@ -import { - conversionUtil, - multiplyCurrencies, -} from '../../../shared/modules/conversion.utils'; -import { addHexPrefix } from '../../../app/scripts/lib/util'; import { MIN_GAS_LIMIT_HEX } from '../../../shared/constants/gas'; +import { Numeric } from '../../../shared/modules/Numeric'; +import { EtherDenomination } from '../../../shared/constants/common'; const MIN_GAS_PRICE_DEC = '0'; const MIN_GAS_PRICE_HEX = parseInt(MIN_GAS_PRICE_DEC, 10).toString(16); -const MIN_GAS_LIMIT_DEC = '21000'; +const MIN_GAS_LIMIT_DEC = new Numeric('21000', 10); const MAX_GAS_LIMIT_DEC = '7920027'; const HIGH_FEE_WARNING_MULTIPLIER = 1.5; -const MIN_GAS_PRICE_GWEI = addHexPrefix( - conversionUtil(MIN_GAS_PRICE_HEX, { - fromDenomination: 'WEI', - toDenomination: 'GWEI', - fromNumericBase: 'hex', - toNumericBase: 'hex', - numberOfDecimals: 1, - }), -); +const MIN_GAS_PRICE_GWEI = new Numeric( + MIN_GAS_PRICE_HEX, + 16, + EtherDenomination.WEI, +) + .toDenomination(EtherDenomination.GWEI) + .round(1) + .toPrefixedHexString(); -const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT_HEX, MIN_GAS_PRICE_HEX, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 16, -}); +const MIN_GAS_TOTAL = new Numeric(MIN_GAS_LIMIT_HEX, 16) + .times(new Numeric(MIN_GAS_PRICE_HEX, 16, EtherDenomination.WEI)) + .toPrefixedHexString(); const TOKEN_TRANSFER_FUNCTION_SIGNATURE = '0xa9059cbb'; const COLLECTIBLE_TRANSFER_FROM_FUNCTION_SIGNATURE = '0x23b872dd'; diff --git a/ui/pages/send/send.utils.js b/ui/pages/send/send.utils.js index 317a6f8cd..4463fd9b3 100644 --- a/ui/pages/send/send.utils.js +++ b/ui/pages/send/send.utils.js @@ -1,16 +1,8 @@ import abi from 'ethereumjs-abi'; -import { - addCurrencies, - conversionUtil, - conversionGTE, - multiplyCurrencies, - conversionGreaterThan, - conversionLessThan, -} from '../../../shared/modules/conversion.utils'; import { addHexPrefix } from '../../../app/scripts/lib/util'; import { TokenStandard } from '../../../shared/constants/transaction'; -import { calcTokenAmount } from '../../../shared/lib/transactions-controller-utils'; +import { Numeric } from '../../../shared/modules/Numeric'; import { TOKEN_TRANSFER_FUNCTION_SIGNATURE, COLLECTIBLE_TRANSFER_FROM_FUNCTION_SIGNATURE, @@ -33,46 +25,22 @@ function isBalanceSufficient({ gasTotal = '0x0', primaryCurrency, }) { - const totalAmount = addCurrencies(amount, gasTotal, { - aBase: 16, - bBase: 16, - toNumericBase: 'hex', - }); + let totalAmount = new Numeric(amount, 16).add(new Numeric(gasTotal, 16)); + let balanceNumeric = new Numeric(balance, 16); - const balanceIsSufficient = conversionGTE( - { - value: balance, - fromNumericBase: 'hex', - fromCurrency: primaryCurrency, - conversionRate, - }, - { - value: totalAmount, - fromNumericBase: 'hex', - conversionRate, - fromCurrency: primaryCurrency, - }, - ); + if (typeof primaryCurrency !== 'undefined' && primaryCurrency !== null) { + totalAmount = totalAmount.applyConversionRate(conversionRate); + balanceNumeric = balanceNumeric.applyConversionRate(conversionRate); + } - return balanceIsSufficient; + return balanceNumeric.greaterThanOrEqualTo(totalAmount); } function isTokenBalanceSufficient({ amount = '0x0', tokenBalance, decimals }) { - const amountInDec = conversionUtil(amount, { - fromNumericBase: 'hex', - }); + const amountNumeric = new Numeric(amount, 16).shiftedBy(decimals); + const tokenBalanceNumeric = new Numeric(tokenBalance, 16); - const tokenBalanceIsSufficient = conversionGTE( - { - value: tokenBalance, - fromNumericBase: 'hex', - }, - { - value: calcTokenAmount(amountInDec, decimals), - }, - ); - - return tokenBalanceIsSufficient; + return tokenBalanceNumeric.greaterThanOrEqualTo(amountNumeric); } function addGasBuffer( @@ -80,43 +48,25 @@ function addGasBuffer( blockGasLimitHex, bufferMultiplier = 1.5, ) { - const upperGasLimit = multiplyCurrencies(blockGasLimitHex, 0.9, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 10, - numberOfDecimals: '0', - }); - const bufferedGasLimit = multiplyCurrencies( - initialGasLimitHex, - bufferMultiplier, - { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 10, - numberOfDecimals: '0', - }, - ); + const initialGasLimit = new Numeric(initialGasLimitHex, 16); + const upperGasLimit = new Numeric(blockGasLimitHex, 16) + .times(new Numeric(0.9, 10)) + .round(0); + + const bufferedGasLimit = initialGasLimit + .times(new Numeric(bufferMultiplier, 10)) + .round(0); // if initialGasLimit is above blockGasLimit, dont modify it - if ( - conversionGreaterThan( - { value: initialGasLimitHex, fromNumericBase: 'hex' }, - { value: upperGasLimit, fromNumericBase: 'hex' }, - ) - ) { + if (initialGasLimit.greaterThanOrEqualTo(upperGasLimit)) { return initialGasLimitHex; } // if bufferedGasLimit is below blockGasLimit, use bufferedGasLimit - if ( - conversionLessThan( - { value: bufferedGasLimit, fromNumericBase: 'hex' }, - { value: upperGasLimit, fromNumericBase: 'hex' }, - ) - ) { - return bufferedGasLimit; + if (bufferedGasLimit.lessThan(upperGasLimit)) { + return bufferedGasLimit.toString(); } // otherwise use blockGasLimit - return upperGasLimit; + return upperGasLimit.toString(); } function generateERC20TransferData({ diff --git a/ui/pages/send/send.utils.test.js b/ui/pages/send/send.utils.test.js index 4c772298f..401bc696b 100644 --- a/ui/pages/send/send.utils.test.js +++ b/ui/pages/send/send.utils.test.js @@ -1,11 +1,5 @@ import { rawEncode } from 'ethereumjs-abi'; -import { - addCurrencies, - conversionGTE, - conversionUtil, -} from '../../../shared/modules/conversion.utils'; - import { generateERC20TransferData, isBalanceSufficient, @@ -13,35 +7,6 @@ import { ellipsify, } from './send.utils'; -jest.mock('../../../shared/modules/conversion.utils', () => ({ - addCurrencies: jest.fn((a, b) => { - let [a1, b1] = [a, b]; - if (String(a).match(/^0x.+/u)) { - a1 = Number(String(a).slice(2)); - } - if (String(b).match(/^0x.+/u)) { - b1 = Number(String(b).slice(2)); - } - return a1 + b1; - }), - conversionUtil: jest.fn((val) => parseInt(val, 16)), - conversionGTE: jest.fn((obj1, obj2) => obj1.value >= obj2.value), - multiplyCurrencies: jest.fn((a, b) => `${a}x${b}`), - conversionGreaterThan: (obj1, obj2) => obj1.value > obj2.value, - conversionLessThan: (obj1, obj2) => obj1.value < obj2.value, -})); - -jest.mock('../../../shared/lib/transactions-controller-utils', () => { - const originalModule = jest.requireActual( - '../../../shared/lib/transactions-controller-utils', - ); - - return { - ...originalModule, - calcTokenAmount: (a, d) => `calc:${a}${d}`, - }; -}); - jest.mock('ethereumjs-abi', () => ({ rawEncode: jest.fn().mockReturnValue(16, 1100), })); @@ -84,7 +49,7 @@ describe('send utils', () => { }); describe('isBalanceSufficient()', () => { - it('should correctly call addCurrencies and return the result of calling conversionGTE', () => { + it('should correctly sum the appropriate currencies and ensure that balance is greater', () => { const result = isBalanceSufficient({ amount: 15, balance: 100, @@ -92,53 +57,29 @@ describe('send utils', () => { gasTotal: 17, primaryCurrency: 'ABC', }); - expect(addCurrencies).toHaveBeenCalledWith(15, 17, { - aBase: 16, - bBase: 16, - toNumericBase: 'hex', - }); - expect(conversionGTE).toHaveBeenCalledWith( - { - value: 100, - fromNumericBase: 'hex', - fromCurrency: 'ABC', - conversionRate: 3, - }, - { - value: 32, - fromNumericBase: 'hex', - conversionRate: 3, - fromCurrency: 'ABC', - }, - ); - expect(result).toStrictEqual(true); }); }); describe('isTokenBalanceSufficient()', () => { - it('should correctly call conversionUtil and return the result of calling conversionGTE', () => { + it('should return true for a sufficient balance for token spend', () => { const result = isTokenBalanceSufficient({ amount: '0x10', tokenBalance: 123, decimals: 10, }); - expect(conversionUtil).toHaveBeenCalledWith('0x10', { - fromNumericBase: 'hex', + expect(result).toStrictEqual(true); + }); + + it('should return false for an insufficient balance for token spend', () => { + const result = isTokenBalanceSufficient({ + amount: '0x10000', + tokenBalance: 123, + decimals: 10, }); - expect(conversionGTE).toHaveBeenCalledWith( - { - value: 123, - fromNumericBase: 'hex', - }, - { - value: 'calc:1610', - }, - ); - - expect(result).toStrictEqual(false); + expect(result).toStrictEqual(true); }); }); diff --git a/ui/selectors/custom-gas.js b/ui/selectors/custom-gas.js index 1a0b276ca..fa2a39ed2 100644 --- a/ui/selectors/custom-gas.js +++ b/ui/selectors/custom-gas.js @@ -1,9 +1,5 @@ import { addHexPrefix } from '../../app/scripts/lib/util'; -import { - conversionUtil, - conversionGreaterThan, - decEthToConvertedCurrency, -} from '../../shared/modules/conversion.utils'; +import { decEthToConvertedCurrency } from '../../shared/modules/conversion.utils'; import { formatCurrency } from '../helpers/utils/confirm-tx.util'; import { formatETHFee } from '../helpers/utils/formatters'; @@ -15,6 +11,8 @@ import { isEIP1559Network, } from '../ducks/metamask/metamask'; import { calcGasTotal } from '../../shared/lib/transactions-controller-utils'; +import { Numeric } from '../../shared/modules/Numeric'; +import { EtherDenomination } from '../../shared/constants/common'; import { getIsMainnet } from '.'; export function getCustomGasLimit(state) { @@ -91,15 +89,9 @@ export function isCustomPriceSafe(state) { return false; } - const customPriceSafe = conversionGreaterThan( - { - value: customGasPrice, - fromNumericBase: 'hex', - fromDenomination: 'WEI', - toDenomination: 'GWEI', - }, - { value: safeLow, fromNumericBase: 'dec' }, - ); + const customPriceSafe = new Numeric(customGasPrice, 16, EtherDenomination.WEI) + .toDenomination(EtherDenomination.GWEI) + .greaterThan(safeLow, 10); return customPriceSafe; } @@ -117,15 +109,9 @@ export function isCustomPriceSafeForCustomNetwork(state) { return false; } - const customPriceSafe = conversionGreaterThan( - { - value: customGasPrice, - fromNumericBase: 'hex', - fromDenomination: 'WEI', - toDenomination: 'GWEI', - }, - { value: estimatedPrice, fromNumericBase: 'dec' }, - ); + const customPriceSafe = new Numeric(customGasPrice, 16, EtherDenomination.WEI) + .toDenomination(EtherDenomination.GWEI) + .greaterThan(estimatedPrice, 10); return customPriceSafe; } @@ -139,18 +125,13 @@ export function isCustomPriceExcessive(state, checkSend = false) { } // Custom gas should be considered excessive when it is 1.5 times greater than the fastest estimate. - const customPriceExcessive = conversionGreaterThan( - { - value: customPrice, - fromNumericBase: 'hex', - fromDenomination: 'WEI', - toDenomination: 'GWEI', - }, - { - fromNumericBase: 'dec', - value: Math.floor(fastPrice * 1.5), - }, - ); + const customPriceExcessive = new Numeric( + customPrice, + 16, + EtherDenomination.WEI, + ) + .toDenomination(EtherDenomination.GWEI) + .greaterThan(Math.floor(fastPrice * 1.5), 10); return customPriceExcessive; } @@ -160,12 +141,14 @@ export function basicPriceEstimateToETHTotal( gasLimit, numberOfDecimals = 9, ) { - return conversionUtil(calcGasTotal(gasLimit, estimate), { - fromNumericBase: 'hex', - toNumericBase: 'dec', - fromDenomination: 'GWEI', - numberOfDecimals, - }); + return new Numeric( + calcGasTotal(gasLimit, estimate), + 16, + EtherDenomination.GWEI, + ) + .round(numberOfDecimals) + .toBase(10) + .toString(); } export function getRenderableEthFee( @@ -174,10 +157,7 @@ export function getRenderableEthFee( numberOfDecimals = 9, nativeCurrency = 'ETH', ) { - const value = conversionUtil(estimate, { - fromNumericBase: 'dec', - toNumericBase: 'hex', - }); + const value = new Numeric(estimate, 10).toBase(16).toString(); const fee = basicPriceEstimateToETHTotal(value, gasLimit, numberOfDecimals); return formatETHFee(fee, nativeCurrency); } @@ -188,10 +168,7 @@ export function getRenderableConvertedCurrencyFee( convertedCurrency, conversionRate, ) { - const value = conversionUtil(estimate, { - fromNumericBase: 'dec', - toNumericBase: 'hex', - }); + const value = new Numeric(estimate, 10).toBase(16).toString(); const fee = basicPriceEstimateToETHTotal(value, gasLimit); const feeInCurrency = decEthToConvertedCurrency( fee, @@ -202,20 +179,14 @@ export function getRenderableConvertedCurrencyFee( } export function priceEstimateToWei(priceEstimate) { - return conversionUtil(priceEstimate, { - fromNumericBase: 'hex', - toNumericBase: 'hex', - fromDenomination: 'GWEI', - toDenomination: 'WEI', - numberOfDecimals: 9, - }); + return new Numeric(priceEstimate, 16, EtherDenomination.GWEI) + .toDenomination(EtherDenomination.WEI) + .round(9) + .toString(); } export function getGasPriceInHexWei(price) { - const value = conversionUtil(price, { - fromNumericBase: 'dec', - toNumericBase: 'hex', - }); + const value = new Numeric(price, 10).toBase(16).toString(); return addHexPrefix(priceEstimateToWei(value)); }