From 19d82ece30ed749874250f561d2b1fad2ee13fdb Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Wed, 7 Oct 2020 21:15:14 -0300 Subject: [PATCH 1/9] Replace all harcoded values --- .../loadIncomingTransactions.ts | 11 +++++----- .../loadOutgoingTransactions.ts | 4 +++- .../transactions/utils/transactionHelpers.ts | 12 ++++++----- src/logic/tokens/utils/humanReadableValue.ts | 14 +++++++++++++ src/logic/tokens/utils/tokenHelpers.ts | 10 +++------ src/logic/wallets/getWeb3.ts | 1 - .../components/ReviewInformation/index.tsx | 14 ++++++------- .../ContractInteraction/Review/index.tsx | 21 +++++++++---------- .../ReviewCustomTx/index.tsx | 20 ++++++++++-------- .../screens/ReviewCollectible/index.tsx | 18 +++++++++------- .../SendModal/screens/ReviewTx/index.tsx | 21 +++++++++---------- .../SendModal/screens/SendFunds/index.tsx | 4 +++- .../Tokens/screens/AssetsList/AssetRow.tsx | 5 +++-- .../Tokens/screens/TokenList/TokenRow.tsx | 6 +++--- .../safe/components/Balances/dataFetcher.ts | 14 +++++++------ .../AddOwnerModal/screens/Review/index.tsx | 16 +++++++------- .../RemoveOwnerModal/screens/Review/index.tsx | 16 +++++++------- .../screens/Review/index.tsx | 16 +++++++------- .../ChangeThreshold/index.tsx | 13 ++++++------ .../ExpandedTx/ApproveTxModal/index.tsx | 15 +++++++------ .../ExpandedTx/RejectTxModal/index.tsx | 15 +++++++------ 21 files changed, 142 insertions(+), 124 deletions(-) diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts index ec79aa234a..a9e1647fdb 100644 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts +++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts @@ -1,6 +1,6 @@ import bn from 'bignumber.js' import { List, Map } from 'immutable' - +import { getNetworkInfo } from 'src/config' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { ALTERNATIVE_TOKEN_ABI } from 'src/logic/tokens/utils/alternativeAbi' import { web3ReadOnly } from 'src/logic/wallets/getWeb3' @@ -43,13 +43,14 @@ const buildIncomingTransactionFrom = ([tx, symbol, decimals, fee]: [ const batchIncomingTxsTokenDataRequest = (txs: IncomingTxServiceModel[]) => { const batch = new web3ReadOnly.BatchRequest() + const { nativeCoin } = getNetworkInfo() const whenTxsValues = txs.map((tx) => { const methods = [ 'symbol', 'decimals', - { method: 'getTransaction', args: [tx.transactionHash], type: 'eth' }, - { method: 'getTransactionReceipt', args: [tx.transactionHash], type: 'eth' }, + { method: 'getTransaction', args: [tx.transactionHash], type: nativeCoin.symbol.toLowerCase() }, + { method: 'getTransactionReceipt', args: [tx.transactionHash], type: nativeCoin.symbol.toLowerCase() }, ] return generateBatchRequests({ @@ -66,8 +67,8 @@ const batchIncomingTxsTokenDataRequest = (txs: IncomingTxServiceModel[]) => { return Promise.all(whenTxsValues).then((txsValues) => txsValues.map(([tx, symbol, decimals, { gasPrice }, { gasUsed }]) => [ tx, - symbol === null ? 'ETH' : symbol, - decimals === null ? '18' : decimals, + symbol === null ? nativeCoin.symbol : symbol, + decimals === null ? nativeCoin.decimals : decimals, new bn(gasPrice).times(gasUsed), ]), ) diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts index 89d53d9599..00bdcfcd49 100644 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts +++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts @@ -1,5 +1,6 @@ import { fromJS, List, Map } from 'immutable' +import { getNetworkInfo } from 'src/config' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { TOKEN_REDUCER_ID } from 'src/logic/tokens/store/reducer/tokens' import { web3ReadOnly } from 'src/logic/wallets/getWeb3' @@ -103,6 +104,7 @@ const extractCancelAndOutgoingTxs = (safeAddress: string, outgoingTxs: TxService * @returns {Promise<[Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>]>} */ const batchRequestContractCode = (transactions: any[]): Promise => { + const { nativeCoin } = getNetworkInfo() if (!transactions || !Array.isArray(transactions)) { throw new Error('`transactions` must be provided in order to lookup information') } @@ -115,7 +117,7 @@ const batchRequestContractCode = (transactions: any[]): Promise => { address: tx.to, batch, context: tx, - methods: [{ method: 'getCode', type: 'eth', args: [tx.to] }], + methods: [{ method: 'getCode', type: nativeCoin.symbol.toLowerCase(), args: [tx.to] }], }) }) diff --git a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts index 9ac91d11f4..ad52ebc8b6 100644 --- a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts +++ b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts @@ -1,5 +1,5 @@ import { List, Map } from 'immutable' - +import { getNetworkInfo } from 'src/config' import { TOKEN_REDUCER_ID } from 'src/logic/tokens/store/reducer/tokens' import { getERC20DecimalsAndSymbol, @@ -100,12 +100,13 @@ export const getRefundParams = async ( tx: TxServiceModel, tokenInfo: (string) => Promise<{ decimals: number; symbol: string } | null>, ): Promise => { + const { nativeCoin } = getNetworkInfo() const txGasPrice = Number(tx.gasPrice) let refundParams: RefundParams | null = null if (txGasPrice > 0) { - let refundSymbol = 'ETH' - let refundDecimals = 18 + let refundSymbol = nativeCoin.symbol + let refundDecimals = nativeCoin.decimals if (tx.gasToken !== ZERO_ADDRESS) { const gasToken = await tokenInfo(tx.gasToken) @@ -243,6 +244,7 @@ export const buildTx = async ({ txCode, }: BuildTx): Promise => { const safeAddress = safe.address + const { nativeCoin } = getNetworkInfo() const isModifySettingsTx = isModifySettingsTransaction(tx, safeAddress) const isTxCancelled = isTransactionCancelled(tx, outgoingTxs, cancellationTxs) const isSendERC721Tx = isSendERC721Transaction(tx, txCode, knownTokens) @@ -255,8 +257,8 @@ export const buildTx = async ({ const decodedParams = getDecodedParams(tx) const confirmations = getConfirmations(tx) - let tokenDecimals = 18 - let tokenSymbol = 'ETH' + let tokenDecimals = nativeCoin.decimals + let tokenSymbol = nativeCoin.symbol try { if (isSendERC20Tx) { const { decimals, symbol } = await getERC20DecimalsAndSymbol(tx.to) diff --git a/src/logic/tokens/utils/humanReadableValue.ts b/src/logic/tokens/utils/humanReadableValue.ts index 7716a1d547..16c11e235a 100644 --- a/src/logic/tokens/utils/humanReadableValue.ts +++ b/src/logic/tokens/utils/humanReadableValue.ts @@ -3,3 +3,17 @@ import { BigNumber } from 'bignumber.js' export const humanReadableValue = (value: number | string, decimals = 18): string => { return new BigNumber(value).times(`1e-${decimals}`).toFixed() } + +export const fromTokenUnit = (amount: string, decimals: string | number): string => + new BigNumber(amount).times(`1e-${decimals}`).toFixed() + +export const toTokenUnit = (amount: string, decimals: string | number): string => { + const amountBN = new BigNumber(amount).times(`1e${decimals}`) + const [, amountDecimalPlaces] = amount.split('.') + + if (amountDecimalPlaces?.length >= +decimals) { + return amountBN.toFixed(0, BigNumber.ROUND_DOWN) + } + + return amountBN.toFixed() +} diff --git a/src/logic/tokens/utils/tokenHelpers.ts b/src/logic/tokens/utils/tokenHelpers.ts index 48134bdb2b..186b05a242 100644 --- a/src/logic/tokens/utils/tokenHelpers.ts +++ b/src/logic/tokens/utils/tokenHelpers.ts @@ -1,4 +1,4 @@ -import logo from 'src/assets/icons/icon_etherTokens.svg' +import { getNetworkInfo } from 'src/config' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { getStandardTokenContract, @@ -12,16 +12,12 @@ import { isEmptyData } from 'src/logic/safe/store/actions/transactions/utils/tra import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' import { Map } from 'immutable' -export const ETH_ADDRESS = '0x000' export const SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH = '42842e0e' export const getEthAsToken = (balance: string | number): Token => { + const { nativeCoin } = getNetworkInfo() return makeToken({ - address: ETH_ADDRESS, - name: 'Ether', - symbol: 'ETH', - decimals: 18, - logoUri: logo, + ...nativeCoin, balance, }) } diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index 0b303d660e..5f7934df30 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -1,7 +1,6 @@ import Web3 from 'web3' import { provider as Provider } from 'web3-core' import { ContentHash } from 'web3-eth-ens' - import { getNetworkId } from 'src/config' import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { NETWORK } from 'src/utils/constants' diff --git a/src/routes/open/components/ReviewInformation/index.tsx b/src/routes/open/components/ReviewInformation/index.tsx index f76792b79b..d5a7af7d16 100644 --- a/src/routes/open/components/ReviewInformation/index.tsx +++ b/src/routes/open/components/ReviewInformation/index.tsx @@ -1,7 +1,8 @@ import TableContainer from '@material-ui/core/TableContainer' import classNames from 'classnames' import React, { useEffect, useState } from 'react' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -13,7 +14,7 @@ import Row from 'src/components/layout/Row' import OpenPaper from 'src/components/Stepper/OpenPaper' import { estimateGasForDeployingSafe } from 'src/logic/contracts/safeContracts' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { getAccountsFrom, getNamesFrom } from 'src/routes/open/utils/safeDataExtractor' import { FIELD_CONFIRMATIONS, FIELD_NAME, getNumOwnersFrom } from '../fields' @@ -37,11 +38,10 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { if (!addresses.length || !numOwners || !userAccount) { return } - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils - const estimatedGasCosts = await estimateGasForDeployingSafe(addresses, numOwners, userAccount) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const { nativeCoin } = getNetworkInfo() + const estimatedGasCosts = await (await estimateGasForDeployingSafe(addresses, numOwners, userAccount)).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) setGasCosts(formattedGasCosts) } diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx index 5d2d1c1064..20869b714f 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx @@ -2,7 +2,8 @@ import { makeStyles } from '@material-ui/core/styles' import { useSnackbar } from 'notistack' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' - +import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import AddressInfo from 'src/components/AddressInfo' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' @@ -16,7 +17,6 @@ import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers' -import { getWeb3 } from 'src/logic/wallets/getWeb3' import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/style' import Header from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Header' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' @@ -46,17 +46,18 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} const [gasCosts, setGasCosts] = useState('< 0.001') - + const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async (): Promise => { - const { fromWei, toBN } = getWeb3().utils const txData = tx.data ? tx.data.trim() : '' - const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const estimatedGasCosts = await ( + await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) + ).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -68,14 +69,12 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE return () => { isCurrent = false } - }, [safeAddress, tx.contractAddress, tx.data]) + }, [nativeCoin.decimals, safeAddress, tx.contractAddress, tx.data]) const submitTx = async () => { - const web3 = getWeb3() const txRecipient = tx.contractAddress const txData = tx.data ? tx.data.trim() : '' - const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : '0' - + const txValue = tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0' dispatch( createTransaction({ safeAddress, diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx index 4b8129ee4b..a1014ef180 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx @@ -3,6 +3,8 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' @@ -20,7 +22,7 @@ import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { sm } from 'src/theme/variables' @@ -42,17 +44,18 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} const [gasCosts, setGasCosts] = useState('< 0.001') - + const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async () => { - const { fromWei, toBN } = getWeb3().utils const txData = tx.data ? tx.data.trim() : '' - const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const estimatedGasCosts = await ( + await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) + ).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -64,13 +67,12 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { return () => { isCurrent = false } - }, [safeAddress, tx.data, tx.contractAddress]) + }, [safeAddress, tx.data, tx.contractAddress, nativeCoin.decimals]) const submitTx = async (): Promise => { - const web3 = getWeb3() const txRecipient = tx.contractAddress const txData = tx.data ? tx.data.trim() : '' - const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : '0' + const txValue = tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0' dispatch( createTransaction({ diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx index b9783e58a3..2a4e04d9be 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import { withSnackbar } from 'notistack' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -27,7 +28,7 @@ import { } from 'src/logic/tokens/store/actions/fetchTokens' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH } from 'src/logic/tokens/utils/tokenHelpers' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { sm } from 'src/theme/variables' @@ -46,6 +47,7 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx const { address: safeAddress } = useSelector(safeSelector) || {} const nftTokens = useSelector(nftTokensSelector) const [gasCosts, setGasCosts] = useState('< 0.001') + const { nativeCoin } = getNetworkInfo() const txToken = nftTokens.find( ({ assetAddress, tokenId }) => assetAddress === tx.assetAddress && tokenId === tx.nftTokenId, ) @@ -55,8 +57,6 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx let isCurrent = true const estimateGas = async () => { - const { fromWei, toBN } = getWeb3().utils - const supportsSafeTransfer = await containsMethodByHash(tx.assetAddress, SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH) const methodToCall = supportsSafeTransfer ? `0x${SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH}` : 'transfer' const transferParams = [tx.recipientAddress, tx.nftTokenId] @@ -66,9 +66,11 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx const tokenInstance = await ERC721Token.at(tx.assetAddress) const txData = tokenInstance.contract.methods[methodToCall](...params).encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.recipientAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const estimatedGasCosts = await ( + await estimateTxGasCosts(safeAddress as string, tx.recipientAddress, txData) + ).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -81,7 +83,7 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx return () => { isCurrent = false } - }, [safeAddress, tx.assetAddress, tx.nftTokenId, tx.recipientAddress]) + }, [nativeCoin.decimals, safeAddress, tx.assetAddress, tx.nftTokenId, tx.recipientAddress]) const submitTx = async () => { dispatch( diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx index 0fe167da22..481072743c 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx @@ -5,6 +5,8 @@ import { BigNumber } from 'bignumber.js' import { withSnackbar } from 'notistack' import React, { useEffect, useMemo, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { toTokenUnit, fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' @@ -22,9 +24,8 @@ import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { getHumanFriendlyToken } from 'src/logic/tokens/store/actions/fetchTokens' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ETH_ADDRESS } from 'src/logic/tokens/utils/tokenHelpers' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { extendedSafeTokensSelector } from 'src/routes/safe/container/selector' @@ -40,20 +41,19 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { const classes = useStyles() const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} + const { nativeCoin } = getNetworkInfo() const tokens = useSelector(extendedSafeTokensSelector) const [gasCosts, setGasCosts] = useState('< 0.001') const [data, setData] = useState('') const txToken = useMemo(() => tokens.find((token) => token.address === tx.token), [tokens, tx.token]) - const isSendingETH = txToken?.address === ETH_ADDRESS + const isSendingETH = txToken?.address === nativeCoin.address const txRecipient = isSendingETH ? tx.recipientAddress : txToken?.address useEffect(() => { let isCurrent = true const estimateGas = async () => { - const { fromWei, toBN } = getWeb3().utils - if (!txToken) { return } @@ -69,9 +69,9 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, txAmount).encodeABI() } - const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, txRecipient, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const estimatedGasCosts = await (await estimateTxGasCosts(safeAddress as string, txRecipient, txData)).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -84,14 +84,13 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { return () => { isCurrent = false } - }, [isSendingETH, safeAddress, tx.amount, tx.recipientAddress, txRecipient, txToken]) + }, [isSendingETH, nativeCoin.decimals, safeAddress, tx.amount, tx.recipientAddress, txRecipient, txToken]) const submitTx = async () => { - const web3 = getWeb3() // txAmount should be 0 if we send tokens // the real value is encoded in txData and will be used by the contract // if txAmount > 0 it would send ETH from the Safe - const txAmount = isSendingETH ? web3.utils.toWei(tx.amount, 'ether') : '0' + const txAmount = isSendingETH ? toTokenUnit(tx.amount, nativeCoin.decimals) : '0' dispatch( createTransaction({ diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx index 4d1ea8e3b1..3e02ae8924 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx @@ -2,6 +2,7 @@ import IconButton from '@material-ui/core/IconButton' import InputAdornment from '@material-ui/core/InputAdornment' import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' +import { getNetworkInfo } from 'src/config' import React, { useState } from 'react' import { OnChange } from 'react-final-form-listeners' import { useSelector } from 'react-redux' @@ -78,6 +79,7 @@ const SendFunds = ({ const [pristine, setPristine] = useState(true) const [isValidAddress, setIsValidAddress] = useState(false) + const { nativeCoin } = getNetworkInfo() React.useMemo(() => { if (selectedEntry === null && pristine) { @@ -212,7 +214,7 @@ const SendFunds = ({ diff --git a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx index 4d0af38c9e..b1fb65a331 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx +++ b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx @@ -9,7 +9,7 @@ import React, { memo } from 'react' import { styles } from './style' import Img from 'src/components/layout/Img' -import { ETH_ADDRESS } from 'src/logic/tokens/utils/tokenHelpers' +import { getNetworkInfo } from 'src/config' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' export const TOGGLE_ASSET_TEST_ID = 'toggle-asset-btn' @@ -20,6 +20,7 @@ const AssetRow = memo(({ classes, data, index, style }: any) => { const asset = assets.get(index) const { address, image, name, symbol } = asset const isActive = activeAssetsAddresses.has(asset.address) + const { nativeCoin } = getNetworkInfo() return (
@@ -28,7 +29,7 @@ const AssetRow = memo(({ classes, data, index, style }: any) => { {name} - {address !== ETH_ADDRESS && ( + {address !== nativeCoin.address && ( { const { activeTokensAddresses, onSwitch, tokens } = data const token = tokens.get(index) const isActive = activeTokensAddresses.has(token.address) - + const { nativeCoin } = getNetworkInfo() return (
@@ -28,7 +28,7 @@ const TokenRow = memo(({ classes, data, index, style }: any) => { {token.name} - {token.address !== ETH_ADDRESS && ( + {token.address !== nativeCoin.address && ( { - if (token.address === ETH_ADDRESS && !tokenAddress) { + const { nativeCoin } = getNetworkInfo() + if (token.address === nativeCoin.address && !tokenAddress) { return true } @@ -54,8 +54,9 @@ export const getBalanceData = ( currencySelected?: AVAILABLE_CURRENCIES, currencyValues?: BalanceCurrencyList, currencyRate?: number, -): List => - activeTokens.map((token) => ({ +): List => { + const { nativeCoin } = getNetworkInfo() + return activeTokens.map((token) => ({ [BALANCE_TABLE_ASSET_ID]: { name: token.name, logoUri: token.logoUri, @@ -65,9 +66,10 @@ export const getBalanceData = ( assetOrder: token.name, [BALANCE_TABLE_BALANCE_ID]: `${formatAmountInUsFormat(token.balance?.toString() || '0')} ${token.symbol}`, balanceOrder: Number(token.balance), - [FIXED]: token.symbol === 'ETH', + [FIXED]: token.symbol === nativeCoin.symbol, [BALANCE_TABLE_VALUE_ID]: getTokenPriceInCurrency(token, currencySelected, currencyValues, currencyRate), })) +} export const generateColumns = (): List => { const assetColumn: TableColumn = { diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx index cd5a6cb9ac..729b8a1edc 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -18,7 +19,7 @@ import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -29,18 +30,17 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) + const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const txData = safeInstance.methods.addOwnerWithThreshold(values.ownerAddress, values.threshold).encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) + const estimatedGasCosts = await (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) } @@ -51,7 +51,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => return () => { isCurrent = false } - }, [safeAddress, values.ownerAddress, values.threshold]) + }, [nativeCoin.decimals, safeAddress, values.ownerAddress, values.threshold]) const handleSubmit = () => { onSubmit() diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx index f10e362041..012f1133af 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -18,7 +19,7 @@ import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from 'src/logic/contracts/s import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -29,21 +30,20 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) + const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) const safeOwners = await gnosisSafe.methods.getOwners().call() const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] const txData = gnosisSafe.methods.removeOwner(prevAddress, ownerAddress, values.threshold).encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const estimatedGasCosts = await (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -54,7 +54,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre return () => { isCurrent = false } - }, [ownerAddress, safeAddress, values.threshold]) + }, [nativeCoin.decimals, ownerAddress, safeAddress, values.threshold]) return ( <> diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx index 3b1ce84db6..3464ede273 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -23,7 +24,7 @@ import { } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -35,20 +36,19 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) const threshold = useSelector(safeThresholdSelector) + const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) const safeOwners = await gnosisSafe.methods.getOwners().call() const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] const txData = gnosisSafe.methods.swapOwner(prevAddress, ownerAddress, values.ownerAddress).encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const estimatedGasCosts = await (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) } @@ -58,7 +58,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre return () => { isCurrent = false } - }, [ownerAddress, safeAddress, values.ownerAddress]) + }, [nativeCoin.decimals, ownerAddress, safeAddress, values.ownerAddress]) return ( <> diff --git a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx index e821d4d3ed..35c3f04b05 100644 --- a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx +++ b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx @@ -3,7 +3,8 @@ import MenuItem from '@material-ui/core/MenuItem' import { withStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import { styles } from './style' import Field from 'src/components/forms/Field' @@ -19,22 +20,20 @@ import Row from 'src/components/layout/Row' import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getWeb3 } from 'src/logic/wallets/getWeb3' const THRESHOLD_FIELD_NAME = 'threshold' const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddress, threshold }) => { const [gasCosts, setGasCosts] = useState('< 0.001') + const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGasCosts = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const txData = safeInstance.methods.changeThreshold('1').encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') + const estimatedGasCosts = await (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() + const gasCostsAsEth = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCostsAsEth) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -46,7 +45,7 @@ const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddr return () => { isCurrent = false } - }, [safeAddress]) + }, [nativeCoin.decimals, safeAddress]) const handleSubmit = (values) => { const newThreshold = values[THRESHOLD_FIELD_NAME] diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx index e6eb22ee76..fb25502c82 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx @@ -5,6 +5,8 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import { styles } from './style' @@ -18,7 +20,6 @@ import Row from 'src/components/layout/Row' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getWeb3 } from 'src/logic/wallets/getWeb3' import { userAccountSelector } from 'src/logic/wallets/store/selectors' import processTransaction from 'src/logic/safe/store/actions/processTransaction' @@ -80,23 +81,21 @@ const ApproveTxModal = ({ const { description, title } = getModalTitleAndDescription(thresholdReached, isCancelTx) const oneConfirmationLeft = !thresholdReached && tx.confirmations.size + 1 === threshold const isTheTxReadyToBeExecuted = oneConfirmationLeft ? true : thresholdReached + const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils - const estimatedGasCosts = await estimateTxGasCosts( safeAddress, tx.recipient, tx.data as string, tx, approveAndExecute ? userAddress : undefined, - ) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + ).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) } @@ -107,7 +106,7 @@ const ApproveTxModal = ({ return () => { isCurrent = false } - }, [approveAndExecute, safeAddress, tx, userAddress]) + }, [approveAndExecute, nativeCoin, safeAddress, tx, userAddress]) const handleExecuteCheckbox = () => setApproveAndExecute((prevApproveAndExecute) => !prevApproveAndExecute) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx index e5372d4c15..b43fba086d 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx @@ -3,6 +3,8 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import { styles } from './style' @@ -17,7 +19,6 @@ import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { getWeb3 } from 'src/logic/wallets/getWeb3' import createTransaction from 'src/logic/safe/store/actions/createTransaction' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' @@ -35,17 +36,15 @@ const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { const [gasCosts, setGasCosts] = useState('< 0.001') const dispatch = useDispatch() const safeAddress = useSelector(safeParamAddressFromStateSelector) as string + const { nativeCoin } = getNetworkInfo() const classes = useStyles() useEffect(() => { let isCurrent = true const estimateGasCosts = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils - - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, EMPTY_DATA) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const estimatedGasCosts = await (await estimateTxGasCosts(safeAddress, safeAddress, EMPTY_DATA)).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) } @@ -56,7 +55,7 @@ const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { return () => { isCurrent = false } - }, [safeAddress]) + }, [nativeCoin.decimals, safeAddress]) const sendReplacementTransaction = () => { dispatch( From 7a8f2c7cc5945fff9351687ab5fce9461086fc3e Mon Sep 17 00:00:00 2001 From: fernandomg Date: Fri, 9 Oct 2020 11:52:45 -0300 Subject: [PATCH 2/9] fix `generateBatchRequest` calls --- .../fetchTransactions/loadIncomingTransactions.ts | 4 ++-- .../fetchTransactions/loadOutgoingTransactions.ts | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts index a9e1647fdb..4accf5dd83 100644 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts +++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts @@ -49,8 +49,8 @@ const batchIncomingTxsTokenDataRequest = (txs: IncomingTxServiceModel[]) => { const methods = [ 'symbol', 'decimals', - { method: 'getTransaction', args: [tx.transactionHash], type: nativeCoin.symbol.toLowerCase() }, - { method: 'getTransactionReceipt', args: [tx.transactionHash], type: nativeCoin.symbol.toLowerCase() }, + { method: 'getTransaction', args: [tx.transactionHash], type: 'eth' }, + { method: 'getTransactionReceipt', args: [tx.transactionHash], type: 'eth' }, ] return generateBatchRequests({ diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts index 00bdcfcd49..89d53d9599 100644 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts +++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts @@ -1,6 +1,5 @@ import { fromJS, List, Map } from 'immutable' -import { getNetworkInfo } from 'src/config' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { TOKEN_REDUCER_ID } from 'src/logic/tokens/store/reducer/tokens' import { web3ReadOnly } from 'src/logic/wallets/getWeb3' @@ -104,7 +103,6 @@ const extractCancelAndOutgoingTxs = (safeAddress: string, outgoingTxs: TxService * @returns {Promise<[Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>]>} */ const batchRequestContractCode = (transactions: any[]): Promise => { - const { nativeCoin } = getNetworkInfo() if (!transactions || !Array.isArray(transactions)) { throw new Error('`transactions` must be provided in order to lookup information') } @@ -117,7 +115,7 @@ const batchRequestContractCode = (transactions: any[]): Promise => { address: tx.to, batch, context: tx, - methods: [{ method: 'getCode', type: nativeCoin.symbol.toLowerCase(), args: [tx.to] }], + methods: [{ method: 'getCode', type: 'eth', args: [tx.to] }], }) }) From 38e8e83a1eca53f010c20bc0fca7f1097dea2c92 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 9 Oct 2020 13:27:56 -0300 Subject: [PATCH 3/9] Fix some ETH harcoded values + Add tests --- src/components/AddressInfo/index.tsx | 5 ++- .../utils/__tests__/tokenHelpers.test.ts | 38 +++++++++++++++++++ src/logic/tokens/utils/humanReadableValue.ts | 6 +-- .../ContractInteraction/Review/index.tsx | 9 ++--- .../ReviewCustomTx/index.tsx | 4 +- .../screens/ReviewCollectible/index.tsx | 4 +- .../SendModal/screens/ReviewTx/index.tsx | 2 +- .../AddOwnerModal/screens/Review/index.tsx | 2 +- .../RemoveOwnerModal/screens/Review/index.tsx | 2 +- .../screens/Review/index.tsx | 2 +- .../ChangeThreshold/index.tsx | 2 +- .../ExpandedTx/ApproveTxModal/index.tsx | 2 +- .../ExpandedTx/RejectTxModal/index.tsx | 2 +- 13 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/components/AddressInfo/index.tsx b/src/components/AddressInfo/index.tsx index 99f94a0903..f2a1a4cd93 100644 --- a/src/components/AddressInfo/index.tsx +++ b/src/components/AddressInfo/index.tsx @@ -1,5 +1,5 @@ import React from 'react' - +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -43,6 +43,7 @@ interface Props { } const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props): React.ReactElement => { + const { nativeCoin } = getNetworkInfo() return (
@@ -64,7 +65,7 @@ const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props): React.ReactE {ethBalance && ( - Balance: {`${ethBalance} ETH`} + Balance: {`${ethBalance} ${nativeCoin.symbol}`} )} diff --git a/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts b/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts index 7afee4ed9e..3686f0e112 100644 --- a/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts +++ b/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts @@ -1,6 +1,7 @@ import { makeToken } from 'src/logic/tokens/store/model/token' import { getERC20DecimalsAndSymbol, isERC721Contract, isTokenTransfer } from 'src/logic/tokens/utils/tokenHelpers' import { getMockedTxServiceModel } from 'src/test/utils/safeHelper' +import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' describe('isTokenTransfer', () => { const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' @@ -171,4 +172,41 @@ describe('isERC721Contract', () => { expect(result).toEqual(expectedResult) expect(standardContractSpy).toHaveBeenCalled() }) + it('It should return the gas cost with right amount of decimals', () => { + // given + const decimals = Number(18) + const symbol = 'ETH' + + const nativeCoin = { + decimals, + symbol, + } + const expectedResult = '0.0000000000000000003' + const ESTIMATED_GASCOSTS = 0.3 + + // when + const gasCosts = fromTokenUnit(ESTIMATED_GASCOSTS, nativeCoin.decimals) + + // then + expect(gasCosts).toEqual(expectedResult) + }) + + it('It should return the tx value as a token unit', () => { + // given + const decimals = Number(18) + const symbol = 'ETH' + + const nativeCoin = { + decimals, + symbol, + } + const expectedResult = '300000000000000000' + const VALUE = 0.3 + + // when + const txValue = toTokenUnit(VALUE, nativeCoin.decimals) + + // then + expect(txValue).toEqual(expectedResult) + }) }) diff --git a/src/logic/tokens/utils/humanReadableValue.ts b/src/logic/tokens/utils/humanReadableValue.ts index 16c11e235a..84361cffae 100644 --- a/src/logic/tokens/utils/humanReadableValue.ts +++ b/src/logic/tokens/utils/humanReadableValue.ts @@ -4,12 +4,12 @@ export const humanReadableValue = (value: number | string, decimals = 18): strin return new BigNumber(value).times(`1e-${decimals}`).toFixed() } -export const fromTokenUnit = (amount: string, decimals: string | number): string => +export const fromTokenUnit = (amount: number | string, decimals: string | number): string => new BigNumber(amount).times(`1e-${decimals}`).toFixed() -export const toTokenUnit = (amount: string, decimals: string | number): string => { +export const toTokenUnit = (amount: number | string, decimals: string | number): string => { const amountBN = new BigNumber(amount).times(`1e${decimals}`) - const [, amountDecimalPlaces] = amount.split('.') + const [, amountDecimalPlaces] = amount.toString().split('.') if (amountDecimalPlaces?.length >= +decimals) { return amountBN.toFixed(0, BigNumber.ROUND_DOWN) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx index 873a6c8957..d9b76e5474 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx @@ -40,22 +40,21 @@ type Props = { tx: TransactionReviewType } +const { nativeCoin } = getNetworkInfo() + const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const { enqueueSnackbar, closeSnackbar } = useSnackbar() const classes = useStyles() const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} const [gasCosts, setGasCosts] = useState('< 0.001') - const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async (): Promise => { const txData = tx.data ? tx.data.trim() : '' - const estimatedGasCosts = ( - await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - ).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) @@ -69,7 +68,7 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE return () => { isCurrent = false } - }, [nativeCoin.decimals, safeAddress, tx.contractAddress, tx.data]) + }, [safeAddress, tx.contractAddress, tx.data]) const submitTx = async () => { const txRecipient = tx.contractAddress diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx index 8e50416b02..34980e8cd0 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx @@ -50,9 +50,7 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const estimateGas = async () => { const txData = tx.data ? tx.data.trim() : '' - const estimatedGasCosts = ( - await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - ).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx index 58a91e06b6..8ed95fdaea 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx @@ -65,9 +65,7 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx const tokenInstance = await ERC721Token.at(tx.assetAddress) const txData = tokenInstance.contract.methods[methodToCall](...params).encodeABI() - const estimatedGasCosts = ( - await estimateTxGasCosts(safeAddress as string, tx.recipientAddress, txData) - ).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.recipientAddress, txData) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx index 912b08be8e..23bbc77a02 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx @@ -68,7 +68,7 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, txAmount).encodeABI() } - const estimatedGasCosts = (await estimateTxGasCosts(safeAddress as string, txRecipient, txData)).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, txRecipient, txData) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx index 36733e8b0b..deb96b680e 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx @@ -36,7 +36,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const txData = safeInstance.methods.addOwnerWithThreshold(values.ownerAddress, values.threshold).encodeABI() - const estimatedGasCosts = (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx index 2674718d0f..7b46ef0ef1 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx @@ -40,7 +40,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] const txData = gnosisSafe.methods.removeOwner(prevAddress, ownerAddress, values.threshold).encodeABI() - const estimatedGasCosts = (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx index 26c90e5edc..3abc231176 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx @@ -45,7 +45,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] const txData = gnosisSafe.methods.swapOwner(prevAddress, ownerAddress, values.ownerAddress).encodeABI() - const estimatedGasCosts = (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { diff --git a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx index 89cc525367..3a1d997c4b 100644 --- a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx +++ b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx @@ -32,7 +32,7 @@ const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddr const estimateGasCosts = async () => { const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const txData = safeInstance.methods.changeThreshold('1').encodeABI() - const estimatedGasCosts = (await estimateTxGasCosts(safeAddress, safeAddress, txData)).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) const gasCostsAsEth = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCostsAsEth) if (isCurrent) { diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx index fb25502c82..47119480a0 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx @@ -93,7 +93,7 @@ const ApproveTxModal = ({ tx.data as string, tx, approveAndExecute ? userAddress : undefined, - ).toString() + ) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx index 2276fc5477..7f93bee153 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx @@ -42,7 +42,7 @@ const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { useEffect(() => { let isCurrent = true const estimateGasCosts = async () => { - const estimatedGasCosts = (await estimateTxGasCosts(safeAddress, safeAddress, EMPTY_DATA)).toString() + const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, EMPTY_DATA) const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { From e01912511e6e4bc25f7847b7ec7d33619e269c44 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 9 Oct 2020 13:32:29 -0300 Subject: [PATCH 4/9] Fix null or undefinded value --- src/logic/safe/store/actions/fetchSafe.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logic/safe/store/actions/fetchSafe.ts b/src/logic/safe/store/actions/fetchSafe.ts index 061f02a70b..a398ffb733 100644 --- a/src/logic/safe/store/actions/fetchSafe.ts +++ b/src/logic/safe/store/actions/fetchSafe.ts @@ -128,14 +128,14 @@ export const checkAndUpdateSafe = (safeAdd: string) => async (dispatch: Dispatch // If the remote owners does not contain a local address, we remove that local owner localOwners.forEach((localAddress) => { - const remoteOwnerIndex = remoteOwners?.findIndex((remoteAddress) => sameAddress(remoteAddress, localAddress)) + const remoteOwnerIndex = remoteOwners.findIndex((remoteAddress) => sameAddress(remoteAddress, localAddress)) if (remoteOwnerIndex === -1) { dispatch(removeSafeOwner({ safeAddress, ownerAddress: localAddress })) } }) // If the remote has an owner that we don't have locally, we add it - remoteOwners?.forEach((remoteAddress) => { + remoteOwners.forEach((remoteAddress) => { const localOwnerIndex = localOwners.findIndex((localAddress) => sameAddress(remoteAddress, localAddress)) if (localOwnerIndex === -1) { dispatch( From 93a4e765dcb3c3f6819482ada374f30dd759e9d9 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 9 Oct 2020 15:43:02 -0300 Subject: [PATCH 5/9] Move nativeCoin outside component + fix toTokenInput function --- src/components/AddressInfo/index.tsx | 3 ++- src/logic/tokens/utils/humanReadableValue.ts | 2 +- .../Balances/SendModal/screens/ReviewCollectible/index.tsx | 5 +++-- .../ManageOwners/AddOwnerModal/screens/Review/index.tsx | 5 +++-- .../ManageOwners/RemoveOwnerModal/screens/Review/index.tsx | 6 +++--- .../ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx | 5 +++-- .../Settings/ThresholdSettings/ChangeThreshold/index.tsx | 5 +++-- .../TxsTable/ExpandedTx/RejectTxModal/index.tsx | 5 +++-- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/components/AddressInfo/index.tsx b/src/components/AddressInfo/index.tsx index f2a1a4cd93..0e618a2a91 100644 --- a/src/components/AddressInfo/index.tsx +++ b/src/components/AddressInfo/index.tsx @@ -42,8 +42,9 @@ interface Props { ethBalance?: string } +const { nativeCoin } = getNetworkInfo() + const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props): React.ReactElement => { - const { nativeCoin } = getNetworkInfo() return (
diff --git a/src/logic/tokens/utils/humanReadableValue.ts b/src/logic/tokens/utils/humanReadableValue.ts index 84361cffae..2d2afc1793 100644 --- a/src/logic/tokens/utils/humanReadableValue.ts +++ b/src/logic/tokens/utils/humanReadableValue.ts @@ -12,7 +12,7 @@ export const toTokenUnit = (amount: number | string, decimals: string | number): const [, amountDecimalPlaces] = amount.toString().split('.') if (amountDecimalPlaces?.length >= +decimals) { - return amountBN.toFixed(0, BigNumber.ROUND_DOWN) + return amountBN.toFixed(+decimals, BigNumber.ROUND_DOWN) } return amountBN.toFixed() diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx index 8ed95fdaea..5a443b9821 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx @@ -37,6 +37,8 @@ import ArrowDown from '../assets/arrow-down.svg' import { styles } from './style' +const { nativeCoin } = getNetworkInfo() + const useStyles = makeStyles(styles as any) const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { @@ -46,7 +48,6 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx const { address: safeAddress } = useSelector(safeSelector) || {} const nftTokens = useSelector(nftTokensSelector) const [gasCosts, setGasCosts] = useState('< 0.001') - const { nativeCoin } = getNetworkInfo() const txToken = nftTokens.find( ({ assetAddress, tokenId }) => assetAddress === tx.assetAddress && tokenId === tx.nftTokenId, ) @@ -80,7 +81,7 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx return () => { isCurrent = false } - }, [nativeCoin.decimals, safeAddress, tx.assetAddress, tx.nftTokenId, tx.recipientAddress]) + }, [safeAddress, tx.assetAddress, tx.nftTokenId, tx.recipientAddress]) const submitTx = async () => { dispatch( diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx index deb96b680e..0572ba3298 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx @@ -24,12 +24,13 @@ import { styles } from './style' export const ADD_OWNER_SUBMIT_BTN_TEST_ID = 'add-owner-submit-btn' +const { nativeCoin } = getNetworkInfo() + const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => { const [gasCosts, setGasCosts] = useState('< 0.001') const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) - const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true const estimateGas = async () => { @@ -50,7 +51,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => return () => { isCurrent = false } - }, [nativeCoin.decimals, safeAddress, values.ownerAddress, values.threshold]) + }, [safeAddress, values.ownerAddress, values.threshold]) const handleSubmit = () => { onSubmit() diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx index 7b46ef0ef1..e3dea9b406 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx @@ -24,13 +24,13 @@ import { styles } from './style' export const REMOVE_OWNER_REVIEW_BTN_TEST_ID = 'remove-owner-review-btn' +const { nativeCoin } = getNetworkInfo() + const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddress, ownerName, values }) => { const [gasCosts, setGasCosts] = useState('< 0.001') const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) - const { nativeCoin } = getNetworkInfo() - useEffect(() => { let isCurrent = true @@ -53,7 +53,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre return () => { isCurrent = false } - }, [nativeCoin.decimals, ownerAddress, safeAddress, values.threshold]) + }, [ownerAddress, safeAddress, values.threshold]) return ( <> diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx index 3abc231176..d6221a4e24 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx @@ -29,13 +29,14 @@ import { styles } from './style' export const REPLACE_OWNER_SUBMIT_BTN_TEST_ID = 'replace-owner-submit-btn' +const { nativeCoin } = getNetworkInfo() + const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddress, ownerName, values }) => { const [gasCosts, setGasCosts] = useState('< 0.001') const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) const threshold = useSelector(safeThresholdSelector) - const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true @@ -57,7 +58,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre return () => { isCurrent = false } - }, [nativeCoin.decimals, ownerAddress, safeAddress, values.ownerAddress]) + }, [ownerAddress, safeAddress, values.ownerAddress]) return ( <> diff --git a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx index 3a1d997c4b..2cc4dfeecd 100644 --- a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx +++ b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx @@ -23,9 +23,10 @@ import { formatAmount } from 'src/logic/tokens/utils/formatAmount' const THRESHOLD_FIELD_NAME = 'threshold' +const { nativeCoin } = getNetworkInfo() + const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddress, threshold }) => { const [gasCosts, setGasCosts] = useState('< 0.001') - const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true @@ -45,7 +46,7 @@ const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddr return () => { isCurrent = false } - }, [nativeCoin.decimals, safeAddress]) + }, [safeAddress]) const handleSubmit = (values) => { const newThreshold = values[THRESHOLD_FIELD_NAME] diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx index 7f93bee153..f31448e9dd 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx @@ -32,11 +32,12 @@ type Props = { tx: Transaction } +const { nativeCoin } = getNetworkInfo() + const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { const [gasCosts, setGasCosts] = useState('< 0.001') const dispatch = useDispatch() const safeAddress = useSelector(safeParamAddressFromStateSelector) as string - const { nativeCoin } = getNetworkInfo() const classes = useStyles() useEffect(() => { @@ -55,7 +56,7 @@ const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { return () => { isCurrent = false } - }, [nativeCoin.decimals, safeAddress]) + }, [safeAddress]) const sendReplacementTransaction = () => { dispatch( From fe728c3cf3bca9a107b448948341fc6ab9538f02 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 9 Oct 2020 15:45:09 -0300 Subject: [PATCH 6/9] Remove native coin from useEffect --- .../screens/ContractInteraction/ReviewCustomTx/index.tsx | 5 +++-- .../TxsTable/ExpandedTx/ApproveTxModal/index.tsx | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx index 34980e8cd0..65bb402eec 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx @@ -38,12 +38,13 @@ type Props = { const useStyles = makeStyles(styles) +const { nativeCoin } = getNetworkInfo() + const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const classes = useStyles() const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} const [gasCosts, setGasCosts] = useState('< 0.001') - const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true @@ -64,7 +65,7 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { return () => { isCurrent = false } - }, [safeAddress, tx.data, tx.contractAddress, nativeCoin.decimals]) + }, [safeAddress, tx.data, tx.contractAddress]) const submitTx = async (): Promise => { const txRecipient = tx.contractAddress diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx index 47119480a0..9518b1f6fa 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx @@ -62,6 +62,7 @@ type Props = { thresholdReached: boolean tx: Transaction } +const { nativeCoin } = getNetworkInfo() const ApproveTxModal = ({ canExecute, @@ -81,7 +82,6 @@ const ApproveTxModal = ({ const { description, title } = getModalTitleAndDescription(thresholdReached, isCancelTx) const oneConfirmationLeft = !thresholdReached && tx.confirmations.size + 1 === threshold const isTheTxReadyToBeExecuted = oneConfirmationLeft ? true : thresholdReached - const { nativeCoin } = getNetworkInfo() useEffect(() => { let isCurrent = true @@ -106,7 +106,7 @@ const ApproveTxModal = ({ return () => { isCurrent = false } - }, [approveAndExecute, nativeCoin, safeAddress, tx, userAddress]) + }, [approveAndExecute, safeAddress, tx, userAddress]) const handleExecuteCheckbox = () => setApproveAndExecute((prevApproveAndExecute) => !prevApproveAndExecute) From 70cb3f37f72a7dcffd4d386a38747a552be3c6fc Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Tue, 13 Oct 2020 17:08:50 +0200 Subject: [PATCH 7/9] Delete FETCH_HEAD --- FETCH_HEAD | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 FETCH_HEAD diff --git a/FETCH_HEAD b/FETCH_HEAD deleted file mode 100644 index e69de29bb2..0000000000 From 015f7008c8565d3acc400fb10247fb431110d2f8 Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Tue, 13 Oct 2020 17:20:22 +0200 Subject: [PATCH 8/9] Fix app not running correctly Simplify tests logic --- .../AppLayout/Sidebar/SafeHeader/index.tsx | 2 +- .../utils/__tests__/tokenHelpers.test.ts | 22 +++++-------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx index 48e1c7fc7c..16a0268d1d 100644 --- a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx +++ b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx @@ -13,7 +13,7 @@ import { import FlexSpacer from 'src/components/FlexSpacer' import { getExplorerInfo, getNetworkInfo } from 'src/config' -import { NetworkSettings } from 'src/config/networks/network' +import { NetworkSettings } from 'src/config/networks/network.d' import { border, fontColor } from 'src/theme/variables' export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN' diff --git a/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts b/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts index 3686f0e112..459e82e0c8 100644 --- a/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts +++ b/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts @@ -172,39 +172,29 @@ describe('isERC721Contract', () => { expect(result).toEqual(expectedResult) expect(standardContractSpy).toHaveBeenCalled() }) - it('It should return the gas cost with right amount of decimals', () => { + it('It should return the right conversion from unit to token', () => { // given const decimals = Number(18) - const symbol = 'ETH' - const nativeCoin = { - decimals, - symbol, - } - const expectedResult = '0.0000000000000000003' - const ESTIMATED_GASCOSTS = 0.3 + const expectedResult = '0.000000003' + const ESTIMATED_GAS_COST = 3e9 // 3 Gwei // when - const gasCosts = fromTokenUnit(ESTIMATED_GASCOSTS, nativeCoin.decimals) + const gasCosts = fromTokenUnit(ESTIMATED_GAS_COST, decimals) // then expect(gasCosts).toEqual(expectedResult) }) - it('It should return the tx value as a token unit', () => { + it('It should return the right conversion from token to unit', () => { // given const decimals = Number(18) - const symbol = 'ETH' - const nativeCoin = { - decimals, - symbol, - } const expectedResult = '300000000000000000' const VALUE = 0.3 // when - const txValue = toTokenUnit(VALUE, nativeCoin.decimals) + const txValue = toTokenUnit(VALUE, decimals) // then expect(txValue).toEqual(expectedResult) From 23e85523965492145c59e455c9796fd58f37ce2b Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Tue, 13 Oct 2020 17:22:33 +0200 Subject: [PATCH 9/9] Fix await order --- src/routes/open/components/ReviewInformation/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/open/components/ReviewInformation/index.tsx b/src/routes/open/components/ReviewInformation/index.tsx index e8f1e93569..e83c786a4a 100644 --- a/src/routes/open/components/ReviewInformation/index.tsx +++ b/src/routes/open/components/ReviewInformation/index.tsx @@ -38,7 +38,7 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { return } const { nativeCoin } = getNetworkInfo() - const estimatedGasCosts = await estimateGasForDeployingSafe(addresses, numOwners, userAccount).toString() + const estimatedGasCosts = (await estimateGasForDeployingSafe(addresses, numOwners, userAccount)).toString() const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) setGasCosts(formattedGasCosts)