Commit fc0bf229 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

fix: improve v2 network support (#7012)

* fix: improve v2 network support

* add an unsupported message to all v2 pages

* test: add v2 pool tests

* add guard on transaction callbacks

* fix: dep array

---------
Co-authored-by: default avatareddie <66155195+just-toby@users.noreply.github.com>
parent b55680db
import { Trans } from '@lingui/macro'
import { AutoColumn } from 'components/Column'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'
const TextWrapper = styled.div`
border: 1px solid ${({ theme }) => theme.textPrimary};
padding: 16px 12px;
border-radius: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
`
export function V2Unsupported() {
return (
<AutoColumn gap="lg" justify="center">
<AutoColumn gap="md" style={{ width: '100%' }}>
<TextWrapper>
<ThemedText.BodySecondary color="textSecondary" textAlign="center">
<Trans>Uniswap V2 is not available on this network.</Trans>
</ThemedText.BodySecondary>
</TextWrapper>
</AutoColumn>
</AutoColumn>
)
}
...@@ -41,16 +41,9 @@ export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = [ ...@@ -41,16 +41,9 @@ export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = [
] as const ] as const
/** /**
* Unsupported networks for V2 pool behavior. * Supported networks for V2 pool behavior.
*/ */
export const UNSUPPORTED_V2POOL_CHAIN_IDS = [ export const SUPPORTED_V2POOL_CHAIN_IDS = [ChainId.MAINNET, ChainId.GOERLI] as const
ChainId.POLYGON,
ChainId.OPTIMISM,
ChainId.ARBITRUM_ONE,
ChainId.BNB,
ChainId.ARBITRUM_GOERLI,
ChainId.AVALANCHE,
] as const
export const TESTNET_CHAIN_IDS = [ export const TESTNET_CHAIN_IDS = [
ChainId.GOERLI, ChainId.GOERLI,
......
import { useWeb3React } from '@web3-react/core'
import { SUPPORTED_V2POOL_CHAIN_IDS } from 'constants/chains'
export function useNetworkSupportsV2() {
const { chainId } = useWeb3React()
return chainId && SUPPORTED_V2POOL_CHAIN_IDS.includes(chainId)
}
...@@ -9,6 +9,8 @@ import { useToggleAccountDrawer } from 'components/AccountDrawer' ...@@ -9,6 +9,8 @@ import { useToggleAccountDrawer } from 'components/AccountDrawer'
import { sendEvent } from 'components/analytics' import { sendEvent } from 'components/analytics'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter' import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink' import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import { V2Unsupported } from 'components/V2Unsupported'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
import { useCallback, useState } from 'react' import { useCallback, useState } from 'react'
import { Plus } from 'react-feather' import { Plus } from 'react-feather'
import { useLocation, useNavigate, useParams } from 'react-router-dom' import { useLocation, useNavigate, useParams } from 'react-router-dom'
...@@ -132,9 +134,10 @@ export default function AddLiquidity() { ...@@ -132,9 +134,10 @@ export default function AddLiquidity() {
const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], router?.address) const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], router?.address)
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
const networkSupportsV2 = useNetworkSupportsV2()
async function onAdd() { async function onAdd() {
if (!chainId || !provider || !account || !router) return if (!chainId || !provider || !account || !router || !networkSupportsV2) return
const { [Field.CURRENCY_A]: parsedAmountA, [Field.CURRENCY_B]: parsedAmountB } = parsedAmounts const { [Field.CURRENCY_A]: parsedAmountA, [Field.CURRENCY_B]: parsedAmountB } = parsedAmounts
if (!parsedAmountA || !parsedAmountB || !currencyA || !currencyB || !deadline) { if (!parsedAmountA || !parsedAmountB || !currencyA || !currencyB || !deadline) {
...@@ -318,6 +321,8 @@ export default function AddLiquidity() { ...@@ -318,6 +321,8 @@ export default function AddLiquidity() {
const addIsUnsupported = useIsSwapUnsupported(currencies?.CURRENCY_A, currencies?.CURRENCY_B) const addIsUnsupported = useIsSwapUnsupported(currencies?.CURRENCY_A, currencies?.CURRENCY_B)
if (!networkSupportsV2) return <V2Unsupported />
return ( return (
<> <>
<AppBody> <AppBody>
......
...@@ -14,8 +14,10 @@ import RangeSelector from 'components/RangeSelector' ...@@ -14,8 +14,10 @@ import RangeSelector from 'components/RangeSelector'
import RateToggle from 'components/RateToggle' import RateToggle from 'components/RateToggle'
import SettingsTab from 'components/Settings' import SettingsTab from 'components/Settings'
import { Dots } from 'components/swap/styleds' import { Dots } from 'components/swap/styleds'
import { V2Unsupported } from 'components/V2Unsupported'
import { ApprovalState, useApproveCallback } from 'hooks/useApproveCallback' import { ApprovalState, useApproveCallback } from 'hooks/useApproveCallback'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp' import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
import { PoolState, usePool } from 'hooks/usePools' import { PoolState, usePool } from 'hooks/usePools'
import useTransactionDeadline from 'hooks/useTransactionDeadline' import useTransactionDeadline from 'hooks/useTransactionDeadline'
import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit' import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit'
...@@ -262,6 +264,8 @@ function V2PairMigration({ ...@@ -262,6 +264,8 @@ function V2PairMigration({
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
const isMigrationPending = useIsTransactionPending(pendingMigrationHash ?? undefined) const isMigrationPending = useIsTransactionPending(pendingMigrationHash ?? undefined)
const networkSupportsV2 = useNetworkSupportsV2()
const migrate = useCallback(() => { const migrate = useCallback(() => {
if ( if (
!migrator || !migrator ||
...@@ -272,7 +276,8 @@ function V2PairMigration({ ...@@ -272,7 +276,8 @@ function V2PairMigration({
typeof tickUpper !== 'number' || typeof tickUpper !== 'number' ||
!v3Amount0Min || !v3Amount0Min ||
!v3Amount1Min || !v3Amount1Min ||
!chainId !chainId ||
!networkSupportsV2
) )
return return
...@@ -354,31 +359,34 @@ function V2PairMigration({ ...@@ -354,31 +359,34 @@ function V2PairMigration({
setConfirmingMigration(false) setConfirmingMigration(false)
}) })
}, [ }, [
chainId,
isNotUniswap,
migrator, migrator,
noLiquidity, account,
deadline,
blockTimestamp, blockTimestamp,
token0,
token1,
feeAmount,
pairBalance,
tickLower, tickLower,
tickUpper, tickUpper,
sqrtPrice,
v3Amount0Min, v3Amount0Min,
v3Amount1Min, v3Amount1Min,
account, chainId,
deadline, networkSupportsV2,
signatureData, signatureData,
addTransaction, noLiquidity,
pair, pair.address,
pairBalance.quotient,
token0.address,
token1.address,
feeAmount,
sqrtPrice,
isNotUniswap,
currency0, currency0,
currency1, currency1,
addTransaction,
]) ])
const isSuccessfullyMigrated = !!pendingMigrationHash && JSBI.equal(pairBalance.quotient, ZERO) const isSuccessfullyMigrated = !!pendingMigrationHash && JSBI.equal(pairBalance.quotient, ZERO)
if (!networkSupportsV2) return <V2Unsupported />
return ( return (
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<ThemedText.DeprecatedBody my={9} style={{ fontWeight: 400 }}> <ThemedText.DeprecatedBody my={9} style={{ fontWeight: 400 }}>
......
...@@ -7,6 +7,8 @@ import { useWeb3React } from '@web3-react/core' ...@@ -7,6 +7,8 @@ import { useWeb3React } from '@web3-react/core'
import MigrateSushiPositionCard from 'components/PositionCard/Sushi' import MigrateSushiPositionCard from 'components/PositionCard/Sushi'
import MigrateV2PositionCard from 'components/PositionCard/V2' import MigrateV2PositionCard from 'components/PositionCard/V2'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink' import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import { V2Unsupported } from 'components/V2Unsupported'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
import { PairState, useV2Pairs } from 'hooks/useV2Pairs' import { PairState, useV2Pairs } from 'hooks/useV2Pairs'
import { ReactNode, useMemo } from 'react' import { ReactNode, useMemo } from 'react'
import { Text } from 'rebass' import { Text } from 'rebass'
...@@ -110,6 +112,9 @@ export default function MigrateV2() { ...@@ -110,6 +112,9 @@ export default function MigrateV2() {
const v2Pairs = useV2Pairs(tokenPairsWithV2Balance) const v2Pairs = useV2Pairs(tokenPairsWithV2Balance)
const v2IsLoading = fetchingPairBalances || v2Pairs.some(([pairState]) => pairState === PairState.LOADING) const v2IsLoading = fetchingPairBalances || v2Pairs.some(([pairState]) => pairState === PairState.LOADING)
const networkSupportsV2 = useNetworkSupportsV2()
if (!networkSupportsV2) return <V2Unsupported />
return ( return (
<> <>
<BodyWrapper style={{ padding: 24 }}> <BodyWrapper style={{ padding: 24 }}>
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { BrowserEvent, InterfaceElementName, InterfaceEventName, InterfacePageName } from '@uniswap/analytics-events' import { BrowserEvent, InterfaceElementName, InterfaceEventName, InterfacePageName } from '@uniswap/analytics-events'
import { V2_FACTORY_ADDRESSES } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { Trace, TraceEvent } from 'analytics' import { Trace, TraceEvent } from 'analytics'
import { useToggleAccountDrawer } from 'components/AccountDrawer' import { useToggleAccountDrawer } from 'components/AccountDrawer'
...@@ -12,6 +11,7 @@ import { RowBetween, RowFixed } from 'components/Row' ...@@ -12,6 +11,7 @@ import { RowBetween, RowFixed } from 'components/Row'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink' import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import { isSupportedChain } from 'constants/chains' import { isSupportedChain } from 'constants/chains'
import { useFilterPossiblyMaliciousPositions } from 'hooks/useFilterPossiblyMaliciousPositions' import { useFilterPossiblyMaliciousPositions } from 'hooks/useFilterPossiblyMaliciousPositions'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
import { useV3Positions } from 'hooks/useV3Positions' import { useV3Positions } from 'hooks/useV3Positions'
import { useMemo } from 'react' import { useMemo } from 'react'
import { AlertTriangle, BookOpen, ChevronDown, ChevronsRight, Inbox, Layers } from 'react-feather' import { AlertTriangle, BookOpen, ChevronDown, ChevronsRight, Inbox, Layers } from 'react-feather'
...@@ -190,6 +190,7 @@ function WrongNetworkCard() { ...@@ -190,6 +190,7 @@ function WrongNetworkCard() {
export default function Pool() { export default function Pool() {
const { account, chainId } = useWeb3React() const { account, chainId } = useWeb3React()
const networkSupportsV2 = useNetworkSupportsV2()
const toggleWalletDrawer = useToggleAccountDrawer() const toggleWalletDrawer = useToggleAccountDrawer()
const theme = useTheme() const theme = useTheme()
...@@ -217,7 +218,6 @@ export default function Pool() { ...@@ -217,7 +218,6 @@ export default function Pool() {
} }
const showConnectAWallet = Boolean(!account) const showConnectAWallet = Boolean(!account)
const showV2Features = Boolean(V2_FACTORY_ADDRESSES[chainId])
const menuItems = [ const menuItems = [
{ {
...@@ -262,7 +262,7 @@ export default function Pool() { ...@@ -262,7 +262,7 @@ export default function Pool() {
<Trans>Pools</Trans> <Trans>Pools</Trans>
</ThemedText.LargeHeader> </ThemedText.LargeHeader>
<ButtonRow> <ButtonRow>
{showV2Features && ( {networkSupportsV2 && (
<PoolMenu <PoolMenu
menuItems={menuItems} menuItems={menuItems}
flyoutAlignment={FlyoutAlignment.LEFT} flyoutAlignment={FlyoutAlignment.LEFT}
......
...@@ -3,7 +3,8 @@ import { InterfacePageName } from '@uniswap/analytics-events' ...@@ -3,7 +3,8 @@ import { InterfacePageName } from '@uniswap/analytics-events'
import { Pair } from '@uniswap/v2-sdk' import { Pair } from '@uniswap/v2-sdk'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { Trace } from 'analytics' import { Trace } from 'analytics'
import { UNSUPPORTED_V2POOL_CHAIN_IDS } from 'constants/chains' import { V2Unsupported } from 'components/V2Unsupported'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
import JSBI from 'jsbi' import JSBI from 'jsbi'
import { useMemo } from 'react' import { useMemo } from 'react'
import { ChevronsRight } from 'react-feather' import { ChevronsRight } from 'react-feather'
...@@ -35,8 +36,9 @@ const PageWrapper = styled(AutoColumn)` ...@@ -35,8 +36,9 @@ const PageWrapper = styled(AutoColumn)`
`}; `};
` `
const VoteCard = styled(DataCard)` const LPFeeExplainer = styled(DataCard)`
background: radial-gradient(76.02% 75.41% at 1.84% 0%, #27ae60 0%, #000000 100%); background: radial-gradient(76.02% 75.41% at 1.84% 0%, #27ae60 0%, #000000 100%);
margin: 0 0 16px 0;
overflow: hidden; overflow: hidden;
` `
...@@ -85,18 +87,14 @@ const EmptyProposals = styled.div` ...@@ -85,18 +87,14 @@ const EmptyProposals = styled.div`
align-items: center; align-items: center;
` `
const Layer2Prompt = styled(EmptyProposals)`
margin-top: 16px;
`
export default function Pool() { export default function Pool() {
const theme = useTheme() const theme = useTheme()
const { account, chainId } = useWeb3React() const { account } = useWeb3React()
const unsupportedV2Network = chainId && UNSUPPORTED_V2POOL_CHAIN_IDS.includes(chainId) const networkSupportsV2 = useNetworkSupportsV2()
// fetch the user's balances of all tracked V2 LP tokens // fetch the user's balances of all tracked V2 LP tokens
let trackedTokenPairs = useTrackedTokenPairs() let trackedTokenPairs = useTrackedTokenPairs()
if (unsupportedV2Network) trackedTokenPairs = [] if (!networkSupportsV2) trackedTokenPairs = []
const tokenPairsWithLiquidityTokens = useMemo( const tokenPairsWithLiquidityTokens = useMemo(
() => trackedTokenPairs.map((tokens) => ({ liquidityToken: toV2LiquidityToken(tokens), tokens })), () => trackedTokenPairs.map((tokens) => ({ liquidityToken: toV2LiquidityToken(tokens), tokens })),
[trackedTokenPairs] [trackedTokenPairs]
...@@ -145,7 +143,7 @@ export default function Pool() { ...@@ -145,7 +143,7 @@ export default function Pool() {
<Trace page={InterfacePageName.POOL_PAGE} shouldLogImpression> <Trace page={InterfacePageName.POOL_PAGE} shouldLogImpression>
<> <>
<PageWrapper> <PageWrapper>
<VoteCard> <LPFeeExplainer>
<CardBGImage /> <CardBGImage />
<CardNoise /> <CardNoise />
<CardSection> <CardSection>
...@@ -176,18 +174,10 @@ export default function Pool() { ...@@ -176,18 +174,10 @@ export default function Pool() {
</CardSection> </CardSection>
<CardBGImage /> <CardBGImage />
<CardNoise /> <CardNoise />
</VoteCard> </LPFeeExplainer>
{unsupportedV2Network ? ( {!networkSupportsV2 ? (
<AutoColumn gap="lg" justify="center"> <V2Unsupported />
<AutoColumn gap="md" style={{ width: '100%' }}>
<Layer2Prompt>
<ThemedText.DeprecatedBody color={theme.textTertiary} textAlign="center">
<Trans>Uniswap V2 is not available on this network.</Trans>
</ThemedText.DeprecatedBody>
</Layer2Prompt>
</AutoColumn>
</AutoColumn>
) : ( ) : (
<AutoColumn gap="lg" justify="center"> <AutoColumn gap="lg" justify="center">
<AutoColumn gap="md" style={{ width: '100%' }}> <AutoColumn gap="md" style={{ width: '100%' }}>
......
...@@ -3,6 +3,8 @@ import { InterfacePageName } from '@uniswap/analytics-events' ...@@ -3,6 +3,8 @@ import { InterfacePageName } from '@uniswap/analytics-events'
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { Trace } from 'analytics' import { Trace } from 'analytics'
import { V2Unsupported } from 'components/V2Unsupported'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
import JSBI from 'jsbi' import JSBI from 'jsbi'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { Plus } from 'react-feather' import { Plus } from 'react-feather'
...@@ -96,6 +98,9 @@ export default function PoolFinder() { ...@@ -96,6 +98,9 @@ export default function PoolFinder() {
</LightCard> </LightCard>
) )
const networkSupportsV2 = useNetworkSupportsV2()
if (!networkSupportsV2) return <V2Unsupported />
return ( return (
<Trace page={InterfacePageName.POOL_PAGE} shouldLogImpression> <Trace page={InterfacePageName.POOL_PAGE} shouldLogImpression>
<> <>
......
...@@ -8,7 +8,9 @@ import { useWeb3React } from '@web3-react/core' ...@@ -8,7 +8,9 @@ import { useWeb3React } from '@web3-react/core'
import { TraceEvent } from 'analytics' import { TraceEvent } from 'analytics'
import { useToggleAccountDrawer } from 'components/AccountDrawer' import { useToggleAccountDrawer } from 'components/AccountDrawer'
import { sendEvent } from 'components/analytics' import { sendEvent } from 'components/analytics'
import { V2Unsupported } from 'components/V2Unsupported'
import { isSupportedChain } from 'constants/chains' import { isSupportedChain } from 'constants/chains'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit' import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit'
import { PositionPageUnsupportedContent } from 'pages/Pool/PositionPage' import { PositionPageUnsupportedContent } from 'pages/Pool/PositionPage'
import { useCallback, useMemo, useState } from 'react' import { useCallback, useMemo, useState } from 'react'
...@@ -157,8 +159,12 @@ function RemoveLiquidity() { ...@@ -157,8 +159,12 @@ function RemoveLiquidity() {
// tx sending // tx sending
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
const networkSupportsV2 = useNetworkSupportsV2()
async function onRemove() { async function onRemove() {
if (!chainId || !provider || !account || !deadline || !router) throw new Error('missing dependencies') if (!chainId || !provider || !account || !deadline || !router || !networkSupportsV2) {
throw new Error('missing dependencies')
}
const { [Field.CURRENCY_A]: currencyAmountA, [Field.CURRENCY_B]: currencyAmountB } = parsedAmounts const { [Field.CURRENCY_A]: currencyAmountA, [Field.CURRENCY_B]: currencyAmountB } = parsedAmounts
if (!currencyAmountA || !currencyAmountB) { if (!currencyAmountA || !currencyAmountB) {
throw new Error('missing currency amounts') throw new Error('missing currency amounts')
...@@ -439,6 +445,8 @@ function RemoveLiquidity() { ...@@ -439,6 +445,8 @@ function RemoveLiquidity() {
liquidityPercentChangeCallback liquidityPercentChangeCallback
) )
if (!networkSupportsV2) return <V2Unsupported />
return ( return (
<> <>
<AppBody> <AppBody>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment