Skip to content

Commit c042e2b

Browse files
vrtnd0xngmi
andauthored
Mark multichain tokens (LlamaSwap#217)
* Mark multichain tokens * add more warnings --------- Co-authored-by: 0xngmi <0xngmi@protonmail.com>
1 parent 71dd583 commit c042e2b

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

src/components/Aggregator/router.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import { adapters } from './list';
55
export const adaptersNames = adapters.map(({ name }) => name);
66

77
const adaptersMap = adapters.reduce((acc, adapter) => ({ ...acc, [adapter.name]: adapter }), {});
8-
const delistedChains = ['fantom'];
98

109
export function getAllChains() {
1110
const chains = new Set<string>();
1211
for (const adapter of adapters) {
1312
Object.keys(adapter.chainToId).forEach((chain) => chains.add(chain));
1413
}
15-
const chainsArr = Array.from(chains).filter((c) => !delistedChains.includes(c));
14+
const chainsArr = Array.from(chains);
1615

1716
const chainsOptions = chainsArr.map((c) => {
1817
const chain = allChains.find(({ id }) => id === chainsMap[c]);

src/components/InputAmountAndTokenSelect/TokenSelect.tsx

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ethers } from 'ethers';
22
import { useMemo, useRef, useState } from 'react';
33
import { useVirtualizer } from '@tanstack/react-virtual';
44
import { Modal, ModalOverlay, ModalContent, ModalCloseButton, useDisclosure, Input } from '@chakra-ui/react';
5-
import { QuestionIcon, WarningTwoIcon } from '@chakra-ui/icons';
5+
import { WarningTwoIcon } from '@chakra-ui/icons';
66
import { Header, IconImage, PairRow } from '../Aggregator/Search';
77
import { useToken } from 'wagmi';
88
import { Button, Flex, Text, Tooltip } from '@chakra-ui/react';
@@ -15,7 +15,7 @@ import { ChevronDown } from 'react-feather';
1515

1616
const Row = ({ chain, token, onClick }) => {
1717
const blockExplorer = allChains.find((c) => c.id == chain.id)?.blockExplorers?.default;
18-
18+
const isMultichain = token.isMultichain;
1919
return (
2020
<PairRow
2121
key={token.value}
@@ -25,12 +25,23 @@ const Row = ({ chain, token, onClick }) => {
2525
<IconImage src={token.logoURI} onError={(e) => (e.currentTarget.src = token.logoURI2 || '/placeholder.png')} />
2626

2727
<Text display="flex" flexDir="column" whiteSpace="nowrap" textOverflow="ellipsis" overflow="hidden">
28-
<Text
29-
as="span"
30-
whiteSpace="nowrap"
31-
textOverflow="ellipsis"
32-
overflow="hidden"
33-
>{`${token.name} (${token.symbol})`}</Text>
28+
<Tooltip
29+
label="This token could have been affected by the multichain hack."
30+
bg="black"
31+
color="white"
32+
isDisabled={!isMultichain}
33+
>
34+
<Text
35+
as="span"
36+
whiteSpace="nowrap"
37+
textOverflow="ellipsis"
38+
overflow="hidden"
39+
color={isMultichain ? 'orange.200' : 'white'}
40+
>
41+
{`${token.name} (${token.symbol})`}
42+
{token.isMultichain ? <WarningTwoIcon color={'orange.200'} style={{ marginLeft: '0.4em' }} /> : null}
43+
</Text>
44+
</Tooltip>
3445

3546
{token.isGeckoToken && (
3647
<>
@@ -300,6 +311,15 @@ export const TokenSelect = ({ tokens, onClick, token, selectedChain }) => {
300311
/>
301312
)}
302313

314+
<Tooltip
315+
label="This token could have been affected by the multichain hack."
316+
bg="black"
317+
color="white"
318+
isDisabled={!token?.isMultichain}
319+
>
320+
{token?.isMultichain ? <WarningTwoIcon color={'orange.200'} /> : <></>}
321+
</Tooltip>
322+
303323
<Text as="span" color="white" overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" fontWeight={400}>
304324
{token ? token.symbol : 'Select Token'}
305325
</Text>

src/props/getTokenList.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const tokensToRemove = {
1313
}
1414
};
1515

16+
const FANTOM_ID = 250;
17+
1618
const oneInchChains = {
1719
ethereum: 1,
1820
bsc: 56,
@@ -46,6 +48,25 @@ const fixTotkens = (tokenlist) => {
4648
return tokenlist;
4749
};
4850

51+
const markMultichain = async (tokens) => {
52+
const multichainList = await fetch(`https://bridgeapi.multichain.org/v4/tokenlistv4/${FANTOM_ID}`)
53+
.then((r) => r.json())
54+
.then((r) => Object.values(r));
55+
56+
tokens[FANTOM_ID] = tokens[FANTOM_ID].map((token) => {
57+
const isMultichain = !!multichainList.find(
58+
(multitoken: IToken) => multitoken.address?.toLowerCase() === token.address.toLowerCase()
59+
);
60+
61+
return {
62+
...token,
63+
isMultichain
64+
};
65+
});
66+
67+
return tokens;
68+
};
69+
4970
export async function getTokenList() {
5071
// const uniList = await fetch('https://tokens.uniswap.org/').then((r) => r.json());
5172
// const sushiList = await fetch('https://token-list.sushi.com/').then((r) => r.json());
@@ -55,6 +76,7 @@ export async function getTokenList() {
5576
fetch(`https://tokens.1inch.io/v1.1/${chainId}`).then((r) => r.json())
5677
)
5778
);
79+
5880
// const hecoList = await fetch('https://token-list.sushi.com/').then((r) => r.json()); // same as sushi
5981
// const lifiList = await fetch('https://li.quest/v1/tokens').then((r) => r.json());
6082

@@ -106,6 +128,8 @@ export async function getTokenList() {
106128

107129
tokensFiltered = fixTotkens(tokensFiltered);
108130

131+
tokensFiltered = await markMultichain(tokensFiltered);
132+
109133
// get top tokens on each chain
110134
const topTokensByChain = await Promise.allSettled(
111135
Object.keys(tokensFiltered).map((chain) => getTopTokensByChain(chain))

0 commit comments

Comments
 (0)