mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
Replace usages of conversion util in rest of UI folder in favor of Numeric (#17334)
This commit is contained in:
parent
dd09245ff6
commit
3ff12d70e9
@ -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?).
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}`;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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', () => {
|
||||
|
@ -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);
|
||||
|
@ -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: <Unix Timestamp> ) -> 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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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`;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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({
|
||||
|
@ -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(
|
||||
|
@ -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 (
|
||||
<div className="request-decrypt-message__balance">
|
||||
|
@ -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 (
|
||||
<div className="request-encryption-public-key__balance">
|
||||
|
@ -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 : <LoadingHeartBeat />;
|
||||
|
@ -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';
|
||||
|
@ -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({
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user