1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 19:26:13 +02:00

Ensure tokenAmount is always a string (#9374)

* Ensure tokenAmount is always a string

* roundExponential: add docstring, remove unnecessary cast
This commit is contained in:
Erik Marks 2020-09-08 21:58:06 -07:00 committed by GitHub
commit 707c7193e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 109 deletions

View File

@ -121,10 +121,17 @@ export function hasUnconfirmedTransactions (state) {
return unconfirmedTransactionsCountSelector(state) > 0 return unconfirmedTransactionsCountSelector(state) > 0
} }
export function roundExponential (value) { /**
* Rounds the given decimal string to 4 significant digits.
*
* @param {string} decimalString - The base-ten number to round.
* @returns {string} The rounded number, or the original number if no
* rounding was necessary.
*/
export function roundExponential (decimalString) {
const PRECISION = 4 const PRECISION = 4
const bigNumberValue = new BigNumber(String(value)) const bigNumberValue = new BigNumber(decimalString)
// In JS, numbers with exponentials greater than 20 get displayed as an exponential. // In JS, numbers with exponentials greater than 20 get displayed as an exponential.
return bigNumberValue.e > 20 ? Number(bigNumberValue.toPrecision(PRECISION)) : value return bigNumberValue.e > 20 ? bigNumberValue.toPrecision(PRECISION) : decimalString
} }

View File

@ -7,7 +7,7 @@ export default class ConfirmSendToken extends Component {
static propTypes = { static propTypes = {
history: PropTypes.object, history: PropTypes.object,
editTransaction: PropTypes.func, editTransaction: PropTypes.func,
tokenAmount: PropTypes.number, tokenAmount: PropTypes.string,
} }
handleEdit (confirmTransactionData) { handleEdit (confirmTransactionData) {

View File

@ -150,68 +150,15 @@ export const tokenAddressSelector = createSelector(
(txParams) => txParams && txParams.to, (txParams) => txParams && txParams.to,
) )
const TOKEN_PARAM_SPENDER = '_spender'
const TOKEN_PARAM_TO = '_to' const TOKEN_PARAM_TO = '_to'
const TOKEN_PARAM_VALUE = '_value' const TOKEN_PARAM_VALUE = '_value'
export const tokenAmountAndToAddressSelector = createSelector(
tokenDataArgsSelector,
tokenDecimalsSelector,
(args, tokenDecimals) => {
let toAddress = ''
let tokenAmount = 0
if (args && args.length) {
const toParam = args[TOKEN_PARAM_TO]
const valueParam = args[TOKEN_PARAM_VALUE]
toAddress = toParam || args[0]
const value = valueParam ? valueParam.toString() : args[1].toString()
if (tokenDecimals) {
tokenAmount = calcTokenAmount(value, tokenDecimals).toString()
}
tokenAmount = roundExponential(tokenAmount)
}
return {
toAddress,
tokenAmount,
}
},
)
export const approveTokenAmountAndToAddressSelector = createSelector(
tokenDataArgsSelector,
tokenDecimalsSelector,
(args, tokenDecimals) => {
let toAddress = ''
let tokenAmount = 0
if (args && args.length) {
toAddress = args[TOKEN_PARAM_SPENDER]
const value = args[TOKEN_PARAM_VALUE].toString()
if (tokenDecimals) {
tokenAmount = calcTokenAmount(value, tokenDecimals).toString()
}
tokenAmount = roundExponential(tokenAmount)
}
return {
toAddress,
tokenAmount,
}
},
)
export const sendTokenTokenAmountAndToAddressSelector = createSelector( export const sendTokenTokenAmountAndToAddressSelector = createSelector(
tokenDataArgsSelector, tokenDataArgsSelector,
tokenDecimalsSelector, tokenDecimalsSelector,
(args, tokenDecimals) => { (args, tokenDecimals) => {
let toAddress = '' let toAddress = ''
let tokenAmount = 0 let tokenAmount = '0'
if (args && args.length) { if (args && args.length) {
toAddress = args[TOKEN_PARAM_TO] toAddress = args[TOKEN_PARAM_TO]

View File

@ -1,8 +1,6 @@
import assert from 'assert' import assert from 'assert'
import { import {
unconfirmedTransactionsCountSelector, unconfirmedTransactionsCountSelector,
tokenAmountAndToAddressSelector,
approveTokenAmountAndToAddressSelector,
sendTokenTokenAmountAndToAddressSelector, sendTokenTokenAmountAndToAddressSelector,
contractExchangeRateSelector, contractExchangeRateSelector,
conversionRateSelector, conversionRateSelector,
@ -43,54 +41,6 @@ describe('Confirm Transaction Selector', function () {
}) })
}) })
describe('tokenAmountAndToAddressSelector', function () {
const state = {
confirmTransaction: {
tokenData: {
name: 'transfer',
args: getEthersArrayLikeFromObj({
'_to': '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
'_value': { toString: () => '1' },
}),
},
tokenProps: {
tokenDecimals: '2',
tokenSymbol: 'META',
},
},
}
it('returns calculated token amount based on token value and token decimals and recipient address', function () {
assert.deepEqual(tokenAmountAndToAddressSelector(state),
{ toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: 0.01 })
})
})
describe('approveTokenAmountAndToAddressSelector', function () {
const state = {
confirmTransaction: {
tokenData: {
name: 'approve',
args: getEthersArrayLikeFromObj({
'_spender': '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
'_value': { toString: () => '1' },
}),
},
tokenProps: {
tokenDecimals: '2',
tokenSymbol: 'META',
},
},
}
it('returns token amount and recipient for approve token allocation spending', function () {
assert.deepEqual(approveTokenAmountAndToAddressSelector(state),
{ toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: 0.01 })
})
})
describe('sendTokenTokenAmountAndToAddressSelector', function () { describe('sendTokenTokenAmountAndToAddressSelector', function () {
const state = { const state = {
@ -111,7 +61,7 @@ describe('Confirm Transaction Selector', function () {
it('returns token address and calculated token amount', function () { it('returns token address and calculated token amount', function () {
assert.deepEqual(sendTokenTokenAmountAndToAddressSelector(state), assert.deepEqual(sendTokenTokenAmountAndToAddressSelector(state),
{ toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: 0.01 }) { toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: '0.01' })
}) })
}) })