diff --git a/bridge_ui/src/hooks/useHandleAttest.tsx b/bridge_ui/src/hooks/useHandleAttest.tsx index baf64fad..86691d81 100644 --- a/bridge_ui/src/hooks/useHandleAttest.tsx +++ b/bridge_ui/src/hooks/useHandleAttest.tsx @@ -19,7 +19,8 @@ import { parseSequenceFromLogSolana, parseSequenceFromLogTerra, uint8ArrayToHex, - parseTargetChainFromLogEth + parseTargetChainFromLogEth, + CHAIN_ID_ETH } from "@alephium/wormhole-sdk"; import { CHAIN_ID_UNSET } from "@alephium/wormhole-sdk/lib/esm"; import { Alert } from "@material-ui/lab"; @@ -71,7 +72,7 @@ import { getSignedVAAWithRetry } from "../utils/getSignedVAAWithRetry"; import parseError from "../utils/parseError"; import { signSendAndConfirm } from "../utils/solana"; import { postWithFees, waitForTerraExecution } from "../utils/terra"; -import { attestFromEthWithoutWait } from "../utils/ethereum"; +import { attestFromEthWithoutWait, checkETHToken } from "../utils/ethereum"; import { useWallet, Wallet as AlephiumWallet } from "@alephium/web3-react"; async function algo( @@ -139,6 +140,10 @@ async function evm( ) { dispatch(setIsSending(true)); try { + if (chainId === CHAIN_ID_ETH) { + await checkETHToken(sourceAsset) + } + // Klaytn requires specifying gasPrice const overrides = chainId === CHAIN_ID_KLAYTN diff --git a/bridge_ui/src/utils/ethereum.ts b/bridge_ui/src/utils/ethereum.ts index 3876d638..be89405d 100644 --- a/bridge_ui/src/utils/ethereum.ts +++ b/bridge_ui/src/utils/ethereum.ts @@ -8,9 +8,36 @@ import { } from "../hooks/useGetSourceParsedTokenAccounts"; import { BSC_RPC_HOST, CLUSTER, ETH_RPC_HOST, getTokenBridgeAddressForChain } from "./consts"; import { Multicall, ContractCallContext } from 'ethereum-multicall'; +import axios from "axios" export const DefaultEVMChainConfirmations = 15 +interface TokenInfo { + address: string + name: string + symbol: string + decimals: number + logoURI: string +} + +let _whitelist: TokenInfo[] | undefined = undefined + +async function loadETHTokenWhitelist(): Promise { + if (_whitelist !== undefined) return _whitelist + const { data: { tokens } } = await axios.get('https://tokens.1inch.eth.link/') + _whitelist = tokens + return tokens +} + +export async function checkETHToken(tokenAddress: string) { + if (CLUSTER !== 'mainnet') return + + const tokenWhitelist = await loadETHTokenWhitelist() + if (tokenWhitelist.find((token) => token.address === tokenAddress) === undefined) { + throw new Error(`Token ${tokenAddress} does not exists in the token list`) + } +} + //This is a valuable intermediate step to the parsed token account, as the token has metadata information on it. export async function getEthereumToken( tokenAddress: string,