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:
parent
1ac13c63dd
commit
b0849ee97f
|
@ -12,8 +12,7 @@ import { fetchTokenList } from '~/logic/tokens/api'
|
||||||
import { type TokenProps, makeToken } from '~/logic/tokens/store/model/token'
|
import { type TokenProps, makeToken } from '~/logic/tokens/store/model/token'
|
||||||
import { tokensSelector } from '~/logic/tokens/store/selectors'
|
import { tokensSelector } from '~/logic/tokens/store/selectors'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { type GlobalState } from '~/store'
|
import { type GlobalState, store } from '~/store'
|
||||||
import { store } from '~/store/index'
|
|
||||||
import { ensureOnce } from '~/utils/singleton'
|
import { ensureOnce } from '~/utils/singleton'
|
||||||
|
|
||||||
const createStandardTokenContract = async () => {
|
const createStandardTokenContract = async () => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import ERC20Detailed from '@openzeppelin/contracts/build/contracts/ERC20Detailed.json'
|
||||||
import { List } from 'immutable'
|
import { List } from 'immutable'
|
||||||
|
|
||||||
import logo from '~/assets/icons/icon_etherTokens.svg'
|
import logo from '~/assets/icons/icon_etherTokens.svg'
|
||||||
|
@ -56,6 +57,17 @@ export const isAddressAToken = async (tokenAddress: string) => {
|
||||||
return call !== '0x'
|
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 =>
|
export const isTokenTransfer = (data: string, value: number): boolean =>
|
||||||
!!data && data.substring(0, 10) === '0xa9059cbb' && value === 0
|
!!data && data.substring(0, 10) === '0xa9059cbb' && value === 0
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ import { getLocalSafe } from '~/logic/safe/utils'
|
||||||
import { getTokenInfos } from '~/logic/tokens/store/actions/fetchTokens'
|
import { getTokenInfos } from '~/logic/tokens/store/actions/fetchTokens'
|
||||||
import { ALTERNATIVE_TOKEN_ABI } from '~/logic/tokens/utils/alternativeAbi'
|
import { ALTERNATIVE_TOKEN_ABI } from '~/logic/tokens/utils/alternativeAbi'
|
||||||
import {
|
import {
|
||||||
DECIMALS_METHOD_HASH,
|
|
||||||
SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH,
|
SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH,
|
||||||
|
hasDecimalsMethod,
|
||||||
isMultisendTransaction,
|
isMultisendTransaction,
|
||||||
isTokenTransfer,
|
isTokenTransfer,
|
||||||
isUpgradeTransaction,
|
isUpgradeTransaction,
|
||||||
|
@ -102,7 +102,7 @@ export const buildTransactionFrom = async (safeAddress: string, tx: TxServiceMod
|
||||||
const code = tx.to ? await web3.eth.getCode(tx.to) : ''
|
const code = tx.to ? await web3.eth.getCode(tx.to) : ''
|
||||||
const isERC721Token =
|
const isERC721Token =
|
||||||
code.includes(SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH) ||
|
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 isSendTokenTx = !isERC721Token && isTokenTransfer(tx.data, Number(tx.value))
|
||||||
const isMultiSendTx = isMultisendTransaction(tx.data, Number(tx.value))
|
const isMultiSendTx = isMultisendTransaction(tx.data, Number(tx.value))
|
||||||
const isUpgradeTx = isMultiSendTx && isUpgradeTransaction(tx.data)
|
const isUpgradeTx = isMultiSendTx && isUpgradeTransaction(tx.data)
|
||||||
|
|
Loading…
Reference in New Issue