diff --git a/.env b/.env index 37116069b..97e18576a 100644 --- a/.env +++ b/.env @@ -12,7 +12,7 @@ REACT_APP_TX_GRAPH_API_URL="https://api.thegraph.com/subgraphs/name/sameepsi/qui REACT_APP_PRDT_URL="https://prdt-quickswap-main.pages.dev/" REACT_APP_SCAN_BASE_URL="https://polygonscan.com" REACT_APP_TOKEN_LIST_DEFAULT_URL="https://unpkg.com/quickswap-default-token-list@latest/build/quickswap-default.tokenlist.json" -REACT_APP_STAKING_LIST_DEFAULT_URL="https://unpkg.com/quickswap-default-staking-list@latest/build/quickswap-default.lpfarms.json" -REACT_APP_DUAL_STAKING_LIST_DEFAULT_URL="https://unpkg.com/quickswap-default-staking-list@latest/build/quickswap-default.dualfarms.json" -REACT_APP_SYRUP_LIST_DEFAULT_URL="https://unpkg.com/quickswap-default-staking-list@latest/build/quickswap-default.syrups.json" +REACT_APP_STAKING_LIST_DEFAULT_URL="https://unpkg.com/quickswap-default-staking-list-address@latest/build/quickswap-default.lpfarms.json" +REACT_APP_DUAL_STAKING_LIST_DEFAULT_URL="https://unpkg.com/quickswap-default-staking-list-address@latest/build/quickswap-default.dualfarms.json" +REACT_APP_SYRUP_LIST_DEFAULT_URL="https://unpkg.com/quickswap-default-staking-list-address@latest/build/quickswap-default.syrups.json" REACT_APP_LEGACY_APP_URL="https://legacy.quickswap.exchange" \ No newline at end of file diff --git a/src/components/FarmCard/FarmCardDetails.tsx b/src/components/FarmCard/FarmCardDetails.tsx index 1da29ee4e..9592d7839 100644 --- a/src/components/FarmCard/FarmCardDetails.tsx +++ b/src/components/FarmCard/FarmCardDetails.tsx @@ -277,11 +277,13 @@ const FarmCardDetails: React.FC<{ ${(isLPFarm ? lpRewards : dualRewards).toLocaleString()} / {t('day')} +
{isLPFarm ? ( {lpPoolRate} ) : ( <> {dualPoolRateA} +
{dualPoolRateB} )} @@ -299,7 +301,7 @@ const FarmCardDetails: React.FC<{ )} {!stakingInfo.ended && ( - + {t('inwallet')}: diff --git a/src/components/RewardSlider/RewardSlider.tsx b/src/components/RewardSlider/RewardSlider.tsx index ee1b912b5..46dc21b8c 100755 --- a/src/components/RewardSlider/RewardSlider.tsx +++ b/src/components/RewardSlider/RewardSlider.tsx @@ -25,15 +25,21 @@ const RewardSlider: React.FC = () => { const dualrewardItems = useDualStakingInfo(defaultChainId, null, 0, 1); const [bulkPairs, setBulkPairs] = useState(null); - const stakingPairLists = useMemo(() => { + const stakingPairListStr = useMemo(() => { return lprewardItems .map((item) => item.pair) - .concat(dualrewardItems.map((item) => item.pair)); + .concat(dualrewardItems.map((item) => item.pair)) + .join(','); }, [dualrewardItems, lprewardItems]); + const stakingPairLists = stakingPairListStr.split(','); + useEffect(() => { - getBulkPairData(stakingPairLists).then((data) => setBulkPairs(data)); - }, [stakingPairLists]); + const stakingPairLists = stakingPairListStr.split(','); + if (stakingPairListStr) { + getBulkPairData(stakingPairLists).then((data) => setBulkPairs(data)); + } + }, [stakingPairListStr]); const stakingAPYs = useMemo(() => { if (bulkPairs && stakingPairLists.length > 0) { diff --git a/src/components/SyrupCard/SyrupCardDetails.tsx b/src/components/SyrupCard/SyrupCardDetails.tsx index 64caa8560..e509f1dab 100755 --- a/src/components/SyrupCard/SyrupCardDetails.tsx +++ b/src/components/SyrupCard/SyrupCardDetails.tsx @@ -155,16 +155,16 @@ const SyrupCardDetails: React.FC<{ syrup: SyrupInfo; dQUICKAPY: string }> = ({ {syrup && ( <> - + {isMobile && ( - - + + {syrup.stakingToken.symbol} {t('deposits')}: {depositAmount} - + {t('dailyRewards')}: {syrup.rate >= 1000000 @@ -174,10 +174,10 @@ const SyrupCardDetails: React.FC<{ syrup: SyrupInfo; dQUICKAPY: string }> = ({ / {t('day')} - + - + {t('apr')}: @@ -191,7 +191,7 @@ const SyrupCardDetails: React.FC<{ syrup: SyrupInfo; dQUICKAPY: string }> = ({ )} - + {t('inwallet')} {userLiquidityUnstaked @@ -209,7 +209,7 @@ const SyrupCardDetails: React.FC<{ syrup: SyrupInfo; dQUICKAPY: string }> = ({ - + {t('staked')} {formatTokenAmount(syrup.stakedAmount)}{' '} diff --git a/src/components/SyrupCard/SyrupTimerLabel.tsx b/src/components/SyrupCard/SyrupTimerLabel.tsx index 4e6719685..02f8fe190 100644 --- a/src/components/SyrupCard/SyrupTimerLabel.tsx +++ b/src/components/SyrupCard/SyrupTimerLabel.tsx @@ -41,7 +41,7 @@ const SyrupTimerLabel: React.FC<{ exactEnd: number; isEnded: boolean }> = ({ {!isEnded && Number.isFinite(timeRemaining) && (

diff --git a/src/components/styles/FarmCard.scss b/src/components/styles/FarmCard.scss index 35fa1f941..557ca7642 100644 --- a/src/components/styles/FarmCard.scss +++ b/src/components/styles/FarmCard.scss @@ -126,7 +126,7 @@ align-items: center; } .farmCardMobileRow { - margin-top: 16px; + margin-bottom: 16px; width: 100%; display: flex; justify-content: space-between; diff --git a/src/components/styles/SyrupCard.scss b/src/components/styles/SyrupCard.scss index 65960cf94..857b92428 100644 --- a/src/components/styles/SyrupCard.scss +++ b/src/components/styles/SyrupCard.scss @@ -9,6 +9,9 @@ & .dailyRateWrapper { margin-bottom: 0; margin-top: 16px; + @include media("screen", " = ({ children, name }) => { return ( - + {openPassModal && }

{!isProMode && } diff --git a/src/pages/FarmPage/FarmsList.tsx b/src/pages/FarmPage/FarmsList.tsx index 6eb76540b..99a771f21 100644 --- a/src/pages/FarmPage/FarmsList.tsx +++ b/src/pages/FarmPage/FarmsList.tsx @@ -48,7 +48,6 @@ const FarmsList: React.FC = ({ bulkPairs, farmIndex }) => { const isMobile = useMediaQuery(breakpoints.down('xs')); const { chainId } = useActiveWeb3React(); const [pageIndex, setPageIndex] = useState(0); - const [pageloading, setPageLoading] = useState(false); //this is used for not loading farms immediately when user is on farms page const [isEndedFarm, setIsEndedFarm] = useState(false); const [sortBy, setSortBy] = useState(0); const [sortDesc, setSortDesc] = useState(false); @@ -64,14 +63,10 @@ const FarmsList: React.FC = ({ bulkPairs, farmIndex }) => { const addedLPStakingInfos = useStakingInfo( chainIdOrDefault, null, - pageloading || - farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || - isEndedFarm + farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || isEndedFarm ? 0 : undefined, - pageloading || - farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || - isEndedFarm + farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || isEndedFarm ? 0 : undefined, { search: farmSearch, isStaked: stakedOnly }, @@ -79,14 +74,10 @@ const FarmsList: React.FC = ({ bulkPairs, farmIndex }) => { const addedLPStakingOldInfos = useOldStakingInfo( chainIdOrDefault, null, - pageloading || - farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || - !isEndedFarm + farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || !isEndedFarm ? 0 : undefined, - pageloading || - farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || - !isEndedFarm + farmIndex === GlobalConst.farmIndex.DUALFARM_INDEX || !isEndedFarm ? 0 : undefined, { search: farmSearch, isStaked: stakedOnly }, @@ -94,13 +85,9 @@ const FarmsList: React.FC = ({ bulkPairs, farmIndex }) => { const addedDualStakingInfos = useDualStakingInfo( chainIdOrDefault, null, - pageloading || farmIndex === GlobalConst.farmIndex.LPFARM_INDEX - ? 0 - : undefined, - pageloading || farmIndex === GlobalConst.farmIndex.LPFARM_INDEX - ? 0 - : undefined, - { search: farmSearch, isStaked: stakedOnly }, + farmIndex === GlobalConst.farmIndex.LPFARM_INDEX ? 0 : undefined, + farmIndex === GlobalConst.farmIndex.LPFARM_INDEX ? 0 : undefined, + { search: farmSearch, isStaked: stakedOnly, isEndedFarm }, ); const sortIndex = sortDesc ? 1 : -1; diff --git a/src/state/dualfarms/hooks.ts b/src/state/dualfarms/hooks.ts index fdad2d351..5f455a8f8 100644 --- a/src/state/dualfarms/hooks.ts +++ b/src/state/dualfarms/hooks.ts @@ -4,8 +4,10 @@ import { useSelector } from 'react-redux'; import { AppState } from 'state'; import { DualFarmListInfo, DualStakingRaw, DualStakingBasic } from 'types'; import { Token } from '@uniswap/sdk'; -import { getTokenFromKey } from 'utils'; +import { getTokenFromAddress } from 'utils'; import { TokenAddressMap, useSelectedTokenList } from 'state/lists/hooks'; +import { useTokens } from 'hooks/Tokens'; +import { GlobalValue } from 'constants/index'; export class WrappedDualFarmInfo implements DualStakingBasic { public readonly stakingInfo: DualStakingRaw; @@ -23,10 +25,15 @@ export class WrappedDualFarmInfo implements DualStakingBasic { public readonly rateA: number; public readonly rateB: number; - constructor(stakingInfo: DualStakingRaw, tokenAddressMap: TokenAddressMap) { + constructor( + stakingInfo: DualStakingRaw, + tokenAddressMap: TokenAddressMap, + dualFarmTokens: Token[], + chainId: ChainId, + ) { this.stakingInfo = stakingInfo; //TODO: Support Multichain - this.chainId = ChainId.MATIC; + this.chainId = chainId; this.stakingRewardAddress = stakingInfo.stakingRewardAddress; this.ended = stakingInfo.ended; this.pair = stakingInfo.pair; @@ -34,24 +41,45 @@ export class WrappedDualFarmInfo implements DualStakingBasic { this.name = stakingInfo.name; this.rateA = stakingInfo.rateA; this.rateB = stakingInfo.rateB; - //TODO: we should be resolving the following property from the lists state using the address field instead of the key - this.baseToken = getTokenFromKey(stakingInfo.baseToken, tokenAddressMap); + + this.baseToken = getTokenFromAddress( + stakingInfo.baseToken, + chainId, + tokenAddressMap, + dualFarmTokens, + ); this.tokens = [ - getTokenFromKey(stakingInfo.tokens[0], tokenAddressMap), - getTokenFromKey(stakingInfo.tokens[1], tokenAddressMap), + getTokenFromAddress( + stakingInfo.tokens[0], + chainId, + tokenAddressMap, + dualFarmTokens, + ), + getTokenFromAddress( + stakingInfo.tokens[1], + chainId, + tokenAddressMap, + dualFarmTokens, + ), ]; - this.rewardTokenA = getTokenFromKey( + this.rewardTokenA = getTokenFromAddress( stakingInfo.rewardTokenA, + chainId, tokenAddressMap, + dualFarmTokens, ); - this.rewardTokenB = getTokenFromKey( + this.rewardTokenB = getTokenFromAddress( stakingInfo.rewardTokenB, + chainId, tokenAddressMap, + dualFarmTokens, ); - this.rewardTokenBBase = getTokenFromKey( + this.rewardTokenBBase = getTokenFromAddress( stakingInfo.rewardTokenBBase, + chainId, tokenAddressMap, + dualFarmTokens, ); } } @@ -80,6 +108,7 @@ const dualFarmCache: WeakMap | null = export function listToDualFarmMap( list: DualFarmListInfo, tokenAddressMap: TokenAddressMap, + dualFarmTokens: Token[], ): DualFarmInfoAddressMap { const result = dualFarmCache?.get(list); if (result) return result; @@ -89,6 +118,8 @@ export function listToDualFarmMap( const wrappedStakingInfo = new WrappedDualFarmInfo( stakingInfo, tokenAddressMap, + dualFarmTokens, + ChainId.MATIC, ); if ( stakingInfoMap[wrappedStakingInfo.chainId][ @@ -117,17 +148,51 @@ export function useDualFarmList( (state) => state.dualFarms.byUrl, ); const tokenMap = useSelectedTokenList(); + const current = url ? dualFarms[url]?.current : null; + const dualTokenAddresses = + current && tokenMap + ? current.active + .concat(current.closed) + .map((item) => [ + item.baseToken, + item.tokens[0], + item.tokens[1], + item.rewardTokenA, + item.rewardTokenB, + item.rewardTokenBBase, + ]) + .flat() + .filter((item) => !!item) + .filter((address) => !tokenMap[ChainId.MATIC][address]) + .filter( + (address) => + !Object.values(GlobalValue.tokens.COMMON).find( + (token) => + token.address.toLowerCase() === address.toLowerCase(), + ), + ) + .filter( + (address, ind, self) => + self.findIndex( + (addr) => address.toLowerCase() === addr.toLowerCase(), + ) === ind, + ) + : []; + const dualFarmTokens = useTokens(dualTokenAddresses); return useMemo(() => { - if (!url) return EMPTY_LIST; - const current = dualFarms[url]?.current; - if (!current) return EMPTY_LIST; + if ( + !current || + !tokenMap || + dualFarmTokens?.length !== dualTokenAddresses.length + ) + return EMPTY_LIST; try { - return listToDualFarmMap(current, tokenMap); + return listToDualFarmMap(current, tokenMap, dualFarmTokens ?? []); } catch (error) { console.error('Could not show token list due to error', error); return EMPTY_LIST; } - }, [dualFarms, url, tokenMap]); + }, [current, dualFarmTokens, dualTokenAddresses.length, tokenMap]); } export function useDefaultDualFarmList(): DualFarmInfoAddressMap { diff --git a/src/state/farms/hooks.ts b/src/state/farms/hooks.ts index 3ef603189..3cd4980de 100644 --- a/src/state/farms/hooks.ts +++ b/src/state/farms/hooks.ts @@ -5,7 +5,9 @@ import { AppState } from 'state'; import { FarmListInfo, StakingRaw, StakingBasic } from 'types'; import { Token } from '@uniswap/sdk'; import { TokenAddressMap, useSelectedTokenList } from 'state/lists/hooks'; -import { getTokenFromKey } from 'utils'; +import { getTokenFromAddress } from 'utils'; +import { useTokens } from 'hooks/Tokens'; +import { GlobalValue } from 'constants/index'; export class WrappedStakingInfo implements StakingBasic { public readonly stakingInfo: StakingRaw; @@ -20,26 +22,50 @@ export class WrappedStakingInfo implements StakingBasic { public readonly baseToken: Token; public readonly rewardToken: Token; - constructor(stakingInfo: StakingRaw, tokenAddressMap: TokenAddressMap) { + constructor( + stakingInfo: StakingRaw, + tokenAddressMap: TokenAddressMap, + farmTokens: Token[], + chainId: ChainId, + ) { this.stakingInfo = stakingInfo; //TODO: Support Multichain - this.chainId = ChainId.MATIC; + this.chainId = chainId; this.stakingRewardAddress = stakingInfo.stakingRewardAddress; this.rate = stakingInfo.rate; this.ended = stakingInfo.ended; this.pair = stakingInfo.pair; this.lp = stakingInfo.lp; this.name = stakingInfo.name; - //TODO: we should be resolving the following property from the lists state using the address field instead of the key - this.baseToken = getTokenFromKey(stakingInfo.baseToken, tokenAddressMap); - this.tokens = [ - getTokenFromKey(stakingInfo.tokens[0], tokenAddressMap), - getTokenFromKey(stakingInfo.tokens[1], tokenAddressMap), - ]; - this.rewardToken = getTokenFromKey( - stakingInfo.rewardToken ?? 'DQUICK', + + this.baseToken = getTokenFromAddress( + stakingInfo.baseToken, + chainId, tokenAddressMap, + farmTokens, ); + this.tokens = [ + getTokenFromAddress( + stakingInfo.tokens[0], + chainId, + tokenAddressMap, + farmTokens, + ), + getTokenFromAddress( + stakingInfo.tokens[1], + chainId, + tokenAddressMap, + farmTokens, + ), + ]; + this.rewardToken = stakingInfo.rewardToken + ? getTokenFromAddress( + stakingInfo.rewardToken, + chainId, + tokenAddressMap, + farmTokens, + ) + : GlobalValue.tokens.COMMON.OLD_DQUICK; } } @@ -67,6 +93,7 @@ const farmCache: WeakMap | null = export function listToFarmMap( list: FarmListInfo, tokenAddressMap: TokenAddressMap, + farmTokens: Token[], ): StakingInfoAddressMap { const result = farmCache?.get(list); if (result) return result; @@ -76,6 +103,8 @@ export function listToFarmMap( const wrappedStakingInfo = new WrappedStakingInfo( stakingInfo, tokenAddressMap, + farmTokens, + ChainId.MATIC, ); if ( stakingInfoMap[wrappedStakingInfo.chainId][ @@ -103,17 +132,52 @@ export function useFarmList(url: string | undefined): StakingInfoAddressMap { ); const tokenMap = useSelectedTokenList(); + const current = url ? farms[url]?.current : null; + const farmTokenAddresses = + current && tokenMap + ? current.active + .concat(current.closed) + .map((item) => [ + item.baseToken, + item.tokens[0], + item.tokens[1], + item.rewardToken, + ]) + .flat() + .filter((item) => !!item) + .filter((address) => !tokenMap[ChainId.MATIC][address]) + .filter( + (address) => + !Object.values(GlobalValue.tokens.COMMON).find( + (token) => + token.address.toLowerCase() === address.toLowerCase(), + ), + ) + .filter( + (addr, ind, self) => + self.findIndex( + (address) => address.toLowerCase() === addr.toLowerCase(), + ) === ind, + ) + : []; + + console.log('bbb', farmTokenAddresses); + + const farmTokens = useTokens(farmTokenAddresses); return useMemo(() => { - if (!url) return EMPTY_LIST; - const current = farms[url]?.current; - if (!current) return EMPTY_LIST; + if ( + !current || + !tokenMap || + farmTokens?.length !== farmTokenAddresses.length + ) + return EMPTY_LIST; try { - return listToFarmMap(current, tokenMap); + return listToFarmMap(current, tokenMap, farmTokens ?? []); } catch (error) { console.error('Could not show token list due to error', error); return EMPTY_LIST; } - }, [farms, url, tokenMap]); + }, [current, farmTokens, farmTokenAddresses.length, tokenMap]); } export function useDefaultFarmList(): StakingInfoAddressMap { diff --git a/src/state/stake/hooks.ts b/src/state/stake/hooks.ts index 2f81012e8..89ca1f8f0 100755 --- a/src/state/stake/hooks.ts +++ b/src/state/stake/hooks.ts @@ -805,7 +805,7 @@ export function useDualStakingInfo( pairToFilterBy?: Pair | null, startIndex?: number, endIndex?: number, - filter?: { search: string; isStaked: boolean }, + filter?: { search: string; isStaked: boolean; isEndedFarm: boolean }, ): DualStakingInfo[] { const { account } = useActiveWeb3React(); const dualStakingRewardsInfo = useDefaultDualFarmList(); @@ -813,7 +813,7 @@ export function useDualStakingInfo( const info = useMemo( () => Object.values(dualStakingRewardsInfo[chainId]) - .filter((x) => !x.ended) + .filter((x) => (filter?.isEndedFarm ? x.ended : !x.ended)) .slice(startIndex, endIndex) .filter((stakingRewardInfo) => pairToFilterBy === undefined || pairToFilterBy === null @@ -944,11 +944,11 @@ export function useDualStakingInfo( const dummyToken = GlobalValue.tokens.COMMON.NEW_QUICK; const totalRewardRateA = new TokenAmount( dummyToken, - JSBI.BigInt(rateA), + JSBI.BigInt(stakingInfo.ended ? 0 : rateA), ); const totalRewardRateB = new TokenAmount( dummyToken, - JSBI.BigInt(rateB), + JSBI.BigInt(stakingInfo.ended ? 0 : rateB), ); //const pair = info[index].pair.toLowerCase(); //const fees = (pairData && pairData[pair] ? pairData[pair].oneDayVolumeUSD * 0.0025: 0); @@ -1049,15 +1049,17 @@ export function useDualStakingInfo( rewardTokenA: stakingInfo.rewardTokenA, rewardTokenB: stakingInfo.rewardTokenB, rewardTokenBBase: stakingInfo.rewardTokenBBase, - rewardTokenAPrice, - rewardTokenBPrice, + rewardTokenAPrice: stakingInfo.ended ? 0 : rewardTokenAPrice, + rewardTokenBPrice: stakingInfo.ended ? 0 : rewardTokenBPrice, tvl, - perMonthReturnInRewards, - totalSupply, + perMonthReturnInRewards: stakingInfo.ended + ? undefined + : perMonthReturnInRewards, + totalSupply: stakingInfo.ended ? undefined : totalSupply, usdPrice, stakingTokenPair, - oneDayFee, - accountFee, + oneDayFee: stakingInfo.ended ? 0 : oneDayFee, + accountFee: stakingInfo.ended ? 0 : accountFee, }); } return memo; diff --git a/src/state/syrups/hooks.ts b/src/state/syrups/hooks.ts index a837a692e..129849ff0 100644 --- a/src/state/syrups/hooks.ts +++ b/src/state/syrups/hooks.ts @@ -5,7 +5,9 @@ import { AppState } from 'state'; import { SyrupListInfo, SyrupRaw, SyrupBasic } from 'types'; import { Token } from '@uniswap/sdk'; import { TokenAddressMap, useSelectedTokenList } from 'state/lists/hooks'; -import { getTokenFromKey } from 'utils'; +import { getTokenFromAddress } from 'utils'; +import { useTokens } from 'hooks/Tokens'; +import { GlobalValue } from 'constants/index'; export class WrappedSyrupInfo implements SyrupBasic { public readonly stakingInfo: SyrupRaw; @@ -20,7 +22,12 @@ export class WrappedSyrupInfo implements SyrupBasic { public readonly token: Token; public readonly stakingToken: Token; - constructor(syrupInfo: SyrupRaw, tokenAddressMap: TokenAddressMap) { + constructor( + syrupInfo: SyrupRaw, + tokenAddressMap: TokenAddressMap, + syrupTokens: Token[], + chainId: ChainId, + ) { this.stakingInfo = syrupInfo; //TODO: Support Multichain this.chainId = ChainId.MATIC; @@ -30,13 +37,25 @@ export class WrappedSyrupInfo implements SyrupBasic { this.lp = syrupInfo.lp; this.name = syrupInfo.name; this.ending = syrupInfo.ending; - //TODO: we should be resolving the following property from the lists state using the address field instead of the key - this.baseToken = getTokenFromKey(syrupInfo.baseToken, tokenAddressMap); - this.stakingToken = getTokenFromKey( + + this.baseToken = getTokenFromAddress( + syrupInfo.baseToken, + chainId, + tokenAddressMap, + syrupTokens, + ); + this.stakingToken = getTokenFromAddress( syrupInfo.stakingToken, + chainId, tokenAddressMap, + syrupTokens, + ); + this.token = getTokenFromAddress( + syrupInfo.token, + chainId, + tokenAddressMap, + syrupTokens, ); - this.token = getTokenFromKey(syrupInfo.token, tokenAddressMap); } } @@ -64,13 +83,19 @@ const syrupCache: WeakMap | null = export function listToSyrupMap( list: SyrupListInfo, tokenAddressMap: TokenAddressMap, + syrupTokens: Token[], ): SyrupInfoAddressMap { const result = syrupCache?.get(list); if (result) return result; const map = list.active.concat(list.closed).reduce( (syrupInfoMap, syrup) => { - const wrappedSyrupInfo = new WrappedSyrupInfo(syrup, tokenAddressMap); + const wrappedSyrupInfo = new WrappedSyrupInfo( + syrup, + tokenAddressMap, + syrupTokens, + ChainId.MATIC, + ); if ( syrupInfoMap[wrappedSyrupInfo.chainId][ wrappedSyrupInfo.stakingRewardAddress @@ -96,17 +121,44 @@ export function useSyrupList(url: string | undefined): SyrupInfoAddressMap { (state) => state.syrups.byUrl, ); const tokenMap = useSelectedTokenList(); + const current = url ? syrups[url]?.current : null; + const syrupTokenAddresses = + current && tokenMap + ? current.active + .concat(current.closed) + .map((item) => [item.baseToken, item.token, item.stakingToken]) + .flat() + .filter((item) => !!item) + .filter((address) => !tokenMap[ChainId.MATIC][address]) + .filter( + (address) => + !Object.values(GlobalValue.tokens.COMMON).find( + (token) => + token.address.toLowerCase() === address.toLowerCase(), + ), + ) + .filter( + (address, ind, self) => + self.findIndex( + (addr) => address.toLowerCase() === addr.toLowerCase(), + ) === ind, + ) + : []; + const syrupTokens = useTokens(syrupTokenAddresses); return useMemo(() => { - if (!url) return EMPTY_LIST; - const current = syrups[url]?.current; - if (!current) return EMPTY_LIST; + if ( + !current || + !tokenMap || + syrupTokenAddresses.length !== syrupTokens?.length + ) + return EMPTY_LIST; try { - return listToSyrupMap(current, tokenMap); + return listToSyrupMap(current, tokenMap, syrupTokens ?? []); } catch (error) { console.error('Could not show token list due to error', error); return EMPTY_LIST; } - }, [syrups, url, tokenMap]); + }, [current, tokenMap, syrupTokenAddresses.length, syrupTokens]); } export function useDefaultSyrupList(): SyrupInfoAddressMap { diff --git a/src/utils/index.ts b/src/utils/index.ts index f161c37b2..34f6f81cb 100755 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -49,7 +49,6 @@ import { formatUnits } from 'ethers/lib/utils'; import { AddressZero } from '@ethersproject/constants'; import { GlobalConst, GlobalValue, SUPPORTED_WALLETS } from 'constants/index'; import { TokenAddressMap } from 'state/lists/hooks'; -import tokenData from 'constants/tokens.json'; import { DualStakingInfo, LairInfo, @@ -1731,54 +1730,33 @@ export function formatNumber( } } -export function getTokenFromKey(tokenKey: string, tokenMap: TokenAddressMap) { - //TODO: eventually we need to remove returnTokenFromKey completely - //TODO: we need to support this until the token list also lists our (unwhitelisted tokens) - const tokenData = returnTokenFromKey(tokenKey); - - //TODO: New Tokens may not exist in the old token.json, using object.values to enumerate the map - // is expensive so we don't want to have to do it everytime we call this method. - if (!tokenData) { - // Hack: this requires us to enumerate all the values of the token map which can be expensive - // - const tokensMatchingSymbol = Object.values(tokenMap[ChainId.MATIC]).filter( - (t) => (t.symbol ?? '').toUpperCase() == tokenKey.toUpperCase(), +export function getTokenFromAddress( + tokenAddress: string, + chainId: ChainId, + tokenMap: TokenAddressMap, + tokens: Token[], +) { + const wrappedTokenInfo = tokenMap[chainId][tokenAddress]; + if (!wrappedTokenInfo) { + console.log('missing from token list:' + tokenAddress); + const token = tokens.find( + (item) => item.address.toLowerCase() === tokenAddress.toLowerCase(), ); - if (tokensMatchingSymbol.length === 0) { - console.log('no token exists in the map'); + if (!token) { + const commonToken = Object.values(GlobalValue.tokens.COMMON).find( + (token) => token.address.toLowerCase() === tokenAddress.toLowerCase(), + ); + if (!commonToken) { + return GlobalValue.tokens.COMMON.EMPTY; + } + return commonToken; } - - return tokensMatchingSymbol[0]; - } - - const wrappedTokenInfo = tokenMap[tokenData.chainId][tokenData.address]; - if (!wrappedTokenInfo) { - console.log('missing from token list:' + tokenKey); - return tokenData; + return token; } return wrappedTokenInfo; } -export function returnTokenFromKey(key: string): Token | undefined { - if (key === 'MATIC') { - return GlobalValue.tokens.MATIC; - } - const token = (tokenData as any)[key]; - - if (!token) { - return; - } - - return new Token( - ChainId.MATIC, - getAddress(token.address), - token.decimals, - token.symbol, - token.name, - ); -} - export function getChartDates(chartData: any[] | null, durationIndex: number) { if (chartData) { const dates: string[] = [];