diff --git a/apis/farms/src/v3.ts b/apis/farms/src/v3.ts index 99fe13f45..6bb94958d 100644 --- a/apis/farms/src/v3.ts +++ b/apis/farms/src/v3.ts @@ -1,4 +1,6 @@ -import { masterChefV3Addresses } from '@pancakeswap/farms' +/* eslint-disable no-await-in-loop */ +/* eslint-disable no-param-reassign */ +import { masterChefV3Addresses, FarmSupportedChainId } from '@pancakeswap/farms' import { ChainId, ERC20Token } from '@pancakeswap/sdk' import { CurrencyAmount } from '@pancakeswap/swap-sdk-core' import { PositionMath } from '@pancakeswap/v3-sdk' @@ -21,7 +23,7 @@ export const V3_SUBGRAPH_CLIENTS = { [ChainId.BSC_TESTNET]: new GraphQLClient('https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-chapel', { fetch, }), -} satisfies Record +} satisfies Record const zChainId = z.enum(['56', '1', '5', '97']) diff --git a/apps/web/src/components/Logo/CurrencyLogo.tsx b/apps/web/src/components/Logo/CurrencyLogo.tsx index 9702e2f4e..7377e2c6c 100644 --- a/apps/web/src/components/Logo/CurrencyLogo.tsx +++ b/apps/web/src/components/Logo/CurrencyLogo.tsx @@ -47,7 +47,7 @@ export default function CurrencyLogo({ currency, size = '24px', style }: LogoPro return } return ( - + ) } diff --git a/apps/web/src/components/Menu/config/config.ts b/apps/web/src/components/Menu/config/config.ts index 36dd1daf6..de1fdd4f9 100644 --- a/apps/web/src/components/Menu/config/config.ts +++ b/apps/web/src/components/Menu/config/config.ts @@ -17,7 +17,7 @@ import { ContextApi } from '@pancakeswap/localization' import { SUPPORTED_CHAIN_IDS as POOL_SUPPORTED_CHAINS } from '@pancakeswap/pools' import { nftsBaseUrl } from 'views/Nft/market/constants' import { getPerpetualUrl } from 'utils/getPerpetualUrl' -import { SUPPORT_ONLY_BSC } from 'config/constants/supportChains' +import { SUPPORT_FARMS, SUPPORT_ONLY_BSC } from 'config/constants/supportChains' import { NewIconButton } from 'views/BuyCrypto/components/NewIcon' export type ConfigMenuDropDownItemsType = DropdownMenuItems & { hideSubNav?: boolean } @@ -95,10 +95,12 @@ const config: ( icon: EarnIcon, fillIcon: EarnFillIcon, image: '/images/decorations/pe2.png', + supportChainIds: SUPPORT_FARMS, items: [ { label: t('Farms'), href: '/farms', + supportChainIds: SUPPORT_FARMS, }, { label: t('Pools'), diff --git a/apps/web/src/components/NetworkModal/NetworkModal.tsx b/apps/web/src/components/NetworkModal/NetworkModal.tsx index a4ec3d3a9..0b6378f9f 100644 --- a/apps/web/src/components/NetworkModal/NetworkModal.tsx +++ b/apps/web/src/components/NetworkModal/NetworkModal.tsx @@ -45,20 +45,20 @@ export const NetworkModal = ({ pageSupportedChains = SUPPORT_ONLY_BSC }: { pageS ) } - if ((chain?.unsupported ?? false) || isPageNotSupported) { + if (isWrongNetwork && !dismissWrongNetwork && !isPageNotSupported) { + const currentChain = chains.find((c) => c.id === chainId) + if (!currentChain) return null return ( - - + setDismissWrongNetwork(true)}> + setDismissWrongNetwork(true)} /> ) } - if (isWrongNetwork && !dismissWrongNetwork) { - const currentChain = chains.find((c) => c.id === chainId) - if (!currentChain) return null + if ((chain?.unsupported ?? false) || isPageNotSupported) { return ( - setDismissWrongNetwork(true)}> - setDismissWrongNetwork(true)} /> + + ) } diff --git a/apps/web/src/components/NetworkSwitcher.tsx b/apps/web/src/components/NetworkSwitcher.tsx index 9b7d8d1dc..592fb1bce 100644 --- a/apps/web/src/components/NetworkSwitcher.tsx +++ b/apps/web/src/components/NetworkSwitcher.tsx @@ -42,7 +42,11 @@ const NetworkSelect = ({ switchNetwork, chainId }) => { {chains - .filter((chain) => !('testnet' in chain && chain.testnet) || chain.id === chainId) + .filter( + (chain) => + // chain.id === ChainId.LINEA_TESTNET || + !('testnet' in chain && chain.testnet) || chain.id === chainId, + ) .map((chain) => ( { ) } +const SHORT_SYMBOL = { + [ChainId.ETHEREUM]: 'ETH', + [ChainId.BSC]: 'BNB', + [ChainId.BSC_TESTNET]: 'tBNB', + [ChainId.GOERLI]: 'GOR', + [ChainId.ARBITRUM_ONE]: 'ARB', + [ChainId.ARBITRUM_GOERLI]: 'tARB', + [ChainId.POLYGON_ZKEVM]: 'Polygon zkEVM', + [ChainId.POLYGON_ZKEVM_TESTNET]: 'tZkEVM', + [ChainId.ZKSYNC]: 'zkSync', + [ChainId.ZKSYNC_TESTNET]: 'tZkSync', + [ChainId.LINEA_TESTNET]: 'tLinea', +} as const satisfies Record + export const NetworkSwitcher = () => { const { t } = useTranslation() const { chainId, isWrongNetwork, isNotMatched } = useActiveChainId() @@ -144,7 +162,7 @@ export const NetworkSwitcher = () => { () => chains.find((c) => c.id === (isLoading ? pendingChainId || chainId : chainId)), [isLoading, pendingChainId, chainId], ) - const symbol = NATIVE[foundChain?.id]?.symbol ?? foundChain?.nativeCurrency?.symbol + const symbol = SHORT_SYMBOL[foundChain?.id] ?? NATIVE[foundChain?.id]?.symbol ?? foundChain?.nativeCurrency?.symbol const { targetRef, tooltip, tooltipVisible } = useTooltip( t('Unable to switch network. Please try it on your wallet'), { placement: 'bottom' }, diff --git a/apps/web/src/components/SubgraphHealthIndicator/FloatingSubgraphHealthIndicators.tsx b/apps/web/src/components/SubgraphHealthIndicator/FloatingSubgraphHealthIndicators.tsx index 03d02cab3..d2f5f3d4b 100644 --- a/apps/web/src/components/SubgraphHealthIndicator/FloatingSubgraphHealthIndicators.tsx +++ b/apps/web/src/components/SubgraphHealthIndicator/FloatingSubgraphHealthIndicators.tsx @@ -24,8 +24,12 @@ export function subgraphHealthIndicatorFactory({ getSubgraphName }: FactoryParam } export const V3SubgraphHealthIndicator = subgraphHealthIndicatorFactory({ - getSubgraphName: (chainId) => - V3_SUBGRAPH_URLS[chainId]?.replace('https://api.thegraph.com/subgraphs/name/', '') || '', + getSubgraphName: (chainId) => { + if (V3_SUBGRAPH_URLS[chainId]?.startsWith('https://api.thegraph.com/subgraphs/name/')) { + return V3_SUBGRAPH_URLS[chainId].replace('https://api.thegraph.com/subgraphs/name/', '') || '' + } + return '' + }, }) export const LotterySubgraphHealthIndicator = subgraphHealthIndicatorFactory({ diff --git a/apps/web/src/config/__tests__/contracts.test.ts b/apps/web/src/config/__tests__/contracts.test.ts index ea0043b2b..81942692f 100644 --- a/apps/web/src/config/__tests__/contracts.test.ts +++ b/apps/web/src/config/__tests__/contracts.test.ts @@ -4,7 +4,9 @@ import contracts from 'config/constants/contracts' describe('Config contracts', () => { it.each(map(contracts, (contract, key) => [key, contract]))('Contract %s has a unique address', (key, contract) => { - const duplicates = filter(contracts, (c) => contract[56] === c[56]) - expect(duplicates).toHaveLength(1) + if (contract[56]) { + const duplicates = filter(contracts, (c) => contract[56] === c[56]) + expect(duplicates).toHaveLength(1) + } }) }) diff --git a/apps/web/src/config/chains.ts b/apps/web/src/config/chains.ts index 6507ccd2c..b55e36eb3 100644 --- a/apps/web/src/config/chains.ts +++ b/apps/web/src/config/chains.ts @@ -1,20 +1,43 @@ import { ChainId } from '@pancakeswap/sdk' import memoize from 'lodash/memoize' -import invert from 'lodash/invert' -import { bsc as bsc_, bscTestnet, goerli, mainnet, Chain } from 'wagmi/chains' +import { + bsc as bsc_, + bscTestnet, + goerli, + mainnet, + // zkSync as zkSync_, + // zkSyncTestnet as zkSyncTestnet_, + // polygonZkEvmTestnet as polygonZkEvmTestnet_, + // polygonZkEvm as polygonZkEvm_, + lineaTestnet as lineaTestnet_, + // arbitrumGoerli, + Chain, +} from 'wagmi/chains' export const CHAIN_QUERY_NAME = { [ChainId.ETHEREUM]: 'eth', [ChainId.GOERLI]: 'goerli', [ChainId.BSC]: 'bsc', [ChainId.BSC_TESTNET]: 'bscTestnet', + [ChainId.ARBITRUM_ONE]: 'arb', + [ChainId.ARBITRUM_GOERLI]: 'arbGoerli', + [ChainId.POLYGON_ZKEVM]: 'polygonZkEVM', + [ChainId.POLYGON_ZKEVM_TESTNET]: 'polygonZkEVMTestnet', + [ChainId.ZKSYNC]: 'zkSync', + [ChainId.ZKSYNC_TESTNET]: 'zkSyncTestnet', + [ChainId.LINEA_TESTNET]: 'lineaTestnet', } as const satisfies Record -const CHAIN_QUERY_NAME_TO_ID = invert(CHAIN_QUERY_NAME) +const CHAIN_QUERY_NAME_TO_ID = Object.entries(CHAIN_QUERY_NAME).reduce((acc, [chainId, chainName]) => { + return { + [chainName.toLowerCase()]: chainId as unknown as ChainId, + ...acc, + } +}, {} as Record) export const getChainId = memoize((chainName: string) => { if (!chainName) return undefined - return CHAIN_QUERY_NAME_TO_ID[chainName] ? +CHAIN_QUERY_NAME_TO_ID[chainName] : undefined + return CHAIN_QUERY_NAME_TO_ID[chainName.toLowerCase()] ? +CHAIN_QUERY_NAME_TO_ID[chainName.toLowerCase()] : undefined }) const bsc = { @@ -32,12 +55,84 @@ const bsc = { }, } satisfies Chain -export const CHAINS = [bsc, mainnet, bscTestnet, goerli] +// const zkSync = { +// ...zkSync_, +// contracts: { +// multicall3: { +// address: '0x47898B2C52C957663aE9AB46922dCec150a2272c', +// blockCreated: 1536804, +// }, +// }, +// } as const satisfies Chain + +// const zkSyncTestnet = { +// ...zkSyncTestnet_, +// contracts: { +// multicall3: { +// address: '0x5640049C9e2d33127B34F1bef5C070509f14B5D0', +// blockCreated: 5137723, +// }, +// }, +// } as const satisfies Chain + +// const polygonZkEvm = { +// ...polygonZkEvm_, +// contracts: { +// multicall3: { +// address: '0xcA11bde05977b3631167028862bE2a173976CA11', +// blockCreated: 57746, +// }, +// }, +// } as const satisfies Chain + +// const polygonZkEvmTestnet = { +// ...polygonZkEvmTestnet_, +// contracts: { +// multicall3: { +// address: '0xcA11bde05977b3631167028862bE2a173976CA11', +// blockCreated: 525686, +// }, +// }, +// } as const satisfies Chain + +const lineaTestnet = { + ...lineaTestnet_, + blockExplorers: { + etherscan: { + name: 'LineaScan', + url: 'https://goerli.lineascan.build', + }, + default: { + name: 'LineaScan', + url: 'https://goerli.lineascan.build', + }, + }, +} as const satisfies Chain /** * Controls some L2 specific behavior, e.g. slippage tolerance, special UI behavior. * The expectation is that all of these networks have immediate transaction confirmation. */ -export const L2_CHAIN_IDS: ChainId[] = [] +export const L2_CHAIN_IDS: ChainId[] = [ + ChainId.ARBITRUM_ONE, + ChainId.ARBITRUM_GOERLI, + ChainId.POLYGON_ZKEVM, + ChainId.POLYGON_ZKEVM_TESTNET, + ChainId.ZKSYNC, + ChainId.ZKSYNC_TESTNET, + ChainId.LINEA_TESTNET, +] -export const MAINNET_CHAINS = [bsc, mainnet] +export const CHAINS = [ + bsc, + mainnet, + bscTestnet, + goerli, + // zkSync, + // zkSyncTestnet, + // polygonZkEvm, + // polygonZkEvmTestnet, + lineaTestnet, + // arbitrumGoerli, + // arbitrum, +] diff --git a/apps/web/src/config/constants/contracts.ts b/apps/web/src/config/constants/contracts.ts index 02d4f4c01..dc99b7908 100644 --- a/apps/web/src/config/constants/contracts.ts +++ b/apps/web/src/config/constants/contracts.ts @@ -160,12 +160,10 @@ export default { 97: '0x56666300A1E25624489b661f3C6c456c159a109a', }, nonBscVault: { - 56: '0xE6c904424417D03451fADd6E3f5b6c26BcC43841', // Only for pass contracts test 1: '0x2e71B2688019ebdFDdE5A45e6921aaebb15b25fb', 5: '0xE6c904424417D03451fADd6E3f5b6c26BcC43841', }, crossFarmingSender: { - 56: '0x327d26dE30f92600620A99043034e0A5FD9402C8', // Only for pass contracts test 1: '0x8EA90Ef07f37c77137453C7A1B72B7886d51eCFb', 5: '0x327d26dE30f92600620A99043034e0A5FD9402C8', }, @@ -188,6 +186,14 @@ export default { 5: '0x427bF5b37357632377eCbEC9de3626C71A5396c1', 56: '0x46A15B0b27311cedF172AB29E4f4766fbE7F4364', 97: '0x427bF5b37357632377eCbEC9de3626C71A5396c1', + // TODO: new chains + 280: '0x1ede0FF9b7Bd6DC0625e3ba579d5FD697e6698b2', + 324: '0x', + 1101: '0x46A15B0b27311cedF172AB29E4f4766fbE7F4364', + 1442: '0x1f489dd5B559E976AE74303F939Cfd0aF1b62C2B', + 42161: '0x46A15B0b27311cedF172AB29E4f4766fbE7F4364', + 59140: '0xacFa791C833120c769Fd3066c940B7D30Cd8BC73', + 421613: '0xb10120961f7504766976A89E29802Fa00553da5b', }, v3PoolDeployer: DEPLOYER_ADDRESSES, v3Migrator: { @@ -195,6 +201,14 @@ export default { 5: '0x46A15B0b27311cedF172AB29E4f4766fbE7F4364', 56: '0xbC203d7f83677c7ed3F7acEc959963E7F4ECC5C2', 97: '0x46A15B0b27311cedF172AB29E4f4766fbE7F4364', + // TODO: new chains + 280: '0x612662964B5bd12111504C13D694eeEF566f3916', + 324: '0x', + 1101: '0xbC203d7f83677c7ed3F7acEc959963E7F4ECC5C2', + 1442: '0x4A3902773F947ce028969db670E568fFC9524E8C', + 42161: '0xbC203d7f83677c7ed3F7acEc959963E7F4ECC5C2', + 59140: '0x3652Fc6EDcbD76161b8554388867d3dAb65eCA93', + 421613: '0xCcf770BdBD8ccC57a7a7ABff53825fD895a06238', }, quoter: V3_QUOTER_ADDRESSES, v3Airdrop: { diff --git a/apps/web/src/config/constants/endpoints.ts b/apps/web/src/config/constants/endpoints.ts index 83976b42d..2d26c8d27 100644 --- a/apps/web/src/config/constants/endpoints.ts +++ b/apps/web/src/config/constants/endpoints.ts @@ -42,6 +42,8 @@ export const CELER_API = 'https://api.celerscan.com/scan' export const INFO_CLIENT_WITH_CHAIN = { [ChainId.BSC]: INFO_CLIENT, [ChainId.ETHEREUM]: INFO_CLIENT_ETH, + [ChainId.LINEA_TESTNET]: 'https://thegraph.goerli.zkevm.consensys.net/subgraphs/name/pancakeswap/exhange-eth/', + [ChainId.ARBITRUM_ONE]: 'https://thegraph.com/hosted-service/subgraph/chef-jojo/exchange-v2-arb', } export const BLOCKS_CLIENT_WITH_CHAIN = { @@ -56,7 +58,16 @@ export const V3_SUBGRAPH_URLS = { [ChainId.GOERLI]: 'https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-goerli', [ChainId.BSC]: `https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-bsc`, [ChainId.BSC_TESTNET]: 'https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-chapel', -} satisfies Record + // TODO: new chains + [ChainId.ARBITRUM_ONE]: 'https://thegraph.com/hosted-service/subgraph/chef-jojo/exchange-v3-arb', + [ChainId.ARBITRUM_GOERLI]: 'https://api.thegraph.com/subgraphs/name/chef-jojo/exhange-v3-arb-goerli', + [ChainId.POLYGON_ZKEVM]: 'https://api.studio.thegraph.com/query/45376/exchange-v3-polygon-zkevm/v0.0.0', + [ChainId.POLYGON_ZKEVM_TESTNET]: null, + [ChainId.ZKSYNC]: null, + [ChainId.ZKSYNC_TESTNET]: 'https://api.studio.thegraph.com/query/45376/exchange-v3-zksync-testnet/v0.0.1', + [ChainId.LINEA_TESTNET]: + 'https://thegraph.goerli.zkevm.consensys.net/subgraphs/name/pancakeswap/exchange-v3-linea-goerli', +} satisfies Record export const TRADING_REWARD_API = 'https://pancake-trading-fee-rebate-api.pancake.run/api/v1' diff --git a/apps/web/src/config/constants/exchange.ts b/apps/web/src/config/constants/exchange.ts index 6696ea519..03aa8a60c 100644 --- a/apps/web/src/config/constants/exchange.ts +++ b/apps/web/src/config/constants/exchange.ts @@ -1,65 +1,55 @@ import { ChainId, Percent, Token, WNATIVE } from '@pancakeswap/sdk' -import { bscTokens, bscTestnetTokens, USDC, USDT, BUSD, WBTC_ETH } from '@pancakeswap/tokens' -import { ChainMap, ChainTokenList } from './types' +import { + bscTokens, + bscTestnetTokens, + USDC, + USDT, + BUSD, + WBTC_ETH, + arbitrumTokens, + polygonZkEvmTokens, + polygonZkEvmTestnetTokens, + zksyncTokens, + zkSyncTestnetTokens, + lineaTestnetTokens, + arbitrumGoerliTokens, +} from '@pancakeswap/tokens' +import { ChainTokenList } from './types' + +export { + ADDITIONAL_BASES, + V2_ROUTER_ADDRESS, + BASES_TO_CHECK_TRADES_AGAINST, + CUSTOM_BASES, +} from '@pancakeswap/smart-router/evm' export const CHAIN_REFRESH_TIME = { [ChainId.ETHEREUM]: 12_000, [ChainId.GOERLI]: 12_000, [ChainId.BSC]: 6_000, [ChainId.BSC_TESTNET]: 6_000, + [ChainId.ARBITRUM_ONE]: 4_000, + [ChainId.ARBITRUM_GOERLI]: 4_000, + [ChainId.POLYGON_ZKEVM]: 7_000, + [ChainId.POLYGON_ZKEVM_TESTNET]: 7_000, + [ChainId.ZKSYNC]: 3_000, + [ChainId.ZKSYNC_TESTNET]: 3_000, + [ChainId.LINEA_TESTNET]: 12_000, } as const satisfies Record -export const ROUTER_ADDRESS: ChainMap = { - [ChainId.ETHEREUM]: '0xEfF92A263d31888d860bD50809A8D171709b7b1c', - [ChainId.GOERLI]: '0xEfF92A263d31888d860bD50809A8D171709b7b1c', - [ChainId.BSC]: '0x10ED43C718714eb63d5aA57B78B54704E256024E', - [ChainId.BSC_TESTNET]: '0xD99D1c33F9fC3444f8101754aBC46c52416550D1', -} - -// used to construct intermediary pairs for trading -export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = { - [ChainId.ETHEREUM]: [WNATIVE[ChainId.ETHEREUM], USDC[ChainId.ETHEREUM], USDT[ChainId.ETHEREUM], WBTC_ETH], - [ChainId.GOERLI]: [WNATIVE[ChainId.GOERLI], USDC[ChainId.GOERLI], BUSD[ChainId.GOERLI]], - [ChainId.BSC]: [ - bscTokens.wbnb, - bscTokens.cake, - bscTokens.busd, - bscTokens.usdt, - bscTokens.btcb, - bscTokens.eth, - bscTokens.usdc, - ], - [ChainId.BSC_TESTNET]: [bscTestnetTokens.wbnb, bscTestnetTokens.cake, bscTestnetTokens.busd], -} - -/** - * Additional bases for specific tokens - * @example { [WBTC.address]: [renBTC], [renBTC.address]: [WBTC] } - */ -export const ADDITIONAL_BASES: { [chainId in ChainId]?: { [tokenAddress: string]: Token[] } } = { - [ChainId.BSC]: { - // SNFTS-SFUND - [bscTokens.snfts.address]: [bscTokens.sfund], - }, -} - -/** - * Some tokens can only be swapped via certain pairs, so we override the list of bases that are considered for these - * tokens. - * @example [AMPL.address]: [DAI, WNATIVE[ChainId.BSC]] - */ -export const CUSTOM_BASES: { [chainId in ChainId]?: { [tokenAddress: string]: Token[] } } = { - [ChainId.BSC]: { - [bscTokens.axlusdc.address]: [bscTokens.usdt], - }, -} - // used for display in the default list when adding liquidity export const SUGGESTED_BASES: ChainTokenList = { [ChainId.ETHEREUM]: [USDC[ChainId.ETHEREUM], USDT[ChainId.ETHEREUM], WNATIVE[ChainId.ETHEREUM], WBTC_ETH], [ChainId.GOERLI]: [USDC[ChainId.GOERLI], WNATIVE[ChainId.GOERLI], BUSD[ChainId.GOERLI]], [ChainId.BSC]: [bscTokens.usdt, bscTokens.cake, bscTokens.btcb], [ChainId.BSC_TESTNET]: [bscTestnetTokens.wbnb, bscTestnetTokens.cake, bscTestnetTokens.busd], + [ChainId.ARBITRUM_ONE]: [arbitrumTokens.weth, arbitrumTokens.usdt, arbitrumTokens.usdc], + [ChainId.ARBITRUM_GOERLI]: [arbitrumGoerliTokens.weth, arbitrumGoerliTokens.usdc], + [ChainId.POLYGON_ZKEVM]: [polygonZkEvmTokens.weth, polygonZkEvmTokens.usdt, polygonZkEvmTokens.usdc], + [ChainId.POLYGON_ZKEVM_TESTNET]: [polygonZkEvmTestnetTokens.weth, polygonZkEvmTestnetTokens.usdt], + [ChainId.ZKSYNC]: [zksyncTokens.usdc, zksyncTokens.weth], + [ChainId.ZKSYNC_TESTNET]: [zkSyncTestnetTokens.usdc, zkSyncTestnetTokens.weth], + [ChainId.LINEA_TESTNET]: [lineaTestnetTokens.usdc, lineaTestnetTokens.weth], } // used to construct the list of all pairs we consider by default in the frontend @@ -68,6 +58,13 @@ export const BASES_TO_TRACK_LIQUIDITY_FOR: ChainTokenList = { [ChainId.GOERLI]: [USDC[ChainId.GOERLI], WNATIVE[ChainId.GOERLI], BUSD[ChainId.GOERLI]], [ChainId.BSC]: [bscTokens.wbnb, bscTokens.dai, bscTokens.busd, bscTokens.usdt, bscTokens.cake], [ChainId.BSC_TESTNET]: [bscTestnetTokens.wbnb, bscTestnetTokens.cake, bscTestnetTokens.busd], + [ChainId.ARBITRUM_ONE]: [arbitrumTokens.weth, arbitrumTokens.usdt, arbitrumTokens.usdc], + [ChainId.ARBITRUM_GOERLI]: [arbitrumGoerliTokens.weth, arbitrumGoerliTokens.usdc], + [ChainId.POLYGON_ZKEVM]: [polygonZkEvmTokens.weth, polygonZkEvmTokens.usdt, polygonZkEvmTokens.usdc], + [ChainId.POLYGON_ZKEVM_TESTNET]: [polygonZkEvmTestnetTokens.weth, polygonZkEvmTestnetTokens.usdt], + [ChainId.ZKSYNC]: [zksyncTokens.usdc, zksyncTokens.weth], + [ChainId.ZKSYNC_TESTNET]: [zkSyncTestnetTokens.usdc, zkSyncTestnetTokens.weth], + [ChainId.LINEA_TESTNET]: [lineaTestnetTokens.usdc, lineaTestnetTokens.weth], } export const PINNED_PAIRS: { readonly [chainId in ChainId]?: [Token, Token][] } = { @@ -81,6 +78,15 @@ export const PINNED_PAIRS: { readonly [chainId in ChainId]?: [Token, Token][] } [bscTokens.busd, bscTokens.usdt], [bscTokens.dai, bscTokens.usdt], ], + [ChainId.ARBITRUM_ONE]: [ + [arbitrumTokens.weth, arbitrumTokens.usdt], + [arbitrumTokens.weth, arbitrumTokens.usdc], + ], + [ChainId.ARBITRUM_GOERLI]: [[arbitrumGoerliTokens.weth, arbitrumGoerliTokens.usdc]], + [ChainId.POLYGON_ZKEVM]: [[polygonZkEvmTokens.weth, polygonZkEvmTokens.usdt]], + [ChainId.ZKSYNC]: [[zksyncTokens.usdc, zksyncTokens.weth]], + [ChainId.ZKSYNC_TESTNET]: [[zkSyncTestnetTokens.usdc, zkSyncTestnetTokens.weth]], + [ChainId.LINEA_TESTNET]: [[lineaTestnetTokens.usdc, lineaTestnetTokens.weth]], } export const BIG_INT_ZERO = 0n diff --git a/apps/web/src/config/constants/lists.ts b/apps/web/src/config/constants/lists.ts index f69dc05e5..e6370c1d9 100644 --- a/apps/web/src/config/constants/lists.ts +++ b/apps/web/src/config/constants/lists.ts @@ -10,7 +10,7 @@ export const ETH_URLS = [PANCAKE_ETH_DEFAULT, PANCAKE_ETH_MM, COINGECKO_ETH] export const BSC_URLS = [PANCAKE_EXTENDED, CMC, COINGECKO, PANCAKE_BSC_MM] // List of official tokens list -export const OFFICIAL_LISTS = [PANCAKE_EXTENDED, PANCAKE_ETH_DEFAULT, PANCAKE_ETH_MM] +export const OFFICIAL_LISTS = [PANCAKE_EXTENDED, PANCAKE_ETH_DEFAULT] export const UNSUPPORTED_LIST_URLS: string[] = [] export const WARNING_LIST_URLS: string[] = [] diff --git a/apps/web/src/config/constants/tokenLists/pancake-default.tokenlist.json b/apps/web/src/config/constants/tokenLists/pancake-default.tokenlist.json index 12cbd3040..d19a81a83 100644 --- a/apps/web/src/config/constants/tokenLists/pancake-default.tokenlist.json +++ b/apps/web/src/config/constants/tokenLists/pancake-default.tokenlist.json @@ -58,62 +58,6 @@ "decimals": 18, "logoURI": "https://pancakeswap.finance/images/tokens/0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82.png" }, - { - "name": "Venus", - "symbol": "XVS", - "address": "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63", - "chainId": 56, - "decimals": 18, - "logoURI": "https://pancakeswap.finance/images/tokens/0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63.png" - }, - { - "name": "VAI Stablecoin", - "symbol": "VAI", - "address": "0x4BD17003473389A42DAF6a0a729f6Fdb328BbBd7", - "chainId": 56, - "decimals": 18, - "logoURI": "https://pancakeswap.finance/images/tokens/0x4BD17003473389A42DAF6a0a729f6Fdb328BbBd7.png" - }, - { - "name": "Alpaca", - "symbol": "ALPACA", - "address": "0x8F0528cE5eF7B51152A59745bEfDD91D97091d2F", - "chainId": 56, - "decimals": 18, - "logoURI": "https://pancakeswap.finance/images/tokens/0x8F0528cE5eF7B51152A59745bEfDD91D97091d2F.png" - }, - { - "name": "Belt", - "symbol": "BELT", - "address": "0xE0e514c71282b6f4e823703a39374Cf58dc3eA4f", - "chainId": 56, - "decimals": 18, - "logoURI": "https://pancakeswap.finance/images/tokens/0xE0e514c71282b6f4e823703a39374Cf58dc3eA4f.png" - }, - { - "name": "TokoCrypto", - "symbol": "TKO", - "address": "0x9f589e3eabe42ebC94A44727b3f3531C0c877809", - "chainId": 56, - "decimals": 18, - "logoURI": "https://pancakeswap.finance/images/tokens/0x9f589e3eabe42ebC94A44727b3f3531C0c877809.png" - }, - { - "name": "Nerve Finance", - "symbol": "NRV", - "address": "0x42F6f551ae042cBe50C739158b4f0CAC0Edb9096", - "chainId": 56, - "decimals": 18, - "logoURI": "https://pancakeswap.finance/images/tokens/0x42F6f551ae042cBe50C739158b4f0CAC0Edb9096.png" - }, - { - "name": "Ellipsis", - "symbol": "EPS", - "address": "0xA7f552078dcC247C2684336020c03648500C6d9F", - "chainId": 56, - "decimals": 18, - "logoURI": "https://pancakeswap.finance/images/tokens/0xA7f552078dcC247C2684336020c03648500C6d9F.png" - }, { "name": "PancakeSwap Token", "symbol": "CAKE", @@ -155,35 +99,59 @@ "logoURI": "https://tokens.pancakeswap.finance/images/symbol/busd.png" }, { - "name": "BUSD Token", - "symbol": "BUSD", - "address": "0x4e2442A6f7AeCE64Ca33d31756B5390860BF973E", - "chainId": 4, + "name": "Wrapped Ether", + "address": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", + "symbol": "WETH", "decimals": 18, - "logoURI": "https://tokens.pancakeswap.finance/images/symbol/busd.png" + "chainId": 5, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/weth.png" }, { "name": "Wrapped Ether", - "address": "0xc778417E063141139Fce010982780140Aa0cD5Ab", + "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "symbol": "WETH", "decimals": 18, - "chainId": 4, + "chainId": 1, "logoURI": "https://tokens.pancakeswap.finance/images/symbol/weth.png" }, { "name": "Wrapped Ether", - "address": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", + "address": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", "symbol": "WETH", "decimals": 18, - "chainId": 5, + "chainId": 42161, "logoURI": "https://tokens.pancakeswap.finance/images/symbol/weth.png" }, { "name": "Wrapped Ether", - "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "address": "0x20b28B1e4665FFf290650586ad76E977EAb90c5D", "symbol": "WETH", "decimals": 18, - "chainId": 1, + "chainId": 280, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/weth.png" + }, + { + "name": "Wrapped Ether", + "address": "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", + "symbol": "WETH", + "decimals": 18, + "chainId": 324, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/weth.png" + }, + { + "name": "Wrapped Ether", + "address": "0xEe01c0CD76354C383B8c7B4e65EA88D00B06f36f", + "symbol": "WETH", + "decimals": 18, + "chainId": 421613, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/weth.png" + }, + { + "name": "Wrapped Ether", + "address": "0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9", + "symbol": "WETH", + "decimals": 18, + "chainId": 1101, "logoURI": "https://tokens.pancakeswap.finance/images/symbol/weth.png" }, { @@ -195,11 +163,51 @@ "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" }, { - "name": "Test USD Coin", - "address": "0x4DBCdF9B62e891a7cec5A2568C3F4FAF9E8Abe2b", - "symbol": "tUSDC", + "name": "USD Coin", + "address": "0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4", + "symbol": "USDC", + "decimals": 6, + "chainId": 324, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" + }, + { + "name": "USD Coin", + "address": "0x0faF6df7054946141266420b43783387A78d82A9", + "symbol": "USDC", + "decimals": 6, + "chainId": 280, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" + }, + { + "name": "USD Coin", + "address": "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", + "symbol": "USDC", + "decimals": 6, + "chainId": 42161, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" + }, + { + "name": "USD Coin", + "address": "0xf56dc6695cF1f5c364eDEbC7Dc7077ac9B586068", + "symbol": "USDC", + "decimals": 6, + "chainId": 59140, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" + }, + { + "name": "USD Coin", + "address": "0x179522635726710Dd7D2035a81d856de4Aa7836c", + "symbol": "USDC", "decimals": 6, - "chainId": 4, + "chainId": 421613, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" + }, + { + "name": "USD Coin", + "address": "0xA8CE8aee21bC2A48a5EF670afCc9274C7bbbC035", + "symbol": "USDC", + "decimals": 6, + "chainId": 1101, "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" }, { @@ -210,6 +218,14 @@ "chainId": 5, "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" }, + { + "name": "Test USD Coin", + "address": "0x7379a261bC347BDD445484A91648Abf4A2BDEe5E", + "symbol": "tUSDC", + "decimals": 6, + "chainId": 1442, + "logoURI": "https://tokens.pancakeswap.finance/images/symbol/usdc.png" + }, { "name": "Tether USD", "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", diff --git a/apps/web/src/config/nodes.ts b/apps/web/src/config/nodes.ts index 357f577f3..4ba83bf11 100644 --- a/apps/web/src/config/nodes.ts +++ b/apps/web/src/config/nodes.ts @@ -1,4 +1,5 @@ import { ChainId } from '@pancakeswap/sdk' +import { arbitrum, polygonZkEvm, zkSync, zkSyncTestnet, polygonZkEvmTestnet, arbitrumGoerli } from 'wagmi/chains' import { getNodeRealUrlV2 } from 'utils/nodeReal' export const SERVER_NODES = { @@ -17,7 +18,21 @@ export const SERVER_NODES = { getNodeRealUrlV2(ChainId.GOERLI, process.env.SERVER_NODE_REAL_API_GOERLI), 'https://eth-goerli.public.blastapi.io', ].filter(Boolean), -} satisfies Record + [ChainId.ARBITRUM_ONE]: arbitrum.rpcUrls.public.http, + [ChainId.ARBITRUM_GOERLI]: arbitrumGoerli.rpcUrls.public.http, + [ChainId.POLYGON_ZKEVM]: polygonZkEvm.rpcUrls.public.http, + [ChainId.POLYGON_ZKEVM_TESTNET]: [ + 'https://polygon-zkevm-testnet.rpc.thirdweb.com', + ...polygonZkEvmTestnet.rpcUrls.public.http, + ], + [ChainId.ZKSYNC]: zkSync.rpcUrls.public.http, + [ChainId.ZKSYNC_TESTNET]: zkSyncTestnet.rpcUrls.public.http, + [ChainId.LINEA_TESTNET]: [ + 'https://rpc.goerli.linea.build', + 'https://linea-testnet.rpc.thirdweb.com', + 'https://consensys-zkevm-goerli-prealpha.infura.io/v3/93e8a17747e34ec0ac9a554c1b403965', + ], +} satisfies Record export const PUBLIC_NODES = { [ChainId.BSC]: [ @@ -36,4 +51,18 @@ export const PUBLIC_NODES = { getNodeRealUrlV2(ChainId.GOERLI, process.env.NEXT_PUBLIC_NODE_REAL_API_GOERLI), 'https://eth-goerli.public.blastapi.io', ].filter(Boolean), -} satisfies Record + [ChainId.ARBITRUM_ONE]: arbitrum.rpcUrls.public.http, + [ChainId.ARBITRUM_GOERLI]: arbitrumGoerli.rpcUrls.public.http, + [ChainId.POLYGON_ZKEVM]: polygonZkEvm.rpcUrls.public.http, + [ChainId.POLYGON_ZKEVM_TESTNET]: [ + 'https://polygon-zkevm-testnet.rpc.thirdweb.com', + ...polygonZkEvmTestnet.rpcUrls.public.http, + ], + [ChainId.ZKSYNC]: zkSync.rpcUrls.public.http, + [ChainId.ZKSYNC_TESTNET]: zkSyncTestnet.rpcUrls.public.http, + [ChainId.LINEA_TESTNET]: [ + 'https://rpc.goerli.linea.build', + 'https://linea-testnet.rpc.thirdweb.com', + 'https://consensys-zkevm-goerli-prealpha.infura.io/v3/93e8a17747e34ec0ac9a554c1b403965', + ], +} satisfies Record diff --git a/apps/web/src/config/pools.ts b/apps/web/src/config/pools.ts index 4746f955f..fbd5bd383 100644 --- a/apps/web/src/config/pools.ts +++ b/apps/web/src/config/pools.ts @@ -6,7 +6,14 @@ export const POOLS_FAST_REVALIDATE = { [ChainId.BSC]: 10_000, [ChainId.ETHEREUM]: 20_000, [ChainId.GOERLI]: 20_000, -} + [ChainId.ARBITRUM_ONE]: 10_000, + [ChainId.ARBITRUM_GOERLI]: 10_000, + [ChainId.POLYGON_ZKEVM]: 15_000, + [ChainId.POLYGON_ZKEVM_TESTNET]: 15_000, + [ChainId.ZKSYNC]: 15_000, + [ChainId.ZKSYNC_TESTNET]: 15_000, + [ChainId.LINEA_TESTNET]: 20_000, +} as const satisfies Record // Revalidate interval in milliseconds export const POOLS_NORMAL_REVALIDATE = { @@ -14,11 +21,25 @@ export const POOLS_NORMAL_REVALIDATE = { [ChainId.BSC]: 15_000, [ChainId.ETHEREUM]: 20_000, [ChainId.GOERLI]: 20_000, -} + [ChainId.ARBITRUM_ONE]: 15_000, + [ChainId.ARBITRUM_GOERLI]: 15_000, + [ChainId.POLYGON_ZKEVM]: 15_000, + [ChainId.POLYGON_ZKEVM_TESTNET]: 15_000, + [ChainId.ZKSYNC]: 15_000, + [ChainId.ZKSYNC_TESTNET]: 15_000, + [ChainId.LINEA_TESTNET]: 20_000, +} as const satisfies Record export const POOLS_SLOW_REVALIDATE = { [ChainId.BSC_TESTNET]: 20_000, [ChainId.BSC]: 20_000, [ChainId.ETHEREUM]: 40_000, [ChainId.GOERLI]: 40_000, -} + [ChainId.ARBITRUM_ONE]: 20_000, + [ChainId.ARBITRUM_GOERLI]: 20_000, + [ChainId.POLYGON_ZKEVM]: 20_000, + [ChainId.POLYGON_ZKEVM_TESTNET]: 20_000, + [ChainId.ZKSYNC]: 20_000, + [ChainId.ZKSYNC_TESTNET]: 20_000, + [ChainId.LINEA_TESTNET]: 30_000, +} as const satisfies Record diff --git a/apps/web/src/hooks/useApproveCallback.ts b/apps/web/src/hooks/useApproveCallback.ts index 9abec7465..0686680b4 100644 --- a/apps/web/src/hooks/useApproveCallback.ts +++ b/apps/web/src/hooks/useApproveCallback.ts @@ -3,7 +3,7 @@ import { useTranslation } from '@pancakeswap/localization' import { Currency, CurrencyAmount, ERC20Token, Trade, TradeType } from '@pancakeswap/sdk' import { useToast } from '@pancakeswap/uikit' import { useAccount, Address } from 'wagmi' -import { ROUTER_ADDRESS } from 'config/constants/exchange' +import { V2_ROUTER_ADDRESS } from 'config/constants/exchange' import { useCallback, useMemo } from 'react' import { isUserRejected, logError } from 'utils/sentry' import { SendTransactionResult } from 'wagmi/actions' @@ -168,7 +168,7 @@ export function useApproveCallbackFromTrade( [trade, allowedSlippage], ) - return useApproveCallback(amountToApprove, ROUTER_ADDRESS[chainId]) + return useApproveCallback(amountToApprove, V2_ROUTER_ADDRESS[chainId]) } export function useApproveCallbackFromAmount({ diff --git a/apps/web/src/hooks/useBUSDPrice.ts b/apps/web/src/hooks/useBUSDPrice.ts index f2bffa3b4..e5e75344c 100644 --- a/apps/web/src/hooks/useBUSDPrice.ts +++ b/apps/web/src/hooks/useBUSDPrice.ts @@ -47,9 +47,9 @@ export function useStablecoinPrice( const cakePrice = useCakePriceAsBN() const stableCoin = chainId in ChainId ? STABLE_COIN[chainId as ChainId] : undefined - const isCake = currency?.wrapped.equals(CAKE[chainId]) + const isCake = currency && CAKE[chainId] && currency.wrapped.equals(CAKE[chainId]) - const isStableCoin = currency?.wrapped.equals(stableCoin) + const isStableCoin = currency && stableCoin && currency.wrapped.equals(stableCoin) const shouldEnabled = currency && stableCoin && enabled && currentChainId === chainId && !isCake && !isStableCoin @@ -57,9 +57,9 @@ export function useStablecoinPrice( // we don't have too many AMM pools on ethereum yet, try to get it from api const { data: priceFromLlama, isLoading } = useSWRImmutable( - enableLlama && ['fiat-price-ethereum', currency], + currency && enableLlama && ['fiat-price-ethereum', currency], async () => { - const address = currency.isToken ? currency.address : WETH9[ChainId.ETHEREUM].address + const address = currency?.isToken ? currency.address : WETH9[ChainId.ETHEREUM]?.address return fetch(`https://coins.llama.fi/prices/current/ethereum:${address}`) // <3 llama .then((res) => res.json()) .then( @@ -259,6 +259,9 @@ export const usePriceByPairs = (currencyA?: Currency, currencyB?: Currency) => { if (!reserves) { return null } + if (!tokenA || !tokenB) { + return null + } const [reserve0, reserve1] = reserves const [token0, token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA] diff --git a/apps/web/src/hooks/useCommonPools.ts b/apps/web/src/hooks/useCommonPools.ts index d86eb740b..4ae38983b 100644 --- a/apps/web/src/hooks/useCommonPools.ts +++ b/apps/web/src/hooks/useCommonPools.ts @@ -40,7 +40,6 @@ function commonPoolsHookCreator({ useV3Pools }: FactoryOptions) { syncing: v3Syncing, blockNumber: v3BlockNumber, refresh: v3Refresh, - error, } = useV3Pools(currencyA, currencyB, { blockNumber, enabled }) const { pools: v2Pools, @@ -71,10 +70,22 @@ function commonPoolsHookCreator({ useV3Pools }: FactoryOptions) { // FIXME: allow inconsistent block not working as expected const pools = useMemo( () => - v2Pools && (v3Pools || error) && stablePools && (allowInconsistentBlock || !!consistentBlockNumber) - ? [...v2Pools, ...(v3Pools || []), ...stablePools] + (!v2Loading || v2Pools) && + (!v3Loading || v3Pools) && + (!stableLoading || stablePools) && + (allowInconsistentBlock || !!consistentBlockNumber) + ? [...(v2Pools || []), ...(v3Pools || []), ...(stablePools || [])] : undefined, - [v2Pools, v3Pools, stablePools, allowInconsistentBlock, consistentBlockNumber, error], + [ + v2Loading, + v2Pools, + v3Loading, + v3Pools, + stableLoading, + stablePools, + allowInconsistentBlock, + consistentBlockNumber, + ], ) const refresh = useCallback(() => { diff --git a/apps/web/src/hooks/useDomain.ts b/apps/web/src/hooks/useDomain.ts index 880f75a83..4b1b726d1 100644 --- a/apps/web/src/hooks/useDomain.ts +++ b/apps/web/src/hooks/useDomain.ts @@ -14,11 +14,12 @@ export const useDomainNameForAddress = (address: `0x${string}` | string, fetchDa ) const { data: ensName, isLoading: isEnsLoading } = useEnsName({ address: address as Address, - chainId, + chainId: chainId === ChainId.GOERLI ? ChainId.GOERLI : ChainId.ETHEREUM, enabled: chainId !== ChainId.BSC && chainId !== ChainId.BSC_TESTNET, }) const { data: ensAvatar, isLoading: isEnsAvatarLoading } = useEnsAvatar({ name: ensName, + chainId: chainId === ChainId.GOERLI ? ChainId.GOERLI : ChainId.ETHEREUM, enabled: chainId !== ChainId.BSC && chainId !== ChainId.BSC_TESTNET, }) diff --git a/apps/web/src/hooks/useInfoUserSavedTokensAndPoolsList.ts b/apps/web/src/hooks/useInfoUserSavedTokensAndPoolsList.ts index eb1b2f29e..7fd4e4ba8 100644 --- a/apps/web/src/hooks/useInfoUserSavedTokensAndPoolsList.ts +++ b/apps/web/src/hooks/useInfoUserSavedTokensAndPoolsList.ts @@ -21,6 +21,34 @@ const defaultTokenAndPoolList: TokenAndPoolList = { tokens: [], pools: [], }, + [ChainId.ARBITRUM_ONE]: { + tokens: [], + pools: [], + }, + [ChainId.ARBITRUM_GOERLI]: { + tokens: [], + pools: [], + }, + [ChainId.POLYGON_ZKEVM]: { + tokens: [], + pools: [], + }, + [ChainId.POLYGON_ZKEVM_TESTNET]: { + tokens: [], + pools: [], + }, + [ChainId.ZKSYNC]: { + tokens: [], + pools: [], + }, + [ChainId.ZKSYNC_TESTNET]: { + tokens: [], + pools: [], + }, + [ChainId.LINEA_TESTNET]: { + tokens: [], + pools: [], + }, } const tokensAtom = atomWithStorage('pcs:infoSavedTOkensAndPools', defaultTokenAndPoolList) diff --git a/apps/web/src/hooks/useSubgraphHealth.ts b/apps/web/src/hooks/useSubgraphHealth.ts index 269cd2c82..bb35699a9 100644 --- a/apps/web/src/hooks/useSubgraphHealth.ts +++ b/apps/web/src/hooks/useSubgraphHealth.ts @@ -23,7 +23,7 @@ export type SubgraphHealthState = { const NOT_OK_BLOCK_DIFFERENCE = 200 // ~15 minutes delay const WARNING_BLOCK_DIFFERENCE = 50 // ~2.5 minute delay -const useSubgraphHealth = (subgraphName: string) => { +const useSubgraphHealth = (subgraphName?: string) => { const [sgHealth, setSgHealth] = useState({ status: SubgraphStatus.UNKNOWN, currentBlock: 0, @@ -90,7 +90,9 @@ const useSubgraphHealth = (subgraphName: string) => { }) } } - getSubgraphHealth() + if (subgraphName) { + getSubgraphHealth() + } }, [subgraphName], ) diff --git a/apps/web/src/hooks/useSwapCallback.ts b/apps/web/src/hooks/useSwapCallback.ts index ad09a54d9..061549240 100644 --- a/apps/web/src/hooks/useSwapCallback.ts +++ b/apps/web/src/hooks/useSwapCallback.ts @@ -180,6 +180,8 @@ export function useSwapCallback( }, ) logSwap({ + account, + hash: response, chainId, inputAmount, outputAmount, diff --git a/apps/web/src/hooks/useV3Pools.ts b/apps/web/src/hooks/useV3Pools.ts index 1ce46cdc2..87c7542b0 100644 --- a/apps/web/src/hooks/useV3Pools.ts +++ b/apps/web/src/hooks/useV3Pools.ts @@ -85,6 +85,7 @@ export function useV3CandidatePoolsWithoutTicks( } return POOLS_FAST_REVALIDATE[currencyA.chainId] || 0 }, [currencyA?.chainId]) + const { data, refetch, diff --git a/apps/web/src/hooks/v3/useV3Positions.ts b/apps/web/src/hooks/v3/useV3Positions.ts index 0502f7351..e613f0985 100644 --- a/apps/web/src/hooks/v3/useV3Positions.ts +++ b/apps/web/src/hooks/v3/useV3Positions.ts @@ -103,7 +103,7 @@ export function useV3TokenIdsByAccount( address: contractAddress as `0x${string}`, args: [account ?? undefined], functionName: 'balanceOf', - enabled: !!account, + enabled: !!account && !!contractAddress, watch: true, chainId, }) diff --git a/apps/web/src/pages/api/v3/[chainId]/farms/index.ts b/apps/web/src/pages/api/v3/[chainId]/farms/index.ts index 0248d78ee..f03099766 100644 --- a/apps/web/src/pages/api/v3/[chainId]/farms/index.ts +++ b/apps/web/src/pages/api/v3/[chainId]/farms/index.ts @@ -19,7 +19,7 @@ const handler: NextApiHandler = async (req, res) => { const chainId = parsed.data - if (farmFetcherV3.isChainSupported(chainId) === false) { + if (!farmFetcherV3.isChainSupported(chainId)) { return res.status(400).json({ error: 'Chain not supported' }) } const farms = farmsV3ConfigChainMap[chainId] @@ -27,7 +27,7 @@ const handler: NextApiHandler = async (req, res) => { const commonPrice = await fetchCommonTokenUSDValue(priceHelperTokens[chainId]) const data = await farmFetcherV3.fetchFarms({ - chainId: parsed.data, + chainId, farms, commonPrice, }) diff --git a/apps/web/src/pages/liquidity/[tokenId].tsx b/apps/web/src/pages/liquidity/[tokenId].tsx index 183fc4937..80a8e93c5 100644 --- a/apps/web/src/pages/liquidity/[tokenId].tsx +++ b/apps/web/src/pages/liquidity/[tokenId].tsx @@ -278,8 +278,7 @@ export default function PoolPage() { !currency0ForFeeCollectionPurposes || !currency1ForFeeCollectionPurposes || !chainId || - !positionManager || - !masterchefV3 || + !manager || !account || !tokenId ) @@ -339,14 +338,12 @@ export default function PoolPage() { currency0ForFeeCollectionPurposes, currency1ForFeeCollectionPurposes, chainId, - positionManager, - masterchefV3, + manager, account, tokenId, interfaceManager, feeValue0, feeValue1, - manager.address, signer, sendTransactionAsync, addTransaction, diff --git a/apps/web/src/pages/liquidity/index.tsx b/apps/web/src/pages/liquidity/index.tsx index 66418264a..6e251a253 100644 --- a/apps/web/src/pages/liquidity/index.tsx +++ b/apps/web/src/pages/liquidity/index.tsx @@ -15,10 +15,9 @@ import { useModal, } from '@pancakeswap/uikit' import { PositionDetails } from '@pancakeswap/farms' - +import { isStableSwapSupported } from '@pancakeswap/smart-router/evm' import NextLink from 'next/link' import styled from 'styled-components' -import { useWeb3React } from '@pancakeswap/wagmi' import { AppBody, AppHeader } from 'components/App' import { useV3Positions } from 'hooks/v3/useV3Positions' import { CHAIN_IDS } from 'utils/wagmi' @@ -43,6 +42,7 @@ import atomWithStorageWithErrorCatch from 'utils/atomWithStorageWithErrorCatch' import { useAtom } from 'jotai' import { FindOtherLP } from '@pancakeswap/uikit/src/widgets/Liquidity' import { V3SubgraphHealthIndicator } from 'components/SubgraphHealthIndicator' +import useActiveWeb3React from 'hooks/useActiveWeb3React' const Body = styled(CardBody)` background-color: ${({ theme }) => theme.colors.dropdownDeep}; @@ -77,7 +77,7 @@ function useHideClosePosition() { } export default function PoolListPage() { - const { account } = useWeb3React() + const { account, chainId } = useActiveWeb3React() const { t } = useTranslation() const [selectedTypeIndex, setSelectedTypeIndex] = useState(FILTER.ALL) @@ -238,7 +238,9 @@ export default function PoolListPage() { > {t('All')} V3 - {t('StableSwap')} + + {t('StableSwap')} + V2 diff --git a/apps/web/src/pages/v2/migrate/[address].tsx b/apps/web/src/pages/v2/migrate/[address].tsx index 4d891d3bc..d58696682 100644 --- a/apps/web/src/pages/v2/migrate/[address].tsx +++ b/apps/web/src/pages/v2/migrate/[address].tsx @@ -1,8 +1,8 @@ +import { ChainId } from '@pancakeswap/sdk' import { AppHeader } from 'components/App' import { BodyWrapper } from 'components/App/AppBody' import { useRouter } from 'next/router' import { isAddress } from 'utils' -import { CHAIN_IDS } from 'utils/wagmi' import LiquidityFormProvider from 'views/AddLiquidityV3/formViews/V3FormView/form/LiquidityFormProvider' import { Migrate } from 'views/AddLiquidityV3/Migrate' import Page from 'views/Page' @@ -28,4 +28,4 @@ function MigratePage() { export default MigratePage -MigratePage.chains = CHAIN_IDS +MigratePage.chains = [ChainId.BSC, ChainId.ETHEREUM, ChainId.BSC_TESTNET, ChainId.GOERLI] diff --git a/apps/web/src/state/farms/hooks.ts b/apps/web/src/state/farms/hooks.ts index 3704fbb71..9f10fc1d7 100644 --- a/apps/web/src/state/farms/hooks.ts +++ b/apps/web/src/state/farms/hooks.ts @@ -7,7 +7,13 @@ import useSWRImmutable from 'swr/immutable' import { useBCakeProxyContractAddress } from 'views/Farms/hooks/useBCakeProxyContractAddress' import { getMasterChefContract } from 'utils/contractHelpers' import { getFarmConfig } from '@pancakeswap/farms/constants' -import { DeserializedFarm, DeserializedFarmsState, DeserializedFarmUserData } from '@pancakeswap/farms' +import { + DeserializedFarm, + DeserializedFarmsState, + DeserializedFarmUserData, + supportedChainIdV2, + bCakeSupportedChainId, +} from '@pancakeswap/farms' import { useActiveChainId } from 'hooks/useActiveChainId' import { useCakePriceAsBN } from '@pancakeswap/utils/useCakePrice' @@ -22,19 +28,25 @@ import { export function useFarmsLength() { const { chainId } = useActiveChainId() - return useSWRImmutable(chainId ? ['farmsLength', chainId] : null, async () => { - const mc = getMasterChefContract(undefined, chainId) - return Number(await mc.read.poolLength()) - }) + return useSWRImmutable( + chainId && supportedChainIdV2.includes(chainId) ? ['farmsLength', chainId] : null, + async () => { + const mc = getMasterChefContract(undefined, chainId) + return Number(await mc.read.poolLength()) + }, + ) } export function useFarmV2PublicAPI() { const { chainId } = useActiveChainId() - return useSWRImmutable(chainId ? ['farm-v2-pubic-api', chainId] : null, async () => { - return fetch(`https://farms-api.pancakeswap.com/${chainId}`) - .then((res) => res.json()) - .then((res) => res.data) - }) + return useSWRImmutable( + chainId && supportedChainIdV2.includes(chainId) ? ['farm-v2-pubic-api', chainId] : null, + async () => { + return fetch(`https://farms-api.pancakeswap.com/${chainId}`) + .then((res) => res.json()) + .then((res) => res.data) + }, + ) } export const usePollFarmsWithUserData = () => { @@ -47,9 +59,10 @@ export const usePollFarmsWithUserData = () => { } = useBCakeProxyContractAddress(account, chainId) useSWRImmutable( - chainId ? ['publicFarmData', chainId] : null, + chainId && supportedChainIdV2.includes(chainId) ? ['publicFarmData', chainId] : null, async () => { - const farmsConfig = (await getFarmConfig(chainId)) || [] + const farmsConfig = await getFarmConfig(chainId) + if (!farmsConfig) return const pids = farmsConfig.map((farmToFetch) => farmToFetch.pid) dispatch(fetchFarmsPublicDataAsync({ pids, chainId })) @@ -64,9 +77,10 @@ export const usePollFarmsWithUserData = () => { : ['farmsWithUserData', account, chainId] useSWRImmutable( - account && chainId && !isProxyContractLoading ? name : null, + account && chainId && bCakeSupportedChainId.includes(chainId) && !isProxyContractLoading ? name : null, async () => { - const farmsConfig = (await getFarmConfig(chainId)) || [] + const farmsConfig = await getFarmConfig(chainId) + if (!farmsConfig) return const pids = farmsConfig.map((farmToFetch) => farmToFetch.pid) const params = proxyCreated ? { account, pids, proxyAddress, chainId } : { account, pids, chainId } dispatch(fetchFarmUserDataAsync(params)) diff --git a/apps/web/src/state/farmsV3/hooks.ts b/apps/web/src/state/farmsV3/hooks.ts index 38980d5ef..8c6f215a0 100644 --- a/apps/web/src/state/farmsV3/hooks.ts +++ b/apps/web/src/state/farmsV3/hooks.ts @@ -59,7 +59,7 @@ export const useFarmsV3Public = () => { const { chainId } = useActiveChainId() return useSWR( - [chainId, 'farmV3ApiFetch'], + farmFetcherV3.isChainSupported(chainId) && [chainId, 'farmV3ApiFetch'], async () => { if (API_FLAG) { return farmV3ApiFetch(chainId).catch((err) => { diff --git a/apps/web/src/state/lists/hooks.ts b/apps/web/src/state/lists/hooks.ts index d0d31a8a8..d78d5d19b 100644 --- a/apps/web/src/state/lists/hooks.ts +++ b/apps/web/src/state/lists/hooks.ts @@ -221,6 +221,13 @@ function combineMaps(map1: TokenAddressMap, map2: TokenAddressMap): TokenAddress [ChainId.GOERLI]: { ...map1[ChainId.GOERLI], ...map2[ChainId.GOERLI] }, [ChainId.BSC]: { ...map1[ChainId.BSC], ...map2[ChainId.BSC] }, [ChainId.BSC_TESTNET]: { ...map1[ChainId.BSC_TESTNET], ...map2[ChainId.BSC_TESTNET] }, + [ChainId.ARBITRUM_ONE]: { ...map1[ChainId.ARBITRUM_ONE], ...map2[ChainId.ARBITRUM_ONE] }, + [ChainId.ARBITRUM_GOERLI]: { ...map1[ChainId.ARBITRUM_GOERLI], ...map2[ChainId.ARBITRUM_GOERLI] }, + [ChainId.POLYGON_ZKEVM]: { ...map1[ChainId.POLYGON_ZKEVM], ...map2[ChainId.POLYGON_ZKEVM] }, + [ChainId.POLYGON_ZKEVM_TESTNET]: { ...map1[ChainId.POLYGON_ZKEVM_TESTNET], ...map2[ChainId.POLYGON_ZKEVM_TESTNET] }, + [ChainId.ZKSYNC]: { ...map1[ChainId.ZKSYNC], ...map2[ChainId.ZKSYNC] }, + [ChainId.ZKSYNC_TESTNET]: { ...map1[ChainId.ZKSYNC_TESTNET], ...map2[ChainId.ZKSYNC_TESTNET] }, + [ChainId.LINEA_TESTNET]: { ...map1[ChainId.LINEA_TESTNET], ...map2[ChainId.LINEA_TESTNET] }, } } diff --git a/apps/web/src/state/multicall/fetchChunk.ts b/apps/web/src/state/multicall/fetchChunk.ts index fe8520bbd..2ea15c3e8 100644 --- a/apps/web/src/state/multicall/fetchChunk.ts +++ b/apps/web/src/state/multicall/fetchChunk.ts @@ -1,9 +1,17 @@ +import { ChainId } from '@pancakeswap/sdk' import { getViemClients } from 'utils/viem' import { multicallABI } from 'config/abi/Multicall' import { getMulticallAddress } from 'utils/addressHelpers' import { Call } from './actions' import { RetryableError } from './retry' +const l2DifferentBlockNumberChains = [ + ChainId.ZKSYNC, + ChainId.ZKSYNC_TESTNET, + ChainId.ARBITRUM_ONE, + ChainId.ARBITRUM_GOERLI, +] + export type FetchChunkResult = ReturnType /** @@ -57,9 +65,15 @@ export async function fetchChunk( console.debug('Failed to fetch chunk inside retry', error) throw error } - if (Number(resultsBlockNumber) < minBlockNumber) { + + const l2DifferentBlockNumber = l2DifferentBlockNumberChains.includes(chainId) + + if (Number(resultsBlockNumber) < minBlockNumber && !l2DifferentBlockNumber) { console.debug(`Fetched results for old block number: ${resultsBlockNumber.toString()} vs. ${minBlockNumber}`) } - return { results: returnData, blockNumber: Number(resultsBlockNumber) } + return { + results: returnData, + blockNumber: l2DifferentBlockNumber ? minBlockNumber : Number(resultsBlockNumber), + } } diff --git a/apps/web/src/state/swap/fetch/fetchDerivedPriceData.ts b/apps/web/src/state/swap/fetch/fetchDerivedPriceData.ts index ea53a4ee3..e3e754a42 100644 --- a/apps/web/src/state/swap/fetch/fetchDerivedPriceData.ts +++ b/apps/web/src/state/swap/fetch/fetchDerivedPriceData.ts @@ -1,5 +1,11 @@ import { ChainId } from '@pancakeswap/sdk' -import { INFO_CLIENT, INFO_CLIENT_ETH, STABLESWAP_SUBGRAPH_CLIENT, V3_SUBGRAPH_URLS } from 'config/constants/endpoints' +import { + INFO_CLIENT, + INFO_CLIENT_ETH, + INFO_CLIENT_WITH_CHAIN, + STABLESWAP_SUBGRAPH_CLIENT, + V3_SUBGRAPH_URLS, +} from 'config/constants/endpoints' import { ONE_DAY_UNIX, ONE_HOUR_SECONDS } from 'config/constants/info' import { getUnixTime, startOfHour, sub } from 'date-fns' import request from 'graphql-request' @@ -31,6 +37,20 @@ const SWAP_INFO_BY_CHAIN = { v3: V3_SUBGRAPH_URLS[ChainId.BSC_TESTNET], }, [ChainId.GOERLI]: {}, + // TODO: new chains + [ChainId.ARBITRUM_ONE]: { + v2: INFO_CLIENT_WITH_CHAIN[ChainId.ARBITRUM_ONE], + v3: V3_SUBGRAPH_URLS[ChainId.ARBITRUM_ONE], + }, + [ChainId.ARBITRUM_GOERLI]: {}, + [ChainId.POLYGON_ZKEVM]: {}, + [ChainId.POLYGON_ZKEVM_TESTNET]: {}, + [ChainId.ZKSYNC]: {}, + [ChainId.ZKSYNC_TESTNET]: {}, + [ChainId.LINEA_TESTNET]: { + v2: INFO_CLIENT_WITH_CHAIN[ChainId.LINEA_TESTNET], + v3: V3_SUBGRAPH_URLS[ChainId.LINEA_TESTNET], + }, } satisfies Record> export const getTokenBestTvlProtocol = async (tokenAddress: string, chainId: ChainId): Promise => { diff --git a/apps/web/src/state/swap/hooks.ts b/apps/web/src/state/swap/hooks.ts index 9767fc186..5e9ba9712 100644 --- a/apps/web/src/state/swap/hooks.ts +++ b/apps/web/src/state/swap/hooks.ts @@ -1,6 +1,6 @@ import { useTranslation } from '@pancakeswap/localization' import { Currency, CurrencyAmount, Price, Trade, TradeType } from '@pancakeswap/sdk' -import { CAKE, USDC } from '@pancakeswap/tokens' +import { CAKE, USDC, USDT } from '@pancakeswap/tokens' import tryParseAmount from '@pancakeswap/utils/tryParseAmount' import { useUserSlippage } from '@pancakeswap/utils/user' import { SLOW_INTERVAL } from 'config/constants' @@ -259,7 +259,11 @@ export function useDefaultsFromURLSearch(): useEffect(() => { if (!chainId || !native || !isReady) return - const parsed = queryParametersToSwapState(query, native.symbol, CAKE[chainId]?.address ?? USDC[chainId]?.address) + const parsed = queryParametersToSwapState( + query, + native.symbol, + CAKE[chainId]?.address ?? USDC[chainId]?.address ?? USDT[chainId]?.address, + ) dispatch( replaceSwapState({ diff --git a/apps/web/src/utils/addressHelpers.ts b/apps/web/src/utils/addressHelpers.ts index 7954f5d4b..90c62c63e 100644 --- a/apps/web/src/utils/addressHelpers.ts +++ b/apps/web/src/utils/addressHelpers.ts @@ -10,6 +10,10 @@ export const getAddressFromMap = (address: Addresses, chainId?: number): `0x${st return address[chainId] ? address[chainId] : address[ChainId.BSC] } +export const getAddressFromMapNoFallback = (address: Addresses, chainId?: number): `0x${string}` | null => { + return address[chainId] +} + export const getMasterChefV2Address = (chainId?: number) => { return getAddressFromMap(addresses.masterChef, chainId) } @@ -114,7 +118,7 @@ export const getStableSwapNativeHelperAddress = (chainId?: number) => { } export const getMasterChefV3Address = (chainId?: number) => { - return getAddressFromMap(addresses.masterChefV3, chainId) + return getAddressFromMapNoFallback(addresses.masterChefV3, chainId) } export const getV3MigratorAddress = (chainId?: number) => { diff --git a/apps/web/src/utils/contractHelpers.ts b/apps/web/src/utils/contractHelpers.ts index 96654eedd..ed26b6881 100644 --- a/apps/web/src/utils/contractHelpers.ts +++ b/apps/web/src/utils/contractHelpers.ts @@ -335,12 +335,15 @@ export const getMasterChefContract = (signer?: WalletClient, chainId?: number) = }) } export const getMasterChefV3Contract = (signer?: WalletClient, chainId?: number) => { - return getContract({ - abi: masterChefV3ABI, - address: getMasterChefV3Address(chainId), - chainId, - signer, - }) + const mcv3Address = getMasterChefV3Address(chainId) + return mcv3Address + ? getContract({ + abi: masterChefV3ABI, + address: getMasterChefV3Address(chainId), + chainId, + signer, + }) + : null } export const getV3MigratorContract = (signer?: WalletClient, chainId?: number) => { diff --git a/apps/web/src/utils/exchange.ts b/apps/web/src/utils/exchange.ts index ad8b9e042..868be93ad 100644 --- a/apps/web/src/utils/exchange.ts +++ b/apps/web/src/utils/exchange.ts @@ -8,7 +8,7 @@ import { BLOCKED_PRICE_IMPACT_NON_EXPERT, INPUT_FRACTION_AFTER_FEE, ONE_HUNDRED_PERCENT, - ROUTER_ADDRESS, + V2_ROUTER_ADDRESS, } from 'config/constants/exchange' import { StableTrade } from 'config/constants/types' @@ -33,7 +33,7 @@ export function calculateSlippageAmount(value: CurrencyAmount, slippag export function useRouterContract() { const { chainId } = useActiveChainId() - return useContract(ROUTER_ADDRESS[chainId], pancakeRouter02ABI) + return useContract(V2_ROUTER_ADDRESS[chainId], pancakeRouter02ABI) } // computes price breakdown for the trade diff --git a/apps/web/src/utils/graphql.ts b/apps/web/src/utils/graphql.ts index d560edead..4d57812da 100644 --- a/apps/web/src/utils/graphql.ts +++ b/apps/web/src/utils/graphql.ts @@ -38,6 +38,12 @@ export const v3Clients = { [ChainId.GOERLI]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.GOERLI]), [ChainId.BSC]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.BSC]), [ChainId.BSC_TESTNET]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.BSC_TESTNET]), + [ChainId.ARBITRUM_ONE]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.ARBITRUM_ONE]), + [ChainId.ARBITRUM_GOERLI]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.ARBITRUM_GOERLI]), + // TODO: new chain + [ChainId.POLYGON_ZKEVM]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.POLYGON_ZKEVM]), + [ChainId.ZKSYNC_TESTNET]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.ZKSYNC_TESTNET]), + [ChainId.LINEA_TESTNET]: new GraphQLClient(V3_SUBGRAPH_URLS[ChainId.LINEA_TESTNET]), } export const v3InfoClients = { ...v3Clients, [ChainId.BSC]: new GraphQLClient(V3_BSC_INFO_CLIENT) } diff --git a/apps/web/src/utils/log.ts b/apps/web/src/utils/log.ts index a74ae3091..2ed33ef09 100644 --- a/apps/web/src/utils/log.ts +++ b/apps/web/src/utils/log.ts @@ -11,6 +11,8 @@ export const logSwap = ({ inputAmount, outputAmount, chainId, + account, + hash, type, }: { input: Currency @@ -18,6 +20,8 @@ export const logSwap = ({ inputAmount: string outputAmount: string chainId: number + account: `0x${string}` + hash: `0x${string}` type: 'V2Swap' | 'SmartSwap' | 'StableSwap' | 'MarketMakerSwap' | 'V3SmartSwap' }) => { try { @@ -26,6 +30,8 @@ export const logSwap = ({ outputAddress: output.isToken ? output.address.toLowerCase() : output.symbol, inputAmount, outputAmount, + account, + hash, chainId, }) } catch (error) { diff --git a/apps/web/src/views/AddLiquidity/index.tsx b/apps/web/src/views/AddLiquidity/index.tsx index c43f7392b..d544bca7a 100644 --- a/apps/web/src/views/AddLiquidity/index.tsx +++ b/apps/web/src/views/AddLiquidity/index.tsx @@ -4,7 +4,7 @@ import { useModal } from '@pancakeswap/uikit' import { useTranslation } from '@pancakeswap/localization' import { useUserSlippage } from '@pancakeswap/utils/user' -import { ROUTER_ADDRESS } from 'config/constants/exchange' +import { V2_ROUTER_ADDRESS } from 'config/constants/exchange' import { useIsTransactionUnsupported, useIsTransactionWarning } from 'hooks/Trades' import { useLPApr } from 'state/swap/useLPApr' import { isUserRejected, logError } from 'utils/sentry' @@ -152,8 +152,8 @@ export default function AddLiquidity({ ) // check whether the user has approved the router on the tokens - const [approvalA, approveACallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_A], ROUTER_ADDRESS[chainId]) - const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], ROUTER_ADDRESS[chainId]) + const [approvalA, approveACallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_A], V2_ROUTER_ADDRESS[chainId]) + const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], V2_ROUTER_ADDRESS[chainId]) const addTransaction = useTransactionAdder() diff --git a/apps/web/src/views/AddLiquidityV3/IncreaseLiquidityV3.tsx b/apps/web/src/views/AddLiquidityV3/IncreaseLiquidityV3.tsx index fd79854bd..2d4d61266 100644 --- a/apps/web/src/views/AddLiquidityV3/IncreaseLiquidityV3.tsx +++ b/apps/web/src/views/AddLiquidityV3/IncreaseLiquidityV3.tsx @@ -146,7 +146,7 @@ export default function IncreaseLiquidityV3({ currencyA: baseCurrency, currencyB const showApprovalB = approvalB !== ApprovalState.APPROVED && !!parsedAmounts[Field.CURRENCY_B] const onIncrease = useCallback(async () => { - if (!chainId || !sendTransactionAsync || !account || !positionManager || !masterchefV3) return + if (!chainId || !sendTransactionAsync || !account || !interfaceManager || !manager) return if (tokenIdsInMCv3Loading || !positionManager || !baseCurrency || !quoteCurrency) { return @@ -225,8 +225,7 @@ export default function IncreaseLiquidityV3({ currencyA: baseCurrency, currencyB deadline, hasExistingPosition, interfaceManager, - manager.address, - masterchefV3, + manager, noLiquidity, parsedAmounts, position, diff --git a/apps/web/src/views/AddLiquidityV3/Migrate.tsx b/apps/web/src/views/AddLiquidityV3/Migrate.tsx index 04dc8baa7..8b5bc08fd 100644 --- a/apps/web/src/views/AddLiquidityV3/Migrate.tsx +++ b/apps/web/src/views/AddLiquidityV3/Migrate.tsx @@ -31,7 +31,7 @@ import { FeeAmount, Pool, Position, priceToClosestTick, TickMath } from '@pancak import { Address, useContractRead, useSignTypedData } from 'wagmi' import { CommitButton } from 'components/CommitButton' import LiquidityChartRangeInput from 'components/LiquidityChartRangeInput' -import { ROUTER_ADDRESS } from 'config/constants/exchange' +import { V2_ROUTER_ADDRESS } from 'config/constants/exchange' import { ApprovalState, useApproveCallback } from 'hooks/useApproveCallback' import { useV2Pair } from 'hooks/usePairs' import useTotalSupply from 'hooks/useTotalSupply' @@ -302,7 +302,7 @@ function V2PairMigrate({ } | null>(null) const [approval, approveCallback] = useApproveCallback( CurrencyAmount.fromRawAmount(pair.liquidityToken, pairBalance.toString()), - ROUTER_ADDRESS[chainId], + V2_ROUTER_ADDRESS[chainId], ) const pairContractRead = usePairContract(pair?.liquidityToken?.address) diff --git a/apps/web/src/views/AddLiquidityV3/hooks/useCurrencyParams.ts b/apps/web/src/views/AddLiquidityV3/hooks/useCurrencyParams.ts index f9b658a68..57f8d228b 100644 --- a/apps/web/src/views/AddLiquidityV3/hooks/useCurrencyParams.ts +++ b/apps/web/src/views/AddLiquidityV3/hooks/useCurrencyParams.ts @@ -1,4 +1,4 @@ -import { CAKE, USDC } from '@pancakeswap/tokens' +import { CAKE, USDC, USDT } from '@pancakeswap/tokens' import { FeeAmount } from '@pancakeswap/v3-sdk' import { useActiveChainId } from 'hooks/useActiveChainId' import useNativeCurrency from 'hooks/useNativeCurrency' @@ -14,7 +14,10 @@ export function useCurrencyParams(): { const native = useNativeCurrency() const [currencyIdA, currencyIdB, feeAmountFromUrl] = router.isReady - ? router.query.currency || [native.symbol, CAKE[chainId]?.address || USDC[chainId]?.address] + ? router.query.currency || [ + native.symbol, + CAKE[chainId]?.address || USDC[chainId]?.address || USDT[chainId]?.address, + ] : [undefined, undefined, undefined] const feeAmount: FeeAmount | undefined = diff --git a/apps/web/src/views/Farms/components/UpdatePositionsReminder.tsx b/apps/web/src/views/Farms/components/UpdatePositionsReminder.tsx index a947f0780..4e7c0cb2b 100644 --- a/apps/web/src/views/Farms/components/UpdatePositionsReminder.tsx +++ b/apps/web/src/views/Farms/components/UpdatePositionsReminder.tsx @@ -73,16 +73,16 @@ export function UpdatePositionsReminder_() { contracts: useMemo( () => stakedTokenIds.map((tokenId) => ({ - abi: masterchefV3.abi, - address: masterchefV3.address, + abi: masterchefV3?.abi, + address: masterchefV3?.address, functionName: 'userPositionInfos', args: [tokenId.toString()], chainId, })), - [chainId, masterchefV3.abi, masterchefV3.address, stakedTokenIds], + [chainId, masterchefV3, stakedTokenIds], ), cacheTime: 0, - enabled: !loading && stakedTokenIds.length > 0, + enabled: Boolean(!loading && stakedTokenIds.length > 0 && masterchefV3), }) const isOverRewardGrowthGlobalUserInfos = stakedUserInfos?.data @@ -149,7 +149,7 @@ export function UpdatePositionsReminder_() { // eslint-disable-next-line consistent-return const handleUpdateAll = async () => { - if (!needRetrigger) return null + if (!needRetrigger || !sendTransactionAsync) return null const calldata = [] needRetrigger.forEach((userInfo) => { if (userInfo.needReduce) { diff --git a/apps/web/src/views/Farms/hooks/useBCakeProxyContractAddress.ts b/apps/web/src/views/Farms/hooks/useBCakeProxyContractAddress.ts index 66944fa9b..e4022238b 100644 --- a/apps/web/src/views/Farms/hooks/useBCakeProxyContractAddress.ts +++ b/apps/web/src/views/Farms/hooks/useBCakeProxyContractAddress.ts @@ -2,8 +2,8 @@ import useSWRImmutable from 'swr/immutable' import { NO_PROXY_CONTRACT } from 'config/constants' import { useBCakeFarmBoosterContract } from 'hooks/useContract' import { FetchStatus } from 'config/constants/types' -import { bCakeSupportedChainId } from '@pancakeswap/farms/src/index' import { Address } from 'wagmi' +import { bCakeSupportedChainId } from '@pancakeswap/farms' export const useBCakeProxyContractAddress = (account?: Address, chainId?: number) => { const bCakeFarmBoosterContract = useBCakeFarmBoosterContract() diff --git a/apps/web/src/views/RemoveLiquidity/RemoveLiquidityV3.tsx b/apps/web/src/views/RemoveLiquidity/RemoveLiquidityV3.tsx index 5f291396a..70dbb065a 100644 --- a/apps/web/src/views/RemoveLiquidity/RemoveLiquidityV3.tsx +++ b/apps/web/src/views/RemoveLiquidity/RemoveLiquidityV3.tsx @@ -133,11 +133,14 @@ function Remove({ tokenId }: { tokenId: bigint }) { const isStakedInMCv3 = Boolean(tokenId && stakedTokenIds.find((id) => id === tokenId)) + const manager = isStakedInMCv3 ? masterchefV3 : positionManager + const interfaceManager = isStakedInMCv3 ? MasterChefV3 : NonfungiblePositionManager + const onRemove = useCallback(async () => { if ( tokenIdsInMCv3Loading || - !masterchefV3 || - !positionManager || + !interfaceManager || + !manager || !liquidityValue0 || !liquidityValue1 || !deadline || @@ -150,9 +153,6 @@ function Remove({ tokenId }: { tokenId: bigint }) { return } - const manager = isStakedInMCv3 ? masterchefV3 : positionManager - const interfaceManager = isStakedInMCv3 ? MasterChefV3 : NonfungiblePositionManager - setAttemptingTxn(true) // we fall back to expecting 0 fees in case the fetch fails, which is safe in the @@ -202,8 +202,8 @@ function Remove({ tokenId }: { tokenId: bigint }) { }) }, [ tokenIdsInMCv3Loading, - masterchefV3, - positionManager, + interfaceManager, + manager, liquidityValue0, liquidityValue1, deadline, @@ -212,7 +212,6 @@ function Remove({ tokenId }: { tokenId: bigint }) { positionSDK, liquidityPercentage, sendTransactionAsync, - isStakedInMCv3, tokenId, allowedSlippage, feeValue0, diff --git a/apps/web/src/views/RemoveLiquidity/index.tsx b/apps/web/src/views/RemoveLiquidity/index.tsx index 7459a1834..e47a72ade 100644 --- a/apps/web/src/views/RemoveLiquidity/index.tsx +++ b/apps/web/src/views/RemoveLiquidity/index.tsx @@ -33,7 +33,7 @@ import { ZapCheckbox } from 'components/CurrencyInputPanel/ZapCheckbox' import { CommitButton } from 'components/CommitButton' import { useTranslation } from '@pancakeswap/localization' import { useUserSlippage } from '@pancakeswap/utils/user' -import { ROUTER_ADDRESS } from 'config/constants/exchange' +import { V2_ROUTER_ADDRESS } from 'config/constants/exchange' import { transactionErrorToUserReadableMessage } from 'utils/transactionErrorToUserReadableMessage' import { useLPApr } from 'state/swap/useLPApr' import { formattedCurrencyAmount } from 'components/Chart/FormattedCurrencyAmount/FormattedCurrencyAmount' @@ -158,7 +158,7 @@ export default function RemoveLiquidity({ currencyA, currencyB, currencyIdA, cur const [signatureData, setSignatureData] = useState<{ v: number; r: string; s: string; deadline: number } | null>(null) const [approval, approveCallback] = useApproveCallback( parsedAmounts[Field.LIQUIDITY], - isZap ? getZapAddress(chainId) : ROUTER_ADDRESS[chainId], + isZap ? getZapAddress(chainId) : V2_ROUTER_ADDRESS[chainId], ) async function onAttemptToApprove() { @@ -193,7 +193,7 @@ export default function RemoveLiquidity({ currencyA, currencyB, currencyIdA, cur ] const message = { owner: account, - spender: ROUTER_ADDRESS[chainId], + spender: V2_ROUTER_ADDRESS[chainId], value: liquidityAmount.quotient.toString(), nonce, deadline: Number(deadline), diff --git a/apps/web/src/views/Swap/MMLinkPools/hooks/useSwapCallback.ts b/apps/web/src/views/Swap/MMLinkPools/hooks/useSwapCallback.ts index 6db835959..b646a5c27 100644 --- a/apps/web/src/views/Swap/MMLinkPools/hooks/useSwapCallback.ts +++ b/apps/web/src/views/Swap/MMLinkPools/hooks/useSwapCallback.ts @@ -170,6 +170,8 @@ export function useSwapCallback( }, ) logSwap({ + account, + hash: response, chainId, inputAmount, outputAmount, diff --git a/apps/web/src/views/Swap/SwapFeaturesContext.tsx b/apps/web/src/views/Swap/SwapFeaturesContext.tsx index 54e467b69..05e7a55d4 100644 --- a/apps/web/src/views/Swap/SwapFeaturesContext.tsx +++ b/apps/web/src/views/Swap/SwapFeaturesContext.tsx @@ -5,6 +5,7 @@ import { useExchangeChartManager } from 'state/user/hooks' import { useActiveChainId } from 'hooks/useActiveChainId' export const SwapFeaturesContext = createContext<{ + isHotTokenSupported: boolean isChartSupported: boolean isStableSupported: boolean isAccessTokenSupported: boolean @@ -13,6 +14,7 @@ export const SwapFeaturesContext = createContext<{ setIsChartExpanded: React.Dispatch> setIsChartDisplayed: React.Dispatch> }>({ + isHotTokenSupported: false, isChartSupported: false, isStableSupported: false, isAccessTokenSupported: false, @@ -29,6 +31,7 @@ const CHART_SUPPORT_CHAIN_IDS = [ ] const ACCESS_TOKEN_SUPPORT_CHAIN_IDS = [ChainId.BSC] const STABLE_SUPPORT_CHAIN_IDS = [ChainId.BSC_TESTNET, ChainId.BSC] +const HOT_TOKEN_SUPPORT_CHAIN_IDS = [ChainId.BSC, ChainId.ETHEREUM] export const SwapFeaturesProvider: React.FC = ({ children }) => { const { isMobile } = useMatchBreakpoints() @@ -48,12 +51,15 @@ export const SwapFeaturesProvider: React.FC = ({ childr const isAccessTokenSupported = useMemo(() => ACCESS_TOKEN_SUPPORT_CHAIN_IDS.includes(chainId), [chainId]) + const isHotTokenSupported = useMemo(() => HOT_TOKEN_SUPPORT_CHAIN_IDS.includes(chainId), [chainId]) + useEffect(() => { setUserChartPreference(isChartDisplayed) }, [isChartDisplayed, setUserChartPreference]) const value = useMemo(() => { return { + isHotTokenSupported, isChartSupported, isStableSupported, isAccessTokenSupported, @@ -63,6 +69,7 @@ export const SwapFeaturesProvider: React.FC = ({ childr setIsChartExpanded, } }, [ + isHotTokenSupported, isChartSupported, isStableSupported, isAccessTokenSupported, diff --git a/apps/web/src/views/Swap/V3Swap/containers/SwapCommitButton.tsx b/apps/web/src/views/Swap/V3Swap/containers/SwapCommitButton.tsx index b6f748327..7ddf2335c 100644 --- a/apps/web/src/views/Swap/V3Swap/containers/SwapCommitButton.tsx +++ b/apps/web/src/views/Swap/V3Swap/containers/SwapCommitButton.tsx @@ -13,7 +13,7 @@ import { Dots, } from '@pancakeswap/uikit' import { useCallback, useEffect, useState, useMemo, memo } from 'react' -import { SWAP_ROUTER_ADDRESSES, SmartRouterTrade } from '@pancakeswap/smart-router/evm' +import { SMART_ROUTER_ADDRESSES, SmartRouterTrade } from '@pancakeswap/smart-router/evm' import { logGTMClickSwapEvent } from 'utils/customGTMEventTracking' import { useIsTransactionUnsupported } from 'hooks/Trades' @@ -83,7 +83,7 @@ export const SwapCommitButton = memo(function SwapCommitButton({ const showWrap = wrapType !== WrapType.NOT_APPLICABLE const [isRoutingSettingChange, resetRoutingSetting] = useRoutingSettingChanged() const slippageAdjustedAmounts = useSlippageAdjustedAmounts(trade) - const routerAddress = SWAP_ROUTER_ADDRESSES[trade?.inputAmount?.currency?.chainId] + const routerAddress = SMART_ROUTER_ADDRESSES[trade?.inputAmount?.currency?.chainId] const amountToApprove = slippageAdjustedAmounts[Field.INPUT] const relevantTokenBalances = useCurrencyBalances(account ?? undefined, [ inputCurrency ?? undefined, diff --git a/apps/web/src/views/Swap/V3Swap/hooks/useRouterAddress.ts b/apps/web/src/views/Swap/V3Swap/hooks/useRouterAddress.ts index b812f0a35..125d9628b 100644 --- a/apps/web/src/views/Swap/V3Swap/hooks/useRouterAddress.ts +++ b/apps/web/src/views/Swap/V3Swap/hooks/useRouterAddress.ts @@ -1,7 +1,7 @@ import { TradeType } from '@pancakeswap/sdk' -import { SmartRouterTrade, RouteType, SWAP_ROUTER_ADDRESSES } from '@pancakeswap/smart-router/evm' +import { SmartRouterTrade, RouteType, SMART_ROUTER_ADDRESSES } from '@pancakeswap/smart-router/evm' -import { ROUTER_ADDRESS } from 'config/constants/exchange' +import { V2_ROUTER_ADDRESS } from 'config/constants/exchange' export function useRouterAddress(trade?: SmartRouterTrade) { if (!trade) { @@ -13,7 +13,7 @@ export function useRouterAddress(trade?: SmartRouterTrade) { currency: { chainId }, } = inputAmount if (routes.length === 1 && routes[0].type === RouteType.V2) { - return ROUTER_ADDRESS[chainId] + return V2_ROUTER_ADDRESS[chainId] } - return SWAP_ROUTER_ADDRESSES[chainId] + return SMART_ROUTER_ADDRESSES[chainId] } diff --git a/apps/web/src/views/Swap/V3Swap/hooks/useSendSwapTransaction.ts b/apps/web/src/views/Swap/V3Swap/hooks/useSendSwapTransaction.ts index 94b69814b..531e7df3f 100644 --- a/apps/web/src/views/Swap/V3Swap/hooks/useSendSwapTransaction.ts +++ b/apps/web/src/views/Swap/V3Swap/hooks/useSendSwapTransaction.ts @@ -168,7 +168,9 @@ export default function useSendSwapTransaction( type: 'swap', }) logSwap({ + account, chainId, + hash: response.hash, inputAmount, outputAmount, input: trade.inputAmount.currency, diff --git a/apps/web/src/views/Swap/V3Swap/hooks/useSwapCallArguments.ts b/apps/web/src/views/Swap/V3Swap/hooks/useSwapCallArguments.ts index 7562b19b8..7a4e9a50a 100644 --- a/apps/web/src/views/Swap/V3Swap/hooks/useSwapCallArguments.ts +++ b/apps/web/src/views/Swap/V3Swap/hooks/useSwapCallArguments.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Percent, TradeType } from '@pancakeswap/sdk' -import { SWAP_ROUTER_ADDRESSES, SmartRouterTrade, SwapRouter } from '@pancakeswap/smart-router/evm' +import { SMART_ROUTER_ADDRESSES, SmartRouterTrade, SwapRouter } from '@pancakeswap/smart-router/evm' import { FeeOptions } from '@pancakeswap/v3-sdk' import { useMemo } from 'react' import { isAddress } from 'utils' @@ -46,7 +46,7 @@ export function useSwapCallArguments( return useMemo(() => { if (!trade || !recipient || !account || !chainId) return [] - const swapRouterAddress = chainId ? SWAP_ROUTER_ADDRESSES[chainId] : undefined + const swapRouterAddress = chainId ? SMART_ROUTER_ADDRESSES[chainId] : undefined if (!swapRouterAddress) return [] const { value, calldata } = SwapRouter.swapCallParameters(trade, { diff --git a/apps/web/src/views/Swap/components/AccessRisk/index.tsx b/apps/web/src/views/Swap/components/AccessRisk/index.tsx index 10df852e2..1824339aa 100644 --- a/apps/web/src/views/Swap/components/AccessRisk/index.tsx +++ b/apps/web/src/views/Swap/components/AccessRisk/index.tsx @@ -1,5 +1,5 @@ import { Trans, useTranslation } from '@pancakeswap/localization' -import { ERC20Token, Token } from '@pancakeswap/sdk' +import { ChainId, ERC20Token, Token } from '@pancakeswap/sdk' import isUndefinedOrNull from '@pancakeswap/utils/isUndefinedOrNull' import { Button, @@ -73,9 +73,12 @@ function RetryRisk({ onClick }: { onClick: () => void }) { } export function useTokenRisk(token?: Token) { - return useSWRImmutable(token && token.address && ['risk', token.chainId, token.address], () => { - return fetchRiskToken(token.address, token.chainId) - }) + return useSWRImmutable( + token && token.address && token.chainId === ChainId.BSC && ['risk', token.chainId, token.address], + () => { + return fetchRiskToken(token.address, token.chainId) + }, + ) } const AccessRisk: React.FC = ({ token }) => { diff --git a/apps/web/src/views/Swap/components/CurrencyInputHeader.tsx b/apps/web/src/views/Swap/components/CurrencyInputHeader.tsx index 6bf79b184..109bd668c 100644 --- a/apps/web/src/views/Swap/components/CurrencyInputHeader.tsx +++ b/apps/web/src/views/Swap/components/CurrencyInputHeader.tsx @@ -73,7 +73,8 @@ const CurrencyInputHeader: React.FC> = memo( ...(isMobile && { manualVisible: mobileTooltipShow }), }) - const { isChartSupported, isChartDisplayed, setIsChartDisplayed } = useContext(SwapFeaturesContext) + const { isChartSupported, isChartDisplayed, setIsChartDisplayed, isHotTokenSupported } = + useContext(SwapFeaturesContext) const [expertMode] = useExpertMode() const [isRoutingSettingChange] = useRoutingSettingChanged() const toggleChartDisplayed = () => { @@ -140,32 +141,34 @@ const CurrencyInputHeader: React.FC> = memo( )} )} - { - if (!isSwapHotTokenDisplay && isChartDisplayed) { - toggleChartDisplayed() - } - setIsSwapHotTokenDisplay(!isSwapHotTokenDisplay) - }} - > - {isSwapHotTokenDisplay ? ( - - ) : ( - <> - setMobileTooltipShow(false)} - display="flex" - style={{ justifyContent: 'center' }} - > - - - {tooltipVisible && (!isMobile || mobileTooltipShow) && tooltip} - - )} - + {isHotTokenSupported && ( + { + if (!isSwapHotTokenDisplay && isChartDisplayed) { + toggleChartDisplayed() + } + setIsSwapHotTokenDisplay(!isSwapHotTokenDisplay) + }} + > + {isSwapHotTokenDisplay ? ( + + ) : ( + <> + setMobileTooltipShow(false)} + display="flex" + style={{ justifyContent: 'center' }} + > + + + {tooltipVisible && (!isMobile || mobileTooltipShow) && tooltip} + + )} + + )} diff --git a/apps/web/src/views/Swap/index.tsx b/apps/web/src/views/Swap/index.tsx index 1be184a65..dc032bef7 100644 --- a/apps/web/src/views/Swap/index.tsx +++ b/apps/web/src/views/Swap/index.tsx @@ -23,8 +23,14 @@ import { SwapFeaturesContext } from './SwapFeaturesContext' export default function Swap() { const { query } = useRouter() const { isDesktop } = useMatchBreakpoints() - const { isChartExpanded, isChartDisplayed, setIsChartDisplayed, setIsChartExpanded, isChartSupported } = - useContext(SwapFeaturesContext) + const { + isChartExpanded, + isChartDisplayed, + setIsChartDisplayed, + setIsChartExpanded, + isChartSupported, + isHotTokenSupported, + } = useContext(SwapFeaturesContext) const [isSwapHotTokenDisplay, setIsSwapHotTokenDisplay] = useSwapHotTokenDisplay() const { t } = useTranslation() const [firstTime, setFirstTime] = useState(true) @@ -113,8 +119,13 @@ export default function Swap() { setIsOpen={setIsChartDisplayed} /> )} - {isDesktop && isSwapHotTokenDisplay && } - setIsSwapHotTokenDisplay(false)}> + {isDesktop && isSwapHotTokenDisplay && isHotTokenSupported && ( + + )} + setIsSwapHotTokenDisplay(false)} + > = { +export const tradingRewardPairConfigChainMap: Record = { [ChainId.ETHEREUM]: farm1, [ChainId.GOERLI]: farm5, [ChainId.BSC]: [...farm56, ...tradingRewardV3Pair56], diff --git a/packages/farms/constants/common/index.ts b/packages/farms/constants/common/index.ts index cfa29a355..0e46f7454 100644 --- a/packages/farms/constants/common/index.ts +++ b/packages/farms/constants/common/index.ts @@ -1,6 +1,7 @@ import { ChainId, ERC20Token } from '@pancakeswap/sdk' import { bscTestnetTokens, bscTokens, ethereumTokens, goerliTestnetTokens } from '@pancakeswap/tokens' import type { CommonPrice } from '../../src/fetchFarmsV3' +import type { FarmSupportedChainId } from '../../src' export const CAKE_BNB_LP_MAINNET = '0x0eD7e52944161450477ee417DE9Cd3a859b14fD0' @@ -14,7 +15,7 @@ export const CHAIN_ID_TO_CHAIN_NAME = { [ChainId.ETHEREUM]: 'ethereum', [ChainId.GOERLI]: 'ethereum', [ChainId.BSC_TESTNET]: 'bsc', -} satisfies Record +} satisfies Record export const priceHelperTokens = { [ChainId.ETHEREUM]: { @@ -28,7 +29,7 @@ export const priceHelperTokens = { } satisfies Record // for testing purposes -export const DEFAULT_COMMON_PRICE: Record = { +export const DEFAULT_COMMON_PRICE: Record = { [ChainId.ETHEREUM]: {}, [ChainId.GOERLI]: { [goerliTestnetTokens.mockA.address]: '10', diff --git a/packages/farms/constants/index.ts b/packages/farms/constants/index.ts index 3b5c2047e..ffdacb0e8 100644 --- a/packages/farms/constants/index.ts +++ b/packages/farms/constants/index.ts @@ -1,10 +1,10 @@ import { ChainId } from '@pancakeswap/sdk' -import { isStableFarm, SerializedFarmConfig } from '..' +import { isStableFarm, SerializedFarmConfig, supportedChainIdV3 } from '..' let logged = false export const getFarmConfig = async (chainId: ChainId) => { - if (chainId in ChainId) { + if (supportedChainIdV3.includes(chainId as number)) { try { return (await import(`/${chainId}.ts`)).default.filter( (f: SerializedFarmConfig) => f.pid !== null, @@ -21,7 +21,7 @@ export const getFarmConfig = async (chainId: ChainId) => { } export const getStableConfig = async (chainId: ChainId) => { - if (chainId in ChainId) { + if (supportedChainIdV3.includes(chainId as number)) { try { const farms = (await import(`/${chainId}.ts`)).default as SerializedFarmConfig[] diff --git a/packages/farms/constants/v3/index.ts b/packages/farms/constants/v3/index.ts index 871d0f61c..72aed17f6 100644 --- a/packages/farms/constants/v3/index.ts +++ b/packages/farms/constants/v3/index.ts @@ -1,11 +1,12 @@ import { ChainId } from '@pancakeswap/sdk' import { ComputedFarmConfigV3 } from '../../src/types' +import { FarmSupportedChainId } from '../../src' import { farmsV3 as farm1 } from '../1' import { farmsV3 as farm5 } from '../5' import { farmsV3 as farm56 } from '../56' import { farmsV3 as farm97 } from '../97' -export const farmsV3ConfigChainMap: Record = { +export const farmsV3ConfigChainMap: Record = { [ChainId.ETHEREUM]: farm1, [ChainId.GOERLI]: farm5, [ChainId.BSC]: farm56, diff --git a/packages/farms/src/const.ts b/packages/farms/src/const.ts index e97037af3..d6a51e3c6 100644 --- a/packages/farms/src/const.ts +++ b/packages/farms/src/const.ts @@ -1,7 +1,13 @@ import { ChainId } from '@pancakeswap/sdk' +export const supportedChainIdV2 = [ChainId.GOERLI, ChainId.BSC, ChainId.BSC_TESTNET, ChainId.ETHEREUM] as const +export const supportedChainIdV3 = [ChainId.GOERLI, ChainId.BSC, ChainId.BSC_TESTNET, ChainId.ETHEREUM] as const +export const bCakeSupportedChainId = [ChainId.BSC] as const + export const FARM_AUCTION_HOSTING_IN_SECONDS = 691200 +export type FarmSupportedChainId = (typeof supportedChainIdV3)[number] + export const masterChefAddresses = { [ChainId.BSC_TESTNET]: '0xB4A466911556e39210a6bB2FaECBB59E4eB7E43d', [ChainId.BSC]: '0xa5f8C5Dbd5F286960b9d90548680aE5ebFf07652', @@ -12,7 +18,7 @@ export const masterChefV3Addresses = { [ChainId.GOERLI]: '0x864ED564875BdDD6F421e226494a0E7c071C06f8', [ChainId.BSC]: '0x556B9306565093C855AEA9AE92A594704c2Cd59e', [ChainId.BSC_TESTNET]: '0x4c650FB471fe4e0f476fD3437C3411B1122c4e3B', -} as const satisfies Record +} as const satisfies Record export const nonBSCVaultAddresses = { [ChainId.ETHEREUM]: '0x2e71B2688019ebdFDdE5A45e6921aaebb15b25fb', diff --git a/packages/farms/src/index.ts b/packages/farms/src/index.ts index 867f32892..c14601070 100644 --- a/packages/farms/src/index.ts +++ b/packages/farms/src/index.ts @@ -1,7 +1,14 @@ import { PublicClient, formatEther } from 'viem' import { ChainId } from '@pancakeswap/sdk' import BigNumber from 'bignumber.js' -import { masterChefAddresses, masterChefV3Addresses } from './const' +import { + FarmSupportedChainId, + masterChefAddresses, + masterChefV3Addresses, + supportedChainIdV2, + supportedChainIdV3, + bCakeSupportedChainId, +} from './const' import { farmV2FetchFarms, FetchFarmsParams, fetchMasterChefV2Data } from './v2/fetchFarmsV2' import { farmV3FetchFarms, @@ -14,9 +21,7 @@ import { } from './fetchFarmsV3' import { ComputedFarmConfigV3, FarmV3DataWithPrice } from './types' -const supportedChainId = [ChainId.GOERLI, ChainId.BSC, ChainId.BSC_TESTNET, ChainId.ETHEREUM] -const supportedChainIdV3 = [ChainId.GOERLI, ChainId.BSC, ChainId.BSC_TESTNET, ChainId.ETHEREUM] -export const bCakeSupportedChainId = [ChainId.BSC] +export { type FarmSupportedChainId, supportedChainIdV3, bCakeSupportedChainId, supportedChainIdV2 } export function createFarmFetcher(provider: ({ chainId }: { chainId: number }) => PublicClient) { const fetchFarms = async ( @@ -52,8 +57,8 @@ export function createFarmFetcher(provider: ({ chainId }: { chainId: number }) = return { fetchFarms, - isChainSupported: (chainId: number) => supportedChainId.includes(chainId), - supportedChainId, + isChainSupported: (chainId: number) => supportedChainIdV2.includes(chainId), + supportedChainId: supportedChainIdV2, isTestnet: (chainId: number) => ![ChainId.BSC, ChainId.ETHEREUM].includes(chainId), } } @@ -64,8 +69,8 @@ export function createFarmFetcherV3(provider: ({ chainId }: { chainId: number }) chainId, commonPrice, }: { - chainId: ChainId farms: ComputedFarmConfigV3[] + chainId: FarmSupportedChainId commonPrice: CommonPrice }) => { const masterChefAddress = masterChefV3Addresses[chainId] @@ -121,7 +126,7 @@ export function createFarmFetcherV3(provider: ({ chainId }: { chainId: number }) return { fetchFarms, getCakeAprAndTVL, - isChainSupported: (chainId: number) => supportedChainIdV3.includes(chainId), + isChainSupported: (chainId: number): chainId is FarmSupportedChainId => supportedChainIdV3.includes(chainId), supportedChainId: supportedChainIdV3, isTestnet: (chainId: number) => ![ChainId.BSC, ChainId.ETHEREUM].includes(chainId), } diff --git a/packages/smart-router/evm/constants/common.ts b/packages/smart-router/evm/constants/common.ts index db3d0d589..1511615e4 100644 --- a/packages/smart-router/evm/constants/common.ts +++ b/packages/smart-router/evm/constants/common.ts @@ -11,6 +11,13 @@ export const BETTER_TRADE_LESS_HOPS_THRESHOLD = new Percent(50n, BIPS_BASE) export const CHAIN_ID_TO_CHAIN_NAME = { [ChainId.BSC]: 'bsc', [ChainId.ETHEREUM]: 'ethereum', - [ChainId.GOERLI]: 'ethereum', - [ChainId.BSC_TESTNET]: 'bsc', + [ChainId.GOERLI]: '', + [ChainId.BSC_TESTNET]: '', + [ChainId.ARBITRUM_ONE]: 'arbitrum', + [ChainId.ARBITRUM_GOERLI]: '', + [ChainId.POLYGON_ZKEVM]: 'polygon_zkevm', + [ChainId.POLYGON_ZKEVM_TESTNET]: '', + [ChainId.ZKSYNC]: 'era', + [ChainId.ZKSYNC_TESTNET]: '', + [ChainId.LINEA_TESTNET]: '', } satisfies Record diff --git a/packages/smart-router/evm/constants/exchange.ts b/packages/smart-router/evm/constants/exchange.ts index 8fa3089dc..3b5a55877 100644 --- a/packages/smart-router/evm/constants/exchange.ts +++ b/packages/smart-router/evm/constants/exchange.ts @@ -1,20 +1,50 @@ -import { ChainId, Token, WBNB, WNATIVE } from '@pancakeswap/sdk' -import { ethereumTokens, bscTokens, bscTestnetTokens, BUSD, USDC, USDT, WBTC_ETH } from '@pancakeswap/tokens' +import { ChainId, Token, WNATIVE } from '@pancakeswap/sdk' +import { + bscTokens, + bscTestnetTokens, + BUSD, + USDC, + USDT, + WBTC_ETH, + arbitrumTokens, + arbitrumGoerliTokens, + ethereumTokens, + polygonZkEvmTokens, + polygonZkEvmTestnetTokens, + zksyncTokens, + zkSyncTestnetTokens, + lineaTestnetTokens, +} from '@pancakeswap/tokens' import { ChainMap, ChainTokenList } from '../types' -export const SWAP_ROUTER_ADDRESSES = { +export const SMART_ROUTER_ADDRESSES = { [ChainId.ETHEREUM]: '0x13f4EA83D0bd40E75C8222255bc855a974568Dd4', [ChainId.GOERLI]: '0x9a489505a00cE272eAa5e07Dba6491314CaE3796', [ChainId.BSC]: '0x13f4EA83D0bd40E75C8222255bc855a974568Dd4', [ChainId.BSC_TESTNET]: '0x9a489505a00cE272eAa5e07Dba6491314CaE3796', + // TODO: new chains + [ChainId.ARBITRUM_ONE]: '0x32226588378236Fd0c7c4053999F88aC0e5cAc77', + [ChainId.ARBITRUM_GOERLI]: '0xBee35e9Cbd9595355Eaf5DE2055EF525adB41bE6', + [ChainId.POLYGON_ZKEVM]: '0x678Aa4bF4E210cf2166753e054d5b7c31cc7fa86', + [ChainId.POLYGON_ZKEVM_TESTNET]: '0x365C5F0B816828936320ea143e337fbA7D1b911E', + [ChainId.ZKSYNC]: '', + [ChainId.ZKSYNC_TESTNET]: '0x2CecA0100bB12F3Ee164D260b058281809C7e1E8', + [ChainId.LINEA_TESTNET]: '0x21d809FB4052bb1807cfe2418bA638d72F4aEf87', } as const satisfies Record -export const ROUTER_ADDRESS: ChainMap = { +export const V2_ROUTER_ADDRESS: ChainMap = { [ChainId.ETHEREUM]: '0x3BC722f252C7bAE2f55647e49aDcB9d33Ff6eBcC', [ChainId.GOERLI]: '0x3BC722f252C7bAE2f55647e49aDcB9d33Ff6eBcC', [ChainId.BSC]: '0x10ED43C718714eb63d5aA57B78B54704E256024E', [ChainId.BSC_TESTNET]: '0xD99D1c33F9fC3444f8101754aBC46c52416550D1', + [ChainId.ARBITRUM_ONE]: '0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb', + [ChainId.ARBITRUM_GOERLI]: '0xB8054A1F11090fbe82B45aC3c72e86732f8355DC', + [ChainId.POLYGON_ZKEVM]: '0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb', + [ChainId.POLYGON_ZKEVM_TESTNET]: '0x1ac9F6489487a282961b3929bCFA0a773251315E', + [ChainId.ZKSYNC]: '0xbFc9a73c77d5D8cE972FBa2806Ac18e7d913Deb6', + [ChainId.ZKSYNC_TESTNET]: '0x8A1fB895Ac009Bdc2e773d117695F21C1BF13D99', + [ChainId.LINEA_TESTNET]: '0xD7A304138D50C125733d1fE8a2041199E4944Aa1', } export const STABLE_SWAP_INFO_ADDRESS: ChainMap = { @@ -22,6 +52,13 @@ export const STABLE_SWAP_INFO_ADDRESS: ChainMap = { [ChainId.GOERLI]: '', [ChainId.BSC]: '0xa680d27f63Fa5E213C502d1B3Ca1EB6a3C1b31D6', [ChainId.BSC_TESTNET]: '0xaE6C14AAA753B3FCaB96149e1E10Bc4EDF39F546', + [ChainId.ARBITRUM_ONE]: '', + [ChainId.ARBITRUM_GOERLI]: '', + [ChainId.POLYGON_ZKEVM]: '', + [ChainId.POLYGON_ZKEVM_TESTNET]: '', + [ChainId.ZKSYNC]: '', + [ChainId.ZKSYNC_TESTNET]: '', + [ChainId.LINEA_TESTNET]: '', } // used to construct intermediary pairs for trading @@ -38,6 +75,13 @@ export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = { bscTokens.usdc, ], [ChainId.BSC_TESTNET]: [bscTestnetTokens.wbnb, bscTestnetTokens.cake, bscTestnetTokens.busd], + [ChainId.ARBITRUM_ONE]: [arbitrumTokens.weth, arbitrumTokens.usdt, arbitrumTokens.usdc], + [ChainId.ARBITRUM_GOERLI]: [arbitrumGoerliTokens.weth, arbitrumGoerliTokens.usdc], + [ChainId.POLYGON_ZKEVM]: [polygonZkEvmTokens.weth, polygonZkEvmTokens.usdt], + [ChainId.POLYGON_ZKEVM_TESTNET]: [polygonZkEvmTestnetTokens.weth, polygonZkEvmTestnetTokens.usdt], + [ChainId.ZKSYNC]: [zksyncTokens.usdc, zksyncTokens.weth], + [ChainId.ZKSYNC_TESTNET]: [zkSyncTestnetTokens.usdc, zkSyncTestnetTokens.weth], + [ChainId.LINEA_TESTNET]: [lineaTestnetTokens.usdc, lineaTestnetTokens.weth], } /** @@ -84,42 +128,3 @@ export const CUSTOM_BASES: { [bscTokens.axlusdc.address]: [bscTokens.usdt], }, } - -// used for display in the default list when adding liquidity -export const SUGGESTED_BASES: ChainTokenList = { - [ChainId.ETHEREUM]: [USDC[ChainId.ETHEREUM], WBNB[ChainId.ETHEREUM], BUSD[ChainId.ETHEREUM], USDT[ChainId.ETHEREUM]], - [ChainId.GOERLI]: [USDC[ChainId.GOERLI], WNATIVE[ChainId.GOERLI], BUSD[ChainId.GOERLI]], - [ChainId.BSC]: [bscTokens.busd, bscTokens.cake, bscTokens.btcb], - [ChainId.BSC_TESTNET]: [bscTestnetTokens.wbnb, bscTestnetTokens.cake, bscTestnetTokens.busd], -} - -// used to construct the list of all pairs we consider by default in the frontend -export const BASES_TO_TRACK_LIQUIDITY_FOR: ChainTokenList = { - [ChainId.ETHEREUM]: [ - USDC[ChainId.ETHEREUM], - WNATIVE[ChainId.ETHEREUM], - BUSD[ChainId.ETHEREUM], - USDT[ChainId.ETHEREUM], - WBNB[ChainId.ETHEREUM], - ], - [ChainId.GOERLI]: [USDC[ChainId.GOERLI], WNATIVE[ChainId.GOERLI], BUSD[ChainId.GOERLI]], - [ChainId.BSC]: [bscTokens.wbnb, bscTokens.dai, bscTokens.busd, bscTokens.usdt, bscTokens.cake], - [ChainId.BSC_TESTNET]: [bscTestnetTokens.wbnb, bscTestnetTokens.cake, bscTestnetTokens.busd], -} - -export const PINNED_PAIRS: { - readonly [chainId in ChainId]?: [Token, Token][] -} = { - [ChainId.ETHEREUM]: [ - [WNATIVE[ChainId.ETHEREUM], USDC[ChainId.ETHEREUM]], - [WBNB[ChainId.ETHEREUM], USDC[ChainId.ETHEREUM]], - [WBNB[ChainId.ETHEREUM], BUSD[ChainId.ETHEREUM]], - [WBNB[ChainId.ETHEREUM], USDT[ChainId.ETHEREUM]], - [WBNB[ChainId.ETHEREUM], WNATIVE[ChainId.ETHEREUM]], - ], - [ChainId.BSC]: [ - [bscTokens.cake, bscTokens.wbnb], - [bscTokens.busd, bscTokens.usdt], - [bscTokens.dai, bscTokens.usdt], - ], -} diff --git a/packages/smart-router/evm/constants/gasModel/index.ts b/packages/smart-router/evm/constants/gasModel/index.ts index d890a9b0e..0674a2939 100644 --- a/packages/smart-router/evm/constants/gasModel/index.ts +++ b/packages/smart-router/evm/constants/gasModel/index.ts @@ -1,19 +1,32 @@ import { ChainId, Token } from '@pancakeswap/sdk' -import { ethereumTokens, bscTokens, bscTestnetTokens, goerliTestnetTokens } from '@pancakeswap/tokens' +import { + ethereumTokens, + bscTokens, + bscTestnetTokens, + goerliTestnetTokens, + polygonZkEvmTokens, + polygonZkEvmTestnetTokens, + zkSyncTestnetTokens, + zksyncTokens, + lineaTestnetTokens, + arbitrumGoerliTokens, + arbitrumTokens, +} from '@pancakeswap/tokens' -export const usdGasTokensByChain: { [chainId in ChainId]?: Token[] } = { +export const usdGasTokensByChain = { [ChainId.ETHEREUM]: [ethereumTokens.usdt], [ChainId.GOERLI]: [goerliTestnetTokens.usdc], [ChainId.BSC]: [bscTokens.busd], [ChainId.BSC_TESTNET]: [bscTestnetTokens.busd], -} - -export const nativeWrappedTokenByChain: { [chainId in ChainId]?: Token } = { - [ChainId.ETHEREUM]: ethereumTokens.weth, - [ChainId.GOERLI]: goerliTestnetTokens.weth, - [ChainId.BSC]: bscTokens.wbnb, - [ChainId.BSC_TESTNET]: bscTestnetTokens.wbnb, -} + // TODO: new chains + [ChainId.ARBITRUM_ONE]: [arbitrumTokens.usdc], + [ChainId.ARBITRUM_GOERLI]: [arbitrumGoerliTokens.usdc], + [ChainId.POLYGON_ZKEVM]: [polygonZkEvmTokens.usdc], + [ChainId.POLYGON_ZKEVM_TESTNET]: [polygonZkEvmTestnetTokens.usdt], + [ChainId.ZKSYNC]: [zksyncTokens.usdc], + [ChainId.ZKSYNC_TESTNET]: [zkSyncTestnetTokens.usdc], + [ChainId.LINEA_TESTNET]: [lineaTestnetTokens.usdc], +} satisfies Record export * from './v2' export * from './v3' diff --git a/packages/smart-router/evm/constants/index.ts b/packages/smart-router/evm/constants/index.ts index 41a14360e..a05e65dc1 100644 --- a/packages/smart-router/evm/constants/index.ts +++ b/packages/smart-router/evm/constants/index.ts @@ -3,3 +3,4 @@ export * from './exchange' export * from './v3' export * from './gasModel' export * from './multicall' +export { isStableSwapSupported } from './stableSwap' diff --git a/packages/smart-router/evm/constants/multicall.ts b/packages/smart-router/evm/constants/multicall.ts index aca9f2e9e..2e4badedc 100644 --- a/packages/smart-router/evm/constants/multicall.ts +++ b/packages/smart-router/evm/constants/multicall.ts @@ -2,61 +2,83 @@ import { ChainId } from '@pancakeswap/sdk' import { ChainMap, BatchMulticallConfigs } from '../types' +const DEFAULT = { + defaultConfig: { + multicallChunk: 150, + gasLimitOverride: 1_000_000, + }, + gasErrorFailureOverride: { + gasLimitOverride: 1_000_000, + multicallChunk: 30, + }, + successRateFailureOverrides: { + gasLimitOverride: 1_000_000, + multicallChunk: 40, + }, +} + export const BATCH_MULTICALL_CONFIGS: ChainMap = { - [ChainId.BSC_TESTNET]: { + [ChainId.BSC_TESTNET]: DEFAULT, + [ChainId.BSC]: { defaultConfig: { - multicallChunk: 150, + multicallChunk: 50, gasLimitOverride: 1_000_000, }, gasErrorFailureOverride: { gasLimitOverride: 1_000_000, - multicallChunk: 30, + multicallChunk: 40, }, successRateFailureOverrides: { gasLimitOverride: 1_000_000, - multicallChunk: 50, + multicallChunk: 45, }, }, - [ChainId.BSC]: { + [ChainId.ETHEREUM]: DEFAULT, + [ChainId.GOERLI]: DEFAULT, + [ChainId.ARBITRUM_ONE]: { defaultConfig: { - multicallChunk: 50, - gasLimitOverride: 1_000_000, + multicallChunk: 10, + gasLimitOverride: 12_000_000, }, gasErrorFailureOverride: { - gasLimitOverride: 1_000_000, - multicallChunk: 40, + gasLimitOverride: 30_000_000, + multicallChunk: 6, }, successRateFailureOverrides: { - gasLimitOverride: 1_000_000, - multicallChunk: 45, + gasLimitOverride: 30_000_000, + multicallChunk: 6, }, }, - [ChainId.ETHEREUM]: { + [ChainId.ARBITRUM_GOERLI]: DEFAULT, + [ChainId.POLYGON_ZKEVM]: { defaultConfig: { - multicallChunk: 150, - gasLimitOverride: 1_000_000, + multicallChunk: 3, + gasLimitOverride: 300_000, }, gasErrorFailureOverride: { - gasLimitOverride: 1_000_000, - multicallChunk: 30, + gasLimitOverride: 30_000, + multicallChunk: 1, }, successRateFailureOverrides: { - gasLimitOverride: 1_000_000, - multicallChunk: 40, + gasLimitOverride: 30_000, + multicallChunk: 1, }, }, - [ChainId.GOERLI]: { + [ChainId.POLYGON_ZKEVM_TESTNET]: { defaultConfig: { - multicallChunk: 150, - gasLimitOverride: 1_000_000, + multicallChunk: 3, + gasLimitOverride: 300_000, }, gasErrorFailureOverride: { - gasLimitOverride: 1_000_000, - multicallChunk: 30, + gasLimitOverride: 30_000, + multicallChunk: 1, }, successRateFailureOverrides: { - gasLimitOverride: 1_000_000, - multicallChunk: 40, + gasLimitOverride: 30_000, + multicallChunk: 1, }, }, + [ChainId.ZKSYNC]: DEFAULT, + [ChainId.ZKSYNC_TESTNET]: DEFAULT, + [ChainId.LINEA_TESTNET]: DEFAULT, } diff --git a/packages/smart-router/evm/constants/stableSwap/1.ts b/packages/smart-router/evm/constants/stableSwap/1.ts deleted file mode 100644 index 487974f8f..000000000 --- a/packages/smart-router/evm/constants/stableSwap/1.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { StableSwapPool } from './types' - -export const pools: StableSwapPool[] = [] diff --git a/packages/smart-router/evm/constants/stableSwap/4.ts b/packages/smart-router/evm/constants/stableSwap/4.ts deleted file mode 100644 index 487974f8f..000000000 --- a/packages/smart-router/evm/constants/stableSwap/4.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { StableSwapPool } from './types' - -export const pools: StableSwapPool[] = [] diff --git a/packages/smart-router/evm/constants/stableSwap/5.ts b/packages/smart-router/evm/constants/stableSwap/5.ts deleted file mode 100644 index 487974f8f..000000000 --- a/packages/smart-router/evm/constants/stableSwap/5.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { StableSwapPool } from './types' - -export const pools: StableSwapPool[] = [] diff --git a/packages/smart-router/evm/constants/stableSwap/index.ts b/packages/smart-router/evm/constants/stableSwap/index.ts index df7f2cc16..5c4953041 100644 --- a/packages/smart-router/evm/constants/stableSwap/index.ts +++ b/packages/smart-router/evm/constants/stableSwap/index.ts @@ -10,3 +10,5 @@ export function getStableSwapPools(chainId: ChainId): StableSwapPool[] { } return STABLE_POOL_MAP[chainId] || [] } + +export { isStableSwapSupported } diff --git a/packages/smart-router/evm/constants/v3.ts b/packages/smart-router/evm/constants/v3.ts index 8625f46c2..df71ba456 100644 --- a/packages/smart-router/evm/constants/v3.ts +++ b/packages/smart-router/evm/constants/v3.ts @@ -1,4 +1,5 @@ import { ChainId } from '@pancakeswap/sdk' +import { Address } from 'viem' // = 1 << 23 or 100000000000000000000000 export const V2_FEE_PATH_PLACEHOLDER = 8388608 @@ -11,11 +12,27 @@ export const MIXED_ROUTE_QUOTER_ADDRESSES = { [ChainId.GOERLI]: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997', [ChainId.BSC]: '0x678Aa4bF4E210cf2166753e054d5b7c31cc7fa86', [ChainId.BSC_TESTNET]: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997', -} as const + // TODO: new chains + [ChainId.ARBITRUM_ONE]: '0x3652Fc6EDcbD76161b8554388867d3dAb65eCA93', + [ChainId.ARBITRUM_GOERLI]: '0x805e03325116Da555Babf012C7bd490Bdd6EEa95', + [ChainId.POLYGON_ZKEVM]: '0x4c650FB471fe4e0f476fD3437C3411B1122c4e3B', + [ChainId.POLYGON_ZKEVM_TESTNET]: '0x9CFCdecF9e37Bf25023A2B42537127c1089600fE', + [ChainId.ZKSYNC]: '0x', + [ChainId.ZKSYNC_TESTNET]: '0x5d2D9b1B04735DFECF48E6be1A7F391e7071DDc9', + [ChainId.LINEA_TESTNET]: '0x7d3ed219e45637Cfa77b1a634d0489a2950d1B7F', +} as const satisfies Record export const V3_QUOTER_ADDRESSES = { [ChainId.ETHEREUM]: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997', [ChainId.GOERLI]: '0xbC203d7f83677c7ed3F7acEc959963E7F4ECC5C2', [ChainId.BSC]: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997', [ChainId.BSC_TESTNET]: '0xbC203d7f83677c7ed3F7acEc959963E7F4ECC5C2', -} as const + // TODO: new chains + [ChainId.ARBITRUM_ONE]: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997', + [ChainId.ARBITRUM_GOERLI]: '0xC0F9488345ed89105b3bd135150905F718Bb254E', + [ChainId.POLYGON_ZKEVM]: '0x864ED564875BdDD6F421e226494a0E7c071C06f8', + [ChainId.POLYGON_ZKEVM_TESTNET]: '0xA9c08a89Be4503E04Fd84Eadad4320eE34e9B11D', + [ChainId.ZKSYNC]: '0x', + [ChainId.ZKSYNC_TESTNET]: '0x42929984eBFC7C3AF4e7dA2e33C9dEe593eB0e4F', + [ChainId.LINEA_TESTNET]: '0x669254936caE83bE34008BdFdeeA63C902497B31', +} as const satisfies Record diff --git a/packages/smart-router/evm/utils/currency.ts b/packages/smart-router/evm/utils/currency.ts index 78fa3539e..03c275dd5 100644 --- a/packages/smart-router/evm/utils/currency.ts +++ b/packages/smart-router/evm/utils/currency.ts @@ -17,6 +17,6 @@ export function unwrappedToken(token: Currency): Currency { return token } - if (token.equals(WNATIVE[token.chainId])) return Native.onChain(token.chainId) + if (token.equals(WNATIVE[token.chainId as ChainId])) return Native.onChain(token.chainId) return token } diff --git a/packages/smart-router/evm/v3-router/providers/getCommonTokenPrices.ts b/packages/smart-router/evm/v3-router/providers/getCommonTokenPrices.ts index eb02ebe6e..3206f9204 100644 --- a/packages/smart-router/evm/v3-router/providers/getCommonTokenPrices.ts +++ b/packages/smart-router/evm/v3-router/providers/getCommonTokenPrices.ts @@ -86,7 +86,7 @@ const createGetTokenPriceFromLlmaWithCache = (): GetTokenPrices() return async ({ addresses, chainId }) => { - if (!chainId) { + if (!chainId || !CHAIN_ID_TO_CHAIN_NAME[chainId as keyof typeof CHAIN_ID_TO_CHAIN_NAME]) { throw new Error(`Invalid chain id ${chainId}`) } const [cachedResults, addressesToFetch] = addresses.reduce<[TokenPrice[], string[]]>( @@ -106,7 +106,9 @@ const createGetTokenPriceFromLlmaWithCache = (): GetTokenPrices `${CHAIN_ID_TO_CHAIN_NAME[chainId]}:${address}`).join(',') + const list = addressesToFetch + .map((address) => `${CHAIN_ID_TO_CHAIN_NAME[chainId as keyof typeof CHAIN_ID_TO_CHAIN_NAME]}:${address}`) + .join(',') const result: { coins?: { [key: string]: { price: string } } } = await fetch( `https://coins.llama.fi/prices/current/${list}`, ).then((res) => res.json()) diff --git a/packages/smart-router/evm/v3-router/providers/multicallSwapProvider.ts b/packages/smart-router/evm/v3-router/providers/multicallSwapProvider.ts index 1ba2158f9..9f72b24e5 100644 --- a/packages/smart-router/evm/v3-router/providers/multicallSwapProvider.ts +++ b/packages/smart-router/evm/v3-router/providers/multicallSwapProvider.ts @@ -1,6 +1,6 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ +/* eslint-disable no-console, camelcase, @typescript-eslint/no-non-null-assertion */ import { ChainId } from '@pancakeswap/sdk' -import { encodeFunctionData, PublicClient, decodeFunctionResult } from 'viem' +import { encodeFunctionData, PublicClient, decodeFunctionResult, Address } from 'viem' import stats from 'stats-lite' import IMulticallABI from '../../abis/InterfaceMulticall' @@ -17,7 +17,15 @@ const PANCAKE_MULTICALL_ADDRESSES = { [ChainId.GOERLI]: '0x3D00CdB4785F0ef20C903A13596e0b9B2c652227', [ChainId.BSC]: '0xac1cE734566f390A94b00eb9bf561c2625BF44ea', [ChainId.BSC_TESTNET]: '0x3D00CdB4785F0ef20C903A13596e0b9B2c652227', -} as const + // TODO: new chains + [ChainId.ARBITRUM_ONE]: '0xac1cE734566f390A94b00eb9bf561c2625BF44ea', + [ChainId.ARBITRUM_GOERLI]: '0x7a7e95c0b4d0Be710648C6f773ad0499923560bA', + [ChainId.POLYGON_ZKEVM]: '0xac1cE734566f390A94b00eb9bf561c2625BF44ea', + [ChainId.POLYGON_ZKEVM_TESTNET]: '0x5DCC00121b4a481D8EDF9782Df6c6CF398AF20B8', + [ChainId.ZKSYNC]: '0x', + [ChainId.ZKSYNC_TESTNET]: '0xD43165407500fac1Adb10Fc7359D71b86f66a6f7', + [ChainId.LINEA_TESTNET]: '0x32226588378236Fd0c7c4053999F88aC0e5cAc77', +} as const satisfies Record export type PancakeMulticallConfig = { gasLimitPerCallOverride?: number diff --git a/packages/smart-router/evm/v3-router/providers/onChainQuoteProvider.ts b/packages/smart-router/evm/v3-router/providers/onChainQuoteProvider.ts index f5135806c..7ac31e3bd 100644 --- a/packages/smart-router/evm/v3-router/providers/onChainQuoteProvider.ts +++ b/packages/smart-router/evm/v3-router/providers/onChainQuoteProvider.ts @@ -24,7 +24,14 @@ const SUCCESS_RATE_CONFIG = { [ChainId.BSC]: 0.1, [ChainId.ETHEREUM]: 0.1, [ChainId.GOERLI]: 0.1, -} + [ChainId.ARBITRUM_ONE]: 0.1, + [ChainId.ARBITRUM_GOERLI]: 0.1, + [ChainId.POLYGON_ZKEVM]: 0.1, + [ChainId.POLYGON_ZKEVM_TESTNET]: 0.1, + [ChainId.ZKSYNC]: 0.1, + [ChainId.ZKSYNC_TESTNET]: 0.1, + [ChainId.LINEA_TESTNET]: 0.1, +} as const satisfies Record type V3Inputs = [string, string] type MixedInputs = [string, number[], string] @@ -387,6 +394,7 @@ function onChainQuoteProviderFactory({ getQuoteFunctionName, getQuoterAddress, a } if (failedQuoteStates.length > 0) { + console.log(failedQuoteStates, 'failedQuoteStates') throw new Error(`Failed to get ${failedQuoteStates.length} quotes. Reasons: ${reasonForFailureStr}`) } diff --git a/packages/smart-router/evm/v3-router/providers/poolProviders/getV2CandidatePools.ts b/packages/smart-router/evm/v3-router/providers/poolProviders/getV2CandidatePools.ts index 1309d2f8e..7510a0485 100644 --- a/packages/smart-router/evm/v3-router/providers/poolProviders/getV2CandidatePools.ts +++ b/packages/smart-router/evm/v3-router/providers/poolProviders/getV2CandidatePools.ts @@ -36,8 +36,19 @@ export async function getV2PoolsWithTvlByCommonTokenPrices({ getCommonTokenPrices({ currencyA, currencyB, v3SubgraphProvider }), ]) - if (!poolsFromOnChain || !baseTokenUsdPrices) { - throw new Error('Failed to get v2 candidate pools by base token prices.') + if (!poolsFromOnChain) { + throw new Error('Failed to get v2 candidate pools') + } + + if (!baseTokenUsdPrices) { + console.debug('Failed to get base token prices') + return poolsFromOnChain.map((pool) => { + return { + ...pool, + tvlUSD: BigInt(0), + address: getPoolAddress(pool), + } + }) } return poolsFromOnChain.map((pool) => { diff --git a/packages/smart-router/evm/v3-router/providers/poolProviders/getV3CandidatePools.ts b/packages/smart-router/evm/v3-router/providers/poolProviders/getV3CandidatePools.ts index 34b46019d..4b164fa0f 100644 --- a/packages/smart-router/evm/v3-router/providers/poolProviders/getV3CandidatePools.ts +++ b/packages/smart-router/evm/v3-router/providers/poolProviders/getV3CandidatePools.ts @@ -36,8 +36,10 @@ const getV3PoolTvl = memoize( // Get pools from onchain and use the tvl data from subgraph as reference // The reason we do this is the data from subgraph might delay -const v3PoolsOnChainProviderFactory = (tvlReferenceProvider: (params: Params) => Promise) => { - return async function getV3PoolsWithTvlFromOnChain(params: Params): Promise { +const v3PoolsOnChainProviderFactory =

( + tvlReferenceProvider: (params: P) => Promise, +) => { + return async function getV3PoolsWithTvlFromOnChain(params: P): Promise { const { currencyA, currencyB, pairs: providedPairs, onChainProvider, blockNumber } = params const pairs = providedPairs || getPairCombinations(currencyA, currencyB) @@ -49,6 +51,9 @@ const v3PoolsOnChainProviderFactory = (tvlReferenceProvider: (params: Params) => if (fromOnChain.status === 'fulfilled' && tvlReference.status === 'fulfilled') { const { value: poolsFromOnChain } = fromOnChain const { value: poolTvlReferences } = tvlReference + if (!Array.isArray(poolTvlReferences)) { + throw new Error('Failed to get tvl references') + } return poolsFromOnChain.map((pool) => { const tvlUSD = BigInt(getV3PoolTvl(poolTvlReferences, pool.address)) return { @@ -57,7 +62,7 @@ const v3PoolsOnChainProviderFactory = (tvlReferenceProvider: (params: Params) => } }) } - throw new Error(JSON.stringify([fromOnChain, tvlReference])) + throw new Error(`Getting v3 pools failed. Onchain ${fromOnChain.status}, tvl references ${tvlReference.status}`) } } @@ -87,6 +92,10 @@ const createFallbackTvlRefGetter = () => { const getV3PoolsWithTvlFromOnChainFallback = v3PoolsOnChainProviderFactory(createFallbackTvlRefGetter()) +const getV3PoolsWithTvlFromOnChainStaticFallback = v3PoolsOnChainProviderFactory< + Omit +>(() => Promise.resolve([])) + export async function getV3CandidatePools(params: Params) { const { currencyA, currencyB, pairs: providedPairs, subgraphProvider } = params const pairs = providedPairs || getPairCombinations(currencyA, currencyB) @@ -105,6 +114,11 @@ export async function getV3CandidatePools(params: Params) { // Fallback to get all pools info from subgraph { asyncFn: () => getV3PoolSubgraph({ provider: subgraphProvider, pairs }), + timeout: 3000, + }, + // Fallback to get pools from on chain and static ref + { + asyncFn: () => getV3PoolsWithTvlFromOnChainStaticFallback(params), }, ]) diff --git a/packages/smart-router/evm/v3-router/providers/poolProviders/onChainPoolProviders.ts b/packages/smart-router/evm/v3-router/providers/poolProviders/onChainPoolProviders.ts index 113abd9f6..f60fd7ec9 100644 --- a/packages/smart-router/evm/v3-router/providers/poolProviders/onChainPoolProviders.ts +++ b/packages/smart-router/evm/v3-router/providers/poolProviders/onChainPoolProviders.ts @@ -180,11 +180,11 @@ function createOnChainPoolFactory< } const chainId: ChainId = pairs[0]?.[0]?.chainId - if (!chainId) { + const client = provider({ chainId }) + if (!chainId || !client) { return [] } - const client = provider({ chainId }) const poolAddressSet = new Set() const poolMetas: TPoolMeta[] = [] diff --git a/packages/smart-router/evm/v3-router/providers/poolProviders/poolTvlSelectors.ts b/packages/smart-router/evm/v3-router/providers/poolProviders/poolTvlSelectors.ts index 5f00058d7..90bfdc0c7 100644 --- a/packages/smart-router/evm/v3-router/providers/poolProviders/poolTvlSelectors.ts +++ b/packages/smart-router/evm/v3-router/providers/poolProviders/poolTvlSelectors.ts @@ -100,7 +100,7 @@ function poolSelectorFactory

({ addToPoolSet(top2DirectPools) - const nativeToken = WNATIVE[chainId] + const nativeToken = WNATIVE[chainId as ChainId] const top2EthBaseTokenPool = nativeToken ? poolsFromSubgraph .filter((subgraphPool) => { diff --git a/packages/smart-router/evm/v3-router/utils/getNativeWrappedToken.ts b/packages/smart-router/evm/v3-router/utils/getNativeWrappedToken.ts index 6be13d03d..d5691ff69 100644 --- a/packages/smart-router/evm/v3-router/utils/getNativeWrappedToken.ts +++ b/packages/smart-router/evm/v3-router/utils/getNativeWrappedToken.ts @@ -1,7 +1,5 @@ -import { ChainId, Token } from '@pancakeswap/sdk' - -import { nativeWrappedTokenByChain } from '../../constants' +import { ChainId, Token, WNATIVE } from '@pancakeswap/sdk' export function getNativeWrappedToken(chainId: ChainId): Token | null { - return nativeWrappedTokenByChain[chainId] ?? null + return WNATIVE[chainId] ?? null } diff --git a/packages/smart-router/evm/v3-router/utils/swapRouter.ts b/packages/smart-router/evm/v3-router/utils/swapRouter.ts index a7706b378..c3d63bcc0 100644 --- a/packages/smart-router/evm/v3-router/utils/swapRouter.ts +++ b/packages/smart-router/evm/v3-router/utils/swapRouter.ts @@ -1,5 +1,13 @@ import { encodeFunctionData, Hex, Address } from 'viem' -import { Currency, CurrencyAmount, Percent, TradeType, validateAndParseAddress, WNATIVE } from '@pancakeswap/sdk' +import { + Currency, + CurrencyAmount, + Percent, + TradeType, + validateAndParseAddress, + WNATIVE, + ChainId, +} from '@pancakeswap/sdk' import { FeeOptions, MethodParameters, Payments, PermitOptions, Position, SelfPermit, toHex } from '@pancakeswap/v3-sdk' import invariant from 'tiny-invariant' @@ -695,8 +703,8 @@ export abstract class SwapRouter { const { positionAmountIn, positionAmountOut } = SwapRouter.getPositionAmounts(position, zeroForOne) // if tokens are native they will be converted to WETH9 - const tokenIn = inputIsNative ? WNATIVE[chainId] : positionAmountIn.currency.wrapped - const tokenOut = outputIsNative ? WNATIVE[chainId] : positionAmountOut.currency.wrapped + const tokenIn = inputIsNative ? WNATIVE[chainId as ChainId] : positionAmountIn.currency.wrapped + const tokenOut = outputIsNative ? WNATIVE[chainId as ChainId] : positionAmountOut.currency.wrapped // if swap output does not make up whole outputTokenBalanceDesired, pull in remaining tokens for adding liquidity const amountOutRemaining = positionAmountOut.subtract(quoteAmountOut.wrapped) diff --git a/packages/swap-sdk/jest.config.js b/packages/swap-sdk/jest.config.js deleted file mode 100644 index c587684b4..000000000 --- a/packages/swap-sdk/jest.config.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - testPathIgnorePatterns: ['/node_modules/', '/dist/'], - transform: { - '^.+\\.(t|j)sx?$': [ - '@swc/jest', - { - jsc: { - transform: { - react: { - runtime: 'automatic', - }, - }, - }, - }, - ], - }, - testEnvironment: 'jsdom', -} diff --git a/packages/swap-sdk/package.json b/packages/swap-sdk/package.json index 43fcbe539..4fdf50cb7 100644 --- a/packages/swap-sdk/package.json +++ b/packages/swap-sdk/package.json @@ -43,8 +43,6 @@ "toformat": "^2.0.0" }, "devDependencies": { - "@swc/core": "^1.2.215", - "@swc/jest": "^0.2.21", "@types/big.js": "^4.0.5", "tsup": "^6.7.0" }, diff --git a/packages/swap-sdk/src/constants.ts b/packages/swap-sdk/src/constants.ts index 13e31ef1f..390eaf055 100644 --- a/packages/swap-sdk/src/constants.ts +++ b/packages/swap-sdk/src/constants.ts @@ -7,6 +7,13 @@ export enum ChainId { GOERLI = 5, BSC = 56, BSC_TESTNET = 97, + ZKSYNC_TESTNET = 280, + ZKSYNC = 324, + POLYGON_ZKEVM = 1101, + POLYGON_ZKEVM_TESTNET = 1442, + ARBITRUM_ONE = 42161, + ARBITRUM_GOERLI = 421613, + LINEA_TESTNET = 59140, } export const ZERO_PERCENT = new Percent('0') @@ -16,21 +23,37 @@ export const FACTORY_ADDRESS = '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73' const FACTORY_ADDRESS_ETH = '0x1097053Fd2ea711dad45caCcc45EfF7548fCB362' -export const FACTORY_ADDRESS_MAP: Record = { +export const FACTORY_ADDRESS_MAP = { [ChainId.ETHEREUM]: FACTORY_ADDRESS_ETH, [ChainId.GOERLI]: FACTORY_ADDRESS_ETH, [ChainId.BSC]: FACTORY_ADDRESS, [ChainId.BSC_TESTNET]: '0x6725f303b657a9451d8ba641348b6761a6cc7a17', -} + [ChainId.ARBITRUM_ONE]: '0x02a84c1b3BBD7401a5f7fa98a384EBC70bB5749E', + [ChainId.ARBITRUM_GOERLI]: '0x333EAE459075b1d7dE8eb57997b5d4eee5F1070a', + [ChainId.POLYGON_ZKEVM]: '0x02a84c1b3BBD7401a5f7fa98a384EBC70bB5749E', + [ChainId.POLYGON_ZKEVM_TESTNET]: '0xBA40c83026213F9cbc79998752721a0312bdB74a', + [ChainId.ZKSYNC]: '0x0F70cE1e2c0FB5FC3B67E13ed4F422fE82d832bD', + [ChainId.ZKSYNC_TESTNET]: '0xA4370037e4C151449Fb7166DccB9FcF30B812baF', + [ChainId.LINEA_TESTNET]: '0xB6FAfd4ADbCd21cF665909767e0eD0D05709abfB', +} as const satisfies Record + export const INIT_CODE_HASH = '0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5' const INIT_CODE_HASH_ETH = '0x57224589c67f3f30a6b0d7a1b54cf3153ab84563bc609ef41dfb34f8b2974d2d' -export const INIT_CODE_HASH_MAP: Record = { +export const INIT_CODE_HASH_MAP = { [ChainId.ETHEREUM]: INIT_CODE_HASH_ETH, [ChainId.GOERLI]: INIT_CODE_HASH_ETH, [ChainId.BSC]: INIT_CODE_HASH, [ChainId.BSC_TESTNET]: '0xd0d4c4cd0848c93cb4fd1f498d7013ee6bfb25783ea21593d5834f5d250ece66', -} + [ChainId.ARBITRUM_ONE]: INIT_CODE_HASH_ETH, + [ChainId.ARBITRUM_GOERLI]: INIT_CODE_HASH_ETH, + [ChainId.POLYGON_ZKEVM]: INIT_CODE_HASH_ETH, + [ChainId.POLYGON_ZKEVM_TESTNET]: INIT_CODE_HASH_ETH, + // TODO: new chains + [ChainId.ZKSYNC]: '0x1cb011040b91cd937ddff2327f17c9690653b05b6506e830baadf2493468d657', + [ChainId.ZKSYNC_TESTNET]: '0x0100045707a42494392b3558029b9869f865ff9df8f375dc1bf20b0555093f43', + [ChainId.LINEA_TESTNET]: INIT_CODE_HASH_ETH, +} as const satisfies Record export const WETH9 = { [ChainId.ETHEREUM]: new ERC20Token( @@ -65,6 +88,62 @@ export const WETH9 = { 'ETH', 'https://ethereum.org' ), + [ChainId.ARBITRUM_ONE]: new ERC20Token( + ChainId.ARBITRUM_ONE, + '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + 18, + 'WETH', + 'Wrapped Ether', + 'https://weth.io' + ), + [ChainId.ARBITRUM_GOERLI]: new ERC20Token( + ChainId.ARBITRUM_GOERLI, + '0xEe01c0CD76354C383B8c7B4e65EA88D00B06f36f', + 18, + 'WETH', + 'Wrapped Ether', + 'https://weth.io' + ), + [ChainId.ZKSYNC]: new ERC20Token( + ChainId.ZKSYNC, + '0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91', + 18, + 'WETH', + 'Wrapped Ether', + 'https://weth.io' + ), + [ChainId.ZKSYNC_TESTNET]: new ERC20Token( + ChainId.ZKSYNC_TESTNET, + '0x20b28B1e4665FFf290650586ad76E977EAb90c5D', + 18, + 'WETH', + 'Wrapped Ether', + 'https://weth.io' + ), + [ChainId.POLYGON_ZKEVM]: new ERC20Token( + ChainId.POLYGON_ZKEVM, + '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9', + 18, + 'WETH', + 'Wrapped Ether', + 'https://weth.io' + ), + [ChainId.POLYGON_ZKEVM_TESTNET]: new ERC20Token( + ChainId.POLYGON_ZKEVM_TESTNET, + '0x30ec47F7DFae72eA79646e6cf64a8A7db538915b', + 18, + 'WETH', + 'Wrapped Ether', + 'https://weth.io' + ), + [ChainId.LINEA_TESTNET]: new ERC20Token( + ChainId.LINEA_TESTNET, + '0x2C1b868d6596a18e32E61B901E4060C872647b6C', + 18, + 'WETH', + 'Wrapped Ether', + 'https://weth.io' + ), } export const WBNB = { @@ -94,22 +173,24 @@ export const WBNB = { ), } -export const WNATIVE: Record = { +export const WNATIVE = { [ChainId.ETHEREUM]: WETH9[ChainId.ETHEREUM], [ChainId.GOERLI]: WETH9[ChainId.GOERLI], [ChainId.BSC]: WBNB[ChainId.BSC], [ChainId.BSC_TESTNET]: WBNB[ChainId.BSC_TESTNET], -} + [ChainId.ARBITRUM_ONE]: WETH9[ChainId.ARBITRUM_ONE], + [ChainId.ARBITRUM_GOERLI]: WETH9[ChainId.ARBITRUM_GOERLI], + [ChainId.POLYGON_ZKEVM]: WETH9[ChainId.POLYGON_ZKEVM], + [ChainId.POLYGON_ZKEVM_TESTNET]: WETH9[ChainId.POLYGON_ZKEVM_TESTNET], + [ChainId.ZKSYNC]: WETH9[ChainId.ZKSYNC], + [ChainId.ZKSYNC_TESTNET]: WETH9[ChainId.ZKSYNC_TESTNET], + [ChainId.LINEA_TESTNET]: WETH9[ChainId.LINEA_TESTNET], +} satisfies Record -export const NATIVE: Record< - number, - { - name: string - symbol: string - decimals: number - } -> = { - [ChainId.ETHEREUM]: { name: 'Ether', symbol: 'ETH', decimals: 18 }, +const ETHER = { name: 'Ether', symbol: 'ETH', decimals: 18 } as const + +export const NATIVE = { + [ChainId.ETHEREUM]: ETHER, [ChainId.GOERLI]: { name: 'Goerli Ether', symbol: 'GOR', decimals: 18 }, [ChainId.BSC]: { name: 'Binance Chain Native Token', @@ -121,4 +202,22 @@ export const NATIVE: Record< symbol: 'tBNB', decimals: 18, }, -} + [ChainId.ARBITRUM_ONE]: ETHER, + [ChainId.ARBITRUM_GOERLI]: { + name: 'Arbitrum Goerli Ether', + symbol: 'AGOR', + decimals: 18, + }, + [ChainId.POLYGON_ZKEVM]: ETHER, + [ChainId.POLYGON_ZKEVM_TESTNET]: ETHER, + [ChainId.ZKSYNC]: ETHER, + [ChainId.ZKSYNC_TESTNET]: ETHER, + [ChainId.LINEA_TESTNET]: ETHER, +} satisfies Record< + ChainId, + { + name: string + symbol: string + decimals: number + } +> diff --git a/packages/swap-sdk/src/entities/native.ts b/packages/swap-sdk/src/entities/native.ts index 293c42263..0c02b5826 100644 --- a/packages/swap-sdk/src/entities/native.ts +++ b/packages/swap-sdk/src/entities/native.ts @@ -22,7 +22,7 @@ export class Native extends NativeCurrency { } public get wrapped(): Token { - const wnative = WNATIVE[this.chainId] + const wnative = WNATIVE[this.chainId as keyof typeof WNATIVE] invariant(!!wnative, 'WRAPPED') return wnative } @@ -33,8 +33,8 @@ export class Native extends NativeCurrency { if (chainId in this.cache) { return this.cache[chainId] } - invariant(!!NATIVE[chainId], 'NATIVE_CURRENCY') - const { decimals, name, symbol } = NATIVE[chainId] + invariant(!!NATIVE[chainId as keyof typeof NATIVE], 'NATIVE_CURRENCY') + const { decimals, name, symbol } = NATIVE[chainId as keyof typeof WNATIVE] // eslint-disable-next-line no-return-assign return (this.cache[chainId] = new Native({ chainId, decimals, symbol, name })) } diff --git a/packages/swap-sdk/src/entities/pair.ts b/packages/swap-sdk/src/entities/pair.ts index ae5e5f952..119fe6610 100644 --- a/packages/swap-sdk/src/entities/pair.ts +++ b/packages/swap-sdk/src/entities/pair.ts @@ -28,7 +28,7 @@ import { } from 'viem' import invariant from 'tiny-invariant' -import { FACTORY_ADDRESS_MAP, INIT_CODE_HASH_MAP } from '../constants' +import { ChainId, FACTORY_ADDRESS_MAP, INIT_CODE_HASH_MAP } from '../constants' import { ERC20Token } from './token' let PAIR_ADDRESS_CACHE: { [key: string]: Address } = {} @@ -48,6 +48,15 @@ function getCreate2Address( return getAddress(slice(keccak256(concat([toBytes('0xff'), from, salt, toBytes(initCodeHash)])), 12)) } +const EMPTY_INPU_HASH = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' +const ZKSYNC_PREFIX = '0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494' // keccak256('zksyncCreate2') + +function getCreate2AddressZkSync(from: Address, salt: `0x${string}`, initCodeHash: `0x${string}`): `0x${string}` { + return getAddress( + keccak256(concat([ZKSYNC_PREFIX, pad(from, { size: 32 }), salt, initCodeHash, EMPTY_INPU_HASH])).slice(26) + ) +} + export const computePairAddress = ({ factoryAddress, tokenA, @@ -61,12 +70,16 @@ export const computePairAddress = ({ const key = composeKey(token0, token1) if (PAIR_ADDRESS_CACHE?.[key] === undefined) { + const getCreate2Address_ = + token0.chainId === ChainId.ZKSYNC_TESTNET || token1.chainId === ChainId.ZKSYNC + ? getCreate2AddressZkSync + : getCreate2Address PAIR_ADDRESS_CACHE = { ...PAIR_ADDRESS_CACHE, - [key]: getCreate2Address( + [key]: getCreate2Address_( factoryAddress, keccak256(encodePacked(['address', 'address'], [token0.address, token1.address])), - INIT_CODE_HASH_MAP[token0.chainId] + INIT_CODE_HASH_MAP[token0.chainId as keyof typeof INIT_CODE_HASH_MAP] ), } } @@ -80,7 +93,11 @@ export class Pair { private readonly tokenAmounts: [CurrencyAmount, CurrencyAmount] public static getAddress(tokenA: ERC20Token, tokenB: ERC20Token): Address { - return computePairAddress({ factoryAddress: FACTORY_ADDRESS_MAP[tokenA.chainId], tokenA, tokenB }) + return computePairAddress({ + factoryAddress: FACTORY_ADDRESS_MAP[tokenA.chainId as keyof typeof FACTORY_ADDRESS_MAP], + tokenA, + tokenB, + }) } public constructor(currencyAmountA: CurrencyAmount, tokenAmountB: CurrencyAmount) { diff --git a/packages/swap-sdk/test/pair.test.ts b/packages/swap-sdk/test/pair.test.ts index 9a2a6ae8e..dfe805a93 100644 --- a/packages/swap-sdk/test/pair.test.ts +++ b/packages/swap-sdk/test/pair.test.ts @@ -1,4 +1,5 @@ import { Token, CurrencyAmount, Price } from '@pancakeswap/swap-sdk-core' +import { describe, it, expect } from 'vitest' import { Pair } from '../src/entities' import { ChainId, WNATIVE } from '../src/constants' @@ -22,6 +23,12 @@ describe('Pair', () => { it('returns the correct address', () => { expect(Pair.getAddress(USDC, DAI)).toEqual('0xadBba1EF326A33FDB754f14e62A96D5278b942Bd') }) + + it.todo('returns the correct address for zkSync', () => { + const WETH = new Token(ChainId.ZKSYNC_TESTNET, '0x20b28B1e4665FFf290650586ad76E977EAb90c5D', 18, 'WETH', 'WETH') + const USDC_ = new Token(ChainId.ZKSYNC_TESTNET, '0x0faF6df7054946141266420b43783387A78d82A9', 18, 'USDC', 'USDC') + expect(Pair.getAddress(USDC_, WETH)).toEqual('0x06C4c41108D79B131D2D8456Ede66556eBF23aEa') + }) }) describe('#token0', () => { @@ -129,7 +136,7 @@ describe('Pair', () => { }) }) describe('#involvesToken', () => { - it('invlovesToken', () => { + it('returns true if the token is involved in the pair', () => { expect( new Pair(CurrencyAmount.fromRawAmount(USDC, '100'), CurrencyAmount.fromRawAmount(DAI, '100')).involvesToken( USDC diff --git a/packages/swap-sdk/vitest.config.ts b/packages/swap-sdk/vitest.config.ts new file mode 100644 index 000000000..47cdb0317 --- /dev/null +++ b/packages/swap-sdk/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + globals: true, + }, +}) diff --git a/packages/tokens/src/1101.ts b/packages/tokens/src/1101.ts new file mode 100644 index 000000000..81c7c4638 --- /dev/null +++ b/packages/tokens/src/1101.ts @@ -0,0 +1,8 @@ +import { ChainId, WETH9 } from '@pancakeswap/sdk' +import { USDC, USDT } from './common' + +export const polygonZkEvmTokens = { + weth: WETH9[ChainId.POLYGON_ZKEVM], + usdc: USDC[ChainId.POLYGON_ZKEVM], + usdt: USDT[ChainId.POLYGON_ZKEVM], +} diff --git a/packages/tokens/src/1442.ts b/packages/tokens/src/1442.ts new file mode 100644 index 000000000..69e8c31bc --- /dev/null +++ b/packages/tokens/src/1442.ts @@ -0,0 +1,7 @@ +import { ChainId, WETH9 } from '@pancakeswap/sdk' +import { USDT } from './common' + +export const polygonZkEvmTestnetTokens = { + weth: WETH9[ChainId.POLYGON_ZKEVM_TESTNET], + usdt: USDT[ChainId.POLYGON_ZKEVM_TESTNET], +} diff --git a/packages/tokens/src/280.ts b/packages/tokens/src/280.ts new file mode 100644 index 000000000..bab91899c --- /dev/null +++ b/packages/tokens/src/280.ts @@ -0,0 +1,7 @@ +import { ChainId, WETH9 } from '@pancakeswap/sdk' +import { USDC } from './common' + +export const zkSyncTestnetTokens = { + weth: WETH9[ChainId.ZKSYNC_TESTNET], + usdc: USDC[ChainId.ZKSYNC_TESTNET], +} diff --git a/packages/tokens/src/324.ts b/packages/tokens/src/324.ts new file mode 100644 index 000000000..a14598759 --- /dev/null +++ b/packages/tokens/src/324.ts @@ -0,0 +1,7 @@ +import { ChainId, WETH9 } from '@pancakeswap/sdk' +import { USDC } from './common' + +export const zksyncTokens = { + weth: WETH9[ChainId.ZKSYNC], + usdc: USDC[ChainId.ZKSYNC], +} diff --git a/packages/tokens/src/42161.ts b/packages/tokens/src/42161.ts new file mode 100644 index 000000000..a93a34dda --- /dev/null +++ b/packages/tokens/src/42161.ts @@ -0,0 +1,8 @@ +import { ChainId, WETH9 } from '@pancakeswap/sdk' +import { USDT, USDC } from './common' + +export const arbitrumTokens = { + weth: WETH9[ChainId.ARBITRUM_ONE], + usdt: USDT[ChainId.ARBITRUM_ONE], + usdc: USDC[ChainId.ARBITRUM_ONE], +} diff --git a/packages/tokens/src/421613.ts b/packages/tokens/src/421613.ts new file mode 100644 index 000000000..be4b5c04f --- /dev/null +++ b/packages/tokens/src/421613.ts @@ -0,0 +1,7 @@ +import { ChainId, WETH9 } from '@pancakeswap/sdk' +import { USDC } from './common' + +export const arbitrumGoerliTokens = { + weth: WETH9[ChainId.ARBITRUM_GOERLI], + usdc: USDC[ChainId.ARBITRUM_GOERLI], +} diff --git a/packages/tokens/src/59140.ts b/packages/tokens/src/59140.ts new file mode 100644 index 000000000..5c0362a26 --- /dev/null +++ b/packages/tokens/src/59140.ts @@ -0,0 +1,7 @@ +import { ChainId, WETH9 } from '@pancakeswap/sdk' +import { USDC } from './common' + +export const lineaTestnetTokens = { + weth: WETH9[ChainId.LINEA_TESTNET], + usdc: USDC[ChainId.LINEA_TESTNET], +} diff --git a/packages/tokens/src/common.ts b/packages/tokens/src/common.ts index f5082f7af..26e1e0c6b 100644 --- a/packages/tokens/src/common.ts +++ b/packages/tokens/src/common.ts @@ -106,11 +106,18 @@ export const BUSD_GOERLI = new ERC20Token( 'https://www.paxos.com/busd/', ) -export const BUSD: Record = { +export const BUSD = { [ChainId.ETHEREUM]: BUSD_ETH, [ChainId.GOERLI]: BUSD_GOERLI, [ChainId.BSC]: BUSD_BSC, [ChainId.BSC_TESTNET]: BUSD_TESTNET, + [ChainId.ZKSYNC]: new ERC20Token( + ChainId.ZKSYNC, + '0x2039bb4116B4EFc145Ec4f0e2eA75012D6C0f181', + 18, + 'BUSD', + 'Binance USD', + ), } export const CAKE = { @@ -139,11 +146,68 @@ export const USDC = { [ChainId.BSC_TESTNET]: USDC_TESTNET, [ChainId.ETHEREUM]: USDC_ETH, [ChainId.GOERLI]: USDC_GOERLI, + [ChainId.ZKSYNC]: new ERC20Token(ChainId.ZKSYNC, '0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4', 6, 'USDC', 'USD Coin'), + [ChainId.ZKSYNC_TESTNET]: new ERC20Token( + ChainId.ZKSYNC_TESTNET, + '0x0faF6df7054946141266420b43783387A78d82A9', + 6, + 'USDC', + 'USD Coin', + ), + [ChainId.ARBITRUM_ONE]: new ERC20Token( + ChainId.ARBITRUM_ONE, + '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + 6, + 'USDC', + 'USD Coin', + ), + [ChainId.ARBITRUM_GOERLI]: new ERC20Token( + ChainId.ARBITRUM_GOERLI, + '0x179522635726710Dd7D2035a81d856de4Aa7836c', + 6, + 'USDC', + 'USD Coin', + ), + [ChainId.POLYGON_ZKEVM]: new ERC20Token( + ChainId.POLYGON_ZKEVM, + '0xA8CE8aee21bC2A48a5EF670afCc9274C7bbbC035', + 6, + 'USDC', + 'USD Coin', + ), + [ChainId.LINEA_TESTNET]: new ERC20Token( + ChainId.LINEA_TESTNET, + '0xf56dc6695cF1f5c364eDEbC7Dc7077ac9B586068', + 6, + 'USDC', + 'USD Coin', + ), } export const USDT = { [ChainId.BSC]: USDT_BSC, [ChainId.ETHEREUM]: USDT_ETH, + [ChainId.ARBITRUM_ONE]: new ERC20Token( + ChainId.ARBITRUM_ONE, + '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + 6, + 'USDT', + 'Tether USD', + ), + [ChainId.POLYGON_ZKEVM]: new ERC20Token( + ChainId.POLYGON_ZKEVM, + '0x1E4a5963aBFD975d8c9021ce480b42188849D41d', + 6, + 'USDT', + 'Tether USD', + ), + [ChainId.POLYGON_ZKEVM_TESTNET]: new ERC20Token( + ChainId.POLYGON_ZKEVM_TESTNET, + '0x7379a261bC347BDD445484A91648Abf4A2BDEe5E', + 6, + 'USDT', + 'Tether USD', + ), } export const WBTC_ETH = new ERC20Token( @@ -159,4 +223,11 @@ export const STABLE_COIN = { [ChainId.GOERLI]: USDC[ChainId.GOERLI], [ChainId.BSC]: USDT[ChainId.BSC], [ChainId.BSC_TESTNET]: BUSD[ChainId.BSC_TESTNET], + [ChainId.ARBITRUM_ONE]: USDC[ChainId.ARBITRUM_ONE], + [ChainId.ARBITRUM_GOERLI]: USDC[ChainId.ARBITRUM_GOERLI], + [ChainId.ZKSYNC]: USDC[ChainId.ZKSYNC], + [ChainId.ZKSYNC_TESTNET]: USDC[ChainId.ZKSYNC_TESTNET], + [ChainId.POLYGON_ZKEVM]: USDC[ChainId.POLYGON_ZKEVM], + [ChainId.POLYGON_ZKEVM_TESTNET]: USDT[ChainId.POLYGON_ZKEVM_TESTNET], + [ChainId.LINEA_TESTNET]: USDC[ChainId.LINEA_TESTNET], } satisfies Record diff --git a/packages/tokens/src/helpers.ts b/packages/tokens/src/helpers.ts index 93c35976d..17aa0f714 100644 --- a/packages/tokens/src/helpers.ts +++ b/packages/tokens/src/helpers.ts @@ -9,6 +9,13 @@ export const EMPTY_LIST: TokenAddressMap = { [ChainId.GOERLI]: {}, [ChainId.BSC]: {}, [ChainId.BSC_TESTNET]: {}, + [ChainId.ARBITRUM_ONE]: {}, + [ChainId.ARBITRUM_GOERLI]: {}, + [ChainId.POLYGON_ZKEVM]: {}, + [ChainId.POLYGON_ZKEVM_TESTNET]: {}, + [ChainId.ZKSYNC]: {}, + [ChainId.ZKSYNC_TESTNET]: {}, + [ChainId.LINEA_TESTNET]: {}, } export function serializeTokens(unserializedTokens: any) { diff --git a/packages/tokens/src/index.ts b/packages/tokens/src/index.ts index 52f2cb7b6..b1809bb97 100644 --- a/packages/tokens/src/index.ts +++ b/packages/tokens/src/index.ts @@ -4,3 +4,10 @@ export * from './5' export * from './56' export * from './97' export * from './1' +export * from './42161' +export * from './1101' +export * from './1442' +export * from './324' +export * from './280' +export * from './59140' +export * from './421613' diff --git a/packages/v3-sdk/src/constants.ts b/packages/v3-sdk/src/constants.ts index 322120d26..c3c3def8d 100644 --- a/packages/v3-sdk/src/constants.ts +++ b/packages/v3-sdk/src/constants.ts @@ -1,19 +1,61 @@ import { ChainId } from '@pancakeswap/sdk' -import { Address } from 'viem' +import { Address, Hash } from 'viem' -export const FACTORY_ADDRESS = '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865' +const FACTORY_ADDRESS = '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865' + +/** + * To compute Pool address use DEPLOYER_ADDRESSES instead + */ +export const FACTORY_ADDRESSES = { + [ChainId.ETHEREUM]: FACTORY_ADDRESS, + [ChainId.GOERLI]: FACTORY_ADDRESS, + [ChainId.BSC]: FACTORY_ADDRESS, + [ChainId.BSC_TESTNET]: FACTORY_ADDRESS, + // TODO: new chains + [ChainId.ARBITRUM_ONE]: FACTORY_ADDRESS, + [ChainId.ARBITRUM_GOERLI]: '0xBA40c83026213F9cbc79998752721a0312bdB74a', + [ChainId.POLYGON_ZKEVM]: FACTORY_ADDRESS, + [ChainId.POLYGON_ZKEVM_TESTNET]: '0x2430dbd123BC40f8Be6110065a448C1aA0619Cb1', + [ChainId.ZKSYNC]: '0x', + [ChainId.ZKSYNC_TESTNET]: '0x57d01Fbde077C04381a28840A24aCbEeF8314062', + [ChainId.LINEA_TESTNET]: '0x02a84c1b3BBD7401a5f7fa98a384EBC70bB5749E', +} as const satisfies Record + +const DEPLOYER_ADDRESS = '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9' -export const DEPLOYER_ADDRESS = '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9' export const DEPLOYER_ADDRESSES = { [ChainId.ETHEREUM]: DEPLOYER_ADDRESS, [ChainId.GOERLI]: DEPLOYER_ADDRESS, [ChainId.BSC]: DEPLOYER_ADDRESS, [ChainId.BSC_TESTNET]: DEPLOYER_ADDRESS, + // TODO: new chains + [ChainId.ARBITRUM_ONE]: DEPLOYER_ADDRESS, + [ChainId.ARBITRUM_GOERLI]: '0xbC465fbf687e4184103b67Ed86557A8155FA4343', + [ChainId.POLYGON_ZKEVM]: DEPLOYER_ADDRESS, + [ChainId.POLYGON_ZKEVM_TESTNET]: '0x86808Be3f426C9B4c8C706bCDe29dBC036A1259B', + [ChainId.ZKSYNC]: '0x', + [ChainId.ZKSYNC_TESTNET]: '0x71df5b7ea5355180EAb2A54de8aA534016040008', + [ChainId.LINEA_TESTNET]: '0xdAecee3C08e953Bd5f89A5Cc90ac560413d709E3', } as const satisfies Record export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000' -export const POOL_INIT_CODE_HASH = '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2' +const POOL_INIT_CODE_HASH = '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2' + +export const POOL_INIT_CODE_HASHES = { + [ChainId.ETHEREUM]: POOL_INIT_CODE_HASH, + [ChainId.GOERLI]: POOL_INIT_CODE_HASH, + [ChainId.BSC]: POOL_INIT_CODE_HASH, + [ChainId.BSC_TESTNET]: POOL_INIT_CODE_HASH, + [ChainId.ARBITRUM_ONE]: POOL_INIT_CODE_HASH, + [ChainId.ARBITRUM_GOERLI]: POOL_INIT_CODE_HASH, + [ChainId.POLYGON_ZKEVM]: POOL_INIT_CODE_HASH, + [ChainId.POLYGON_ZKEVM_TESTNET]: POOL_INIT_CODE_HASH, + // TODO: new chains + [ChainId.ZKSYNC]: '0x01001487f1c11a662dda518635f8e1f03a41f505cbf7d981c899ba11bf847a8a', + [ChainId.ZKSYNC_TESTNET]: '0x01001487f1c11a662dda518635f8e1f03a41f505cbf7d981c899ba11bf847a8a', + [ChainId.LINEA_TESTNET]: POOL_INIT_CODE_HASH, +} as const satisfies Record /** * The default factory enabled fee amounts, denominated in hundredths of bips. diff --git a/packages/v3-sdk/src/utils/computePoolAddress.test.ts b/packages/v3-sdk/src/utils/computePoolAddress.test.ts index 967025fc6..9c2e19684 100644 --- a/packages/v3-sdk/src/utils/computePoolAddress.test.ts +++ b/packages/v3-sdk/src/utils/computePoolAddress.test.ts @@ -18,6 +18,19 @@ describe('#computePoolAddress', () => { expect(result).toEqual('0x993B1e86fFEf6609e47416212C17B0df746fa985') }) + it.todo('should correctly compute the pool address zkSync', () => { + const USDC = new Token(280, '0x0faF6df7054946141266420b43783387A78d82A9', 6, 'USDC', 'USD Coin') + const WETH = new Token(280, '0x20b28B1e4665FFf290650586ad76E977EAb90c5D', 18, 'WETH') + const result = computePoolAddress({ + deployerAddress: '0x71df5b7ea5355180EAb2A54de8aA534016040008', + fee: FeeAmount.MEDIUM, + tokenA: USDC, + tokenB: WETH, + }) + + expect(result).toEqual('0x25f728a155C883aa9bFfa8474b3e5Cd82B89e055') + }) + it('should correctly compute the pool address2', () => { const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 18, 'USDC', 'USD Coin') const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin') diff --git a/packages/v3-sdk/src/utils/computePoolAddress.ts b/packages/v3-sdk/src/utils/computePoolAddress.ts index d02173c4e..a8236c917 100644 --- a/packages/v3-sdk/src/utils/computePoolAddress.ts +++ b/packages/v3-sdk/src/utils/computePoolAddress.ts @@ -14,8 +14,8 @@ import { getAddress, ByteArray, } from 'viem' -import { Token } from '@pancakeswap/sdk' -import { FeeAmount, POOL_INIT_CODE_HASH } from '../constants' +import { Token, ChainId } from '@pancakeswap/sdk' +import { FeeAmount, POOL_INIT_CODE_HASHES } from '../constants' function getCreate2Address( from_: GetCreate2AddressOptions['from'], @@ -30,6 +30,15 @@ function getCreate2Address( return getAddress(slice(keccak256(concat([toBytes('0xff'), from, salt, toBytes(initCodeHash)])), 12)) } +const EMPTY_INPU_HASH = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' +const ZKSYNC_PREFIX = '0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494' // keccak256('zksyncCreate2') + +function getCreate2AddressZkSync(from: Address, salt: `0x${string}`, initCodeHash: `0x${string}`): `0x${string}` { + return getAddress( + keccak256(concat([ZKSYNC_PREFIX, pad(from, { size: 32 }), salt, initCodeHash, EMPTY_INPU_HASH])).slice(26) + ) +} + /** * Computes a pool address * @param deployerAddress The Pancake V3 deployer address @@ -54,11 +63,21 @@ export function computePoolAddress({ }): Address { const [token0, token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA] // does safety checks + const salt = keccak256( + encodeAbiParameters(parseAbiParameters(['address, address, uint24']), [token0.address, token1.address, fee]) + ) + + if (token0.chainId === ChainId.ZKSYNC || token0.chainId === ChainId.ZKSYNC_TESTNET) { + return getCreate2AddressZkSync( + deployerAddress, + salt, + initCodeHashManualOverride ?? POOL_INIT_CODE_HASHES[token0.chainId as keyof typeof POOL_INIT_CODE_HASHES] + ) + } + return getCreate2Address( deployerAddress, - keccak256( - encodeAbiParameters(parseAbiParameters(['address, address, uint24']), [token0.address, token1.address, fee]) - ), - initCodeHashManualOverride ?? POOL_INIT_CODE_HASH + salt, + initCodeHashManualOverride ?? POOL_INIT_CODE_HASHES[token0.chainId as keyof typeof POOL_INIT_CODE_HASHES] ) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85925b185..834abf019 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1288,12 +1288,6 @@ importers: specifier: ^1.0.7 version: 1.0.7(typescript@5.1.3)(zod@3.21.4) devDependencies: - '@swc/core': - specifier: ^1.2.215 - version: 1.2.218 - '@swc/jest': - specifier: ^0.2.21 - version: 0.2.22(@swc/core@1.2.218) '@types/big.js': specifier: ^4.0.5 version: 4.0.5