fix: check for `decimals` method in transferredTokens (#748)

Previously we were looking for `decimals` hash in the contract `code`.
There are some contracts like USDC who happen to be behind a FiatTokenProxy, making it upgradable.
By directly calling the `decimals()` method, we interact with the contract and can be sure that the `decimals()` method is present.

fixes #678
This commit is contained in:
Fernando 2020-04-09 05:45:29 -03:00 committed by GitHub
parent 1ac13c63dd
commit b0849ee97f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 716 additions and 29 deletions

View File

@ -12,8 +12,7 @@ import { fetchTokenList } from '~/logic/tokens/api'
import { type TokenProps, makeToken } from '~/logic/tokens/store/model/token'
import { tokensSelector } from '~/logic/tokens/store/selectors'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { type GlobalState } from '~/store'
import { store } from '~/store/index'
import { type GlobalState, store } from '~/store'
import { ensureOnce } from '~/utils/singleton'
const createStandardTokenContract = async () => {

View File

@ -1,4 +1,5 @@
// @flow
import ERC20Detailed from '@openzeppelin/contracts/build/contracts/ERC20Detailed.json'
import { List } from 'immutable'
import logo from '~/assets/icons/icon_etherTokens.svg'
@ -56,6 +57,17 @@ export const isAddressAToken = async (tokenAddress: string) => {
return call !== '0x'
}
export const hasDecimalsMethod = async (address: string): Promise<boolean> => {
try {
const web3 = getWeb3()
const token = new web3.eth.Contract(ERC20Detailed.abi, address)
await token.methods.decimals().call()
return true
} catch (e) {
return false
}
}
export const isTokenTransfer = (data: string, value: number): boolean =>
!!data && data.substring(0, 10) === '0xa9059cbb' && value === 0

View File

@ -15,8 +15,8 @@ import { getLocalSafe } from '~/logic/safe/utils'
import { getTokenInfos } from '~/logic/tokens/store/actions/fetchTokens'
import { ALTERNATIVE_TOKEN_ABI } from '~/logic/tokens/utils/alternativeAbi'
import {
DECIMALS_METHOD_HASH,
SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH,
hasDecimalsMethod,
isMultisendTransaction,
isTokenTransfer,
isUpgradeTransaction,
@ -102,7 +102,7 @@ export const buildTransactionFrom = async (safeAddress: string, tx: TxServiceMod
const code = tx.to ? await web3.eth.getCode(tx.to) : ''
const isERC721Token =
code.includes(SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH) ||
(isTokenTransfer(tx.data, Number(tx.value)) && !code.includes(DECIMALS_METHOD_HASH))
(isTokenTransfer(tx.data, Number(tx.value)) && !(await hasDecimalsMethod(tx.to)))
const isSendTokenTx = !isERC721Token && isTokenTransfer(tx.data, Number(tx.value))
const isMultiSendTx = isMultisendTransaction(tx.data, Number(tx.value))
const isUpgradeTx = isMultiSendTx && isUpgradeTransaction(tx.data)

726
yarn.lock

File diff suppressed because it is too large Load Diff