diff --git a/app/scripts/account-import-strategies/account-import-strategies.test.js b/app/scripts/account-import-strategies/account-import-strategies.test.js index bc2f53ae7..e29561639 100644 --- a/app/scripts/account-import-strategies/account-import-strategies.test.js +++ b/app/scripts/account-import-strategies/account-import-strategies.test.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import ethUtil from 'ethereumjs-util'; +import { stripHexPrefix } from 'ethereumjs-util'; import accountImporter from '.'; describe('Account Import Strategies', function () { @@ -13,7 +13,7 @@ describe('Account Import Strategies', function () { const importPrivKey = await accountImporter.importAccount('Private Key', [ privkey, ]); - assert.equal(importPrivKey, ethUtil.stripHexPrefix(privkey)); + assert.equal(importPrivKey, stripHexPrefix(privkey)); }); it('throws an error for empty string private key', async function () { diff --git a/app/scripts/account-import-strategies/index.js b/app/scripts/account-import-strategies/index.js index 89fd0b8c1..ce52132aa 100644 --- a/app/scripts/account-import-strategies/index.js +++ b/app/scripts/account-import-strategies/index.js @@ -1,7 +1,12 @@ import log from 'loglevel'; import Wallet from 'ethereumjs-wallet'; import importers from 'ethereumjs-wallet/thirdparty'; -import ethUtil from 'ethereumjs-util'; +import { + toBuffer, + isValidPrivate, + bufferToHex, + stripHexPrefix, +} from 'ethereumjs-util'; import { addHexPrefix } from '../lib/util'; const accountImporter = { @@ -22,13 +27,13 @@ const accountImporter = { } const prefixed = addHexPrefix(privateKey); - const buffer = ethUtil.toBuffer(prefixed); + const buffer = toBuffer(prefixed); - if (!ethUtil.isValidPrivate(buffer)) { + if (!isValidPrivate(buffer)) { throw new Error('Cannot import invalid private key.'); } - const stripped = ethUtil.stripHexPrefix(prefixed); + const stripped = stripHexPrefix(prefixed); return stripped; }, 'JSON File': (input, password) => { @@ -47,7 +52,7 @@ const accountImporter = { function walletToPrivateKey(wallet) { const privateKeyBuffer = wallet.getPrivateKey(); - return ethUtil.bufferToHex(privateKeyBuffer); + return bufferToHex(privateKeyBuffer); } export default accountImporter; diff --git a/app/scripts/controllers/ens/index.js b/app/scripts/controllers/ens/index.js index 015c3ee0a..a7d4c696b 100644 --- a/app/scripts/controllers/ens/index.js +++ b/app/scripts/controllers/ens/index.js @@ -1,5 +1,5 @@ import punycode from 'punycode/punycode'; -import ethUtil from 'ethereumjs-util'; +import { toChecksumAddress } from 'ethereumjs-util'; import { ObservableStore } from '@metamask/obs-store'; import log from 'loglevel'; import { CHAIN_ID_TO_NETWORK_ID_MAP } from '../../../../shared/constants/network'; @@ -43,7 +43,7 @@ export default class EnsController { } reverseResolveAddress(address) { - return this._reverseResolveAddress(ethUtil.toChecksumAddress(address)); + return this._reverseResolveAddress(toChecksumAddress(address)); } async _reverseResolveAddress(address) { @@ -79,7 +79,7 @@ export default class EnsController { return undefined; } - if (ethUtil.toChecksumAddress(registeredAddress) !== address) { + if (toChecksumAddress(registeredAddress) !== address) { return undefined; } diff --git a/app/scripts/controllers/ens/index.test.js b/app/scripts/controllers/ens/index.test.js index 6e1a4c047..24197dbd7 100644 --- a/app/scripts/controllers/ens/index.test.js +++ b/app/scripts/controllers/ens/index.test.js @@ -79,7 +79,7 @@ describe('EnsController', function () { const ens = new EnsController({ ens: { reverse: sinon.stub().withArgs(address).returns('peaksignal.eth'), - lookup: sinon.stub().withArgs('peaksignal.eth').returns('0xfoo'), + lookup: sinon.stub().withArgs('peaksignal.eth').returns('0x00'), }, onNetworkDidChange, getCurrentChainId, diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index 00e07009f..6e8fc62a2 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -1,6 +1,6 @@ import { merge, omit } from 'lodash'; import { ObservableStore } from '@metamask/obs-store'; -import { bufferToHex, sha3 } from 'ethereumjs-util'; +import { bufferToHex, keccak } from 'ethereumjs-util'; import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { METAMETRICS_ANONYMOUS_ID, @@ -110,9 +110,11 @@ export default class MetaMetricsController { generateMetaMetricsId() { return bufferToHex( - sha3( - String(Date.now()) + - String(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)), + keccak( + Buffer.from( + String(Date.now()) + + String(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)), + ), ), ); } diff --git a/app/scripts/controllers/token-rates.js b/app/scripts/controllers/token-rates.js index 9d597ce1b..b725b04c9 100644 --- a/app/scripts/controllers/token-rates.js +++ b/app/scripts/controllers/token-rates.js @@ -1,7 +1,7 @@ import { ObservableStore } from '@metamask/obs-store'; import log from 'loglevel'; import { normalize as normalizeAddress } from 'eth-sig-util'; -import ethUtil from 'ethereumjs-util'; +import { toChecksumAddress } from 'ethereumjs-util'; import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; const fetchWithTimeout = getFetchWithTimeout(30000); @@ -45,7 +45,7 @@ export default class TokenRatesController { this._tokens.forEach((token) => { const price = prices[token.address.toLowerCase()] || - prices[ethUtil.toChecksumAddress(token.address)]; + prices[toChecksumAddress(token.address)]; contractExchangeRates[normalizeAddress(token.address)] = price ? price[nativeCurrency] : 0; diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index 3b0b9465d..3067b3e4f 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -1,6 +1,6 @@ import EventEmitter from 'safe-event-emitter'; import { ObservableStore } from '@metamask/obs-store'; -import ethUtil from 'ethereumjs-util'; +import { bufferToHex, keccak, toBuffer } from 'ethereumjs-util'; import Transaction from 'ethereumjs-tx'; import EthQuery from 'ethjs-query'; import { ethErrors } from 'eth-rpc-errors'; @@ -569,9 +569,9 @@ export default class TransactionController extends EventEmitter { // add r,s,v values for provider request purposes see createMetamaskMiddleware // and JSON rpc standard for further explanation - txMeta.r = ethUtil.bufferToHex(ethTx.r); - txMeta.s = ethUtil.bufferToHex(ethTx.s); - txMeta.v = ethUtil.bufferToHex(ethTx.v); + txMeta.r = bufferToHex(ethTx.r); + txMeta.s = bufferToHex(ethTx.s); + txMeta.v = bufferToHex(ethTx.v); this.txStateManager.updateTransaction( txMeta, @@ -580,7 +580,7 @@ export default class TransactionController extends EventEmitter { // set state to signed this.txStateManager.setTxStatusSigned(txMeta.id); - const rawTx = ethUtil.bufferToHex(ethTx.serialize()); + const rawTx = bufferToHex(ethTx.serialize()); return rawTx; } @@ -606,7 +606,7 @@ export default class TransactionController extends EventEmitter { txHash = await this.query.sendRawTransaction(rawTx); } catch (error) { if (error.message.toLowerCase().includes('known transaction')) { - txHash = ethUtil.sha3(addHexPrefix(rawTx)).toString('hex'); + txHash = keccak(toBuffer(addHexPrefix(rawTx), 'hex')).toString('hex'); txHash = addHexPrefix(txHash); } else { throw error; diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 2d1709cdf..a249c17fc 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -1,6 +1,6 @@ import { strict as assert } from 'assert'; import EventEmitter from 'events'; -import ethUtil from 'ethereumjs-util'; +import { toBuffer } from 'ethereumjs-util'; import EthTx from 'ethereumjs-tx'; import { ObservableStore } from '@metamask/obs-store'; import sinon from 'sinon'; @@ -518,7 +518,7 @@ describe('Transaction Controller', function () { noop, ); const rawTx = await txController.signTransaction('1'); - const ethTx = new EthTx(ethUtil.toBuffer(rawTx)); + const ethTx = new EthTx(toBuffer(rawTx)); assert.equal(ethTx.getChainId(), 42); }); }); diff --git a/app/scripts/controllers/transactions/tx-gas-utils.js b/app/scripts/controllers/transactions/tx-gas-utils.js index 75eb60d83..1b84577b1 100644 --- a/app/scripts/controllers/transactions/tx-gas-utils.js +++ b/app/scripts/controllers/transactions/tx-gas-utils.js @@ -1,6 +1,6 @@ import EthQuery from 'ethjs-query'; import log from 'loglevel'; -import ethUtil from 'ethereumjs-util'; +import { addHexPrefix } from 'ethereumjs-util'; import { cloneDeep } from 'lodash'; import { hexToBn, BnMultiplyByFraction, bnToHex } from '../../lib/util'; @@ -103,7 +103,7 @@ export default class TxGasUtil { // add additional gas buffer to our estimation for safety const gasLimit = this.addGasBuffer( - ethUtil.addHexPrefix(estimatedGasHex), + addHexPrefix(estimatedGasHex), blockGasLimit, multiplier, ); diff --git a/app/scripts/lib/decrypt-message-manager.js b/app/scripts/lib/decrypt-message-manager.js index 674c73572..56eabf552 100644 --- a/app/scripts/lib/decrypt-message-manager.js +++ b/app/scripts/lib/decrypt-message-manager.js @@ -1,6 +1,6 @@ import EventEmitter from 'events'; import { ObservableStore } from '@metamask/obs-store'; -import ethUtil from 'ethereumjs-util'; +import { bufferToHex, stripHexPrefix } from 'ethereumjs-util'; import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; @@ -337,7 +337,7 @@ export default class DecryptMessageManager extends EventEmitter { */ normalizeMsgData(data) { try { - const stripped = ethUtil.stripHexPrefix(data); + const stripped = stripHexPrefix(data); if (stripped.match(hexRe)) { return addHexPrefix(stripped); } @@ -345,6 +345,6 @@ export default class DecryptMessageManager extends EventEmitter { log.debug(`Message was not hex encoded, interpreting as utf8.`); } - return ethUtil.bufferToHex(Buffer.from(data, 'utf8')); + return bufferToHex(Buffer.from(data, 'utf8')); } } diff --git a/app/scripts/lib/message-manager.js b/app/scripts/lib/message-manager.js index ce48327f3..bb7756b33 100644 --- a/app/scripts/lib/message-manager.js +++ b/app/scripts/lib/message-manager.js @@ -1,6 +1,6 @@ import EventEmitter from 'events'; import { ObservableStore } from '@metamask/obs-store'; -import ethUtil from 'ethereumjs-util'; +import { bufferToHex } from 'ethereumjs-util'; import { ethErrors } from 'eth-rpc-errors'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; @@ -298,5 +298,5 @@ function normalizeMsgData(data) { return data; } // data is unicode, convert to hex - return ethUtil.bufferToHex(Buffer.from(data, 'utf8')); + return bufferToHex(Buffer.from(data, 'utf8')); } diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index 0149e4802..6002b0709 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -1,6 +1,6 @@ import EventEmitter from 'events'; import { ObservableStore } from '@metamask/obs-store'; -import ethUtil from 'ethereumjs-util'; +import { bufferToHex, stripHexPrefix } from 'ethereumjs-util'; import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; @@ -322,7 +322,7 @@ export default class PersonalMessageManager extends EventEmitter { */ normalizeMsgData(data) { try { - const stripped = ethUtil.stripHexPrefix(data); + const stripped = stripHexPrefix(data); if (stripped.match(hexRe)) { return addHexPrefix(stripped); } @@ -330,6 +330,6 @@ export default class PersonalMessageManager extends EventEmitter { log.debug(`Message was not hex encoded, interpreting as utf8.`); } - return ethUtil.bufferToHex(Buffer.from(data, 'utf8')); + return bufferToHex(Buffer.from(data, 'utf8')); } } diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js index ccf8d1193..46e5b8641 100644 --- a/app/scripts/lib/util.js +++ b/app/scripts/lib/util.js @@ -1,6 +1,6 @@ import assert from 'assert'; import extension from 'extensionizer'; -import ethUtil from 'ethereumjs-util'; +import { stripHexPrefix } from 'ethereumjs-util'; import BN from 'bn.js'; import { memoize } from 'lodash'; @@ -111,7 +111,7 @@ function sufficientBalance(txParams, hexBalance) { * */ function hexToBn(inputHex) { - return new BN(ethUtil.stripHexPrefix(inputHex), 16); + return new BN(stripHexPrefix(inputHex), 16); } /** diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 7e3ec936d..6d4c45ea0 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -10,7 +10,7 @@ import createSubscriptionManager from 'eth-json-rpc-filters/subscriptionManager' import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware'; import KeyringController from 'eth-keyring-controller'; import { Mutex } from 'await-semaphore'; -import ethUtil from 'ethereumjs-util'; +import { toChecksumAddress, stripHexPrefix } from 'ethereumjs-util'; import log from 'loglevel'; import TrezorKeyring from 'eth-trezor-keyring'; import LedgerBridgeKeyring from '@metamask/eth-ledger-bridge-keyring'; @@ -1096,16 +1096,14 @@ export default class MetamaskController extends EventEmitter { // Filter ERC20 tokens const filteredAccountTokens = {}; Object.keys(accountTokens).forEach((address) => { - const checksummedAddress = ethUtil.toChecksumAddress(address); + const checksummedAddress = toChecksumAddress(address); filteredAccountTokens[checksummedAddress] = {}; Object.keys(accountTokens[address]).forEach((chainId) => { filteredAccountTokens[checksummedAddress][chainId] = chainId === MAINNET_CHAIN_ID ? accountTokens[address][chainId].filter( ({ address: tokenAddress }) => { - const checksumAddress = ethUtil.toChecksumAddress( - tokenAddress, - ); + const checksumAddress = toChecksumAddress(tokenAddress); return contractMap[checksumAddress] ? contractMap[checksumAddress].erc20 : true; @@ -1142,10 +1140,10 @@ export default class MetamaskController extends EventEmitter { const accounts = { hd: hdAccounts .filter((item, pos) => hdAccounts.indexOf(item) === pos) - .map((address) => ethUtil.toChecksumAddress(address)), + .map((address) => toChecksumAddress(address)), simpleKeyPair: simpleKeyPairAccounts .filter((item, pos) => simpleKeyPairAccounts.indexOf(item) === pos) - .map((address) => ethUtil.toChecksumAddress(address)), + .map((address) => toChecksumAddress(address)), ledger: [], trezor: [], }; @@ -1155,7 +1153,7 @@ export default class MetamaskController extends EventEmitter { let { transactions } = this.txController.store.getState(); // delete tx for other accounts that we're not importing transactions = transactions.filter((tx) => { - const checksummedTxFrom = ethUtil.toChecksumAddress(tx.txParams.from); + const checksummedTxFrom = toChecksumAddress(tx.txParams.from); return accounts.hd.includes(checksummedTxFrom); }); @@ -1640,7 +1638,7 @@ export default class MetamaskController extends EventEmitter { const msgId = msgParams.metamaskId; const msg = this.decryptMessageManager.getMsg(msgId); try { - const stripped = ethUtil.stripHexPrefix(msgParams.data); + const stripped = stripHexPrefix(msgParams.data); const buff = Buffer.from(stripped, 'hex'); msgParams.data = JSON.parse(buff.toString('utf8')); @@ -1670,7 +1668,7 @@ export default class MetamaskController extends EventEmitter { msgParams, ); - const stripped = ethUtil.stripHexPrefix(cleanMsgParams.data); + const stripped = stripHexPrefix(cleanMsgParams.data); const buff = Buffer.from(stripped, 'hex'); cleanMsgParams.data = JSON.parse(buff.toString('utf8')); diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index 6756025ad..55eb1f083 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -2,7 +2,7 @@ import assert from 'assert'; import sinon from 'sinon'; import { cloneDeep } from 'lodash'; import nock from 'nock'; -import ethUtil from 'ethereumjs-util'; +import { pubToAddress, bufferToHex } from 'ethereumjs-util'; import { obj as createThoughStream } from 'through2'; import EthQuery from 'eth-query'; import proxyquire from 'proxyquire'; @@ -186,9 +186,9 @@ describe('MetaMaskController', function () { ); const privKeyBuffer = simpleKeyrings[0].wallets[0]._privKey; const pubKeyBuffer = simpleKeyrings[0].wallets[0]._pubKey; - const addressBuffer = ethUtil.pubToAddress(pubKeyBuffer); - const privKey = ethUtil.bufferToHex(privKeyBuffer); - const pubKey = ethUtil.bufferToHex(addressBuffer); + const addressBuffer = pubToAddress(pubKeyBuffer); + const privKey = bufferToHex(privKeyBuffer); + const pubKey = bufferToHex(addressBuffer); assert.equal(privKey, addHexPrefix(importPrivkey)); assert.equal(pubKey, '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc'); }); diff --git a/app/scripts/migrations/039.js b/app/scripts/migrations/039.js index adc8390db..7dcf904de 100644 --- a/app/scripts/migrations/039.js +++ b/app/scripts/migrations/039.js @@ -1,5 +1,5 @@ import { cloneDeep } from 'lodash'; -import ethUtil from 'ethereumjs-util'; +import { toChecksumAddress } from 'ethereumjs-util'; const version = 39; @@ -12,7 +12,7 @@ function isOldDai(token = {}) { token && typeof token === 'object' && token.symbol === DAI_V1_TOKEN_SYMBOL && - ethUtil.toChecksumAddress(token.address) === DAI_V1_CONTRACT_ADDRESS + toChecksumAddress(token.address) === DAI_V1_CONTRACT_ADDRESS ); } diff --git a/package.json b/package.json index d3871f8a4..f6ead484d 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "ethereum-ens-network-map": "^1.0.2", "ethereumjs-abi": "^0.6.4", "ethereumjs-tx": "1.3.7", - "ethereumjs-util": "5.1.0", + "ethereumjs-util": "^7.0.9", "ethereumjs-wallet": "^0.6.4", "ethers": "^5.0.8", "ethjs": "^0.4.0", diff --git a/ui/app/components/app/account-menu/account-menu.test.js b/ui/app/components/app/account-menu/account-menu.test.js index ece1cb1b6..7862de005 100644 --- a/ui/app/components/app/account-menu/account-menu.test.js +++ b/ui/app/components/app/account-menu/account-menu.test.js @@ -26,12 +26,12 @@ describe('Account Menu', () => { addressConnectedDomainMap: {}, accounts: [ { - address: '0xAddress', + address: '0x00', name: 'Account 1', balance: '0x0', }, { - address: '0xImportedAddress', + address: '0x1', name: 'Imported Account 1', balance: '0x0', }, @@ -43,7 +43,7 @@ describe('Account Menu', () => { }, { type: 'Simple Key Pair', - accounts: ['0xImportedAddress'], + accounts: ['0x1'], }, ], prevIsAccountMenuOpen: false, @@ -90,9 +90,7 @@ describe('Account Menu', () => { click.first().simulate('click'); expect(props.showAccountDetail.calledOnce).toStrictEqual(true); - expect(props.showAccountDetail.getCall(0).args[0]).toStrictEqual( - '0xAddress', - ); + expect(props.showAccountDetail.getCall(0).args[0]).toStrictEqual('0x00'); }); it('render imported account label', () => { diff --git a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.test.js b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.test.js index b1646b43e..fd89e96f8 100644 --- a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.test.js +++ b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.test.js @@ -18,7 +18,7 @@ describe('Confirm Remove Account', () => { removeAccount: sinon.stub().resolves(), network: '101', identity: { - address: '0xAddress', + address: '0x0', name: 'Account 1', }, }; diff --git a/ui/app/components/app/signature-request-original/signature-request-original.component.js b/ui/app/components/app/signature-request-original/signature-request-original.component.js index 5dbcf9eb7..ae62fcad9 100644 --- a/ui/app/components/app/signature-request-original/signature-request-original.component.js +++ b/ui/app/components/app/signature-request-original/signature-request-original.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import ethUtil from 'ethereumjs-util'; +import { stripHexPrefix } from 'ethereumjs-util'; import classnames from 'classnames'; import { ObjectInspector } from 'react-inspector'; @@ -179,7 +179,7 @@ export default class SignatureRequestOriginal extends Component { msgHexToText = (hex) => { try { - const stripped = ethUtil.stripHexPrefix(hex); + const stripped = stripHexPrefix(hex); const buff = Buffer.from(stripped, 'hex'); return buff.length === 32 ? hex : buff.toString('utf8'); } catch (e) { diff --git a/ui/app/components/ui/identicon/identicon.component.test.js b/ui/app/components/ui/identicon/identicon.component.test.js index 031da5f36..f78a47b6d 100644 --- a/ui/app/components/ui/identicon/identicon.component.test.js +++ b/ui/app/components/ui/identicon/identicon.component.test.js @@ -38,7 +38,7 @@ describe('Identicon', () => { it('renders div with address prop', () => { const wrapper = mount( - , + , ); expect(wrapper.find('div.test-address').prop('className')).toStrictEqual( diff --git a/ui/app/helpers/utils/conversion-util.js b/ui/app/helpers/utils/conversion-util.js index fac0dd415..3d61f4410 100644 --- a/ui/app/helpers/utils/conversion-util.js +++ b/ui/app/helpers/utils/conversion-util.js @@ -23,9 +23,7 @@ import BigNumber from 'bignumber.js'; -import ethUtil, { stripHexPrefix } from 'ethereumjs-util'; - -const { BN } = ethUtil; +import { stripHexPrefix, BN } from 'ethereumjs-util'; // Big Number Constants const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber('1000000000000000000'); diff --git a/ui/app/helpers/utils/util.js b/ui/app/helpers/utils/util.js index 239af55a7..42c88e8d6 100644 --- a/ui/app/helpers/utils/util.js +++ b/ui/app/helpers/utils/util.js @@ -1,7 +1,7 @@ import punycode from 'punycode/punycode'; import abi from 'human-standard-token-abi'; import BigNumber from 'bignumber.js'; -import ethUtil from 'ethereumjs-util'; +import * as ethUtil from 'ethereumjs-util'; import { DateTime } from 'luxon'; import { addHexPrefix } from '../../../../app/scripts/lib/util'; import { @@ -29,25 +29,6 @@ export function formatDateWithYearContext( now.year === dateTime.year ? formatThisYear : fallback, ); } - -const valueTable = { - wei: '1000000000000000000', - kwei: '1000000000000000', - mwei: '1000000000000', - gwei: '1000000000', - szabo: '1000000', - finney: '1000', - ether: '1', - kether: '0.001', - mether: '0.000001', - gether: '0.000000001', - tether: '0.000000000001', -}; -const bnTable = {}; -Object.keys(valueTable).forEach((currency) => { - bnTable[currency] = new ethUtil.BN(valueTable[currency], 10); -}); - /** * Determines if the provided chainId is a default MetaMask chain * @param {string} chainId - chainId to check @@ -198,84 +179,6 @@ export function formatBalance( return formatted; } -export function generateBalanceObject(formattedBalance, decimalsToKeep = 1) { - let balance = formattedBalance.split(' ')[0]; - const label = formattedBalance.split(' ')[1]; - const beforeDecimal = balance.split('.')[0]; - const afterDecimal = balance.split('.')[1]; - const shortBalance = shortenBalance(balance, decimalsToKeep); - - if (beforeDecimal === '0' && afterDecimal.substr(0, 5) === '00000') { - // eslint-disable-next-line eqeqeq - if (afterDecimal == 0) { - balance = '0'; - } else { - balance = '<1.0e-5'; - } - } else if (beforeDecimal !== '0') { - balance = `${beforeDecimal}.${afterDecimal.slice(0, decimalsToKeep)}`; - } - - return { balance, label, shortBalance }; -} - -export function shortenBalance(balance, decimalsToKeep = 1) { - let truncatedValue; - const convertedBalance = parseFloat(balance); - if (convertedBalance > 1000000) { - truncatedValue = (balance / 1000000).toFixed(decimalsToKeep); - return `${truncatedValue}m`; - } else if (convertedBalance > 1000) { - truncatedValue = (balance / 1000).toFixed(decimalsToKeep); - return `${truncatedValue}k`; - } else if (convertedBalance === 0) { - return '0'; - } else if (convertedBalance < 0.001) { - return '<0.001'; - } else if (convertedBalance < 1) { - const stringBalance = convertedBalance.toString(); - if (stringBalance.split('.')[1].length > 3) { - return convertedBalance.toFixed(3); - } - return stringBalance; - } - return convertedBalance.toFixed(decimalsToKeep); -} - -// Takes a BN and an ethereum currency name, -// returns a BN in wei -export function normalizeToWei(amount, currency) { - try { - return amount.mul(bnTable.wei).div(bnTable[currency]); - } catch (e) { - return amount; - } -} - -export function normalizeEthStringToWei(str) { - const parts = str.split('.'); - let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei); - if (parts[1]) { - let decimal = parts[1]; - while (decimal.length < 18) { - decimal += '0'; - } - if (decimal.length > 18) { - decimal = decimal.slice(0, 18); - } - const decimalBN = new ethUtil.BN(decimal, 10); - eth = eth.add(decimalBN); - } - return eth; -} - -const multiple = new ethUtil.BN('10000', 10); -export function normalizeNumberToWei(n, currency) { - const enlarged = n * 10000; - const amount = new ethUtil.BN(String(enlarged), 10); - return normalizeToWei(amount, currency).div(multiple); -} - export function isHex(str) { return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/u)); } diff --git a/ui/app/helpers/utils/util.test.js b/ui/app/helpers/utils/util.test.js index c80118bad..0dfa431f6 100644 --- a/ui/app/helpers/utils/util.test.js +++ b/ui/app/helpers/utils/util.test.js @@ -1,4 +1,4 @@ -import ethUtil from 'ethereumjs-util'; +import { BN, toChecksumAddress } from 'ethereumjs-util'; import * as util from './util'; describe('util', () => { @@ -87,7 +87,7 @@ describe('util', () => { it('should recognize this sample hashed address', () => { const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0'; const result = util.isValidAddress(address); - const hashed = ethUtil.toChecksumAddress(address.toLowerCase()); + const hashed = toChecksumAddress(address.toLowerCase()); expect(hashed).toStrictEqual(address); expect(result).toStrictEqual(true); }); @@ -204,15 +204,13 @@ describe('util', () => { }); it('should return 1.0000 ETH', () => { - const input = new ethUtil.BN(ethInWei, 10).toJSON(); + const input = new BN(ethInWei, 10).toJSON(); const result = util.formatBalance(input, 4); expect(result).toStrictEqual('1.0000 ETH'); }); - it('should return 0.500 ETH', () => { - const input = new ethUtil.BN(ethInWei, 10) - .div(new ethUtil.BN('2', 10)) - .toJSON(); + it('should return 0.500 ETH', function () { + const input = new BN(ethInWei, 10).div(new BN('2', 10)).toJSON(); const result = util.formatBalance(input, 3); expect(result).toStrictEqual('0.500 ETH'); }); @@ -240,85 +238,9 @@ describe('util', () => { }); }); - describe('normalizing values', () => { - describe('#normalizeToWei', () => { - it('should convert an eth to the appropriate equivalent values', () => { - const valueTable = { - wei: '1000000000000000000', - kwei: '1000000000000000', - mwei: '1000000000000', - gwei: '1000000000', - szabo: '1000000', - finney: '1000', - ether: '1', - // kether:'0.001', - // mether:'0.000001', - // AUDIT: We're getting BN numbers on these ones. - // I think they're big enough to ignore for now. - // gether:'0.000000001', - // tether:'0.000000000001', - }; - const oneEthBn = new ethUtil.BN(ethInWei, 10); - - Object.keys(valueTable).forEach((currency) => { - const value = new ethUtil.BN(valueTable[currency], 10); - const output = util.normalizeToWei(value, currency); - expect(output.toString(10)).toStrictEqual( - valueTable.wei, - `value of ${output.toString( - 10, - )} ${currency} should convert to ${oneEthBn}`, - ); - }); - }); - }); - - describe('#normalizeEthStringToWei', () => { - it('should convert decimal eth to pure wei BN', () => { - const input = '1.23456789'; - const output = util.normalizeEthStringToWei(input); - expect(output.toString(10)).toStrictEqual('1234567890000000000'); - }); - - it('should convert 1 to expected wei', () => { - const input = '1'; - const output = util.normalizeEthStringToWei(input); - expect(output.toString(10)).toStrictEqual(ethInWei); - }); - - it('should account for overflow numbers gracefully by dropping extra precision.', () => { - const input = '1.11111111111111111111'; - const output = util.normalizeEthStringToWei(input); - expect(output.toString(10)).toStrictEqual('1111111111111111111'); - }); - - it('should not truncate very exact wei values that do not have extra precision.', () => { - const input = '1.100000000000000001'; - const output = util.normalizeEthStringToWei(input); - expect(output.toString(10)).toStrictEqual('1100000000000000001'); - }); - }); - - describe('#normalizeNumberToWei', () => { - it('should handle a simple use case', () => { - const input = 0.0002; - const output = util.normalizeNumberToWei(input, 'ether'); - const str = output.toString(10); - expect(str).toStrictEqual('200000000000000'); - }); - - it('should convert a kwei number to the appropriate equivalent wei', () => { - const result = util.normalizeNumberToWei(1.111, 'kwei'); - expect(result.toString(10)).toStrictEqual('1111', 'accepts decimals'); - }); - - it('should convert a ether number to the appropriate equivalent wei', () => { - const result = util.normalizeNumberToWei(1.111, 'ether'); - expect(result.toString(10)).toStrictEqual('1111000000000000000'); - }); - }); - describe('#isHex', () => { - it('should return true when given a hex string', () => { + describe('normalizing values', function () { + describe('#isHex', function () { + it('should return true when given a hex string', function () { const result = util.isHex( 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', ); diff --git a/ui/app/pages/add-token/add-token.component.js b/ui/app/pages/add-token/add-token.component.js index 103756e72..c2c9e9fa3 100644 --- a/ui/app/pages/add-token/add-token.component.js +++ b/ui/app/pages/add-token/add-token.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import ethUtil from 'ethereumjs-util'; +import { isValidAddress } from 'ethereumjs-util'; import { checkExistingAddresses } from '../../helpers/utils/util'; import { tokenInfoGetter } from '../../helpers/utils/token-util'; import { CONFIRM_ADD_TOKEN_ROUTE } from '../../helpers/constants/routes'; @@ -165,11 +165,11 @@ class AddToken extends Component { autoFilled: false, }); - const isValidAddress = ethUtil.isValidAddress(customAddress); + const addressIsValid = isValidAddress(customAddress); const standardAddress = addHexPrefix(customAddress).toLowerCase(); switch (true) { - case !isValidAddress: + case !addressIsValid: this.setState({ customAddressError: this.context.t('invalidAddress'), customSymbol: '', diff --git a/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js b/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js index 49a192071..0c37ca083 100644 --- a/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js +++ b/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import ethUtil from 'ethereumjs-util'; +import { toBuffer } from 'ethereumjs-util'; import ConfirmTransactionBase from '../confirm-transaction-base'; export default class ConfirmDeployContract extends Component { @@ -29,7 +29,7 @@ export default class ConfirmDeployContract extends Component {
{`${t('bytes')}:`}
-
{ethUtil.toBuffer(data).length}
+
{toBuffer(data).length}
diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js index 65af5c890..54646ac64 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -1,4 +1,4 @@ -import ethUtil from 'ethereumjs-util'; +import { toBuffer } from 'ethereumjs-util'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'; @@ -365,7 +365,7 @@ export default class ConfirmTransactionBase extends Component {
)}
- {`${t('hexData')}: ${ethUtil.toBuffer(data).length} bytes`} + {`${t('hexData')}: ${toBuffer(data).length} bytes`}
{data}
diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.js index f4830cd7c..a0e05c73c 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.js @@ -1,4 +1,4 @@ -import ethUtil from 'ethereumjs-util'; +import { toChecksumAddress } from 'ethereumjs-util'; import contractMap from '@metamask/contract-metadata'; import { isConfusing } from 'unicode-confusables'; import { @@ -37,8 +37,7 @@ export function getToWarningObject(to, tokens = [], sendToken = null) { let toWarning = null; if ( sendToken && - (ethUtil.toChecksumAddress(to) in contractMap || - checkExistingAddresses(to, tokens)) + (toChecksumAddress(to) in contractMap || checkExistingAddresses(to, tokens)) ) { toWarning = KNOWN_RECIPIENT_ADDRESS_ERROR; } else if (isValidDomainName(to) && isConfusing(to)) { diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index 65bd49418..478460aef 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import ethUtil from 'ethereumjs-util'; +import { isValidAddress } from 'ethereumjs-util'; import { debounce } from 'lodash'; import { getAmountErrorObject, @@ -171,7 +171,7 @@ export default class SendTransactionScreen extends Component { if (qrCodeData) { if (qrCodeData.type === 'address') { scannedAddress = qrCodeData.values.address.toLowerCase(); - if (ethUtil.isValidAddress(scannedAddress)) { + if (isValidAddress(scannedAddress)) { const currentAddress = prevTo?.toLowerCase(); if (currentAddress !== scannedAddress) { updateSendTo(scannedAddress); diff --git a/ui/app/pages/settings/settings.container.js b/ui/app/pages/settings/settings.container.js index f965e525c..ed664bc2f 100644 --- a/ui/app/pages/settings/settings.container.js +++ b/ui/app/pages/settings/settings.container.js @@ -2,7 +2,7 @@ import { compose } from 'redux'; import { connect } from 'react-redux'; import { withRouter } from 'react-router-dom'; import { getAddressBookEntryName } from '../../selectors'; -import { isValidAddress } from '../../helpers/utils/util'; +import { isValidAddress, isHex } from '../../helpers/utils/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { getMostRecentOverviewPage } from '../../ducks/history/history'; @@ -82,7 +82,7 @@ const mapStateToProps = (state, ownProps) => { const addressName = getAddressBookEntryName( state, - isValidAddress(pathNameTail) ? pathNameTail : '', + isHex(pathNameTail) && isValidAddress(pathNameTail) ? pathNameTail : '', ); return { diff --git a/ui/app/store/actions.test.js b/ui/app/store/actions.test.js index a9b9ca399..d3281701e 100644 --- a/ui/app/store/actions.test.js +++ b/ui/app/store/actions.test.js @@ -1394,7 +1394,7 @@ describe('Actions', () => { actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.addToAddressBook('test')); + await store.dispatch(actions.addToAddressBook('0x0000')); expect(setAddressBookStub.callCount).toStrictEqual(1); sinon.restore(); }); diff --git a/yarn.lock b/yarn.lock index c3c720956..bb86894b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3634,6 +3634,13 @@ dependencies: "@types/node" "*" +"@types/bn.js@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== + dependencies: + "@types/node" "*" + "@types/braces@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" @@ -6519,7 +6526,7 @@ bn.js@^1.0.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-1.3.0.tgz#0db4cbf96f8f23b742f5bcb9d1aa7a9994a05e83" integrity sha1-DbTL+W+PI7dC9by50ap6mZSgXoM= -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.7, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0, bn.js@^4.8.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.7, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0: version "4.11.9" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== @@ -10788,17 +10795,6 @@ ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: ethereumjs-common "^1.5.0" ethereumjs-util "^6.0.0" -ethereumjs-util@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.0.tgz#8e9646c13322e75a9c593cf705d27d4a51c991c0" - integrity sha1-jpZGwTMi51qcWTz3BdJ9SlHJkcA= - dependencies: - bn.js "^4.8.0" - create-hash "^1.1.2" - keccak "^1.0.2" - rlp "^2.0.0" - secp256k1 "^3.0.1" - ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" @@ -10837,6 +10833,18 @@ ethereumjs-util@^7.0.2: ethjs-util "0.1.6" rlp "^2.2.4" +ethereumjs-util@^7.0.9: + version "7.0.9" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.9.tgz#2038baeb30f370a3e576ec175bd70bbbb6807d42" + integrity sha512-cRqvYYKJoitq6vMKMf8pXeVwvTrX+dRD0JwHaYqm8jvogK14tqIoCWH/KUHcRwnVxVXEYF/o6pup5jRG4V0xzg== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.4" + ethereumjs-util@~6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8"