): JSX.Element {
return (
-
-
-
- {children}
-
-
-
+
+
+
+
+ {children}
+
+
+
+
)
}
@@ -121,13 +124,15 @@ export function renderHookWithProviders(
function Wrapper({ children }: PropsWithChildren): JSX.Element {
return (
-
-
-
- {children}
-
-
-
+
+
+
+
+ {children}
+
+
+
+
)
}
diff --git a/apps/mobile/src/utils/useOpenBackupReminderModal.ts b/apps/mobile/src/utils/useOpenBackupReminderModal.ts
index 77b7feceec4..44561c6cd36 100644
--- a/apps/mobile/src/utils/useOpenBackupReminderModal.ts
+++ b/apps/mobile/src/utils/useOpenBackupReminderModal.ts
@@ -3,52 +3,29 @@ import { useDispatch, useSelector } from 'react-redux'
import { openModal } from 'src/features/modals/modalSlice'
import { selectModalState } from 'src/features/modals/selectModalState'
import { AccountType } from 'uniswap/src/features/accounts/types'
-import { Experiments, OnboardingRedesignRecoveryBackupProperties } from 'uniswap/src/features/gating/experiments'
-import { useExperimentValueWithExposureLoggingDisabled } from 'uniswap/src/features/gating/hooks'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { useSelectAddressTransactions } from 'uniswap/src/features/transactions/selectors'
import { ONE_SECOND_MS } from 'utilities/src/time/time'
-import {
- selectBackupReminderLastSeenTs,
- selectCreatedOnboardingRedesignAccount,
-} from 'wallet/src/features/behaviorHistory/selectors'
+import { selectBackupReminderLastSeenTs } from 'wallet/src/features/behaviorHistory/selectors'
import { Account } from 'wallet/src/features/wallet/accounts/types'
+const BACKUP_REMINDER_DELAY_MS = 20 * ONE_SECOND_MS
+
export function useOpenBackupReminderModal(activeAccount: Account): void {
const dispatch = useDispatch()
const txns = useSelectAddressTransactions(activeAccount.address)
const { isOpen: isBackupReminderModalOpen } = useSelector(selectModalState(ModalName.BackupReminder))
const backupReminderLastSeenTs = useSelector(selectBackupReminderLastSeenTs)
- const createdOnboardingRedesignAccount = useSelector(selectCreatedOnboardingRedesignAccount)
- const onboardingBackupExperimentEnabled = useExperimentValueWithExposureLoggingDisabled(
- Experiments.OnboardingRedesignRecoveryBackup,
- OnboardingRedesignRecoveryBackupProperties.Enabled,
- false,
- )
- const enableReminder = createdOnboardingRedesignAccount && onboardingBackupExperimentEnabled
-
- const backupReminderOpenDelaySec = useExperimentValueWithExposureLoggingDisabled(
- Experiments.OnboardingRedesignRecoveryBackup,
- OnboardingRedesignRecoveryBackupProperties.BackupReminderDelaySecs,
- 0, // Defaulting to 0 seconds delay
- (x): x is number => typeof x === 'number',
- )
-
const isSignerAccount = activeAccount.type === AccountType.SignerMnemonic
const shouldOpenBackupReminderModal =
!isBackupReminderModalOpen && isSignerAccount && !!txns && !activeAccount.backups
useEffect(() => {
- if (!enableReminder) {
- return undefined
- }
-
- if (shouldOpenBackupReminderModal && onboardingBackupExperimentEnabled && backupReminderLastSeenTs === undefined) {
+ if (shouldOpenBackupReminderModal && backupReminderLastSeenTs === undefined) {
// Get the min addedTime from the transactions (i.e. the user's first transaction)
const minAddedTime = Math.min(...txns.map((txn) => txn.addedTime))
- const delayMs = backupReminderOpenDelaySec * ONE_SECOND_MS
- const remainingTimeMs = Math.max(minAddedTime + delayMs - Date.now(), 0)
+ const remainingTimeMs = Math.max(minAddedTime + BACKUP_REMINDER_DELAY_MS - Date.now(), 0)
const timeoutId = setTimeout(() => {
dispatch(openModal({ name: ModalName.BackupReminder }))
}, remainingTimeMs)
@@ -57,13 +34,5 @@ export function useOpenBackupReminderModal(activeAccount: Account): void {
}
return undefined
- }, [
- dispatch,
- shouldOpenBackupReminderModal,
- backupReminderLastSeenTs,
- txns,
- enableReminder,
- onboardingBackupExperimentEnabled,
- backupReminderOpenDelaySec,
- ])
+ }, [dispatch, shouldOpenBackupReminderModal, backupReminderLastSeenTs, txns])
}
diff --git a/apps/mobile/src/utils/version.ts b/apps/mobile/src/utils/version.ts
index 8b90e3a668c..b0bc1aa46c1 100644
--- a/apps/mobile/src/utils/version.ts
+++ b/apps/mobile/src/utils/version.ts
@@ -44,24 +44,17 @@ export function getStatsigEnvironmentTier(): StatsigEnvironmentTier {
return StatsigEnvironmentTier.PROD
}
-export function getSentryEnvironment(): SentryEnvironment {
+export function getDatadogEnvironment(): DatadogEnvironment {
if (isDevEnv()) {
- return SentryEnvironment.DEV
+ return DatadogEnvironment.DEV
}
if (isBetaEnv()) {
- return SentryEnvironment.BETA
+ return DatadogEnvironment.BETA
}
- return SentryEnvironment.PROD
+ return DatadogEnvironment.PROD
}
-export function getSentryTracesSamplingRate(): number {
- if (isDevEnv() || isBetaEnv()) {
- return 1
- }
- return 0.2
-}
-
-enum SentryEnvironment {
+enum DatadogEnvironment {
DEV = 'development',
BETA = 'beta',
PROD = 'production',
diff --git a/apps/web/cypress/e2e/add-liquidity.test.ts b/apps/web/cypress/e2e/add-liquidity.test.ts
index 0d2cdc114ad..3b30eed81be 100644
--- a/apps/web/cypress/e2e/add-liquidity.test.ts
+++ b/apps/web/cypress/e2e/add-liquidity.test.ts
@@ -1,4 +1,4 @@
-import { getTestSelector, resetHardhatChain } from '../utils'
+import { getTestSelector } from '../utils'
describe('Add Liquidity', () => {
it('loads the token pair', () => {
@@ -8,20 +8,6 @@ describe('Add Liquidity', () => {
cy.contains('0.05% fee tier')
})
- describe('chain changes', () => {
- afterEach(resetHardhatChain)
-
- it('clears the token selection when chain changes', () => {
- cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH/500')
- cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
- cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'ETH')
- cy.get(getTestSelector('chain-selector')).last().click()
- cy.contains('Polygon').click()
- cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'MATIC')
- cy.get('#add-liquidity-input-tokena .token-symbol-container').should('not.contain.text', 'UNI')
- })
- })
-
it('does not crash if token is duplicated', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
diff --git a/apps/web/cypress/e2e/buy-crypto-form.test.ts b/apps/web/cypress/e2e/buy-crypto-form.test.ts
index 70e01aa9472..0045dd489ae 100644
--- a/apps/web/cypress/e2e/buy-crypto-form.test.ts
+++ b/apps/web/cypress/e2e/buy-crypto-form.test.ts
@@ -18,7 +18,7 @@ describe('Buy Crypto Form', () => {
})
it('user input amount', () => {
- cy.get(getTestSelector('buy-form-amount-input')).type('123').should('have.value', '123')
+ cy.get(getTestSelector('buy-form-amount-input')).clear().type('123')
cy.contains('Continue').click()
cy.get('#ChooseProviderModal').should('be.visible')
@@ -27,7 +27,7 @@ describe('Buy Crypto Form', () => {
it('change input token', () => {
cy.contains('ETH').click()
cy.contains('DAI').click()
- cy.get(getTestSelector('buy-form-amount-input')).type('123').should('have.value', '123')
+ cy.get(getTestSelector('buy-form-amount-input')).clear().type('123')
cy.contains('Continue').click()
cy.get('#ChooseProviderModal').should('be.visible')
})
@@ -35,7 +35,7 @@ describe('Buy Crypto Form', () => {
it('change country', () => {
cy.get(getTestSelector('FiatOnRampCountryPicker')).click()
cy.contains('Argentina').click()
- cy.get(getTestSelector('buy-form-amount-input')).type('123').should('have.value', '123')
+ cy.get(getTestSelector('buy-form-amount-input')).clear().type('123')
cy.contains('Continue').click()
cy.get('#ChooseProviderModal').should('be.visible')
})
diff --git a/apps/web/cypress/e2e/mini-portfolio/accounts.test.ts b/apps/web/cypress/e2e/mini-portfolio/accounts.test.ts
index b9d0a3ce64e..18429787516 100644
--- a/apps/web/cypress/e2e/mini-portfolio/accounts.test.ts
+++ b/apps/web/cypress/e2e/mini-portfolio/accounts.test.ts
@@ -116,10 +116,9 @@ describe('Mini Portfolio account drawer', () => {
cy.get(getTestSelector('close-account-drawer')).click()
// Switch chain to Polygon
- cy.get(getTestSelector('chain-selector')).click()
- cy.contains('Polygon').click({ force: true })
+ cy.window().then((win) => win.ethereum.emit('networkChanged', { chainId: '0x137' }))
- //Reopen account drawer
+ // Reopen account drawer
cy.get(getTestSelector('web3-status-connected')).click()
// Simulate wallet changing to Hayden's account
diff --git a/apps/web/cypress/e2e/permit2.test.ts b/apps/web/cypress/e2e/permit2.test.ts
index f4eee9aeba7..1925aa51244 100644
--- a/apps/web/cypress/e2e/permit2.test.ts
+++ b/apps/web/cypress/e2e/permit2.test.ts
@@ -2,7 +2,7 @@ import { BigNumber } from '@ethersproject/bignumber'
import { MaxUint160, MaxUint256 } from '@uniswap/permit2-sdk'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
-import { DAI, USDC_MAINNET, USDT } from 'uniswap/src/constants/tokens'
+import { DAI, USDT } from 'uniswap/src/constants/tokens'
import { HARDHAT_TIMEOUT, setupHardhat } from '../utils'
/** Initiates a swap. */
@@ -57,7 +57,7 @@ describe('Permit2', () => {
after(() => cy.hardhat({ automine: true }))
it('swaps after completing full permit2 approval process', () => {
- setupInputs(DAI, USDC_MAINNET)
+ setupInputs(DAI, USDT)
initiateSwap('Approve and swap')
// verify that the modal retains its state when the window loses focus
@@ -79,7 +79,7 @@ describe('Permit2', () => {
})
it('swaps with existing permit approval and missing token approval', () => {
- setupInputs(DAI, USDC_MAINNET)
+ setupInputs(DAI, USDT)
cy.hardhat().then({ timeout: HARDHAT_TIMEOUT }, async (hardhat) => {
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: DAI })
await hardhat.mine()
@@ -115,7 +115,7 @@ describe('Permit2', () => {
await hardhat.mine()
})
- setupInputs(USDT, USDC_MAINNET)
+ setupInputs(USDT, DAI)
cy.get('#swap-currency-input .token-amount-input').clear().type('2')
initiateSwap('Approve and swap')
@@ -145,7 +145,7 @@ describe('Permit2', () => {
await hardhat.approval.setTokenAllowanceForPermit2({ owner: hardhat.wallet, token: DAI })
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: DAI })
})
- setupInputs(DAI, USDC_MAINNET)
+ setupInputs(DAI, USDT)
initiateSwap()
// Verify transaction
@@ -153,7 +153,7 @@ describe('Permit2', () => {
})
it('swaps after handling user rejection of both approval and signature', () => {
- setupInputs(DAI, USDC_MAINNET)
+ setupInputs(DAI, USDT)
const USER_REJECTION = { code: 4001 }
cy.hardhat().then((hardhat) => {
// Reject token approval
@@ -194,7 +194,7 @@ describe('Permit2', () => {
})
it('prompts token approval when existing approval amount is too low', () => {
- setupInputs(DAI, USDC_MAINNET)
+ setupInputs(DAI, USDT)
cy.hardhat().then({ timeout: HARDHAT_TIMEOUT }, async (hardhat) => {
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: DAI })
await hardhat.approval.setTokenAllowanceForPermit2({ owner: hardhat.wallet, token: DAI }, 1)
@@ -213,7 +213,7 @@ describe('Permit2', () => {
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: DAI }, expiredAllowance)
})
.then(() => {
- setupInputs(DAI, USDC_MAINNET)
+ setupInputs(DAI, USDT)
initiateSwap('Sign and swap')
})
@@ -231,7 +231,7 @@ describe('Permit2', () => {
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: DAI }, smallAllowance)
})
.then(() => {
- setupInputs(DAI, USDC_MAINNET)
+ setupInputs(DAI, USDT)
initiateSwap('Sign and swap')
})
diff --git a/apps/web/cypress/e2e/redirects.test.ts b/apps/web/cypress/e2e/redirects.test.ts
index 907bffb79b8..22cbe7eda92 100644
--- a/apps/web/cypress/e2e/redirects.test.ts
+++ b/apps/web/cypress/e2e/redirects.test.ts
@@ -1,3 +1,5 @@
+import { FeatureFlags } from "uniswap/src/features/gating/flags"
+
describe('Redirect', () => {
it('should redirect to /vote/create-proposal when visiting /create-proposal', () => {
cy.visit('/create-proposal')
@@ -21,3 +23,25 @@ describe('RedirectExplore', () => {
cy.url().should('match', /\/explore\/tokens\/optimism\/NATIVE/)
})
})
+
+describe('Legacy Pool Redirects', () => {
+ it('should redirect /pool to /positions', () => {
+ cy.visit('/pool', {
+ featureFlags: [{
+ flag: FeatureFlags.V4Everywhere,
+ value: true,
+ }]
+ })
+ cy.url().should('match', /\/positions/)
+ })
+
+ it('should redirect /pool/:tokenId with chain param to /positions/v3/:chainName/:tokenId', () => {
+ cy.visit('/pool/123?chain=mainnet', {
+ featureFlags: [{
+ flag: FeatureFlags.V4Everywhere,
+ value: true,
+ }]
+ })
+ cy.url().should('match', /\/positions\/v3\/ethereum\/123/)
+ })
+})
diff --git a/apps/web/cypress/e2e/remove-liquidity.test.ts b/apps/web/cypress/e2e/remove-liquidity.test.ts
index daccedc1fd9..a4cccd3de9a 100644
--- a/apps/web/cypress/e2e/remove-liquidity.test.ts
+++ b/apps/web/cypress/e2e/remove-liquidity.test.ts
@@ -1,14 +1,11 @@
import { MaxUint256, UNI_ADDRESSES } from '@uniswap/sdk-core'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const UNI_MAINNET = UNI_ADDRESSES[UniverseChainId.Mainnet]
describe('Remove Liquidity', () => {
it('loads the token pair in v2', () => {
- cy.visit(`/remove/v2/ETH/${UNI_MAINNET}`, {
- featureFlags: [{ flag: FeatureFlags.V2Everywhere, value: true }],
- })
+ cy.visit(`/remove/v2/ETH/${UNI_MAINNET}`)
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'ETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'UNI')
})
diff --git a/apps/web/cypress/e2e/swap/fees.test.ts b/apps/web/cypress/e2e/swap/fees.test.ts
index 15ff6c82c95..2458bbac98b 100644
--- a/apps/web/cypress/e2e/swap/fees.test.ts
+++ b/apps/web/cypress/e2e/swap/fees.test.ts
@@ -1,6 +1,6 @@
import { CurrencyAmount } from '@uniswap/sdk-core'
import { URAQuoteResponse } from 'state/routing/types'
-import { USDT } from 'uniswap/src/constants/tokens'
+import { DAI, USDT } from 'uniswap/src/constants/tokens'
import { getBalance, getTestSelector } from '../../utils'
describe('Swap with fees', () => {
@@ -19,8 +19,10 @@ describe('Swap with fees', () => {
it('displays $0 fee on swaps without fees', () => {
// Set up a stablecoin <> stablecoin swap (no fees)
+ cy.interceptGraphqlOperation('SearchTokens', 'search_token_dai.json')
cy.get('#swap-currency-input .open-currency-select-button').click()
- cy.get(getTestSelector('token-option-1-WETH')).click()
+ cy.get(getTestSelector('explore-search-input')).type(DAI.address)
+ cy.get(getTestSelector('token-option-1-DAI')).click()
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.get(getTestSelector('token-option-1-USDT')).click()
cy.get('#swap-currency-output .token-amount-input').type('1')
@@ -31,7 +33,10 @@ describe('Swap with fees', () => {
cy.contains('$0')
})
- it('swaps ETH for USDT exact-out with swap fee', () => {
+ // TODO(WEB-5078): universal swap e2e testing
+ // Skipping this test for now because it fails when running in cloud
+ // will revisit during new swap e2e test work
+ it.skip('swaps ETH for USDT exact-out with swap fee', () => {
cy.hardhat().then((hardhat) => {
getBalance(USDT).then((initialBalance) => {
// Set up swap
@@ -139,7 +144,7 @@ describe('Swap with fees', () => {
cy.get('#swap-currency-input .open-currency-select-button').click()
cy.get(getTestSelector('token-option-1-USDT')).click()
cy.get('#swap-currency-output .open-currency-select-button').click()
- cy.get(getTestSelector('token-option-1-ETH')).click()
+ cy.get(getTestSelector('token-option-1-ETH')).first().click()
cy.get('#swap-currency-input .token-amount-input').type('200')
// Verify fee UI is displayed
diff --git a/apps/web/cypress/e2e/swap/swap.test.ts b/apps/web/cypress/e2e/swap/swap.test.ts
index cb134b0714a..4185457c653 100644
--- a/apps/web/cypress/e2e/swap/swap.test.ts
+++ b/apps/web/cypress/e2e/swap/swap.test.ts
@@ -1,4 +1,4 @@
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { UNI, USDC_MAINNET } from 'uniswap/src/constants/tokens'
import { getBalance, getTestSelector } from '../../utils'
import { SwapEventName } from '@uniswap/analytics-events'
@@ -62,19 +62,20 @@ describe('Swap', () => {
})
it('swaps ETH for USDC', () => {
- cy.interceptGraphqlOperation('SearchTokens', 'search_token_usdc.json')
cy.interceptGraphqlOperation('Activity', 'mini-portfolio/empty_activity.json')
cy.visit('/swap')
getBalance(USDC_MAINNET).then((initialBalance) => {
cy.get(`#swap-currency-input .token-symbol-container`).should('contain.text', 'ETH')
-
+
// Select ETH
cy.get('#swap-currency-input .open-currency-select-button').click()
+ cy.interceptGraphqlOperation('SearchTokens', 'search_token_eth.json')
cy.get(getTestSelector('explore-search-input')).type('ETH')
cy.get(getTestSelector('token-option-1-ETH')).click()
-
+
// Select USDC
cy.get('#swap-currency-output .open-currency-select-button').click()
+ cy.interceptGraphqlOperation('SearchTokens', 'search_token_usdc.json')
cy.get(getTestSelector('explore-search-input')).type(USDC_MAINNET.address)
cy.get(getTestSelector('token-option-1-USDC')).click()
diff --git a/apps/web/cypress/e2e/swap/uniswapx.test.ts b/apps/web/cypress/e2e/swap/uniswapx.test.ts
index 2da1f13d969..3a0f590637d 100644
--- a/apps/web/cypress/e2e/swap/uniswapx.test.ts
+++ b/apps/web/cypress/e2e/swap/uniswapx.test.ts
@@ -1,6 +1,6 @@
import { CurrencyAmount } from '@uniswap/sdk-core'
import { DAI, USDC_MAINNET } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { getTestSelector, setupHardhat } from '../../utils'
import { stubNonPriceQuoteWith, stubSwapTxReceipt } from '../../utils/uniswapx-swap'
diff --git a/apps/web/cypress/e2e/swap/uniswapxv2.test.ts b/apps/web/cypress/e2e/swap/uniswapxv2.test.ts
index b03d481ae59..f21c4229e6d 100644
--- a/apps/web/cypress/e2e/swap/uniswapxv2.test.ts
+++ b/apps/web/cypress/e2e/swap/uniswapxv2.test.ts
@@ -1,6 +1,6 @@
import { CurrencyAmount } from '@uniswap/sdk-core'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { getTestSelector, setupHardhat } from '../../utils'
import { stubNonPriceQuoteWith, stubSwapTxReceipt } from '../../utils/uniswapx-swap'
diff --git a/apps/web/cypress/e2e/swap/wrap.test.ts b/apps/web/cypress/e2e/swap/wrap.test.ts
index 98685cba2d7..271ae26c6d1 100644
--- a/apps/web/cypress/e2e/swap/wrap.test.ts
+++ b/apps/web/cypress/e2e/swap/wrap.test.ts
@@ -1,5 +1,5 @@
import { CurrencyAmount, WETH9 } from '@uniswap/sdk-core'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { HARDHAT_TIMEOUT, getBalance, getTestSelector } from '../../utils'
const WETH = WETH9[UniverseChainId.Mainnet]
diff --git a/apps/web/cypress/e2e/token-details.test.ts b/apps/web/cypress/e2e/token-details.test.ts
index 79f58fcbe23..2d53c3826c1 100644
--- a/apps/web/cypress/e2e/token-details.test.ts
+++ b/apps/web/cypress/e2e/token-details.test.ts
@@ -1,7 +1,6 @@
-import { WETH9 } from '@uniswap/sdk-core'
-import { ARB, UNI } from 'uniswap/src/constants/tokens'
+import { UNI, USDT, USDT_ARBITRUM_ONE } from 'uniswap/src/constants/tokens'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { shortenAddress } from 'utilities/src/addresses'
import { getTestSelector } from '../utils'
@@ -105,18 +104,18 @@ describe('Token details', () => {
it('should automatically navigate to the new TDP', () => {
cy.get(`#swap-currency-output .open-currency-select-button`).click()
- cy.get('[data-reach-dialog-content]').contains('WETH').click({ force: true })
- cy.url().should('include', `${WETH9[1].address.toLowerCase()}`)
+ cy.get(getTestSelector('token-option-1-USDT')).click()
+ cy.url().should('include', `${USDT.address}`)
cy.url().should('not.include', `${UNI_MAINNET.address}`)
})
it('should not share swap state with the main swap page', () => {
cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'UNI')
cy.get(`#swap-currency-input .open-currency-select-button`).click()
- cy.get(getTestSelector('token-option-1-WETH')).click()
+ cy.get(getTestSelector('token-option-1-USDT')).click()
cy.visit('/swap')
cy.contains('UNI').should('not.exist')
- cy.contains('WETH').should('not.exist')
+ cy.contains('USDT').should('not.exist')
})
it('can enter an amount into input', () => {
@@ -140,13 +139,12 @@ describe('Token details', () => {
})
it('should show a L2 token even if the user is connected to a different network', () => {
- cy.visit('/explore/tokens')
+ cy.visit('/explore/tokens/ethereum')
cy.get(getTestSelector('tokens-network-filter-selected')).click()
cy.get(getTestSelector('tokens-network-filter-option-arbitrum')).first().click()
cy.get(getTestSelector('tokens-network-filter-selected')).invoke('attr', 'alt').should('eq', `Arbitrum logo`)
- cy.get(getTestSelector(`token-table-row-${ARB.address.toLowerCase()}`)).click()
- cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'ARB')
- cy.contains('Connect to Arbitrum').should('exist')
+ cy.get(getTestSelector(`token-table-row-${USDT_ARBITRUM_ONE.address}`)).click()
+ cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'USDT')
})
})
})
diff --git a/apps/web/cypress/e2e/token-explore-filter.test.ts b/apps/web/cypress/e2e/token-explore-filter.test.ts
index e016b733670..133954af42a 100644
--- a/apps/web/cypress/e2e/token-explore-filter.test.ts
+++ b/apps/web/cypress/e2e/token-explore-filter.test.ts
@@ -33,7 +33,9 @@ describe('Token explore filter', () => {
.map((i, token) => token.innerText)
.get()
- cy.wrap(tokenTexts).should('deep.equal', filteredTokenTexts)
+ const firstToken = [tokenTexts[0]]
+
+ cy.wrap(firstToken).should('deep.equal', filteredTokenTexts)
})
})
})
diff --git a/apps/web/cypress/e2e/token-explore.test.ts b/apps/web/cypress/e2e/token-explore.test.ts
index 079cec4dc6f..8e8e0095e6e 100644
--- a/apps/web/cypress/e2e/token-explore.test.ts
+++ b/apps/web/cypress/e2e/token-explore.test.ts
@@ -39,7 +39,7 @@ describe('Token explore', () => {
it('should navigate to token detail page when row clicked', () => {
cy.visit('/explore/tokens/ethereum')
- cy.get(getTestSelector('token-table-row-NATIVE')).click()
+ cy.get(getTestSelector('token-table-row-NATIVE')).click({ force: true })
cy.url().should('match', /\/explore\/tokens\/ethereum\/NATIVE/)
})
@@ -50,9 +50,9 @@ describe('Token explore', () => {
// note: cannot switch global chain via UI because we cannot approve the network switch
// in metamask modal using plain cypress. this is a workaround.
- cy.visit('/explore/tokens/polygon')
- cy.get(getTestSelector('tokens-network-filter-selected')).invoke('attr', 'alt').should('eq', `Polygon logo`)
- cy.get(getTestSelector('token-table-row-NATIVE')).find(getTestSelector('name-cell')).should('include.text', 'Matic')
+ cy.visit('/explore/tokens/optimism')
+ cy.get(getTestSelector('tokens-network-filter-selected')).invoke('attr', 'alt').should('eq', `Optimism logo`)
+ cy.get(getTestSelector('token-table-row-NATIVE')).find(getTestSelector('name-cell')).should('include.text', 'Ethereum')
})
it('should update when token explore table network changed', () => {
diff --git a/apps/web/cypress/e2e/universal-search.test.ts b/apps/web/cypress/e2e/universal-search.test.ts
index bae1f5d9073..c6041e828d9 100644
--- a/apps/web/cypress/e2e/universal-search.test.ts
+++ b/apps/web/cypress/e2e/universal-search.test.ts
@@ -1,6 +1,6 @@
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { UNI } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { getTestSelector } from '../utils'
const UNI_ADDRESS = UNI[UniverseChainId.Mainnet].address.toLowerCase()
diff --git a/apps/web/cypress/e2e/wallet-dropdown.test.ts b/apps/web/cypress/e2e/wallet-dropdown.test.ts
index c4e404e4150..ad99c71fefa 100644
--- a/apps/web/cypress/e2e/wallet-dropdown.test.ts
+++ b/apps/web/cypress/e2e/wallet-dropdown.test.ts
@@ -21,7 +21,7 @@ describe('Wallet Dropdown', () => {
it('should change locale', () => {
cy.contains('Uniswap available in: English').should('not.exist')
- cy.get(getTestSelector('language-settings-button')).click()
+ cy.get(getTestSelector('language-settings-button')).click()
cy.get(getTestSelector('wallet-language-item')).contains('Afrikaans').click({ force: true })
cy.location('search').should('include', 'lng=af-ZA')
@@ -81,118 +81,118 @@ describe('Wallet Dropdown', () => {
describe('testnet toggle', () => {
beforeEach(() => {
cy.visit('/swap')
+ it('should toggle testnet visibility', () => {
+ cy.get('#swap-currency-input .open-currency-select-button').click()
+ cy.get(getTestSelector('chain-selector')).last().click()
+ cy.get(getTestSelector('network-button-11155111')).should('not.exist')
+
+ cy.get(getTestSelector('web3-status-connected')).click({ force: true })
+ cy.get(getTestSelector('wallet-settings')).click()
+ cy.get(getTestSelector('testnets-toggle')).click()
+ cy.contains('Close').click()
+ cy.get(getTestSelector('close-account-drawer')).click()
+ cy.get(getTestSelector('choose-input-token')).click()
+ cy.get(getTestSelector('token-option-11155111-ETH')).should('exist')
+ })
})
- it('should toggle testnet visibility', () => {
- cy.get('#swap-currency-input .open-currency-select-button').click()
- cy.get(getTestSelector('chain-selector')).last().click()
- cy.get(getTestSelector('network-button-11155111')).should('not.exist')
- cy.get(getTestSelector('web3-status-connected')).click({force: true})
- cy.get(getTestSelector('wallet-settings')).click()
- cy.get(getTestSelector('testnets-toggle')).click()
- cy.get(getTestSelector('close-account-drawer')).click()
- cy.get('#swap-currency-input .open-currency-select-button').click()
- cy.get(getTestSelector('chain-selector')).last().click()
- cy.get(getTestSelector('network-button-11155111')).should('exist')
+ describe('disconnected', () => {
+ beforeEach(() => {
+ cy.visit('/')
+ cy.get(getTestSelector('web3-status-connected')).click()
+ // click twice, first time to show confirmation, second to confirm
+ cy.get(getTestSelector('wallet-disconnect')).click()
+ cy.get(getTestSelector('wallet-disconnect')).should('contain', 'Disconnect')
+ cy.get(getTestSelector('wallet-disconnect')).click()
+ })
+ it('wallet settings should not be accessible', () => {
+ cy.get(getTestSelector('wallet-settings')).should('not.exist')
+ })
})
- })
- describe('disconnected', () => {
- beforeEach(() => {
- cy.visit('/')
- cy.get(getTestSelector('web3-status-connected')).click()
- // click twice, first time to show confirmation, second to confirm
- cy.get(getTestSelector('wallet-disconnect')).click()
- cy.get(getTestSelector('wallet-disconnect')).should('contain', 'Disconnect')
- cy.get(getTestSelector('wallet-disconnect')).click()
- })
- it('wallet settings should not be accessible', () => {
- cy.get(getTestSelector('wallet-settings')).should('not.exist')
- })
- })
-
- // TODO(WEB-3905): Fix tamagui error causing these tests to fail.
- describe.skip('with color theme', () => {
- function visitSwapWithColorTheme({ dark }: { dark: boolean }) {
- cy.visit('/swap', {
- onBeforeLoad(win) {
- cy.stub(win, 'matchMedia')
- .withArgs('(prefers-color-scheme: dark)')
- .returns({
- matches: dark,
- addEventListener() {
- /* noop */
- },
- removeEventListener() {
- /* noop */
- },
- })
- },
+ // TODO(WEB-3905): Fix tamagui error causing these tests to fail.
+ describe.skip('with color theme', () => {
+ function visitSwapWithColorTheme({ dark }: { dark: boolean }) {
+ cy.visit('/swap', {
+ onBeforeLoad(win) {
+ cy.stub(win, 'matchMedia')
+ .withArgs('(prefers-color-scheme: dark)')
+ .returns({
+ matches: dark,
+ addEventListener() {
+ /* noop */
+ },
+ removeEventListener() {
+ /* noop */
+ },
+ })
+ },
+ })
+ }
+
+ it('should properly use dark system theme when auto theme setting is selected', () => {
+ visitSwapWithColorTheme({ dark: true })
+ cy.get(getTestSelector('web3-status-connected')).click()
+ cy.get(getTestSelector('wallet-settings')).click()
+ cy.get(getTestSelector('theme-auto')).click()
+ cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(155, 155, 155)')
})
- }
-
- it('should properly use dark system theme when auto theme setting is selected', () => {
- visitSwapWithColorTheme({ dark: true })
- cy.get(getTestSelector('web3-status-connected')).click()
- cy.get(getTestSelector('wallet-settings')).click()
- cy.get(getTestSelector('theme-auto')).click()
- cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(155, 155, 155)')
- })
- it('should properly use light system theme when auto theme setting is selected', () => {
- visitSwapWithColorTheme({ dark: false })
- cy.get(getTestSelector('web3-status-connected')).click()
- cy.get(getTestSelector('wallet-settings')).click()
- cy.get(getTestSelector('theme-auto')).click()
- cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(125, 125, 125)')
+ it('should properly use light system theme when auto theme setting is selected', () => {
+ visitSwapWithColorTheme({ dark: false })
+ cy.get(getTestSelector('web3-status-connected')).click()
+ cy.get(getTestSelector('wallet-settings')).click()
+ cy.get(getTestSelector('theme-auto')).click()
+ cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(125, 125, 125)')
+ })
})
- })
- describe('mobile', () => {
- beforeEach(() => {
- cy.viewport('iphone-6').visit('/')
- })
+ describe('mobile', () => {
+ beforeEach(() => {
+ cy.viewport('iphone-6').visit('/')
+ })
- it('should dismiss the wallet bottom sheet when clicking buy crypto', () => {
- cy.get(getTestSelector('web3-status-connected')).click()
- cy.get(getTestSelector('wallet-buy-crypto')).click()
- cy.get(getTestSelector('wallet-settings')).should('not.be.visible')
- })
+ it('should dismiss the wallet bottom sheet when clicking buy crypto', () => {
+ cy.get(getTestSelector('web3-status-connected')).click()
+ cy.get(getTestSelector('wallet-buy-crypto')).click()
+ cy.get(getTestSelector('wallet-settings')).should('not.be.visible')
+ })
- it('should use a bottom sheet and dismiss when on a mobile screen size', () => {
- cy.get(getTestSelector('web3-status-connected')).click()
- cy.root().click(15, 20)
- cy.get(getTestSelector('wallet-settings')).should('not.be.visible')
+ it('should use a bottom sheet and dismiss when on a mobile screen size', () => {
+ cy.get(getTestSelector('web3-status-connected')).click()
+ cy.root().click(15, 20)
+ cy.get(getTestSelector('wallet-settings')).should('not.be.visible')
+ })
})
- })
- describe('local currency', () => {
- it('loads local currency from the query param', () => {
- cy.visit('/')
- cy.get(getTestSelector('web3-status-connected')).click()
- cy.get(getTestSelector('wallet-settings')).click()
- cy.contains('USD')
+ describe('local currency', () => {
+ it('loads local currency from the query param', () => {
+ cy.visit('/')
+ cy.get(getTestSelector('web3-status-connected')).click()
+ cy.get(getTestSelector('wallet-settings')).click()
+ cy.contains('USD')
- cy.visit('/?cur=AUD')
- cy.get(getTestSelector('web3-status-connected')).click()
- cy.get(getTestSelector('wallet-settings')).click()
- cy.contains('AUD')
- })
+ cy.visit('/?cur=AUD')
+ cy.get(getTestSelector('web3-status-connected')).click()
+ cy.get(getTestSelector('wallet-settings')).click()
+ cy.contains('AUD')
+ })
- it('loads local currency from menu', () => {
- cy.visit('/')
- cy.get(getTestSelector('web3-status-connected')).click()
- cy.get(getTestSelector('wallet-settings')).click()
- cy.contains('USD')
+ it('loads local currency from menu', () => {
+ cy.visit('/')
+ cy.get(getTestSelector('web3-status-connected')).click()
+ cy.get(getTestSelector('wallet-settings')).click()
+ cy.contains('USD')
- cy.get(getTestSelector('local-currency-settings-button')).click()
- cy.get(getTestSelector('wallet-local-currency-item')).contains('AUD').click({ force: true })
- cy.location('search').should('include', 'cur=AUD')
- cy.contains('AUD')
+ cy.get(getTestSelector('local-currency-settings-button')).click()
+ cy.get(getTestSelector('wallet-local-currency-item')).contains('AUD').click({ force: true })
+ cy.location('search').should('include', 'cur=AUD')
+ cy.contains('AUD')
- cy.get(getTestSelector('wallet-local-currency-item')).contains('USD').click({ force: true })
- cy.location('search').should('include', 'cur=USD')
- cy.contains('USD')
+ cy.get(getTestSelector('wallet-local-currency-item')).contains('USD').click({ force: true })
+ cy.location('search').should('include', 'cur=USD')
+ cy.contains('USD')
+ })
})
})
})
diff --git a/apps/web/cypress/fixtures/search_token_dai.json b/apps/web/cypress/fixtures/search_token_dai.json
new file mode 100644
index 00000000000..1a5a8d391f5
--- /dev/null
+++ b/apps/web/cypress/fixtures/search_token_dai.json
@@ -0,0 +1 @@
+{"data":{"searchTokens":[{"id":"VG9rZW46RVRIRVJFVU1fMHg2YjE3NTQ3NGU4OTA5NGM0NGRhOThiOTU0ZWVkZWFjNDk1MjcxZDBm","chain":"ETHEREUM","address":"0x6b175474e89094c44da98b954eedeac495271d0f","decimals":18,"symbol":"DAI","name":"Dai Stablecoin","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNXzB4NmIxNzU0NzRlODkwOTRjNDRkYTk4Yjk1NGVlZGVhYzQ5NTI3MWQwZl9EYWk=","logoUrl":"https://coin-images.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":{"result":"BENIGN","attackTypes":[],"__typename":"ProtectionInfo"},"__typename":"Token"}]}}
\ No newline at end of file
diff --git a/apps/web/cypress/fixtures/search_token_eth.json b/apps/web/cypress/fixtures/search_token_eth.json
new file mode 100644
index 00000000000..e81cf41b402
--- /dev/null
+++ b/apps/web/cypress/fixtures/search_token_eth.json
@@ -0,0 +1 @@
+{"data":{"searchTokens":[{"id":"VG9rZW46WktTWU5DX251bGw=","chain":"ZKSYNC","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46V09STERDSEFJTl9udWxs","chain":"WORLDCHAIN","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46QkxBU1RfbnVsbA==","chain":"BLAST","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46Wk9SQV9udWxs","chain":"ZORA","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46RVRIRVJFVU1fbnVsbA==","chain":"ETHEREUM","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46QVJCSVRSVU1fbnVsbA==","chain":"ARBITRUM","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46T1BUSU1JU01fbnVsbA==","chain":"OPTIMISM","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46T1BUSU1JU01fbnVsbA==","chain":"BASE","address":null,"decimals":18,"symbol":"ETH","name":"Ethereum","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGxfRXRoZXJldW0=","logoUrl":"https://token-icons.s3.amazonaws.com/eth.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":null,"__typename":"Token"},{"id":"VG9rZW46RVRIRVJFVU1fMHhDMDJhYUEzOWIyMjNGRThEMEEwZTVDNEYyN2VBRDkwODNDNzU2Q2My","chain":"ETHEREUM","address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","decimals":18,"symbol":"WETH","name":"Wrapped Ether","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNXzB4YzAyYWFhMzliMjIzZmU4ZDBhMGU1YzRmMjdlYWQ5MDgzYzc1NmNjMl9XRVRI","logoUrl":"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":{"result":"BENIGN","attackTypes":[],"__typename":"ProtectionInfo"},"__typename":"Token"},{"id":"VG9rZW46QVJCSVRSVU1fMHg4MmFmNDk0NDdkOGEwN2UzYmQ5NWJkMGQ1NmYzNTI0MTUyM2ZiYWIx","chain":"ARBITRUM","address":"0x82af49447d8a07e3bd95bd0d56f35241523fbab1","decimals":18,"symbol":"WETH","name":"Wrapped Ether","project":{"id":"VG9rZW5Qcm9qZWN0OkVUSEVSRVVNXzB4YzAyYWFhMzliMjIzZmU4ZDBhMGU1YzRmMjdlYWQ5MDgzYzc1NmNjMl9BcmJpdHJ1bSBCcmlkZ2VkIFdFVEggKEFyYml0cnVtIE9uZSk=","logoUrl":"https://coin-images.coingecko.com/coins/images/39713/large/WETH.PNG?1723731496","safetyLevel":"VERIFIED","__typename":"TokenProject"},"protectionInfo":{"result":"BENIGN","attackTypes":[],"__typename":"ProtectionInfo"},"__typename":"Token"}]}}
\ No newline at end of file
diff --git a/apps/web/cypress/support/setupTests.ts b/apps/web/cypress/support/setupTests.ts
index 64dd2166a93..707aec511ac 100644
--- a/apps/web/cypress/support/setupTests.ts
+++ b/apps/web/cypress/support/setupTests.ts
@@ -1,5 +1,5 @@
import { CyHttpMessages } from 'cypress/types/net-stubbing'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { revertHardhat, setupHardhat } from '../utils'
export function registerSetupTests() {
diff --git a/apps/web/package.json b/apps/web/package.json
index 2dfa1c5045f..d51868e709b 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -6,7 +6,7 @@
"scripts": {
"ajv": "node scripts/compile-ajv-validators.js",
"check:deps:usage": "depcheck",
- "check:circular": "concurrently \"../../scripts/check-circular-imports.sh ./src/pages/App.tsx 5\" \"../../scripts/check-circular-imports.sh ./src/setupTests.ts 0\"",
+ "check:circular": "concurrently \"../../scripts/check-circular-imports.sh ./src/pages/App.tsx 4\" \"../../scripts/check-circular-imports.sh ./src/setupTests.ts 0\"",
"sitemap:generate": "node scripts/generate-sitemap.js",
"start": "craco start",
"start:cloud": "NODE_OPTIONS=--dns-result-order=ipv4first PORT=3001 REACT_APP_SKIP_CSP=1 npx wrangler pages dev --compatibility-flags=nodejs_compat --compatibility-date=2023-08-01 --proxy=3001 --port=3000 -- yarn start",
@@ -189,10 +189,10 @@
"@uniswap/permit2-sdk": "1.3.0",
"@uniswap/redux-multicall": "1.1.8",
"@uniswap/router-sdk": "1.14.3",
- "@uniswap/sdk-core": "5.8.4",
+ "@uniswap/sdk-core": "5.9.0",
"@uniswap/smart-order-router": "3.17.3",
"@uniswap/token-lists": "1.0.0-beta.33",
- "@uniswap/uniswapx-sdk": "^2.1.0-beta.14",
+ "@uniswap/uniswapx-sdk": "2.1.0-beta.18",
"@uniswap/universal-router-sdk": "4.5.2",
"@uniswap/v2-core": "1.0.1",
"@uniswap/v2-periphery": "1.1.0-beta.0",
@@ -241,7 +241,7 @@
"poisson-disk-sampling": "2.3.1",
"polished": "3.3.2",
"polyfill-object.fromentries": "1.0.1",
- "qs": "6.9.4",
+ "qs": "6.11.0",
"query-string": "7.1.3",
"rc-slider": "10.4.0",
"react": "18.2.0",
diff --git a/apps/web/public/.well-known/apple-app-site-association b/apps/web/public/.well-known/apple-app-site-association
new file mode 100644
index 00000000000..aefa339155f
--- /dev/null
+++ b/apps/web/public/.well-known/apple-app-site-association
@@ -0,0 +1,53 @@
+{
+ "applinks": {
+ "details": [
+ {
+ "appIDs": [
+ "JH3UHGZD75.com.uniswap.mobile",
+ "JH3UHGZD75.com.uniswap.mobile.dev"
+ ],
+ "components": [
+ {
+ "#": "/nfts/asset/*",
+ "comment": "NFT Item"
+ },
+ {
+ "#": "/nfts/collection/*",
+ "comment": "NFT Collection"
+ },
+ {
+ "#": "/tokens/*",
+ "comment": "Token address"
+ },
+ {
+ "#": "/address/*",
+ "comment": "Wallet address"
+ },
+ {
+ "/": "/nfts/asset/*",
+ "comment": "NFT Item"
+ },
+ {
+ "/": "/nfts/collection/*",
+ "comment": "NFT Collection"
+ },
+ {
+ "/": "/tokens/*",
+ "comment": "Token address"
+ },
+ {
+ "/": "/address/*",
+ "comment": "Wallet address"
+ }
+ ]
+ }
+ ]
+ },
+ "webcredentials": {
+ "apps": [
+ "JH3UHGZD75.com.uniswap.mobile",
+ "JH3UHGZD75.com.uniswap.mobile.beta",
+ "JH3UHGZD75.com.uniswap.mobile.dev"
+ ]
+ }
+}
diff --git a/apps/web/public/.well-known/assetlinks.json b/apps/web/public/.well-known/assetlinks.json
index dfcfe7ccd5e..26d1d0fe558 100644
--- a/apps/web/public/.well-known/assetlinks.json
+++ b/apps/web/public/.well-known/assetlinks.json
@@ -1,29 +1,45 @@
[
{
- "relation": ["delegate_permission/common.handle_all_urls"],
+ "relation": [
+ "delegate_permission/common.handle_all_urls",
+ "delegate_permission/common.get_login_creds"
+ ],
"target": {
"namespace": "android_app",
"package_name": "com.uniswap.mobile",
- "sha256_cert_fingerprints":
- ["49:D9:3D:5D:FB:AA:64:A4:64:80:85:0F:39:A8:C1:D9:25:D3:D4:BC:8E:6B:1F:45:0C:EA:AF:B1:0C:27:DF:B8", "F9:E9:E3:F0:04:28:66:62:81:44:50:7E:D6:A9:5F:B9:65:39:02:70:1D:13:74:15:D3:E1:A3:1B:D4:38:3A:1F"]
+ "sha256_cert_fingerprints": [
+ "49:D9:3D:5D:FB:AA:64:A4:64:80:85:0F:39:A8:C1:D9:25:D3:D4:BC:8E:6B:1F:45:0C:EA:AF:B1:0C:27:DF:B8",
+ "F9:E9:E3:F0:04:28:66:62:81:44:50:7E:D6:A9:5F:B9:65:39:02:70:1D:13:74:15:D3:E1:A3:1B:D4:38:3A:1F"
+ ]
}
},
{
- "relation": ["delegate_permission/common.handle_all_urls"],
+ "relation": [
+ "delegate_permission/common.handle_all_urls",
+ "delegate_permission/common.get_login_creds"
+ ],
"target": {
"namespace": "android_app",
"package_name": "com.uniswap.mobile.beta",
- "sha256_cert_fingerprints":
- ["75:41:9C:2D:01:4A:88:4E:8D:C6:EF:E5:51:54:28:6B:99:05:31:43:AD:84:B4:EB:39:28:B8:C3:C4:CE:48:E3", "54:4B:62:33:17:9B:5F:A8:E6:5D:D3:A6:E5:9D:80:5F:A5:02:7F:E2:14:B8:C1:7A:AC:4B:8D:E0:65:49:87:41"]
+ "sha256_cert_fingerprints": [
+ "75:41:9C:2D:01:4A:88:4E:8D:C6:EF:E5:51:54:28:6B:99:05:31:43:AD:84:B4:EB:39:28:B8:C3:C4:CE:48:E3",
+ "54:4B:62:33:17:9B:5F:A8:E6:5D:D3:A6:E5:9D:80:5F:A5:02:7F:E2:14:B8:C1:7A:AC:4B:8D:E0:65:49:87:41"
+ ]
}
},
{
- "relation": ["delegate_permission/common.handle_all_urls"],
+ "relation": [
+ "delegate_permission/common.handle_all_urls",
+ "delegate_permission/common.get_login_creds"
+ ],
"target": {
"namespace": "android_app",
"package_name": "com.uniswap.mobile.dev",
- "sha256_cert_fingerprints":
- ["45:F8:15:02:C5:4F:AD:82:E7:51:F0:9C:D1:CA:77:C8:C9:BF:06:A6:D9:5A:55:4F:9E:B8:5F:81:33:2B:D0:DB", "02:E6:1C:76:8C:75:C3:78:C8:8C:FE:7B:2E:8F:4B:E1:FA:47:F2:F6:1A:DB:57:69:4A:41:99:C6:71:2C:AB:E3", "FA:C6:17:45:DC:09:03:78:6F:B9:ED:E6:2A:96:2B:39:9F:73:48:F0:BB:6F:89:9B:83:32:66:75:91:03:3B:9C"]
+ "sha256_cert_fingerprints": [
+ "45:F8:15:02:C5:4F:AD:82:E7:51:F0:9C:D1:CA:77:C8:C9:BF:06:A6:D9:5A:55:4F:9E:B8:5F:81:33:2B:D0:DB",
+ "02:E6:1C:76:8C:75:C3:78:C8:8C:FE:7B:2E:8F:4B:E1:FA:47:F2:F6:1A:DB:57:69:4A:41:99:C6:71:2C:AB:E3",
+ "FA:C6:17:45:DC:09:03:78:6F:B9:ED:E6:2A:96:2B:39:9F:73:48:F0:BB:6F:89:9B:83:32:66:75:91:03:3B:9C"
+ ]
}
}
-]
\ No newline at end of file
+]
diff --git a/apps/web/public/app-sitemap.xml b/apps/web/public/app-sitemap.xml
index 06bb6000f83..bc83f2fc08c 100644
--- a/apps/web/public/app-sitemap.xml
+++ b/apps/web/public/app-sitemap.xml
@@ -126,16 +126,4 @@
weekly
0.5
-
- https://app.uniswap.org/positions/create
- 2024-09-17T19:57:27.976Z
- weekly
- 0.7
-
-
- https://app.uniswap.org/positions
- 2024-09-17T19:57:27.976Z
- weekly
- 0.7
-
diff --git a/apps/web/public/apple-app-site-association b/apps/web/public/apple-app-site-association
index 9554d3e24b8..aefa339155f 100644
--- a/apps/web/public/apple-app-site-association
+++ b/apps/web/public/apple-app-site-association
@@ -42,5 +42,12 @@
]
}
]
+ },
+ "webcredentials": {
+ "apps": [
+ "JH3UHGZD75.com.uniswap.mobile",
+ "JH3UHGZD75.com.uniswap.mobile.beta",
+ "JH3UHGZD75.com.uniswap.mobile.dev"
+ ]
}
}
diff --git a/apps/web/public/csp.json b/apps/web/public/csp.json
index 8e241ac6062..c6ab9cbf526 100644
--- a/apps/web/public/csp.json
+++ b/apps/web/public/csp.json
@@ -94,7 +94,6 @@
"https://wallet.crypto.com",
"https://web3.1inch.io",
"https://mainnet.era.zksync.io/",
- "https://9bxqhlmige.execute-api.us-east-2.amazonaws.com",
"wss://*.uniswap.org",
"wss://relay.walletconnect.com",
"wss://relay.walletconnect.org",
diff --git a/apps/web/public/nfts-sitemap.xml b/apps/web/public/nfts-sitemap.xml
index 5d053264215..776023dff5d 100644
--- a/apps/web/public/nfts-sitemap.xml
+++ b/apps/web/public/nfts-sitemap.xml
@@ -2,647 +2,702 @@
https://app.uniswap.org/nfts/collection/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x60e4d786628fea6478f785a6d7e704777c86a7c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xed5af388653567af2f388e6224dc7c4b3241c544
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x34d85c9cdeb23fa97cb08333b511ac86e1c4e258
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x99a9b7c1116f9ceeb1652de04d5969cce509b069
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x49cf6f5d44e70224e2e23fdcdd2c053f30ada28b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xb7f7f6c52f2e2fdb1963eab30438024864c313f6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x23581767a106ae21c074b2276d25e5c3e136a68b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x8a90cab2b38dba80c64b7734e58ee1db38b8992e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xba30e5f9bb24caa003e9f2f0497ad287fdf95623
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xbd3531da5cf5857e7cfaa92426877b022e612cf8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x7bd29408f11d2bfc23c34f18275bbf23bb716bc7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x306b1ea3ecdf94ab739f1910bbda052ed4a9f949
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x1a92f7381b9f03921564a437210bb9396471050c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x5cc5b05a8a13e3fbdb0bb9fccd98d38e50f90c38
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x5af0d9827e0c53e4799bb226655a1de152a425a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x3bf2922f4520a8ba0c2efc3d2a1539678dad5e9d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xe785e82358879f061bc3dcac6f0444462d4b5330
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x76be3b62873462d2142405439777e971754e8e77
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xfd43af6d3fe1b916c026f6ac35b3ede068d1ca01
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x1cb1a5e65610aeff2551a50f76a87a7d3fb649c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xff9c1b15b16263c61d017ee9f65c50e4ae0113d7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x6339e5e072086621540d0362c4e3cea0d643e114
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xb932a70a57673d89f4acffbe830e8ed7f75fb9e0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x79fcdef22feed20eddacbb2587640e45491b757f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xa3aee8bce55beea1951ef834b99f3ac60d1abeeb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x769272677fab02575e84945f03eca517acc544cc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x4db1f25d3d98600140dfc18deb7515be5bd293af
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x34eebee6942d8def3c125458d1a86e0a897fd6f9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x59468516a8259058bad1ca5f8f4bff190d30e066
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x394e3d3044fc89fcdd966d3cb35ac0b32b0cda91
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x60bb1e2aa1c9acafb4d34f71585d7e959f387769
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x28472a58a490c5e09a238847f66a68a47cc76f0f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x341a1c534248966c4b6afad165b98daed4b964ef
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x82c7a8f707110f5fbb16184a5933e9f78a34c6ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xccc441ac31f02cd96c153db6fd5fe0a2f4e6a68d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x764aeebcf425d56800ef2c84f2578689415a2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x160c404b2b49cbc3240055ceaee026df1e8497a0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xd2f668a8461d6761115daf8aeb3cdf5f40c532c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x39ee2c7b3cb80254225884ca001f57118c8f21b6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xd774557b647330c91bf44cfeab205095f7e6c367
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x1792a96e5668ad7c167ab804a100ce42395ce54d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x04afa589e2b933f9463c5639f412b183ec062505
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xe75512aa3bec8f00434bbd6ad8b0a3fbff100ad6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x348fc118bcc65a92dc033a951af153d14d945312
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x892848074ddea461a15f337250da3ce55580ca85
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x5946aeaab44e65eb370ffaa6a7ef2218cff9b47d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x282bdd42f4eb70e7a9d9f40c8fea0825b7f68c5d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x4b15a9c28034dc83db40cd810001427d3bd7163d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x7ea3cca10668b8346aec0bf1844a49e995527c8b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xb852c6b5892256c264cc2c888ea462189154d8d7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x9378368ba6b85c1fba5b131b530f5f5bedf21a18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x2acab3dea77832c09420663b0e1cb386031ba17b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x0c2e57efddba8c768147d1fdf9176a0a6ebd5d83
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x08d7c0242953446436f34b4c78fe9da38c73668d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x8943c7bac1914c9a7aba750bf2b6b09fd21037e0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x364c828ee171616a39897688a831c2499ad972ec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x7f36182dee28c45de6072a34d29855bae76dbe2f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xf61f24c2d93bf2de187546b14425bf631f28d6dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x797a48c46be32aafcedcfd3d8992493d8a1f256b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x123b30e25973fecd8354dd5f41cc45a3065ef88c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x6632a9d63e142f17a668064d41a21193b49b41a0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xf4ee95274741437636e748ddac70818b4ed7d043
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x57a204aa1042f6e66dd7730813f4024114d74f37
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xd1258db6ac08eb0e625b75b371c023da478e94a9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x75e95ba5997eb235f40ecf8347cdb11f18ff640b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xd532b88607b1877fe20c181cba2550e3bbd6b31c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xa1d4657e0e6507d5a94d06da93e94dc7c8c44b51
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xedb61f74b0d09b2558f1eeb79b247c1f363ae452
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x7d8820fa92eb1584636f4f5b8515b5476b75171a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x231d3559aa848bf10366fb9868590f01d34bf240
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xad9fd7cb4fc7a0fbce08d64068f60cbde22ed34c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x0e9d6552b85be180d941f1ca73ae3e318d2d4f1f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xb716600ed99b4710152582a124c697a7fe78adbf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xaadc2d4261199ce24a4b0a57370c4fcf43bb60aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x4e1f41613c9084fdb9e34e11fae9412427480e56
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x79986af15539de2db9a5086382daeda917a9cf0c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xc99c679c50033bbc5321eb88752e89a93e9e83c5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xc36cf0cfcb5d905b8b513860db0cfe63f6cf9f5c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x9c8ff314c9bc7f6e59a9d9225fb22946427edc03
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x3110ef5f612208724ca51f5761a69081809f03b7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x036721e5a769cc48b3189efbb9cce4471e8a48b1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x524cab2ec69124574082676e6f654a18df49a048
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x7ab2352b1d2e185560494d5e577f9d3c238b78c5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x32973908faee0bf825a343000fe412ebe56f802a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x7daec605e9e2a1717326eedfd660601e2753a057
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xc1caf0c19a8ac28c41fe59ba6c754e4b9bd54de9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x33fd426905f149f8376e227d0c9d3340aad17af1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x466cfcd0525189b573e794f554b8a751279213ac
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x6be69b2a9b153737887cfcdca7781ed1511c7e36
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x80336ad7a747236ef41f47ed2c7641828a480baa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x9401518f4ebba857baa879d9f76e1cc8b31ed197
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x4b61413d4392c806e6d0ff5ee91e6073c21d6430
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xc3f733ca98e0dad0386979eb96fb1722a1a05e69
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x09233d553058c2f42ba751c87816a8e9fae7ef10
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x960b7a6bcd451c9968473f7bbfd9be826efd549a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x36d30b3b85255473d27dd0f7fd8f35e36a9d6f06
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x698fbaaca64944376e2cdc4cad86eaa91362cf54
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x497a9a79e82e6fc0ff10a16f6f75e6fcd5ae65a8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x41a322b28d0ff354040e2cbc676f0320d8c8850d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xa9c0a07a7cb84ad1f2ffab06de3e55aab7d523e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x8821bee2ba0df28761afff119d66390d594cd280
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x8c6def540b83471664edc6d5cf75883986932674
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x8d9710f0e193d3f95c0723eaaf1a81030dc9116d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x86825dfca7a6224cfbd2da48e85df2fc3aa7c4b1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x629a673a8242c2ac4b7b8c5d8735fbeac21a6205
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x9a534628b4062e123ce7ee2222ec20b86e16ca8f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xc2c747e0f7004f9e8817db2ca4997657a7746928
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x73da73ef3a6982109c4d5bdb0db9dd3e3783f313
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xc92ceddfb8dd984a89fb494c376f9a48b999aafc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x3248e8ba90facc4fdd3814518c14f8cc4d980e4b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x67d9417c9c3c250f61a83c7e8658dac487b56b09
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xb6a37b5d14d502c3ab0ae6f3a0e058bc9517786e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x86c10d10eca1fca9daf87a279abccabe0063f247
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x4b3406a41399c7fd2ba65cbc93697ad9e7ea61e5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xb0640e8b5f24bedc63c33d371923d68fde020303
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xd3d9ddd0cf0a5f0bfb8f7fceae075df687eaebab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xa5c0bd78d1667c13bfb403e2a3336871396713c5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x4d7d2e237d64d1484660b55c0a4cc092fa5e6716
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xfcb1315c4273954f74cb16d5b663dbf479eec62e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x66d1db16101502ed0ca428842c619ca7b62c8fef
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x128675d4fddbc4a0d3f8aa777d8ee0fb8b427c2f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x19b86299c21505cdf59ce63740b240a9c822b5e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xacf63e56fd08970b43401492a02f6f38b6635c91
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0x0bebad1ff25c623dff9605dad4a8f782d5da37df
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.7
https://app.uniswap.org/nfts/collection/0xdceaf1652a131f32a821468dc03a92df0edd86ea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x273f7f8e6489682df756151f5525576e322d51a3
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x77372a4cc66063575b05b44481f059be356964a4
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0xf5b0a3efb8e8e4c201e2a935f110eaaf3ffecb8d
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x22c36bfdcef207f9c0cc941936eff94d4246d14a
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x59325733eb952a92e069c87f0a6168b29e80627f
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x0e3a2a1f2146d86a604adc220b4967a898d7fe07
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x3af2a97414d1101e2107a70e7f33955da1346305
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x5ab21ec0bfa0b29545230395e3adaca7d552c948
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x617913dd43dbdf4236b85ec7bdf9adfd7e35b340
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0x3fe1a4c1481c8351e91b64d5c398b159de07cbc5
+ 2024-11-01T19:06:09.419Z
+ 0.7
+
+
+ https://app.uniswap.org/nfts/collection/0xd4e4078ca3495de5b1d4db434bebc5a986197782
+ 2024-10-25T19:36:47.010Z
0.7
\ No newline at end of file
diff --git a/apps/web/public/pools-sitemap.xml b/apps/web/public/pools-sitemap.xml
index 0903b0778ae..ea90fb4906d 100644
--- a/apps/web/public/pools-sitemap.xml
+++ b/apps/web/public/pools-sitemap.xml
@@ -2,4357 +2,6832 @@
https://app.uniswap.org/explore/pools/ethereum/0xcbcdf9626bc03e24f779434178a73a0b4bad62ed
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x4e68ccd3e89f51c3074ca5072bbac773960dfa36
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x4585fe77225b41b697c938b018e2ac67ac5a20c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc63b0708e2f7e69cb8a1df0e1389a98c35a76d52
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x99ac8ca7087fa4a2a1fb6357269965a2014abc35
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x11b815efb8f581194ae79006d24e0d814b7697f6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa6cc3c2531fdaa6ae1a3ca84c2855806728693e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x5777d92f208679db4b9778590fa3cab3ac9e2168
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x1d42064fc4beb5f8aaf85f4617ae8b3b5b8bd801
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc2e9f25be6257c210d7adf0d4cd6e3e881ba25f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x11950d141ecb863f01007add7d1a342041227b58
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc5c134a1f112efa96003f8559dba6fac0ba77692
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x109830a1aaad605bbf02a9dfa7b0b92ec2fb7daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x1df4c6e36d61416813b42fe32724ef11e363eddc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x12d6867fa648d269835cf69b49f125147754b54d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x3416cf6c708da44db2624d63ea0aaef7113527c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xe8c6c9227491c0a8156a0106a0204d881bb7e531
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x04708077eca6bb527a5bbbd6358ffb043a9c1c14
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x9db9e0e53058c89e5b94e29621a205198648425b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xf239009a101b6b930a527deaab6961b6e7dec8a6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xfe0df74636bc25c7f2400f22fe7dae32d39443d2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xf4c5e0f4590b6679b3030d29a84857f226087fef
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x5764a6f2212d502bc5970f9f129ffcd61e5d7563
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa3f558aebaecaf0e11ca4b2199cc5ed341edfd74
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x99132b53ab44694eeb372e87bced3929e4ab8456
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x6c6bc977e13df9b0de53b251522280bb72383700
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x9d96880952b4c80a55099b9c258250f2cc5813ec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x3afdc5e6dfc0b0a507a8e023c9dce2cafc310316
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x290a6a7460b308ee3f19023d2d00de604bcf5b42
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xac4b3dacb91461209ae9d41ec517c2b9cb1b7daf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x60594a405d53811d3bc4766596efd80fd545a270
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x331399c614ca67dee86733e5a2fba40dbb16827c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x4b5ab61593a2401b1075b90c04cbcdd3f87ce011
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x844eb5c280f38c7462316aad3f338ef9bda62668
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xe936f0073549ad8b1fa53583600d629ba9375161
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x2f62f2b4c5fcd7570a709dec05d68ea19c82a9ec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x381fe4eb128db1621647ca00965da3f9e09f4fac
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x97e7d56a0408570ba1a7852de36350f7713906ec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xcd423f3ab39a11ff1d9208b7d37df56e902c932b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xe15e6583425700993bd08f51bf6e7b73cd5da91b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x69d91b94f0aaf8e8a2586909fa77a5c2c89818d5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xe42318ea3b998e8355a3da364eb9d48ec725eb45
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xad9ef19e289dcbc9ab27b83d2df53cdeff60f02d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x3b685307c8611afb2a9e83ebc8743dc20480716e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x7bea39867e4169dbe237d55c8242a8f2fcdcc387
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x7b1e5d984a43ee732de195628d20d05cfabc3cc7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x7858e59e0c01ea06df3af3d20ac7b0003275d4bf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xae2a25cbdb19d0dc0dddd1d2f6b08a6e48c4a9a9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x21b8065d10f73ee2e260e5b47d3344d3ced7596e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x517f9dd285e75b599234f7221227339478d0fcc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x0af81cd5d9c124b4859d65697a4cd10ee223746a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xca7c2771d248dcbe09eabe0ce57a62e18da178c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x09d1d767edf8fa23a64c51fa559e0688e526812f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x7b73644935b8e68019ac6356c40661e1bc315860
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x180efc1349a69390ade25667487a826164c9c6e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x9c4fe5ffd9a9fc5678cfbd93aa2d4fd684b67c4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa478c2975ab1ea89e8196811f51a7b7ade33eb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xbb2b8038a1640196fbe3e38816f3e67cba72d940
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x9ec9367b8c4dd45ec8e7b800b1f719251053ad60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc91ef786fbf6d62858262c82c63de45085dea659
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x197d7010147df7b99e9025c724f13723b29313f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x25647e01bd0967c1b9599fa3521939871d1d0888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x2f0b1417aa42ebf0b4ca1154212847f6094d708d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x6ada49aeccf6e556bb7a35ef0119cc8ca795294a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x2a6c340bcbb0a79d3deecd3bc5cbc2605ea9259f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xda2d09fbbf8ee4b5051a0e9b562c5fcb4b393b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x48d20b3e529fb3dd7d91293f80638df582ab2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x4028daac072e492d34a3afdbef0ba7e35d8b55c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc2eab7d33d3cb97692ecb231a5d0e4a649cb539d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc5be99a02c6857f9eac67bbce58df5572498f40c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xe4b8583ccb95b25737c016ac88e539d0605949e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x8dbee21e8586ee356130074aaa789c33159921ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x43de4318b6eb91a7cf37975dbb574396a7b5b5c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x9ff68f61ca5eb0c6606dc517a9d44001e564bb66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa29fe6ef9592b5d408cca961d0fb9b1faf497d6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x1b1137dd16faa651e38a9dfb5d9ffff7767fdf62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x470e8de2ebaef52014a47cb5e6af86884947f08c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x8fb8e9921922d2ffb529a95d28a0d06d275d7a59
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xd3d2e2692501a5c9ca623199d38826e513033a17
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x97e1fcb93ae7267dbafad23f7b9afaa08264cfd8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa5e9c917b4b821e4e0a5bbefce078ab6540d6b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x2cc846fff0b08fb3bffad71f53a60b4b6e6d6482
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x959873fb4fc11825fba83c80c4c632db1e936e15
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa7480aafa8ad2af3ce24ac6853f960ae6ac7f0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc7e6b676bfc73ae40bcc4577f22aab1682c691c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x570febdf89c07f256c75686caca215289bb11cfc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x343fd171caf4f0287ae6b87d75a8964dc44516ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xcaa004418eb42cdf00cb057b7c9e28f0ffd840a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xe3d3551bb608e7665472180a20280630d9e938aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xb6b0c651c37ec4ca81c0a128420e02001a57fac2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x4e34da137f0b317c633838458e0c923a5e088752
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xfe9e7931e55c514c33d489c88582fa36e84bd8e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x5281e311734869c64ca60ef047fd87759397efe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x149148acc3b06b8cc73af3a10e84189243a35925
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x8ef79d6c328c25da633559c20c75f638a4863462
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x14af1804dbbf7d621ecc2901eef292a24a0260ea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x80a9ae39310abf666a87c743d6ebbd0e8c42158e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc31e54c7a869b9fcbecc14363cf510d1c41fa443
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x2f5e87c9312fa29aed5c179e456625d79015299c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc6962004f452be9203591991d15f6b388e09e8d0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc6f780497a95e246eb9449f5e4770916dcd6396a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x641c00a822e8b671738d32a431a4fb6074e5c79d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x92c63d0e701caae670c9415d91c474f686298f00
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x1aeedd3727a6431b8f070c0afaa81cc74f273882
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xcda53b1f66614552f834ceef361a8d12a0b8dad8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x35218a1cbac5bbc3e57fd9bd38219d37571b3537
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x17c14d2c404d167802b16c450d3c99f88f2c4f4d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x468b88941e7cc0b88c1869d68ab6b570bcef62ff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xdbaeb7f0dfe3a0aafd798ccecb5b22e708f7852c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x149e36e72726e0bcea5c59d40df2c43f60f5a22d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xbaaf1fc002e31cb12b99e4119e5e350911ec575b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa67f72f21bd9f91db2da2d260590da5e6c437009
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x92fd143a8fa0c84e016c2765648b9733b0aa519e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x7cf803e8d82a50504180f417b8bc7a493c0a0503
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x81c48d31365e6b526f6bbadc5c9aafd822134863
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x446bf9748b4ea044dd759d9b9311c70491df8f29
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc82819f72a9e77e2c0c3a69b3196478f44303cf4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x50c7390dfdd3756139e6efb5a461c2eb7331ceb4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x1dfc1054e0e2a10e33c9ca21aad5aa8a1cce91e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc91b7b39bbb2c733f0e7459348fd0c80259c8471
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x59d72ddb29da32847a4665d08ffc8464a7185fae
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x09ba302a3f5ad2bf8853266e271b005a5b3716fe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa77d77c9773c35e910acc2e30cefe52b54a58414
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x8da66e470403b3d3eee66c67e2c61fda6e248ad1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x2f020e708811c054f146eebcc4d5a215fd4eec26
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x7e7fb3cceca5f2ac952edf221fd2a9f62e411980
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x68c685fd52a56f04665b491d491355a624540e85
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa8328bf492ba1b77ad6381b3f7567d942b000baf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc0cf0f380ddb44dbcaf19a86d094c8bba3efa04a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa169d1ab5c948555954d38700a6cdaa7a4e0c3a0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x1862200e8e7ce1c0827b792d0f9546156f44f892
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x05bbaaa020ff6bea107a9a1e06d2feb7bfd79ed2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xd02a4969dc12bb889754361f8bcf3385ac1b2077
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc24f7d8e51a64dc1238880bd00bb961d54cbeb29
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x7c06736e41236fecd681dd3353aa77ecd19ea565
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc473e2aee3441bf9240be85eb122abb059a3b57c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x14353445c8329df76e6f15e9ead18fa2d45a8bb6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x2039f8c9cd32ba9cd2ea7e575d5b1abea93f7527
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xd3e11119d2680c963f1cdcffece0c4ade823fb58
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x8e295789c9465487074a65b1ae9ce0351172393f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x97bca422ec0ee4851f2110ea743c1cd0a14835a1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xbe3ad6a5669dc0b8b12febc03608860c31e2eef6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x56ebd63a756b94d3de9cea194896b4920b64fb01
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xe2ddd33585b441b9245085588169f35108f85a6e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x84436a2af97f37018db116ae8e1b691666db3d00
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x21b8065d10f73ee2e260e5b47d3344d3ced7596e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x517f9dd285e75b599234f7221227339478d0fcc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x0af81cd5d9c124b4859d65697a4cd10ee223746a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xca7c2771d248dcbe09eabe0ce57a62e18da178c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x09d1d767edf8fa23a64c51fa559e0688e526812f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x7b73644935b8e68019ac6356c40661e1bc315860
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x180efc1349a69390ade25667487a826164c9c6e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x9c4fe5ffd9a9fc5678cfbd93aa2d4fd684b67c4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa478c2975ab1ea89e8196811f51a7b7ade33eb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xbb2b8038a1640196fbe3e38816f3e67cba72d940
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x9ec9367b8c4dd45ec8e7b800b1f719251053ad60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc91ef786fbf6d62858262c82c63de45085dea659
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x197d7010147df7b99e9025c724f13723b29313f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x25647e01bd0967c1b9599fa3521939871d1d0888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x2f0b1417aa42ebf0b4ca1154212847f6094d708d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x6ada49aeccf6e556bb7a35ef0119cc8ca795294a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x2a6c340bcbb0a79d3deecd3bc5cbc2605ea9259f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xda2d09fbbf8ee4b5051a0e9b562c5fcb4b393b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x48d20b3e529fb3dd7d91293f80638df582ab2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x4028daac072e492d34a3afdbef0ba7e35d8b55c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc2eab7d33d3cb97692ecb231a5d0e4a649cb539d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc5be99a02c6857f9eac67bbce58df5572498f40c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xe4b8583ccb95b25737c016ac88e539d0605949e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x8dbee21e8586ee356130074aaa789c33159921ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x43de4318b6eb91a7cf37975dbb574396a7b5b5c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x9ff68f61ca5eb0c6606dc517a9d44001e564bb66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa29fe6ef9592b5d408cca961d0fb9b1faf497d6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x1b1137dd16faa651e38a9dfb5d9ffff7767fdf62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x470e8de2ebaef52014a47cb5e6af86884947f08c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x8fb8e9921922d2ffb529a95d28a0d06d275d7a59
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xd3d2e2692501a5c9ca623199d38826e513033a17
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x97e1fcb93ae7267dbafad23f7b9afaa08264cfd8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa5e9c917b4b821e4e0a5bbefce078ab6540d6b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x2cc846fff0b08fb3bffad71f53a60b4b6e6d6482
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x959873fb4fc11825fba83c80c4c632db1e936e15
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa7480aafa8ad2af3ce24ac6853f960ae6ac7f0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xc7e6b676bfc73ae40bcc4577f22aab1682c691c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x570febdf89c07f256c75686caca215289bb11cfc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x343fd171caf4f0287ae6b87d75a8964dc44516ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xcaa004418eb42cdf00cb057b7c9e28f0ffd840a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xe3d3551bb608e7665472180a20280630d9e938aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xb6b0c651c37ec4ca81c0a128420e02001a57fac2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x4e34da137f0b317c633838458e0c923a5e088752
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xfe9e7931e55c514c33d489c88582fa36e84bd8e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x5281e311734869c64ca60ef047fd87759397efe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x149148acc3b06b8cc73af3a10e84189243a35925
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x8ef79d6c328c25da633559c20c75f638a4863462
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x68f5c0a2de713a54991e01858fd27a3832401849
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x4533bad2dc588f0fadf8d2e72386d4cd6a19b519
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x85149247691df622eaf1a8bd0cafd40bc45154a9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x0392b358ce4547601befa962680bede836606ae2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x1c3140ab59d6caf9fa7459c6f83d4b52ba881d36
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xd1f1bad4c9e6c44dec1e9bf3b94902205c5cd6c3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x03af20bdaaffb4cc0a521796a223f7d85e2aac31
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x73b14a78a0d396c521f954532d43fd5ffe385216
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xac85eaf55e9c60ed40a683de7e549d23fdfbeb33
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x04f6c85a1b00f6d9b75f91fd23835974cc07e65c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x730691cdac3cbd4d41fc5eb9d8abbb0cea795b94
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x535541f1aa08416e69dc4d610131099fa2ae7222
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xfc1f3296458f9b2a27a0b91dd7681c4020e09d05
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x85c31ffa3706d1cce9d525a00f1c7d4a2911754c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xd52533a3309b393afebe3176620e8ccfb6159f8a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xff7fbdf7832ae524deda39ca402e03d92adff7a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xb589969d38ce76d3d7aa319de7133bc9755fd840
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xf334f6104a179207ddacfb41fa3567feea8595c2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x1fb3cf6e48f1e7b10213e7b6d87d4c073c7fdb7b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xd4344ea0c5ade7e22b9b275f0bde7a145dec5a23
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x5b42a63d6741416ce9a7b9f4f16d8c9231ccddd4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x252cbdff917169775be2b552ec9f6781af95e7f6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x2ab22ac86b25bd448a4d9dc041bd2384655299c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xc858a329bf053be78d6239c4a4343b8fbd21472b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa73c628eaf6e283e26a7b1f8001cf186aa4c0e8e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xb533c12fb4e7b53b5524eab9b47d93ff6c7a456f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x2ae3d6096d8215ac2acddf30c60caa984ea5debe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x19ea026886cbb7a900ecb2458636d72b5cae223b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x6f32061f59a21086c334d0d45f804089ce374aaf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xfaf037caafa9620bfaebc04c298bf4a104963613
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xadb35413ec50e0afe41039eac8b930d313e94fa4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xe9e3893921de87b1194a8108f9d70c24bde71c27
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xf1f199342687a7d78bcc16fce79fa2665ef870e1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xf44acaa38be5e965c5ddf374e7a2ba270e580684
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x36e42931a765022790b797963e42c5522d6b585a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x5adba6c5589c50791dd65131df29677595c7efa7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x3249e3e3e4133ee18e65347daf586610cc265f54
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xca1b837c87c6563910c2befa48834fa2a8c3d72d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x6ef7b14bcd8d989cef8f8ec8ba4bf371b2ac95fd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x37ffd11972128fd624337ebceb167c8c0a5115ff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xe62bd99a9501ca33d98913105fc2bec5bae6e5dd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xb2ac2e5a3684411254d58b1c5a542212b782114d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xb0efaf46a1de55c54f333f93b1f0641e73bc16d0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xd0fa3b5264ccde31e8b094b86bca4a1e97d3c603
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xad4c666fc170b468b19988959eb931a3676f0e9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x790fde1fd6d2568050061a88c375d5c2e06b140b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xaefc1edaede6adadcdf3bb344577d45a80b19582
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa8a5356ee5d02fe33d72355e4f698782f8f199e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x55bc964fe3b0c8cc2d4c63d65f1be7aef9bb1a3c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x95d9d28606ee55de7667f0f176ebfc3215cfd9c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x21b8065d10f73ee2e260e5b47d3344d3ced7596e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x517f9dd285e75b599234f7221227339478d0fcc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x0af81cd5d9c124b4859d65697a4cd10ee223746a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xca7c2771d248dcbe09eabe0ce57a62e18da178c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x09d1d767edf8fa23a64c51fa559e0688e526812f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x7b73644935b8e68019ac6356c40661e1bc315860
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x180efc1349a69390ade25667487a826164c9c6e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x9c4fe5ffd9a9fc5678cfbd93aa2d4fd684b67c4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa478c2975ab1ea89e8196811f51a7b7ade33eb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xbb2b8038a1640196fbe3e38816f3e67cba72d940
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x9ec9367b8c4dd45ec8e7b800b1f719251053ad60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xc91ef786fbf6d62858262c82c63de45085dea659
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x197d7010147df7b99e9025c724f13723b29313f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x25647e01bd0967c1b9599fa3521939871d1d0888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x2f0b1417aa42ebf0b4ca1154212847f6094d708d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x6ada49aeccf6e556bb7a35ef0119cc8ca795294a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x2a6c340bcbb0a79d3deecd3bc5cbc2605ea9259f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xda2d09fbbf8ee4b5051a0e9b562c5fcb4b393b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x48d20b3e529fb3dd7d91293f80638df582ab2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x4028daac072e492d34a3afdbef0ba7e35d8b55c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xc2eab7d33d3cb97692ecb231a5d0e4a649cb539d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xc5be99a02c6857f9eac67bbce58df5572498f40c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xe4b8583ccb95b25737c016ac88e539d0605949e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x8dbee21e8586ee356130074aaa789c33159921ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x43de4318b6eb91a7cf37975dbb574396a7b5b5c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x9ff68f61ca5eb0c6606dc517a9d44001e564bb66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa29fe6ef9592b5d408cca961d0fb9b1faf497d6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x1b1137dd16faa651e38a9dfb5d9ffff7767fdf62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x470e8de2ebaef52014a47cb5e6af86884947f08c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x8fb8e9921922d2ffb529a95d28a0d06d275d7a59
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xd3d2e2692501a5c9ca623199d38826e513033a17
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x97e1fcb93ae7267dbafad23f7b9afaa08264cfd8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa5e9c917b4b821e4e0a5bbefce078ab6540d6b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x2cc846fff0b08fb3bffad71f53a60b4b6e6d6482
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x959873fb4fc11825fba83c80c4c632db1e936e15
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa7480aafa8ad2af3ce24ac6853f960ae6ac7f0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xc7e6b676bfc73ae40bcc4577f22aab1682c691c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x570febdf89c07f256c75686caca215289bb11cfc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x343fd171caf4f0287ae6b87d75a8964dc44516ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xcaa004418eb42cdf00cb057b7c9e28f0ffd840a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xe3d3551bb608e7665472180a20280630d9e938aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xb6b0c651c37ec4ca81c0a128420e02001a57fac2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x4e34da137f0b317c633838458e0c923a5e088752
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xfe9e7931e55c514c33d489c88582fa36e84bd8e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x5281e311734869c64ca60ef047fd87759397efe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x149148acc3b06b8cc73af3a10e84189243a35925
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x8ef79d6c328c25da633559c20c75f638a4863462
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x45dda9cb7c25131df268515131f647d726f50608
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x50eaedb835021e4a108b7290636d62e9765cc6d7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x167384319b41f7094e62f7506409eb38079abff8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa374094527e1673a86de625aa59517c5de346d32
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x86f1d8390222a3691c28938ec7404a1661e618e0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xeda1094f59a4781456734e5d258b95e6be20b983
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x847b64f9d3a95e977d157866447a5c0a5dfa0ee5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x94ab9e4553ffb839431e37cc79ba8905f45bfbea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x0e44ceb592acfc5d3f09d996302eb4c499ff8c10
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x1e5bd2ab4c308396c06c182e1b7e7ba8b2935b83
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x9b08288c3be4f62bbf8d1c20ac9c5e6f9467d8b7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xb6e57ed85c4c9dbfef2a68711e9d6f36c56e0fcb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x3e31ab7f37c048fc6574189135d108df80f0ea26
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xd36ec33c8bed5a9f7b6630855f1533455b98a418
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xdac8a8e6dbf8c690ec6815e0ff03491b2770255d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xfe343675878100b344802a6763fd373fdeed07a4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x0a28c2f5e0e8463e047c203f00f649812ae67e4f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x88f3c15523544835ff6c738ddb30995339ad57d6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x98b9162161164de1ed182a0dfa08f5fbf0f733ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xeef1a9507b3d505f0062f2be9453981255b503c8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc4c06c9a239f94fc0a1d3e04d23c159ebe8316f1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x849ec65748107aedc518dbc42961f358ea1361a7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2db87c4831b2fec2e35591221455834193b50d1b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa4d8c89f0c20efbe54cba9e7e7a7e509056228d9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x642f28a89fa9d0fa30e664f71804bfdd7341d21f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2aceda63b5e958c45bd27d916ba701bc1dc08f7a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x781067ef296e5c4a4203f81c593274824b7c185d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x4ccd010148379ea531d6c587cfdd60180196f9b1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xd866fac7db79994d08c0ca2221fee08935595b4b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x941061770214613ba0ca3db9a700c39587bb89b6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa9077cdb3d13f45b8b9d87c43e11bce0e73d8631
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa01f64fa1b923dd9c5c7618b39a6ba8098a88863
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa830ff28bb7a46570a7e43dc24a35a663b9cfc2e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x8837a61644d523cbe5216dde226f8f85e3aa9be3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xca5d44977d6de1846530eb434167b208752fba7d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x4d05f2a005e6f36633778416764e82d1d12e7fbb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x41e64a5bc929fa8e6a9c8d7e3b81a13b21ff3045
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x3ea34cfc9322273311f7843826a2581c4a00fd39
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x785061ed819414dc4269d2a5d5974069c0daea96
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x3f5228d0e7d75467366be7de2c31d0d098ba2c23
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2e3f22e9a1c2470b2e293351f48c99e1fd788f32
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2a08c38c7e1fa969325e2b64047abb085dec3756
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xe6c36eed27c2e8ecb9a233bf12da06c9730b5955
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xefa98fdf168f372e5e9e9b910fcdfd65856f3986
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x76fa081e510f43ac8335efdb4db88c9ff1894413
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc6832ef0af793336aa44a936e54b992bff47e7cd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x865f456479a21e2b3d866561d7171a3d0a7b112d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xbd934a7778771a7e2d9bf80596002a214d8c9304
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x9ab9f658104467604b5afa9a3e1df62f35f7b208
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x6e430d59ba145c59b73a6db674fe3d53c1f31cae
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x21b8065d10f73ee2e260e5b47d3344d3ced7596e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x517f9dd285e75b599234f7221227339478d0fcc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x0af81cd5d9c124b4859d65697a4cd10ee223746a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xca7c2771d248dcbe09eabe0ce57a62e18da178c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x09d1d767edf8fa23a64c51fa559e0688e526812f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x7b73644935b8e68019ac6356c40661e1bc315860
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x180efc1349a69390ade25667487a826164c9c6e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x9c4fe5ffd9a9fc5678cfbd93aa2d4fd684b67c4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa478c2975ab1ea89e8196811f51a7b7ade33eb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xbb2b8038a1640196fbe3e38816f3e67cba72d940
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x9ec9367b8c4dd45ec8e7b800b1f719251053ad60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc91ef786fbf6d62858262c82c63de45085dea659
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x197d7010147df7b99e9025c724f13723b29313f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x25647e01bd0967c1b9599fa3521939871d1d0888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2f0b1417aa42ebf0b4ca1154212847f6094d708d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x6ada49aeccf6e556bb7a35ef0119cc8ca795294a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2a6c340bcbb0a79d3deecd3bc5cbc2605ea9259f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xda2d09fbbf8ee4b5051a0e9b562c5fcb4b393b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x48d20b3e529fb3dd7d91293f80638df582ab2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x4028daac072e492d34a3afdbef0ba7e35d8b55c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc2eab7d33d3cb97692ecb231a5d0e4a649cb539d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc5be99a02c6857f9eac67bbce58df5572498f40c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xe4b8583ccb95b25737c016ac88e539d0605949e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x8dbee21e8586ee356130074aaa789c33159921ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x43de4318b6eb91a7cf37975dbb574396a7b5b5c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x9ff68f61ca5eb0c6606dc517a9d44001e564bb66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa29fe6ef9592b5d408cca961d0fb9b1faf497d6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x1b1137dd16faa651e38a9dfb5d9ffff7767fdf62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x470e8de2ebaef52014a47cb5e6af86884947f08c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x8fb8e9921922d2ffb529a95d28a0d06d275d7a59
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xd3d2e2692501a5c9ca623199d38826e513033a17
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x97e1fcb93ae7267dbafad23f7b9afaa08264cfd8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa5e9c917b4b821e4e0a5bbefce078ab6540d6b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2cc846fff0b08fb3bffad71f53a60b4b6e6d6482
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x959873fb4fc11825fba83c80c4c632db1e936e15
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa7480aafa8ad2af3ce24ac6853f960ae6ac7f0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc7e6b676bfc73ae40bcc4577f22aab1682c691c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x570febdf89c07f256c75686caca215289bb11cfc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x343fd171caf4f0287ae6b87d75a8964dc44516ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xcaa004418eb42cdf00cb057b7c9e28f0ffd840a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xe3d3551bb608e7665472180a20280630d9e938aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xb6b0c651c37ec4ca81c0a128420e02001a57fac2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x4e34da137f0b317c633838458e0c923a5e088752
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xfe9e7931e55c514c33d489c88582fa36e84bd8e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x5281e311734869c64ca60ef047fd87759397efe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x149148acc3b06b8cc73af3a10e84189243a35925
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x8ef79d6c328c25da633559c20c75f638a4863462
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x9e37cb775a047ae99fc5a24dded834127c4180cd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x48413707b70355597404018e7c603b261fcadf3f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xade9bcd4b968ee26bed102dd43a55f6a8c2416df
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xda679706ff21114ac9fac5198bff24543f357a16
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xba3f945812a83471d709bce9c3ca699a19fb46f7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc9034c3e7f58003e6ae0c8438e7c8f4598d5acaa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x4c36388be6f416a29c8d8eee81c771ce6be14b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa1b2457c0b627f97f6cc892946a382451e979014
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x4b0aaf3ebb163dd45f663b38b6d93f6093ebc2d3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xae2ce200bdb67c472030b31f602f0756c9aeb61c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x3bc5180d5439b500f381f9a46f15dd6608101671
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x5122e02898ece3bc62df8c1efdb29a9e914244d3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x24e1cbd6fed006ceed9af0dce688acc7951d57a9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2556230ac694093d4d3b7b965a2f2d77d4c403a4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xdaca082c2c7d052a96fa83ea9d3a7b6839e39586
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa555149210075702a734968f338d5e1cbd509354
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x10648ba41b8565907cfa1496765fa4d95390aa0d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x00bcec1526dae1e170a53017b8775a93b7810d7c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x20e068d76f9e90b90604500b84c7e19dcb923e7e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x6b93950a9b589bc32b82a5df4e5148f98a7fae27
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xd9caa6dbe6791fcb7fc9fb59d1a6b3dd8c1c2339
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x62e81e93136ac42a1ada48d4098f5f9e703e7455
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x84206d33845c9d811438b6fe4e7a0c634748dc50
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xd0b53d9277642d899df5c87a3966a349a798f224
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xcfa7c4bb565915f1c4f9475e2a0536d31efad776
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa7de21f28ca460b45373b217cd4eb111c3faeff8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xb64dff20dd5c47e6dbb56ead80d23568006dec1e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xad4e969f4193878e5cc89cefb57faf6c7c0048da
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xdf5eb97e3e23ca7f5a5fd2264680377c211310ba
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xf16baaae8eb7b37f4280e72924479f69e7a61f32
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xe745a591970e0fa981204cf525e170a2b9e4fb93
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x64b74c66b9ba60ca668b781289767ae7298f37ae
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x17e1ebd791e7253a5e606fd94c5b66c14d873136
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x46715bd57b9ec01deadb35fe096fb44acda79414
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x3447accd4b8e735329d1065244aad2ed630f0122
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2feb7f3ffc243f7de94d5ea5975533d301584e07
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x0d5959a52e7004b601f0be70618d01ac3cdce976
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2170ca774e48a3f51559917ada6f9d7ae8f7bfea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x62a76dfa8951aefcff787e790782db3633ebf422
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x8073679e0b3b2d1d665777cf1b2b5b1c2d3d2d0c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x143f1a6f3fb32e6ab3f22d3cc6b417b5c2197599
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x82ad659c2f152aad59bb37cbc5e7663a2de0c607
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa4efe9e8e2a2d5a2ac46805f233b8e49d0e11955
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xfcc89a1f250d76de198767d33e1ca9138a7fb54b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2faa2b42b782d578a160f61bb7cd763a17476730
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xdd44c0e83c2570062d1e6fdd440b4724862e8f31
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xe3930a14641786e123e7bbe842d701fa1cbfe2df
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x6d03360ce4764e862ed81660c1f76cc2711b14b6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc055f66f228105072315247785c00299d0ce27e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xcae1d141ab11cef0a415cf0440025e1e5e962e06
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x21b8065d10f73ee2e260e5b47d3344d3ced7596e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x517f9dd285e75b599234f7221227339478d0fcc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x0af81cd5d9c124b4859d65697a4cd10ee223746a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xca7c2771d248dcbe09eabe0ce57a62e18da178c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x09d1d767edf8fa23a64c51fa559e0688e526812f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x7b73644935b8e68019ac6356c40661e1bc315860
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x180efc1349a69390ade25667487a826164c9c6e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x9c4fe5ffd9a9fc5678cfbd93aa2d4fd684b67c4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa478c2975ab1ea89e8196811f51a7b7ade33eb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xbb2b8038a1640196fbe3e38816f3e67cba72d940
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x9ec9367b8c4dd45ec8e7b800b1f719251053ad60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc91ef786fbf6d62858262c82c63de45085dea659
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x197d7010147df7b99e9025c724f13723b29313f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x25647e01bd0967c1b9599fa3521939871d1d0888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2f0b1417aa42ebf0b4ca1154212847f6094d708d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x6ada49aeccf6e556bb7a35ef0119cc8ca795294a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2a6c340bcbb0a79d3deecd3bc5cbc2605ea9259f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xda2d09fbbf8ee4b5051a0e9b562c5fcb4b393b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x48d20b3e529fb3dd7d91293f80638df582ab2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x4028daac072e492d34a3afdbef0ba7e35d8b55c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc2eab7d33d3cb97692ecb231a5d0e4a649cb539d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc5be99a02c6857f9eac67bbce58df5572498f40c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xe4b8583ccb95b25737c016ac88e539d0605949e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x8dbee21e8586ee356130074aaa789c33159921ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x43de4318b6eb91a7cf37975dbb574396a7b5b5c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x9ff68f61ca5eb0c6606dc517a9d44001e564bb66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa29fe6ef9592b5d408cca961d0fb9b1faf497d6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x1b1137dd16faa651e38a9dfb5d9ffff7767fdf62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x470e8de2ebaef52014a47cb5e6af86884947f08c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x8fb8e9921922d2ffb529a95d28a0d06d275d7a59
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xd3d2e2692501a5c9ca623199d38826e513033a17
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x97e1fcb93ae7267dbafad23f7b9afaa08264cfd8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa5e9c917b4b821e4e0a5bbefce078ab6540d6b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2cc846fff0b08fb3bffad71f53a60b4b6e6d6482
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x959873fb4fc11825fba83c80c4c632db1e936e15
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa7480aafa8ad2af3ce24ac6853f960ae6ac7f0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc7e6b676bfc73ae40bcc4577f22aab1682c691c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x570febdf89c07f256c75686caca215289bb11cfc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x343fd171caf4f0287ae6b87d75a8964dc44516ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xcaa004418eb42cdf00cb057b7c9e28f0ffd840a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xe3d3551bb608e7665472180a20280630d9e938aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xb6b0c651c37ec4ca81c0a128420e02001a57fac2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x4e34da137f0b317c633838458e0c923a5e088752
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xfe9e7931e55c514c33d489c88582fa36e84bd8e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x5281e311734869c64ca60ef047fd87759397efe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x149148acc3b06b8cc73af3a10e84189243a35925
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x8ef79d6c328c25da633559c20c75f638a4863462
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x0f338ec12d3f7c3d77a4b9fcc1f95f3fb6ad0ea6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x4eaa90264d6a3567228dcb5cfc242200da586437
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x6fe9e9de56356f7edbfcbb29fab7cd69471a4869
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xf420603317a0996a3fce1b1a80993eaef6f7ae1a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x47a90a2d92a8367a91efa1906bfc8c1e05bf10c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x41bf5eeae051fbd2e97b76b5f8f0fdcc1a1e526b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x28df0835942396b7a1b7ae1cd068728e6ddbbafd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa3f3664a52f01b42557524bd14556e379daf5669
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x1fd22fa7274bafebdfb1881321709f1219744829
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xe39cfc1a2e51a09ecbd060a24ee4eef5a97697bb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x06396509195eb9e07c38a016694dc9ff535b128a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x5a1c486edefda2f09d3b349fadc38524f1743826
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x5bf1cf153c102a79d9e18b7fb7c79ba57fa70d0c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x2c3c320d49019d4f9a92352e947c7e5acfe47d68
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x4141325bac36affe9db165e854982230a14e6d48
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x17507bef4c3abc1bc715be723ee1baf571256e05
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x8149b92ea743cc382aada523b68b8834733b9015
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xc98f01bf2141e1140ef8f8cad99d4b021d10718f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x7f9d307973cdabe42769d9712df8ee1cc1a28d10
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x5c87da28a45e5089b762dcbbd86f743d14c54317
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x2cd97604ef77bbcb1fa0cff47545dff8ec7def08
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x7862d9b4be2156b15d54f41ee4ede2d5b0b455e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x554548b404213c7efcdbab933f52edfe3c581834
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x63008c5ea4e47f5421e0e1428b1c5043a507d0d0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x0350ca994791c4b07a5b02b08aaf9d6fc8ab510e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x32776ed4d96ed069a2d812773f0ad8ad9ef83cf8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x84f3ca9b7a1579ff74059bd0e8929424d3fa330e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x5289a8dbf7029ee0b0498a84777ed3941d9acfec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xb2bc284ab4c953b7f7a06d59c0ceb2de26405f22
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x508acf810857fefa86281499068ad5d19ebce325
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xccdfcd1aac447d5b29980f64b831c532a6a33726
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x4fb87838a29b37598099ef5aa6b3fbeeef987c50
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x515e94dc736b9d8b7d28ecf1cece0aba3d75da97
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xfd6e5b7c30538dff2752058e425ad01a56b831cc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xcb99fe720124129520f7a09ca3cbef78d58ed934
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xd2f21358c1549be193537b2a4c5dc7f0228ae011
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x93094ed1c907e4bca7eb041cb659da94f7e1b58e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xd37e6ecb991d1a0e7610c89666817665713362a7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x73234630bd159384c8d43f145407312d64614f43
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xad1ddf00c4ae50573e4dc98e6c5ee93baa04a0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa765593c821f7df9ad81119509a37961e7ffa6c5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x9b501a7ad3087d603ceb34424b7b2a6c348ad0b7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xafebb7cfa1a15fcac4121b609b456cbce3137c20
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x0adaf134ae0c4583b3a38fc3168a83e33162651e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xf9878a5dd55edc120fde01893ea713a4f032229c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x84e47c7f2fe86f6b5efbe14fee46b8bb871b2e05
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xf3e5bec78654049990965f666b0612e116b94fb2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x33e59edd3214e97cb68450c6d3d6c167de072aba
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x2ca76c7e466e560e0cb11a91269bb953e41254bc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xbb124e35ab9e85f8d59ba83500e559dc052b9368
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x21b8065d10f73ee2e260e5b47d3344d3ced7596e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x517f9dd285e75b599234f7221227339478d0fcc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x0af81cd5d9c124b4859d65697a4cd10ee223746a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xca7c2771d248dcbe09eabe0ce57a62e18da178c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x09d1d767edf8fa23a64c51fa559e0688e526812f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x7b73644935b8e68019ac6356c40661e1bc315860
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x180efc1349a69390ade25667487a826164c9c6e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x9c4fe5ffd9a9fc5678cfbd93aa2d4fd684b67c4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa478c2975ab1ea89e8196811f51a7b7ade33eb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xbb2b8038a1640196fbe3e38816f3e67cba72d940
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x9ec9367b8c4dd45ec8e7b800b1f719251053ad60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xc91ef786fbf6d62858262c82c63de45085dea659
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x197d7010147df7b99e9025c724f13723b29313f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x25647e01bd0967c1b9599fa3521939871d1d0888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x2f0b1417aa42ebf0b4ca1154212847f6094d708d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x6ada49aeccf6e556bb7a35ef0119cc8ca795294a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x2a6c340bcbb0a79d3deecd3bc5cbc2605ea9259f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xda2d09fbbf8ee4b5051a0e9b562c5fcb4b393b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x48d20b3e529fb3dd7d91293f80638df582ab2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x4028daac072e492d34a3afdbef0ba7e35d8b55c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xc2eab7d33d3cb97692ecb231a5d0e4a649cb539d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xc5be99a02c6857f9eac67bbce58df5572498f40c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xe4b8583ccb95b25737c016ac88e539d0605949e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x8dbee21e8586ee356130074aaa789c33159921ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x43de4318b6eb91a7cf37975dbb574396a7b5b5c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x9ff68f61ca5eb0c6606dc517a9d44001e564bb66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa29fe6ef9592b5d408cca961d0fb9b1faf497d6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x1b1137dd16faa651e38a9dfb5d9ffff7767fdf62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x470e8de2ebaef52014a47cb5e6af86884947f08c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x8fb8e9921922d2ffb529a95d28a0d06d275d7a59
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xd3d2e2692501a5c9ca623199d38826e513033a17
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x97e1fcb93ae7267dbafad23f7b9afaa08264cfd8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa5e9c917b4b821e4e0a5bbefce078ab6540d6b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x2cc846fff0b08fb3bffad71f53a60b4b6e6d6482
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x959873fb4fc11825fba83c80c4c632db1e936e15
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa7480aafa8ad2af3ce24ac6853f960ae6ac7f0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xc7e6b676bfc73ae40bcc4577f22aab1682c691c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x570febdf89c07f256c75686caca215289bb11cfc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x343fd171caf4f0287ae6b87d75a8964dc44516ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xcaa004418eb42cdf00cb057b7c9e28f0ffd840a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xe3d3551bb608e7665472180a20280630d9e938aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xb6b0c651c37ec4ca81c0a128420e02001a57fac2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x4e34da137f0b317c633838458e0c923a5e088752
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xfe9e7931e55c514c33d489c88582fa36e84bd8e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x5281e311734869c64ca60ef047fd87759397efe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x149148acc3b06b8cc73af3a10e84189243a35925
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x8ef79d6c328c25da633559c20c75f638a4863462
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xd88d5f9e6c10e6febc9296a454f6c2589b1e8fae
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xb90fe7da36ac89448e6dfd7f2bb1e90a66659977
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xbd6313d0796984c578cae6bc5b5e23b27c5540c5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x1f18cd7d1c7ba0dbe3d9abe0d3ec84ce1ad10066
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x7da99753ff017f1b7afb2c8c0542718dc9f15f21
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x079e7a44f42e9cd2442c3b9536244be634e8f888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x1c8dafd358d308b880f71edb5170b010b106ca60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xbd0f6f34baa3c1329448a69bab90111a20756f01
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x3420720e561f3082f1e514a4545f0f2e0c955a5d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xea3fb6e3313a2a90757e4ca3d6749efd0107b0b6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xf130f72f8190f662522774c3367e6e8814f5e219
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x4a46c053bd5c10a959aea258228217b9d3405f3d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xb83258bf5940c98abf54f26c5a02710bd6b83b2c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x6a209c5329f0a225fa1890d4177823c096016f34
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xdb24905b1b080f65dedb0ad978aad5c76363d3c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xddff2cdad11898b901a661e32e9fa010780263a0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x72dd8fe09b5b493012e5816068dfc6fb26a2a9e6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x54fc722a66abfb6500a36d8b7b2646129d0e836a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x53b612b32233c80ec439a64325a29766ce95be7f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xe5edcbe72d1bc223097a1bed1fe6c0e404b4290c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xb928c37b8bd9754d321dc3d3c6ef374d332fe761
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x2d70cbabf4d8e61d5317b62cbe912935fd94e0fe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x953e2937f0515c43ca7995e80c84aedcbbb9385e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x84394d80830ae963b599ded7d9149b90059f182f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa1777e082fa1746eb78dd9c1fbb515419cf6e538
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x112466c8b6e5abe42c78c47eb1b9d40baa3f943c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x9491d57c5687ab75726423b55ac2d87d1cda2c3f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x978799f1845c00c9a4d9fd2629b9ce18df66e488
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xdc55d1fd1c04e005051a40bd59c5f95623257bc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x34757893070b0fc5de37aaf2844255ff90f7f1e0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x7faf167615419228f3f7d71d52d840dab154913c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa4d7b6a50dd4c55334ca6f175dbc6561f269d264
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x0ed413cefde954d8e5c54d981d7d182b587e98e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x524375d0c6a04439128428f400b00eae81a2e9e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x4b7a4530d56ff55a4dce089d917ede812e543307
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x84bb5b9bf1b6782c87cfa3e396f2f571c8e49646
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x723292eea7e1576ae482a5c317934054c0199e24
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x9b42940e8184d866aac6595a91f8d8952a59d3b9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x37622453c614f625d288151101ffe48fd222ced1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x4a94130b9e8eb0a0959c2c0f1ee9583213773fd9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x51514b3dc24afc1db95586242b99f0063bea17c5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xc130254e9196d48bbd9f91240390a6e8203132e9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x60ac25da2ada3be14a2a8c04e45b072bed965966
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x4e392a3883a84225260ff857318517eb50e5d128
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xca0aa06385a42242fe9523cd7015f6d01cd8f6b2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x3e448c17043ce1481bbe53c0fd19481bad8b98a6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x81060e6bf2a683f208b8799a33c7c09830cabed1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x463fe9f646b61ccfb43a022bf947075411cd71c7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x21b8065d10f73ee2e260e5b47d3344d3ced7596e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x517f9dd285e75b599234f7221227339478d0fcc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x0af81cd5d9c124b4859d65697a4cd10ee223746a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xca7c2771d248dcbe09eabe0ce57a62e18da178c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x09d1d767edf8fa23a64c51fa559e0688e526812f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x7b73644935b8e68019ac6356c40661e1bc315860
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x180efc1349a69390ade25667487a826164c9c6e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x9c4fe5ffd9a9fc5678cfbd93aa2d4fd684b67c4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa478c2975ab1ea89e8196811f51a7b7ade33eb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xbb2b8038a1640196fbe3e38816f3e67cba72d940
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x9ec9367b8c4dd45ec8e7b800b1f719251053ad60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xc91ef786fbf6d62858262c82c63de45085dea659
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x197d7010147df7b99e9025c724f13723b29313f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x25647e01bd0967c1b9599fa3521939871d1d0888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x2f0b1417aa42ebf0b4ca1154212847f6094d708d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x6ada49aeccf6e556bb7a35ef0119cc8ca795294a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x2a6c340bcbb0a79d3deecd3bc5cbc2605ea9259f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xda2d09fbbf8ee4b5051a0e9b562c5fcb4b393b18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x48d20b3e529fb3dd7d91293f80638df582ab2daa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x4028daac072e492d34a3afdbef0ba7e35d8b55c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xc2eab7d33d3cb97692ecb231a5d0e4a649cb539d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xc5be99a02c6857f9eac67bbce58df5572498f40c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xe4b8583ccb95b25737c016ac88e539d0605949e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x8dbee21e8586ee356130074aaa789c33159921ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x43de4318b6eb91a7cf37975dbb574396a7b5b5c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x9ff68f61ca5eb0c6606dc517a9d44001e564bb66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa29fe6ef9592b5d408cca961d0fb9b1faf497d6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x1b1137dd16faa651e38a9dfb5d9ffff7767fdf62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x470e8de2ebaef52014a47cb5e6af86884947f08c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x8fb8e9921922d2ffb529a95d28a0d06d275d7a59
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xd3d2e2692501a5c9ca623199d38826e513033a17
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x97e1fcb93ae7267dbafad23f7b9afaa08264cfd8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa5e9c917b4b821e4e0a5bbefce078ab6540d6b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x2cc846fff0b08fb3bffad71f53a60b4b6e6d6482
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x959873fb4fc11825fba83c80c4c632db1e936e15
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa7480aafa8ad2af3ce24ac6853f960ae6ac7f0c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xc7e6b676bfc73ae40bcc4577f22aab1682c691c6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x570febdf89c07f256c75686caca215289bb11cfc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x343fd171caf4f0287ae6b87d75a8964dc44516ab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xcaa004418eb42cdf00cb057b7c9e28f0ffd840a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xe3d3551bb608e7665472180a20280630d9e938aa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xb6b0c651c37ec4ca81c0a128420e02001a57fac2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x4e34da137f0b317c633838458e0c923a5e088752
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xfe9e7931e55c514c33d489c88582fa36e84bd8e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x5281e311734869c64ca60ef047fd87759397efe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x149148acc3b06b8cc73af3a10e84189243a35925
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x8ef79d6c328c25da633559c20c75f638a4863462
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x0f23d49bc92ec52ff591d091b3e16c937034496e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x0f23d49bc92ec52ff591d091b3e16c937034496e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xbf16ef186e715668aa29cef57e2fd7f9d48adfe6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x0f23d49bc92ec52ff591d091b3e16c937034496e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x5645dcb64c059aa11212707fbf4e7f984440a8cf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x0f23d49bc92ec52ff591d091b3e16c937034496e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x3ad4913fa896391c9822a81d8d869cc0d783bdd7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x0f23d49bc92ec52ff591d091b3e16c937034496e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x0f23d49bc92ec52ff591d091b3e16c937034496e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x0f23d49bc92ec52ff591d091b3e16c937034496e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x7a415b19932c0105c82fdb6b720bb01b0cc2cae3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x9b3423373e6e786c9ac367120533abe4ee398373
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x4a25dbdf9629b1782c3e2c7de3bdce41f1c7f801
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xbe80225f09645f172b079394312220637c440a63
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x059615ebf32c946aaab3d44491f78e4f8e97e1d3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x435664008f38b0650fbc1c9fc971d0a3bc2f1e47
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x4b62fa30fea125e43780dc425c2be5acb4ba743b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xc3db44adc1fcdfd5671f555236eae49f4a8eea18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xddd23787a6b80a794d952f5fb036d0b31a8e6aff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xa86aca6d7c393c06dcdc30473ea3d1b05c358dff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x1ffec7119e315b15852557f654ae0052f76e6ae1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x0f027d40c80d8f70f77d3884776531f80b21d20e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x69c66beafb06674db41b22cfc50c34a93b8d82a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xeedff72a683058f8ff531e8c98575f920430fdc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x811cfb75567a252bea23474e2ccd1286927bfe0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x2caccf71bdf8fff97c06a46eca29b611b1a74b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0xf07a84f0732dfe8eea0d3961bcd8f62c761ff508
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/ethereum/0x8c1c499b1796d7f3c2521ac37186b52de024e58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xe5cf22ee4988d54141b77050967e1052bd9c7f7a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x7f580f8a02b759c350e6b8340e7c2d4b8162b6a9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x48b0ab72c2591849e678e7d6f272b75ef9b863f7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x74d0ae8b8e1fca6039707564704a25ad2ee036b0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x5969efdde3cf5c0d9a88ae51e47d721096a97203
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xe32efff8f8b5fdc53803405aa3f623f03f8a8767
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xe8629b6a488f366d27dad801d1b5b445199e2ada
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x066b28f0c160935cf285f75ed600967bf8417035
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xddd23787a6b80a794d952f5fb036d0b31a8e6aff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xa86aca6d7c393c06dcdc30473ea3d1b05c358dff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x1ffec7119e315b15852557f654ae0052f76e6ae1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x0f027d40c80d8f70f77d3884776531f80b21d20e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x69c66beafb06674db41b22cfc50c34a93b8d82a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xeedff72a683058f8ff531e8c98575f920430fdc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x811cfb75567a252bea23474e2ccd1286927bfe0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x2caccf71bdf8fff97c06a46eca29b611b1a74b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0xf07a84f0732dfe8eea0d3961bcd8f62c761ff508
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/arbitrum/0x8c1c499b1796d7f3c2521ac37186b52de024e58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x146b020399769339509c98b7b353d19130c150ec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xd28f71e383e93c570d3edfe82ebbceb35ec6c412
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xadab76dd2dca7ae080a796f0ce86170e482afb4a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x0fb07e6d6e1f52c839608e1436d2ea810cf07257
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xddd23787a6b80a794d952f5fb036d0b31a8e6aff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xa86aca6d7c393c06dcdc30473ea3d1b05c358dff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x1ffec7119e315b15852557f654ae0052f76e6ae1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x0f027d40c80d8f70f77d3884776531f80b21d20e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x69c66beafb06674db41b22cfc50c34a93b8d82a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xeedff72a683058f8ff531e8c98575f920430fdc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x811cfb75567a252bea23474e2ccd1286927bfe0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x2caccf71bdf8fff97c06a46eca29b611b1a74b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0xf07a84f0732dfe8eea0d3961bcd8f62c761ff508
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/optimism/0x8c1c499b1796d7f3c2521ac37186b52de024e58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x95d2483d2a0fff034004f91c53d649623d993896
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x19c5505638383337d2972ce68b493ad78e315147
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc143161ed3ed8049bb63d8da42907c08a10e2269
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xc3286373599dd5af2a17a572ebb7561f05f88bec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xbb98b3d2b18aef63a3178023a920971cf5f29be4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x647fb01a63de9a551b39c7915693b25e6bcec502
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa90c1c009dc8292bd04ced30f9b53a5ff7a806a0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xddd23787a6b80a794d952f5fb036d0b31a8e6aff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xa86aca6d7c393c06dcdc30473ea3d1b05c358dff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x1ffec7119e315b15852557f654ae0052f76e6ae1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x0f027d40c80d8f70f77d3884776531f80b21d20e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x69c66beafb06674db41b22cfc50c34a93b8d82a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xeedff72a683058f8ff531e8c98575f920430fdc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x811cfb75567a252bea23474e2ccd1286927bfe0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x2caccf71bdf8fff97c06a46eca29b611b1a74b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0xf07a84f0732dfe8eea0d3961bcd8f62c761ff508
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/polygon/0x8c1c499b1796d7f3c2521ac37186b52de024e58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xfb765ff72a14735550f1d798a5efd1311f2ddee7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x3537f2a5f99f08f59eb1417073db1fadbebf0c74
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xde8ed0277ee0e84c25756a73ffa7374e4aeadf46
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xd8f3a72d2b2220a5067abe8c38aea57dc2d69a5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x7ec18abf80e865c6799069df91073335935c4185
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x14b1911dd6b451c2771661ae8cd70637d726c356
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x9ae8084c21752971d867597c07f2673765d949a1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xcfaf75a3d292c3535ea3acdb16ed2ee58c2bb091
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x8055e6de251e414e8393b20adab096afb3cf8399
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xffec10fe1355c2d8df4f62affcdeffdb04f06569
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc16454420f100b2e771d8bc4c5b6200068129a34
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x046f405e4ae1d0e786eda4959adadbd417d13ad8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xeccb34691c06c1c9c31ceb2228b22cbd242b5879
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xe22a2dfaaaaec8a7b2b7acb4909eaaa5c5bd6e64
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xe2dda0911e227e73d9fd94745b851c8bc6504610
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x0f082a7870908f8cebbb2cd27a42a9225c19f898
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x69d667281778db0c3bc8177efea3a91ee95c3068
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x30d61bb28a6789f9f49d8c7fb198d63b6aba4b61
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x090f3fd9110621df127c3f9be5c6f58c02f2d5eb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xd56f086e7b796b313d49f2bc926fac4bdd2a2b0b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x7eb847a214192aab8fa1b503f4d4c9ddd2a08db6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x81b3bc0ef974c16d71b8614adb8c22ccc045da01
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xc9b44ca4159dbaf5722a3dc8618e9d4b5f39d5b2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xbeef35a63fc62a3334630d9d3b4db27093d95317
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x3d5d143381916280ff91407febeb52f2b60f33cf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x68c9325cc268df8b9ed4a06429587f28471b5f84
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa00cc1fb7ac185222294777c6b23a13c013f07ce
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x77021e63bcbd3c5296b0cdd8a3c3770fb0ea8fa2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xcc28456d4ff980cee3457ca809a257e52cd9cdb0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xec0b7e8e44c9d60efd67a89dba1d4a6e02a7a4a0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x0c8fed5dd65542ca5f0add1acab14c2e470c9110
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xd56da2b74ba826f19015e6b7dd9dae1903e85da1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x5482c2b11951bbb92b87858242e17abde802b398
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xd95bae63641d822dc591bd4aca7a64e53eac76f9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x06959273e9a65433de71f5a452d529544e07ddd0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x24bf2ee2e09477082d1ddf2f0603baa460b3f5f3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x56d8f846415e08c5e663d89505e79f522d33f947
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x548e923281f372d28a40287d3a2d30dce482fc66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x9d744d3d905897608d24c1b8c1c7db0d30c36cd4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xddd23787a6b80a794d952f5fb036d0b31a8e6aff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xa86aca6d7c393c06dcdc30473ea3d1b05c358dff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x1ffec7119e315b15852557f654ae0052f76e6ae1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x0f027d40c80d8f70f77d3884776531f80b21d20e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x69c66beafb06674db41b22cfc50c34a93b8d82a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xeedff72a683058f8ff531e8c98575f920430fdc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x811cfb75567a252bea23474e2ccd1286927bfe0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x2caccf71bdf8fff97c06a46eca29b611b1a74b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0xf07a84f0732dfe8eea0d3961bcd8f62c761ff508
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/base/0x8c1c499b1796d7f3c2521ac37186b52de024e58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xab46d39cb398fb3649ecba781180016fef75f50b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x25048028ad87484b7fce99bc4e22dcb6c3307470
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xdb2177fee5b0ebdc7b8038cb70f3964bb6d14143
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x42d749f736051d8933b118324cded52d1f92bec1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xb1a1b707b143b911c36e1a0f4f901c5017791aca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x3319a81a316abd4c086f7048904e31ff86648b38
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x4a978a2d4fb7393063babfb0cee741b8bcd4dd4b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xea403e36fb592fdfdc342c38e94284ddbb0d2105
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xe3fb01794d6912f0773171e32e723471ee8df061
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x916d7f23ccbb1d10118dcfc6ad5a10b6446ff73e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xddd23787a6b80a794d952f5fb036d0b31a8e6aff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xa86aca6d7c393c06dcdc30473ea3d1b05c358dff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x1ffec7119e315b15852557f654ae0052f76e6ae1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x0f027d40c80d8f70f77d3884776531f80b21d20e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x69c66beafb06674db41b22cfc50c34a93b8d82a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xeedff72a683058f8ff531e8c98575f920430fdc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x811cfb75567a252bea23474e2ccd1286927bfe0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x2caccf71bdf8fff97c06a46eca29b611b1a74b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0xf07a84f0732dfe8eea0d3961bcd8f62c761ff508
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/bnb/0x8c1c499b1796d7f3c2521ac37186b52de024e58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x6cde5f5a192fbf3fd84df983aa6dc30dbd9f8fac
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xd80d28850bebe6208433c298334392bc940b4fc7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x7f7c4335ccac291ddedcef4429a626c442b627ed
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x628cb3a5a206956423d158009612813b64b19dab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x116361f4f45e310347b43cd098fdfa459760ea7f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x5dc631ad6c26bea1a59fbf2c2680cf3df43d249f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x1a810e0b6c2dd5629afa2f0c898b9512c6f78846
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xac1cb6d3d419da9ead0b53e62d6fb4bb53473523
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x0115d04a88990889471a88e85817aac9e961c07b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xd3409b7f3f54bb097433d0f4cd31c48ac33e569b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x493bfc1adb2e60805693197f23132350ffd2a04e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xcf4f103759770c21f945413781ca787620316988
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xb135ebde27d366b0d62e579bae4118cb991b820e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xecbc2f008c20729b9239317408367377c5473812
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x96e0c440d3377c2dfe4f2a82add0b045e46cbe64
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x6f5304c22ac77e228e8af4732ac6677c46e09030
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xcb037f27eb3952222810966e28e0ceb650c65cd9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xddd23787a6b80a794d952f5fb036d0b31a8e6aff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xa86aca6d7c393c06dcdc30473ea3d1b05c358dff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x1ffec7119e315b15852557f654ae0052f76e6ae1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x0f027d40c80d8f70f77d3884776531f80b21d20e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x69c66beafb06674db41b22cfc50c34a93b8d82a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xeedff72a683058f8ff531e8c98575f920430fdc5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x811cfb75567a252bea23474e2ccd1286927bfe0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x2caccf71bdf8fff97c06a46eca29b611b1a74b5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0xf07a84f0732dfe8eea0d3961bcd8f62c761ff508
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/pools/celo/0x8c1c499b1796d7f3c2521ac37186b52de024e58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x7baece5d47f1bc5e1953fbe0e9931d54dab6d810
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x83abecf7204d5afc1bea5df734f085f2535a9976
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x4eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xaf996125e98b5804c00ffdb4f7ff386307c99a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x7924a818013f39cf800f5589ff1f1f0def54f31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xb2eb5849e2606f99fc492e9add0103c667f806d3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x53c6ca2597711ca7a73b6921faf4031eedf71339
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x4eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xaf996125e98b5804c00ffdb4f7ff386307c99a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x7924a818013f39cf800f5589ff1f1f0def54f31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xd35937ecd47b04a1474f8569f457fc5ac395921a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x4eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xaf996125e98b5804c00ffdb4f7ff386307c99a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x7924a818013f39cf800f5589ff1f1f0def54f31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x6b75f2189f0e11c52e814e09e280eb1a9a8a094a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xb372b5abdb7c2ab8ad9e614be9835a42d0009153
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xf369277650ad6654f25412ea8bfbd5942733babc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x4eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xaf996125e98b5804c00ffdb4f7ff386307c99a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x7924a818013f39cf800f5589ff1f1f0def54f31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x4898cf312fbff8814cab80a8d7f6ee5ad0dc73fb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x5e78afc6c804d4382bede3a0712d210e657e9b4f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x86b211ca7915a0c8d4659dd98242d9e801d88ab4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xb637f7c82fd774c280e23cebc725e7cd807c66d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xd249c43faabc58d6dd4b0a4de598b5a956c5d8d7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x1fbae785ce68b79f7ed4f7b27c3af3ef0e0bc3d4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x3c1376fb8487da57d4ffb263d9d01b578c7b586b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x7b24bed19856f4bb1d4c0421cfb328026cd936bd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x7cf887a863d81e6a483ee947dee05cb51914923c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x588c8cf031809486f015908864ee8699b44017e4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x3987d38a4ff8520a8ef6bcc6f98d6da8bcd69b89
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x4eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xaf996125e98b5804c00ffdb4f7ff386307c99a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x7924a818013f39cf800f5589ff1f1f0def54f31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xde67d05242b18af00b28678db34feec883cc9cd6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x4eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xaf996125e98b5804c00ffdb4f7ff386307c99a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x7924a818013f39cf800f5589ff1f1f0def54f31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x4a5a8b0108f446df7c1c8a459fcfb54e844b7343
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xf6ba006abf768ab2d1b5bba2d22d9f13eb1269d4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x4eefe02fce5b53ca33c7717bbd8ad3c9cb0609f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xaf996125e98b5804c00ffdb4f7ff386307c99a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x7924a818013f39cf800f5589ff1f1f0def54f31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x92c2fc5f306405eab0ff0958f6d85d7f8892cf4d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xcbe856765eeec3fdc505ddebf9dc612da995e593
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x92c2fc5f306405eab0ff0958f6d85d7f8892cf4d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xcbe856765eeec3fdc505ddebf9dc612da995e593
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xc1738d90e2e26c35784a0d3e3d8a9f795074bca4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x92c2fc5f306405eab0ff0958f6d85d7f8892cf4d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xcbe856765eeec3fdc505ddebf9dc612da995e593
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xda908c0bf14ad0b61ea5ebe671ac59b2ce091cbf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x254aa3a898071d6a2da0db11da73b02b4646078f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x92c2fc5f306405eab0ff0958f6d85d7f8892cf4d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xcbe856765eeec3fdc505ddebf9dc612da995e593
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x41824081f2e7beb83048bf52465ddd7c8e471da2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xa0c2ce1723b3939f47ad01a293292f2f75dc629d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xc42442f6402b68626e791a447d87b35cb1c6236e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x84537db6f6aaa2afdb71f325d14b9f5f7825bef1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x13933689ed2c6c66e83aed64336df14896efb7e2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x92c2fc5f306405eab0ff0958f6d85d7f8892cf4d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xcbe856765eeec3fdc505ddebf9dc612da995e593
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x039df62583ddc1c5fda75db152b87113d863b6d6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x92c2fc5f306405eab0ff0958f6d85d7f8892cf4d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xcbe856765eeec3fdc505ddebf9dc612da995e593
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x92c2fc5f306405eab0ff0958f6d85d7f8892cf4d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xcbe856765eeec3fdc505ddebf9dc612da995e593
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc39e83fe4e412a885c0577c08eb53bdb6548004a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xdbac78be00503d10ae0074e5e5873a61fc56647c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc1cd3d0913f4633b43fcddbcd7342bc9b71c676f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x6c4c7f46d9d4ef6bc5c9e155f011ad19fc4ef321
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xb2c86ff752f18499b70e8f642b3421405d50d6e9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x16588709ca8f7b84829b43cc1c5cb7e84a321b16
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xd0a4c8a1a14530c7c9efdad0ba37e8cf4204d230
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xf92f2e3fca01491baba0975264362cc38b1cab7b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x3e6e23198679419cd73bb6376518dcc5168c8260
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x531b6a4b3f962208ea8ed5268c642c84bb29be0b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x553e9c493678d8606d6a5ba284643db2110df823
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe3170d65018882a336743a9c396c52ea4b9c5563
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x1385fc1fe0418ea0b4fcf7adc61fc7535ab7f80d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x5cd0ad98ba6288ed7819246a1ebc0386c32c314b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe945683b3462d2603a18bdfbb19261c6a4f03ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe46935ae80e05cdebd4a4008b6ccaa36d2845370
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x3041cbd36888becc7bbcbc0045e3b1f144466f5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x0ad1e922e764df5ab6d636f5d21ecc2e41e827f0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xe945683b3462d2603a18bdfbb19261c6a4f03ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xe46935ae80e05cdebd4a4008b6ccaa36d2845370
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x3041cbd36888becc7bbcbc0045e3b1f144466f5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x6b3a3d6ed64faf933a7a4b1bd44b2efba47614ac
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x4ce4a1a593ea9f2e6b2c05016a00a2d300c9ffd8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x0843e0f56b9e7fdc4fb95fabba22a01ef4088f41
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x8323d063b1d12acce4742f1e3ed9bc46d71f4222
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xe945683b3462d2603a18bdfbb19261c6a4f03ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xe46935ae80e05cdebd4a4008b6ccaa36d2845370
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x3041cbd36888becc7bbcbc0045e3b1f144466f5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xe30e4dfdbb10949c27501922f845e20cfa579f09
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x7e02ae3f794ebade542c92973eb1c46d7e2e935d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xfa22d298e3b0bc1752e5ef2849cec1149d596674
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x8066ee17156e4184d69277e26fa8cbca3a845edf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x418de8e0ab58abfe916a47821a055c59b9502deb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xfb9caae5a5c0ab91f68542124c05d1efbb97d151
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xb68606a75b117906e06caa0755896ad2b3dd0272
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x6e33c0f5e16b45114679eac217e0c0138cefcd2e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xd64fb39a5681908ad488b487d65f5d8479cb235c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xe945683b3462d2603a18bdfbb19261c6a4f03ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xe46935ae80e05cdebd4a4008b6ccaa36d2845370
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x3041cbd36888becc7bbcbc0045e3b1f144466f5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x0217fc17c642d29b890bcf888e21be2378493e01
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x099d23a43da5a8a9282266dbefeaaef958150300
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xd92e0767473d1e3ff11ac036f2b1db90ad0ae55f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xe945683b3462d2603a18bdfbb19261c6a4f03ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xe46935ae80e05cdebd4a4008b6ccaa36d2845370
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x3041cbd36888becc7bbcbc0045e3b1f144466f5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x40c547e7fd88f60d94788953b83d9342d8d133c6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x397433498c7befde4b4049b98a7ff081a2c17387
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xf9be03505869d719ba194757943575ed2af001f2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x18c40bb9281a07627ff25cea45b7511f68fd0076
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x270d89e983d9821a418bf193684736414fab78c5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xb125aa15ad943d96e813e4a06d0c34716f897e26
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x813c0decbb1097fff46d0ed6a39fb5f6a83043f4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x9a7ac628ba9f330341486380af729c8975388959
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xf2c9339945bff71dd0bffd3c142164112cd05dc6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x12a4619c0bd9710732fbc458e9baa73df6c3d35f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x96530dac7817f186390b64ba63d13becd079b28d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x18fc1e95adb68b556212ebbad777f3fbb644db98
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xabbeb324b090550ca6d15ec71019915813f54f90
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x86d708404d0db1d97843e66d4ed6b86d11be705b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xbfbba3de6a260c8374f8299c38898312c2d6e9a6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xe945683b3462d2603a18bdfbb19261c6a4f03ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xe46935ae80e05cdebd4a4008b6ccaa36d2845370
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x3041cbd36888becc7bbcbc0045e3b1f144466f5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xe945683b3462d2603a18bdfbb19261c6a4f03ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xe46935ae80e05cdebd4a4008b6ccaa36d2845370
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x3041cbd36888becc7bbcbc0045e3b1f144466f5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xd31d41dffa3589bb0c0183e46a1eed983a5e5978
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x391e8501b626c623d39474afca6f9e46c2686649
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xd0fc8ba7e267f2bc56044a7715a489d851dc6d78
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x4fd47e5102dfbf95541f64ed6fe13d4ed26d2546
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xe9033c0011f35547fa90d3f8a6ad4b666a590759
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x0c3561d3b72e17378d99684414aa8669daeb8bd0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x14653ce9f406ba7f35a7ffa43c81fa7ecd99c788
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x3204e9734a56a4d7c6f4f5822e14182d9d1a43c4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x43faefd4c0c25e969ac211cd97a4a51e52c729b7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xa652ab3be697c7a01fbdce4d73f8e8acd990251c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x29962083891241aad61ad97bae46d032c9c0c55c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x26bf3601b77be9c31b13b22ebca02914db9c7468
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x0d2edd335982f56662d772b93d86901eb9bd2ff9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xbaed273edd493930711fe88690ebd1f30f7f55ab
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x16033643947bf4d8a1ae37b055edf57cb183106a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xf59abf32c1e8c5d2c6e3faa2131533bbcd466194
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x0312187403bf72b8d2d80729894d6ac3300bd63f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x416fdbc4fb8d4d1f48d0d3778c59dfa5352e9b15
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x90908e414d3525e33733d320798b5681508255ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x5918aca9ae924e6eaaa3d293bb92bdec9ab79338
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x8270e64d22cf13e92c641c4006408c7d7e3ff341
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x16503510c58da73486950b72a12ead3d1d8355dd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x90908e414d3525e33733d320798b5681508255ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x7505159f644ddc5eae21c119e328d0d5bee574b0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xe870bfe4aacb6e234b645e535d26c53790d50e78
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x2e2d190ad4e0d7be9569baebd4d33298379b0502
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x90908e414d3525e33733d320798b5681508255ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xb834093d7e46f7644be45e77281394d31003e866
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xb5a1fd804342cfb679bd8ada75718bc3ec43097e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x90908e414d3525e33733d320798b5681508255ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x9e71e2b14d7e6d30811628ab0965f28e4e2edbce
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xa011da4a0c9261ecf4694bf73a74d113aa261133
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x7ab922c1bfdf7df977c7531c5782074d866f3adc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xe2d2050430e341a8f3988e2726e44d9370f8cd3a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xed66ba3ea44425805a085b1ca80d00467b055b38
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x40dade19adc198125ec237a2c48b3408568b2f81
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x166bc40da621d3cb978e24334f844b84ddef25f8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x76bf0abd20f1e0155ce40a62615a90a709a6c3d8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x90908e414d3525e33733d320798b5681508255ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x6948d6c8532c6b0006cb67c6fb9c399792c8ac91
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x90908e414d3525e33733d320798b5681508255ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x4e40cf4a7d8724e5adc2b791bbf9451d1e260b93
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x90908e414d3525e33733d320798b5681508255ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc0067d751fb1172dbab1fa003efe214ee8f419b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc3d7aa944105d3fafe07fc1822102449c916a8d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xd6b4cce96ddf8aab2e5750983af9a901f17fbc36
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x4cef551255ec96d89fec975446301b5c4e164c59
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xc0067d751fb1172dbab1fa003efe214ee8f419b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xc3d7aa944105d3fafe07fc1822102449c916a8d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xdd0c6bae8ad5998c358b823df15a2a4181da1b80
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xc0067d751fb1172dbab1fa003efe214ee8f419b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xc3d7aa944105d3fafe07fc1822102449c916a8d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xc0067d751fb1172dbab1fa003efe214ee8f419b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xc3d7aa944105d3fafe07fc1822102449c916a8d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x5e6ff2fa4ca244b6b33c7286d368120822eacc11
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x98efd62b4bfbde6393b18b063c506ce5a77f4810
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x3c5096df639262db0a6cd0172f08709d4161094b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xae31f0e673fc5f33cfc0e9abb426d8051404a7c5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xc0067d751fb1172dbab1fa003efe214ee8f419b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xc3d7aa944105d3fafe07fc1822102449c916a8d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xc0067d751fb1172dbab1fa003efe214ee8f419b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xc3d7aa944105d3fafe07fc1822102449c916a8d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xd10456ce05b9af05c8eede0f93ea8aa80a0daa2f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x065c22a16f6531706681fabbc8df135fe6eb1c2e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x8ab8d851c6b31d8a4d42fd7d3e47b20861b025f2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xc0067d751fb1172dbab1fa003efe214ee8f419b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xc3d7aa944105d3fafe07fc1822102449c916a8d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x2982d3295a0e1a99e6e88ece0e93ffdfc5c761ae
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc593fe9193b745447e86b45ea0bf62565ee030cc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x88051b0eea095007d3bef21ab287be961f3d8598
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xaf21b0ec0197e63a5c6cc30c8e947eb8165c6212
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x9c84f58bb51fabd18698efe95f5bab4f33e96e8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xb31273fd2dfc05e6fd91a3b8a2a681aeb0fbcf48
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xaf7b48ae2f4773fd44f9208cca3db5ae7bfa7e37
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xc2125a452115ff5a300cc2a6ffae99637f6e329d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xb08a8794a5d3ccca3725d92964696858d3201909
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xaf21b0ec0197e63a5c6cc30c8e947eb8165c6212
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x9c84f58bb51fabd18698efe95f5bab4f33e96e8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xae99efe6b04bbe5b8b4ad567946fb84b35681abb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xaf21b0ec0197e63a5c6cc30c8e947eb8165c6212
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x9c84f58bb51fabd18698efe95f5bab4f33e96e8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xaf21b0ec0197e63a5c6cc30c8e947eb8165c6212
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x9c84f58bb51fabd18698efe95f5bab4f33e96e8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x6696710b8e3dc0d844c8b9244767962a4a61ad97
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xcde77ef185a8f886d03b109573cc1dcdcf3cf1f8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xaf21b0ec0197e63a5c6cc30c8e947eb8165c6212
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x9c84f58bb51fabd18698efe95f5bab4f33e96e8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x35f5387decce5a234da1a32ca3c9e338a48bcf37
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x4178dd7eb2eb983ba7f7e41648cf91db6be20190
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xaf21b0ec0197e63a5c6cc30c8e947eb8165c6212
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x9c84f58bb51fabd18698efe95f5bab4f33e96e8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xb6c8f9490314394cfc6edacb8717bfdc1eb8dab5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x1625fe58cdb3726e5841fb2bb367dde9aaa009b3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xb1ed164c736909ba7ddbc1feb7ced4eaad854a87
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x95faa9a91cd6c1c018e4b1a6fc4c89d4f1695e5d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xa143ccf73c25eec6f38bd1b741043ebea228b8e9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x2e067e0eab7fd31c01473c0f56f3295afb82e461
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xbc83c60e853398d263c1d88899cf5a8b408f9654
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xaf21b0ec0197e63a5c6cc30c8e947eb8165c6212
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x9c84f58bb51fabd18698efe95f5bab4f33e96e8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x202a6012894ae5c288ea824cbc8a9bfb26a49b93
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x744159757cac173a7a3ecf5e97adb10d1a725377
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x127452f3f9cdc0389b0bf59ce6131aa3bd763598
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x5ced44f03ff443bbe14d8ea23bc24425fb89e3ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x5ced44f03ff443bbe14d8ea23bc24425fb89e3ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x2264ba9dc0b257c69eeae7782e8ff608cc65d6a7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x5ced44f03ff443bbe14d8ea23bc24425fb89e3ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x00a59c2d0f0f4837028d47a391decbffc1e10608
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x5ced44f03ff443bbe14d8ea23bc24425fb89e3ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xad6e8f6a34087bddfb03815e2c10e4f7bfd4395b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xd5bb156cb73bfca62f68dc3dff7e5ec4e305b861
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xc0d8f259578c985947a050802fb4857261af0bf3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x5ced44f03ff443bbe14d8ea23bc24425fb89e3ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x74f7a360eb36a46b675ea932ea07094a3ace441f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x626761cc5b9fafe4696bf8def4aa015576bb4bef
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x5ced44f03ff443bbe14d8ea23bc24425fb89e3ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xc767c0b2e2e56c455fd29f9ee9b6e6f035c71ed4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x625cb959213d18a9853973c2220df7287f1e5b7d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x5ced44f03ff443bbe14d8ea23bc24425fb89e3ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x7138eae57e8a214f7297e5e67bb6e183df3572d5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc7bbec68d12a0d1830360f8ec58fa599ba1b0e9b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x840deeef2f115cf50da625f7368c24af6fe74410
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x69c7bd26512f52bf6f76fab834140d13dda673ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x69c7bd26512f52bf6f76fab834140d13dda673ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x69c7bd26512f52bf6f76fab834140d13dda673ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xda71299ff6bdac31bdcafde52a41d460f17e3ad9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xabebc245a9a47166ecd10933d43817c8ef6fb825
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x69c7bd26512f52bf6f76fab834140d13dda673ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x69c7bd26512f52bf6f76fab834140d13dda673ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xb007dda6ca7a57785ce04981c30a1934995a197a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x0de383928e4fcf0f90ad2d6a5ee18eb3b9d16a55
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x0a36df020fe3f132e6557899f272bf3d4591620e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x69c7bd26512f52bf6f76fab834140d13dda673ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x69c7bd26512f52bf6f76fab834140d13dda673ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x8c9d230d45d6cfee39a6680fb7cb7e8de7ea8e71
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xcb198a55e2a88841e855be4eacaad99422416b33
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x9b371948735f612be19195f5f6e5ebc03839cdaf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xb3709d0e16b618b15ee4bcf82d19b9e7d4100914
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xe426e1305f5e6093864762bf9d2d8b44bc211c59
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x7b9a5bc920610f54881f2f6359007957de504862
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xfb82dd4d657033133eea6e5b7015042984c5825f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x92560c178ce069cc014138ed3c2f5221ba71f58a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x6ef7d514d75b5a5a3c500dba1b161a81e842e7a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xac70bd92f89e6739b3a08db9b6081a923912f73d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x1ebcf8831b93450ea81b0619c5e05b98751c8322
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x470d0d72c975a7f328bd63808bfffd28194b3eb6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xa961f0473da4864c5ed28e00fcc53a3aab056c1b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x6ef7d514d75b5a5a3c500dba1b161a81e842e7a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xa5b6d588ceb3aa1bf543d095038479188f884690
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x6ef7d514d75b5a5a3c500dba1b161a81e842e7a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x6ef7d514d75b5a5a3c500dba1b161a81e842e7a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xb1419a7f9e8c6e434b1d05377e0dbc4154e3de78
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x6ef7d514d75b5a5a3c500dba1b161a81e842e7a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x70c132a2ddeccf0d76cc9b64a749ffe375a79a21
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x6ef7d514d75b5a5a3c500dba1b161a81e842e7a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x6ef7d514d75b5a5a3c500dba1b161a81e842e7a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x1b942ce8bf08290f740b9e825c91e07fcd0bfe75
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x5016cd7b785a773f7f3a3ff4035a1e7a76543946
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xf6c4e4f339912541d3f8ed99dba64a1372af5e5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x4f122edcd91af8cda38c3a87158afa8687bab57c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xed3fe08bd12f24dad0f1a1e58610644debe374fb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x5016cd7b785a773f7f3a3ff4035a1e7a76543946
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xf6c4e4f339912541d3f8ed99dba64a1372af5e5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x7bc815ca2c2115f896bb14b31b8196388c05e99b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x5016cd7b785a773f7f3a3ff4035a1e7a76543946
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xf6c4e4f339912541d3f8ed99dba64a1372af5e5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xd29c2df656b2e4ae6b6817ccc2ebe932fc6a950b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x1f6082db7c8f4b199e17090cd5c8831a1dad1997
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x5016cd7b785a773f7f3a3ff4035a1e7a76543946
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xf6c4e4f339912541d3f8ed99dba64a1372af5e5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xc64f886397988ff16d72123dbe3d46e5bf33ffac
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x0d2c430c6f7ef48ed34bf4aad0ec377e03cc53cf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x5016cd7b785a773f7f3a3ff4035a1e7a76543946
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xf6c4e4f339912541d3f8ed99dba64a1372af5e5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x2b11a34f52e354ef197f0a2397008699b875ae7e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x5016cd7b785a773f7f3a3ff4035a1e7a76543946
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xf6c4e4f339912541d3f8ed99dba64a1372af5e5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xde27bdec962a74a72fa1c5ef50bff6f3da083e05
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x7766bdc5ff15d3aceb4d37914963aebaccf3de15
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x5016cd7b785a773f7f3a3ff4035a1e7a76543946
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xf6c4e4f339912541d3f8ed99dba64a1372af5e5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x67ab7dc903a10838a0de8861dfdff3287cf98e5c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x88aaeed1fcfca2eda30749afa9ad45a75c80e292
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x2c8e9a1586ed822f79c0a241e1a4d48e839b3182
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x847165954680b989902e354f34d08b09afab3cd9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x590269935821d760c54b32d31db66ba47d4e53b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x03d70bf9e6afbf8cac09ef0c45f9a00a841c2bed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x8b238f615c1f312d22a65762bcf601a37f1eeec7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x5280d5e63b416277d0f81fae54bb1e0444cabdaa
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xf4e43a4a17d2820c7cf724e46844943931a47894
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x5ab53ee1d50eef2c1dd3d5402789cd27bb52c1bb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe6ff8b9a37b0fab776134636d9981aa778c4e718
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x44af8d03393e498eec5fcfc7936ebc381f02974d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x4094915f7849b26e8d43dee1f7e3b7b477a0b5bb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xc3f5e0d4cdff86e85486cf6bd20cc0884df5f98e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x87428a53e14d24ab19c6ca4939b4df93b8996ca9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x9dbe5dffaeb4ac2e0ac14f8b4e08b3bc55de5232
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc3576f38c32e95e36bbd8d91e6cbe646a3723110
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x8d58e202016122aae65be55694dbce1b810b4072
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xc3576f38c32e95e36bbd8d91e6cbe646a3723110
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x8d58e202016122aae65be55694dbce1b810b4072
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xa7bb0d95c6ba0ed0aca70c503b34bc7108589a47
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xbcfac19a0036ada56496316ee5cf388c2af2bf58
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x296b88b607ea3a03c821ca4dc34dd9e7e4efa041
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xc3576f38c32e95e36bbd8d91e6cbe646a3723110
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x8d58e202016122aae65be55694dbce1b810b4072
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x019c29d5c97f8cbaa67013e2cf4b6506a5cf183a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xc3576f38c32e95e36bbd8d91e6cbe646a3723110
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x8d58e202016122aae65be55694dbce1b810b4072
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x30442fcebbd75a5bb58377c0174d5ce637e297d7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x6c561b446416e1a00e8e93e221854d6ea4171372
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x0fb597d6cfe5be0d5258a7f017599c2a4ece34c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xe9b7057f9b81a0120c09306d35f22859473f18cb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x8deb37b048f4b3c7bd61eca7dfccbef7cba726de
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x455fd3ae52a8ab80f319a1bf912457aa8296695a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xe11d03bef391ee0a4b670176e23eb44aad490f12
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xe7f850731fed6af4c36cce93eccfbcda0634a030
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xadad4ce0c68f50a19cf5063e0b91d701daab1df1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x5e9bb3d7682a9537db831060176c4247ab80d1ec
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xe9ed60539a8ea7a4da04ebfa524e631b1fd48525
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x0511791eb6fb175a1aaa645114f0f5c8689ec163
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xf3c7b93db3f28580b0fd10365e619eedceb40e76
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x58ecf9cec06bc58fde9280d348f79ed8f3d3046e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xedc7f0dfd9751ef95bb8786a3b130f490743bb0e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xc3576f38c32e95e36bbd8d91e6cbe646a3723110
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x8d58e202016122aae65be55694dbce1b810b4072
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x6bcb0ba386e9de0c29006e46b2f01f047ca1806e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xc3576f38c32e95e36bbd8d91e6cbe646a3723110
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x8d58e202016122aae65be55694dbce1b810b4072
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xc3576f38c32e95e36bbd8d91e6cbe646a3723110
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x8d58e202016122aae65be55694dbce1b810b4072
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x34a43471377dcce420ce8e3ffd9360b2e08fa7b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x34a43471377dcce420ce8e3ffd9360b2e08fa7b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x34a43471377dcce420ce8e3ffd9360b2e08fa7b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x34a43471377dcce420ce8e3ffd9360b2e08fa7b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x34a43471377dcce420ce8e3ffd9360b2e08fa7b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x34a43471377dcce420ce8e3ffd9360b2e08fa7b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x34a43471377dcce420ce8e3ffd9360b2e08fa7b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x766854992bd5363ebeeff0113f5a5795796befab
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x9438a9d1bdeece02ed4431ac59613a128201e0b9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x0a63d3910ffc1529190e80e10855c4216407cc45
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x89084692453ab2305f5f8ac7d70d5efd37a86b8f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xb34a5657988da5b9888952c439756594613507aa
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x05efb437e4e97efea6450321eca8d7585a731369
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xc973c86afc23ed731ce1a14d7179003a1601205f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x0f44a1c2b66418f784607d2067fe695703809bff
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x0da6253560822973185297d5f32ff8fa38243afe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x622270721fb38fde831ab23a8e177665557f6fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xa95b0f5a65a769d82ab4f3e82842e45b8bbaf101
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x622270721fb38fde831ab23a8e177665557f6fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x886b4f0cb357e0d6ec07b7a3985f346cc17ece7d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x622270721fb38fde831ab23a8e177665557f6fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x50defb73a76efe5d5d35cf267ffb02dfd6cd96bc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x622270721fb38fde831ab23a8e177665557f6fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x7aea2e8a3843516afa07293a10ac8e49906dabd1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x8c7080564b5a792a33ef2fd473fba6364d5495e5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x8f81b80d950e5996346530b76aba2962da5c9edb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x7bc0f74d8d94e8e9fdaa40bbc04cc44fb8e0f081
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x09c149c856e6fb6e40aa39209142411b554b1a41
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x622270721fb38fde831ab23a8e177665557f6fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x7ef0a523c49b1dd07e3593198c5260a95ad7859a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x622270721fb38fde831ab23a8e177665557f6fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x622270721fb38fde831ab23a8e177665557f6fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x15aa01580ae866f9ff4dbe45e06e307941d90c7b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x4548280ac92507c9092a511c7396cbea78fa9e49
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe0554a476a092703abdb3ef35c80e0d76d32939f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc555d55279023e732ccd32d812114caf5838fd46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x421803da50d3932caa36bd1731d36a0e2af93542
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xc555d55279023e732ccd32d812114caf5838fd46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xc555d55279023e732ccd32d812114caf5838fd46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x258a4b7373f6863db5a17de191e0cebb1e0bbc8a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x45126b956401daaec92afba2a9953e14b16fb83f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xc555d55279023e732ccd32d812114caf5838fd46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xa3eaa52b505cf61aadcfe21424d43a6847dd6331
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x722bcf6c16dadcc29914e4e64290c46aa1406de8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x1e1367dcebe168554e82552e0e659a4116926d10
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xc555d55279023e732ccd32d812114caf5838fd46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x4d170f8714367c44787ae98259ce8adb72240067
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xc555d55279023e732ccd32d812114caf5838fd46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xaa97f0689660ea15b7d6f84f2e5250b63f2b381a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xc555d55279023e732ccd32d812114caf5838fd46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xb736330326cf379ecd918dba10614bd63c2713da
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xe3d4faff3179f0a664a3a84c3e1da3b90e27f186
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x50e7b9293aef80c304234e86c84a01be8401c530
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x87dddd2e152bf1955e7e03d9f23a9dcc163eebf6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xd9dd34576c7034beb0b11a99afffc49e91011235
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x394a9fcbab8599437d9ec4e5a4a0eb7cb1fd2f69
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xb3adde966b8a1a6f22a04914ee9fe0798e71fc5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xa2d4a8e00daad32acace1a0dd0905f6aaf57e84e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x2392ae4ba6daf181ce7343d237b695cdf525e233
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc2c390c6cd3c4e6c2b70727d35a45e8a072f18ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x95f4408736988549212db071b1c8d20f7c4e6304
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x52c77b0cb827afbad022e6d6caf2c44452edbc39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x3dd2fdba71282083d440687cce9e4231aaac534e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xe4d9faddd9bca5d8393bee915dc56e916ab94d27
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x95f4408736988549212db071b1c8d20f7c4e6304
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x52c77b0cb827afbad022e6d6caf2c44452edbc39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x9c92ed19a86986124447a73b27625230dd52f805
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x740601243a6aa25ce4ee2d196eef83ac3bec6c65
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x95f4408736988549212db071b1c8d20f7c4e6304
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x52c77b0cb827afbad022e6d6caf2c44452edbc39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x95f4408736988549212db071b1c8d20f7c4e6304
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x52c77b0cb827afbad022e6d6caf2c44452edbc39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xafbb6fcc92ddb091dbc13e9073c3360c7d9600cc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x95f4408736988549212db071b1c8d20f7c4e6304
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x52c77b0cb827afbad022e6d6caf2c44452edbc39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xf54eba95d7f8dbe4bfeb0b6e038b3c2bedd3e40a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x05c0a0b84b6b67499c33e6403686f45cab063810
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x9169bf3657353e4b2b81c75e235f22bc299a7780
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x95f4408736988549212db071b1c8d20f7c4e6304
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x52c77b0cb827afbad022e6d6caf2c44452edbc39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x95f4408736988549212db071b1c8d20f7c4e6304
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x52c77b0cb827afbad022e6d6caf2c44452edbc39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xb0bb2c1d32c7b27f21eec4402c6d1c38795c090a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x534d3930edba2c0b90a7973549a0287141c987ef
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xf27d0dac09460b236d4d9e0da316fe9c3a99b4a2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x0c3fdf9c70835f9be9db9585ecb6a1ee3f20a6c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xdd672b3b768a16b9bcb4ee1060d3e8221435beaa
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x0c3fdf9c70835f9be9db9585ecb6a1ee3f20a6c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xa39fe8f7a00ce28b572617d3a0bc1c2b44110e79
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x0c3fdf9c70835f9be9db9585ecb6a1ee3f20a6c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0x0c3fdf9c70835f9be9db9585ecb6a1ee3f20a6c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x0c3fdf9c70835f9be9db9585ecb6a1ee3f20a6c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x96d5d78b179169ee0a0a0104dc514988f2a797fe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x0c3fdf9c70835f9be9db9585ecb6a1ee3f20a6c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0xb466d5429d6ad9999bf112c225d9d7b15e96c658
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/celo/0x0c3fdf9c70835f9be9db9585ecb6a1ee3f20a6c7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x8a35d2635aeca1aaf667d77ed9ff3b21e48ede24
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe566e99d65b17974fd9db02e25e24ea8020f7a0e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x5c3edc45ae71a353c669cfa71e6488951dce4618
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xa7b3bcc6c88da2856867d29f11c67c3a85634882
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x543842cbfef3b3f5614b2153c28936967218a0e6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xc45a81bc23a64ea556ab4cdf08a86b61cdceea8b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe333e366503f620e0242796431dc74fffd258e66
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0x42161084d0672e1d3f26a9b53e653be2084ff19c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/arbitrum/0xe24f62341d84d11078188d83ca3be118193d6389
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0x782dcc2cd3a65405baeb794269703e9c29a175cc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xae8d5b91fca627410a3bef77f55fcfe208409a40
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xa42eb1c1a212da9e24058c6afc0ea906fecb8351
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x0e3529cf622dc1141a31cfc0fc85f679f558c92b
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x6f5ec7c65c2744a963064f6d49df0f4eea7d7d90
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x9a772018fbd77fcd2d25657e5c547baff3fd7d16
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xfc1505b3d4cd16bb2336394ad11071638710950f
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x8e0a7d4018fb2674346d5742055174f899fe1826
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xf8aa1db87d84118b0b461e2135190ac27fc1859d
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0xe8f7c89c5efa061e340f2d2f206ec78fd8f7e124
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x56534741cd8b152df6d48adf7ac51f75169a83b2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/ethereum/0x73a38006d23517a1d383c88929b2014f8835b38b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/optimism/0xf5d63f66a36be31a106631f276794223b8ce5280
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/polygon/0xcf0bb95967cd006f5eaa1463c9d710d1e1550a96
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xdc9bf303e72a5780c45d53fc12799164e5ba8271
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0x1d4dab3f27c7f656b6323c1d6ef713b48a8f72f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/base/0xafd8f9b89e2af8246523573a369010daf9489b12
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0xbd045175d2a1451a015079f5f3f59ca5c05524ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/pools/bnb/0x859ec3d336bb5508f6d87fea2d49c9294adae311
+ 2024-11-01T19:06:09.419Z
0.8
\ No newline at end of file
diff --git a/apps/web/public/tokens-sitemap.xml b/apps/web/public/tokens-sitemap.xml
index e727529afef..d810947a248 100644
--- a/apps/web/public/tokens-sitemap.xml
+++ b/apps/web/public/tokens-sitemap.xml
@@ -2,3182 +2,7567 @@
https://app.uniswap.org/explore/tokens/ethereum/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xdac17f958d2ee523a2206206994597c13d831ec7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x2260fac5e5542a773aa44fbcfedf7c193bc2c599
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x6982508145454ce325ddbe47a25d4ec3d2311933
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x6b175474e89094c44da98b954eedeac495271d0f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x6123b0049f904d730db3c36a31167d9d4121fa6b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xcf0c122c6b73ff809c693db761e7baebe62b6a2e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xfaba6f8e4a5e8ab82f62fe7c39859fa577269be3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x58cb30368ceb2d194740b144eab4c2da8a917dcb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x4c9edd5852cd905f086c759e8383e09bff1e68b3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xaaee1a9723aadb7afa2810263653a34ba2c21c7a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x514910771af9ca656af840dff83e8264ecf986ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x5b7533812759b45c2b44c19e320ba2cd2681b542
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xae78736cd615f374d3085123a210448e74fc6393
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xb9f599ce614feb2e1bbe58f180f370d05b39344e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd5f7838f5c461feff7fe49ea5ebaf7728bb0adfa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd31a59c85ae9d8edefec411d448f90841571b89c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x6a7eff1e2c355ad6eb91bebb5ded49257f3fed98
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x576e2bed8f7b46d34016198911cdf9886f78bea7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1258d60b224c0c5cd888d37bbf31aa5fcfb7e870
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x62d0a8458ed7719fdaf978fe5929c6d342b0bfce
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x77e06c9eccf2e797fd462a92b6d7642ef85b0a44
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x24fcfc492c1393274b6bcd568ac9e225bec93584
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x27702a26126e0b3702af63ee09ac4d1a084ef628
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd46ba6d942050d489dbd938a2c909a5d5039a161
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xbe9895146f7af43049ca1c1ae358b0541ea49704
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x72f713d11480dcf08b37e1898670e736688d218d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x0001a500a6b18995b03f44bb040a5ffc28e45cb0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x9e9fbde7c7a83c43913bddc8779158f1368f0413
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x5f98805a4e8be255a32880fdec7f6728c6568ba0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x2b591e99afe9f32eaa6214f7b7629768c40eeb39
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1ae7e1d0ce06364ced9ad58225a1705b3e5db92b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x046eee2cc3188071c02bfc1745a6b17c656e3f3d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x84018071282d4b2996272659d9c01cb08dd7327f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x12970e6868f88f6557b76120662c1b3e50a646bf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xaea46a60368a7bd060eec7df8cba43b7ef41ad85
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x6de037ef9ad2725eb40118bb1702ebb27e4aeb24
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xc01154b4ccb518232d6bbfc9b9e6c5068b766f82
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x5a98fcbea516cf06857215779fd812ca3bef1b32
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x102c776ddb30c754ded4fdcc77a19230a60d4e4f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x72e4f9f808c49a2a61de9c5896298920dc4eeea9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x467719ad09025fcc6cf6f8311755809d45a5e5f3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf19308f923582a6f7c465e5ce7a9dc1bec6665b1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x710287d1d39dcf62094a83ebb3e736e79400068a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf951e335afb289353dc249e82926178eac7ded78
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf017d3690346eb8234b85f74cee5e15821fee1f4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x8c282c35b5e1088bb208991c151182a782637699
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xeaa63125dd63f10874f99cdbbb18410e7fc79dd3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xde342a3e269056fc3305f9e315f4c40d917ba521
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x2dff88a56767223a5529ea5960da7a3f5f766406
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x626e8036deb333b408be468f951bdb42433cbf18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xdd66781d0e9a08d4fbb5ec7bac80b691be27f21d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xb23d80f5fefcddaa212212f028021b41ded428cf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xbaac2b4491727d78d2b78815144570b9f2fe8899
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf8ebf4849f1fa4faf0dff2106a173d3a6cb2eb3a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xb90b2a35c65dbc466b04240097ca756ad2005295
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1614f18fc94f47967a3fbe5ffcd46d4e7da3d787
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf1df7305e4bab3885cab5b1e4dfc338452a67891
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x91fbb2503ac69702061f1ac6885759fc853e6eae
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xa9e8acf069c58aec8825542845fd754e41a9489a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x2c95d751da37a5c1d9c5a7fd465c1d50f3d96160
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xe453c3409f8ad2b1fe1ed08e189634d359705a5b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x89d584a1edb3a70b3b07963f9a3ea5399e38b136
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x4507cef57c46789ef8d1a19ea45f4216bae2b528
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd1d2eb1b1e90b638588728b4130137d262c87cae
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xe92344b4edf545f3209094b192e46600a19e7c2d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x8a0a9b663693a22235b896f70a229c4a22597623
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1bbe973bef3a977fc51cbed703e8ffdefe001fed
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xa41d2f8ee4f47d3b860a149765a7df8c3287b7f0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x761d38e5ddf6ccf6cf7c55759d5210750b5d60f3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xc18360217d8f7ab5e7c516566761ea12ce7f9d72
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xe28b3b32b6c345a34ff64674606124dd5aceca30
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x168e209d7b2f58f1f24b8ae7b7d35e662bbf11cc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xb131f4a55907b10d1f0a50d8ab8fa09ec342cd74
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x3472a5a71965499acd81997a54bba8d852c6e53d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x7dd9c5cba05e151c895fde1cf355c9a1d5da6429
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x19efa7d0fc88ffe461d1091f8cbe56dc2708a84f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x14fee680690900ba0cccfc76ad70fd1b95d10e16
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x3c3a81e81dc49a522a592e7622a7e711c06bf354
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xa1290d69c65a6fe4df752f95823fae25cb99e5a7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x92f419fb7a750aed295b0ddf536276bf5a40124f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x2c06ba9e7f0daccbc1f6a33ea67e85bb68fbee3a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x3d658390460295fb963f54dc0899cfb1c30776df
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x8e870d67f660d95d5be530380d0ec0bd388289e1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x853d955acef822db058eb8505911ed77f175b99e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1294f4183763743c7c9519bec51773fb3acd78fd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x4e15361fd6b4bb609fa63c81a2be19d873717870
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x695d38eb4e57e0f137e36df7c1f0f2635981246b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x40a7df3df8b56147b781353d379cb960120211d7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xaaef88cea01475125522e117bfe45cf32044e238
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x163f8c2467924be0ae7b5347228cabf260318753
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x30672ae2680c319ec1028b69670a4a786baa0f35
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xc944e90c64b2c07662a292be6244bdf05cda44a7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x15e6e0d4ebeac120f9a97e71faa6a0235b85ed12
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x7d225c4cc612e61d26523b099b0718d03152edef
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x82af49447d8a07e3bd95bd0d56f35241523fbab1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xaf88d065e77c8cc2239327c5edb3a432268e5831
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xff970a61a04b1ca14834a43f5de4533ebddb5cc8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x912ce59144191c1204e64559fe8253a0e49e6548
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x5979d7b546e38e414f7e9822514be443a4800529
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x35751007a407ca6feffe80b3cb397736d2cf4dbe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xda10009cbd5d07dd0cecc66161fc93d7c9000da1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xeb466342c4d449bc9f53a865d5cb90586f405215
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x0c880f6761f1af8d9aa9c466984b80dab9a8c9e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xf97f4df75117a78c1a5a0dbb814af92458539fb4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x9623063377ad1b27544c965ccd7342f7ea7e88c7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x539bde0d7dbd336b79148aa742883198bbf60342
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3082cc23568ea640225c2467653db90e9250aaa0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x18c11fd286c5ec11c3b683caa813b77f5163a122
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x289ba1701c2f088cf0faf8b3705246331cb8a839
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x4cb9a7ae498cedcbb5eae9f25736ae7d428c9d66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x00cbcf7b3d37844e44b888bc747bdd75fcf4e555
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd79bb960dc8a206806c3a428b31bca49934d18d7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3096e7bfd0878cc65be71f8899bc4cfb57187ba3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x13ad51ed4f1b7e9dc168d8a00cb3f4ddd85efa60
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x4e352cf164e64adcbad318c3a1e222e9eba4ce42
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x11cdb42b0eb46d95f990bedd4695a6e3fa034978
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xba5ddd1f9d7f570dc94a51479a000e3bce967196
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xc8ccbd97b96834b976c995a67bf46e5754e2c48e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd07d35368e04a839dee335e213302b21ef14bb4a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x323665443cef804a3b5206103304bd4872ea4253
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x83d6c8c06ac276465e4c92e7ac8c23740f435140
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x87aaffdf26c6885f6010219208d5b161ec7609c0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x1b8d516e2146d7a32aca0fcbf9482db85fd42c3a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xafccb724e3aec1657fc9514e3e53a0e71e80622d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x4425742f1ec8d98779690b5a3a6276db85ddc01a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xec70dcb4a1efa46b8f2d97c310c9c4790ba5ffa8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3419875b4d3bca7f3fdda2db7a476a79fd31b4fe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3b60ff35d3f7f62d636b067dd0dc0dfdad670e4e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x58b9cb810a68a7f3e1e4f8cb45d1b9b3c79705e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xfa5ed56a203466cbbc2430a43c66b9d8723528e7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x95146881b86b3ee99e63705ec87afe29fcc044d9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x088cd8f5ef3652623c22d48b1605dcfe860cd704
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xbfd5206962267c7b4b4a8b3d76ac2e1b2a5c4d5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x6daf586b7370b14163171544fca24abcc0862ac5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x580e933d90091b9ce380740e3a4a39c67eb85b4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x655a6beebf2361a19549a99486ff65f709bd2646
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x9e64d3b9e8ec387a9a58ced80b71ed815f8d82b5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x2297aebd383787a160dd0d9f71508148769342e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x6694340fc020c5e6b96567843da2df01b2ce1eb6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x772598e9e62155d7fdfe65fdf01eb5a53a8465be
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x431402e8b9de9aa016c743880e04e517074d8cec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd74f5255d557944cf7dd0e45ff521520002d5748
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x6fd58f5a2f3468e35feb098b5f59f04157002407
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x561877b6b3dd7651313794e5f2894b2f18be0766
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xf9ca0ec182a94f6231df9b14bd147ef7fb9fa17c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd77b108d4f6cefaa0cae9506a934e825becca46e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd56734d7f9979dd94fae3d67c7e928234e71cd4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xf1264873436a0771e440e2b28072fafcc5eebd01
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x5575552988a3a80504bbaeb1311674fcfd40ad4b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x0341c0c0ec423328621788d4854119b97f44e391
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x764bfc309090e7f93edce53e5befa374cdcb7b8e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xaaa6c1e32c55a7bfa8066a6fae9b42650f262418
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x9e20461bc2c4c980f62f1b279d71734207a6a356
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x7fb7ede54259cb3d4e1eaf230c7e2b1ffc951e9a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3a18dcc9745edcd1ef33ecb93b0b6eba5671e7ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x000000000026839b3f4181f2cf69336af6153b99
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x8b0e6f19ee57089f7649a455d89d7bc6314d04e8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x31c91d8fb96bff40955dd2dbc909b36e8b104dde
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x25d887ce7a35172c62febfd67a1856f20faebb00
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd4d42f0b6def4ce0383636770ef773390d85c61a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xf8388c2b6edf00e2e27eef5200b1befb24ce141d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x619c82392cb6e41778b7d088860fea8447941f4c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x94025780a1ab58868d9b2dbbb775f44b32e8e6e5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xad4b9c1fbf4923061814dd9d5732eb703faa53d4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd7a892f28dedc74e6b7b33f93be08abfc394a360
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3269a3c00ab86c753856fd135d97b87facb0d848
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x4568ca00299819998501914690d6010ae48a59ba
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x21e60ee73f17ac0a411ae5d690f908c3ed66fe12
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xd3188e0df68559c0b63361f6160c57ad88b239d8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x2b41806cbf1ffb3d9e31a9ece6b738bf9d6f645f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xf19547f9ed24aa66b03c3a552d181ae334fbb8db
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x35e6a59f786d9266c7961ea28c7b768b33959cbb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x59a729658e9245b0cf1f8cb9fb37945d2b06ea27
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xb56c29413af8778977093b9b4947efeea7136c36
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x43ab8f7d2a8dd4102ccea6b438f6d747b1b9f034
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x1d987200df3b744cfa9c14f713f5334cb4bc4d5d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3404149e9ee6f17fb41db1ce593ee48fbdcd9506
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x080f6aed32fc474dd5717105dba5ea57268f46eb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xb5a628803ee72d82098d4bcaf29a42e63531b441
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x1622bf67e6e5747b81866fe0b85178a93c7f86e3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x7dd747d63b094971e6638313a6a2685e80c7fb2e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xa2f9ecf83a48b86265ff5fd36cdbaaa1f349916c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x17a8541b82bf67e10b0874284b4ae66858cb1fd5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xbcd4d5ac29e06e4973a1ddcd782cd035d04bc0b7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x42069d11a2cc72388a2e06210921e839cfbd3280
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xbbea044f9e7c0520195e49ad1e561572e7e1b948
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xe85b662fe97e8562f4099d8a1d5a92d4b453bf30
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x3d9907f9a368ad0a51be60f7da3b97cf940982d8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x4e51ac49bc5e2d87e0ef713e9e5ab2d71ef4f336
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x4200000000000000000000000000000000000006
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x7f5c764cbc14f9669b88837ca1490cca17c31607
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x4200000000000000000000000000000000000042
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x0b2c639c533813f4aa9d7837caf62653d097ff85
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x1f32b1c2345538c0c6f582fcb022739c4a194ebb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x68f180fcce6836688e9084f035309e29bf0a2095
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x94b008aa00579c1307b0ef2c499ad98a8ce58e58
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xda10009cbd5d07dd0cecc66161fc93d7c9000da1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xdc6ff44d5d932cbd77b52e5612ba0529dc6226f1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x8700daec35af8ff88c16bdf0418774cb3d7599b4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x920cf626a271321c151d027030d5d08af699456b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x6c84a8f1c29108f47a79964b5fe888d4f4d0de40
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x9e1028f5f1d5ede59748ffcee5532509976840e0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xeb466342c4d449bc9f53a865d5cb90586f405215
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x17aabf6838a6303fc6e9c5a227dc1eb6d95c829a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xf467c7d5a4a9c4687ffc7986ac6ad5a4c81e1404
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x76fb31fb4af56892a25e32cfc43de717950c9278
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xc5b001dc33727f8f26880b184090d3e252470d45
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x9560e827af36c94d2ac33a39bce1fe78631088db
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x9bcef72be871e61ed4fbbc7630889bee758eb81d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x50c5725949a6f0c72e6c4a641f24049a917db0cb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xf98dcd95217e15e05d8638da4c91125e59590b07
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x4b03afc91295ed778320c2824bad5eb5a1d852dd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xc40f949f8a4e094d1b49a23ea9241d289b7b2819
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x323665443cef804a3b5206103304bd4872ea4253
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x50bce64397c75488465253c0a034b8097fea6578
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x296f55f8fb28e498b858d0bcda06d955b2cb3f97
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x2598c30330d5771ae9f983979209486ae26de875
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x0994206dfe8de6ec6920ff4d779b0d950605fb53
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xc3248a1bd9d72fa3da6e6ba701e58cbf818354eb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x6fd9d7ad17242c41f7131d257212c54a0e816691
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x14778860e937f509e651192a90589de711fb88a9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xdfa46478f9e5ea86d57387849598dbfb2e964b02
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x9b88d293b7a791e40d36a39765ffd5a1b9b5c349
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x3eb398fec5f7327c6b15099a9681d9568ded2e82
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x217d47011b23bb961eb6d93ca9945b7501a5bb11
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xbfd5206962267c7b4b4a8b3d76ac2e1b2a5c4d5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x1cef2d62af4cd26673c7416957cc4ec619a696a7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x9fd22a17b4a96da3f83797d122172c450381fb88
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0xaddb6a0412de1ba0f936dcaeb8aaa24578dcf3b2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x2791bca1f2de4661ed88a30c99a7a9449aa84174
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x7ceb23fd6bc0add59e62ac25578270cff1b9f619
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x3c499c542cef5e3811e1192ce70d8cc03d5c3359
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xc2132d05d31c914a87c6611c10748aeb04b58e8f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x53e0bca35ec356bd5dddfebbd1fc0fd03fabad39
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x61299774020da444af134c82fa83e3810b309991
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xd6df932a45c0f255f85145f286ea0b292b21c90b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x2ad2934d5bfb7912304754479dd1f096d5c807da
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xc3c7d422809852031b44ab29eec9f1eff2a58756
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x8f3cf7ad23cd3cadbd9735aff958023239c6a063
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x750e4c4984a9e0f12978ea6742bc1c5d248f40ed
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x111111517e4929d3dcbdfa7cce55d30d4b6bc4d6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xd0258a3fd00f38aa8090dfee343f10a9d4d30d3f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x430ef9263e76dae63c84292c3409d61c598e9682
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xb33eaad8d922b1083446dc23f610c2567fb5180f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xdc3326e71d45186f113a2f448984ca0e8d201995
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x311434160d7537be358930def317afb606c0d737
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe3f2b1b2229c0333ad17d03f179b87500e7c5e01
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xac0f66379a6d7801d7726d5a943356a172549adb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xf88332547c680f755481bf489d890426248bb275
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe5417af564e4bfda1c483642db72007871397896
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe261d618a959afffd53168cd07d12e37b26761db
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe0b52e49357fd4daf2c15e02058dce6bc0057db4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xbbba073c31bf03b8acf7c28ef0738decf3695683
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe238ecb42c424e877652ad82d8a939183a04c35f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x3b56a704c01d650147ade2b8cee594066b3f9421
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x5fe2b58c013d7601147dcdd68c143a77499f5531
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x172370d5cd63279efa6d502dab29171933a610af
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x53df32548214f51821cf1fe4368109ac5ddea1ff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xff76c0b48363a7c7307868a81548d340049b0023
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x6f8a06447ff6fcf75d803135a7de15ce88c1d4ec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x50b728d8d964fd00c2d0aad81718b71311fef68a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x3a58a54c066fdc0f2d55fc9c89f0415c92ebf3c4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x03b54a6e9a984069379fae1a4fc4dbae93b3bccd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xd93f7e271cb87c23aaa73edc008a79646d1f9912
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x200c234721b5e549c3693ccc93cf191f90dc2af9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x11cd37bb86f65419713f30673a480ea33c826872
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x8a16d4bf8a0a716017e8d2262c4ac32927797a2f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x9a71012b13ca4d3d0cdc72a177df3ef03b0e76a3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xa1c57f48f0deb89f569dfbe6e2b7f46d33606fd4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x190eb8a183d22a4bdf278c6791b152228857c033
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x235737dbb56e8517391473f7c964db31fa6ef280
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x0b220b82f3ea3b7f6d9a1d8ab58930c064a2b5bf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x8bff1bd27e2789fe390acabc379c380a83b68e84
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xb58458c52b6511dc723d7d6f3be8c36d7383b4a8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x323665443cef804a3b5206103304bd4872ea4253
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x2760e46d9bb43dafcbecaad1f64b93207f9f0ed7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x18ec0a6e18e5bc3784fdd3a3634b31245ab704f6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x431d5dff03120afa4bdf332c61a6e1766ef37bdb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x6f7c932e7684666c9fd1d44527765433e01ff61d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xeee3371b89fc43ea970e908536fcddd975135d8a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe5b49820e5a1063f6f4ddf851327b5e8b2301048
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xaa3717090cddc9b227e49d0d84a28ac0a996e6ff
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x62a872d9977db171d9e213a5dc2b782e72ca0033
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x381caf412b45dac0f62fbeec89de306d3eabe384
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe0bceef36f3a6efdd5eebfacd591423f8549b9d5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x23d29d30e35c5e8d321e1dc9a8a61bfd846d4c5c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x282d8efce846a88b159800bd4130ad77443fa1a1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x74dd45dd579cad749f9381d6227e7e02277c944b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x714db550b574b3e927af3d93e26127d15721d4c2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xfa68fb4628dff1028cfec22b4162fccd0d45efb6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe631dabef60c37a37d70d3b4f812871df663226f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xdb725f82818de83e99f1dac22a9b5b51d3d04dd4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x3c59798620e5fec0ae6df1a19c6454094572ab92
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x0d0b8488222f7f83b23e365320a4021b12ead608
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xa380c0b01ad15c8cf6b46890bddab5f0868e87f3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x8a953cfe442c5e8855cc6c61b1293fa648bae472
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x45c32fa6df82ead1e2ef74d17b76547eddfaff89
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x11cd72f7a4b699c67f225ca8abb20bc9f8db90c7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x0c9c7712c83b3c70e7c5e11100d33d9401bdf9dd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x77a6f2e9a9e44fd5d5c3f9be9e52831fc1c3c0a0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xbfc70507384047aa74c29cdc8c5cb88d0f7213ac
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xfcb54da3f4193435184f3f647467e12b50754575
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x9a6a40cdf21a0af417f1b815223fd92c85636c58
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe111178a87a3bff0c8d18decba5798827539ae99
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x82617aa52dddf5ed9bb7b370ed777b3182a30fd1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x2ab0e9e4ee70fff1fb9d67031e44f6410170d00e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xa486c6bc102f409180ccb8a94ba045d39f8fc7cb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xc4a206a306f0db88f98a3591419bc14832536862
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xf0059cc2b3e980065a906940fbce5f9db7ae40a7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x16eccfdbb4ee1a85a33f3a9b21175cd7ae753db4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x553d3d295e0f695b9228246232edf400ed3560b5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x14af1f2f02dccb1e43402339099a05a5e363b83c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x7bdf330f423ea880ff95fc41a280fd5ecfd3d09f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x8505b9d2254a7ae468c0e9dd10ccea3a837aef5c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe2aa7db6da1dae97c5f5c6914d285fbfcc32a128
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xb7b31a6bc18e48888545ce79e83e06003be70930
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x1631244689ec1fecbdd22fb5916e920dfc9b8d30
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xf6372cdb9c1d3674e83842e3800f2a62ac9f3c66
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x692ac1e363ae34b6b489148152b12e2785a3d8d6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x0266f4f08d82372cf0fcbccc0ff74309089c74d1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x7fbc10850cae055b27039af31bd258430e714c62
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xa3fa99a148fa48d14ed51d610c367c61876997f1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x9dbfc1cbf7a1e711503a29b4b5f9130ebeccac96
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x236aa50979d5f3de3bd1eeb40e81137f22ab794b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xf86df9b91f002cfeb2aed0e6d05c4c4eaef7cf02
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x4200000000000000000000000000000000000006
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x6921b130d297cc43754afba22e5eac0fbf8db75b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x5babfc2f240bc5de90eb7e19d789412db1dec402
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x532f27101965dd16442e59d40670faf5ebb142e4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x4ed4e862860bed51a9570b96d89af5e1b0efefed
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xc1cba3fcea344f92d9239c08c0568f6f2f0ee452
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xac1bd2486aaf3b5c0fc3fd868558b082a531b2b4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x0d97f261b1e88845184f678e2d1e7a98d9fd38de
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8129b94753f22ec4e62e2c4d099ffe6773969ebc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x3f14920c99beb920afa163031c4e47a3e03b3e4a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x940181a94a35a4569e4529a3cdfb74e38fd98631
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x3419875b4d3bca7f3fdda2db7a476a79fd31b4fe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xa067436db77ab18b1a315095e4b816791609897c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xafb89a09d82fbde58f18ac6437b3fc81724e4df6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x489fe42c267fe0366b16b0c39e7aeef977e841ef
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x2ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xdc46c1e93b71ff9209a0f8076a9951569dc35855
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x91f45aa2bde7393e0af1cc674ffe75d746b93567
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x236aa50979d5f3de3bd1eeb40e81137f22ab794b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xf6e932ca12afa26665dc4dde7e27be02a7c02e50
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x524d524b4c9366be706d3a90dcf70076ca037ae3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x5b5dee44552546ecea05edea01dcd7be7aa6144a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x2598c30330d5771ae9f983979209486ae26de875
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xfa980ced6895ac314e7de34ef1bfae90a5add21b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x469fda1fb46fcb4befc0d8b994b516bd28c87003
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x4e496c0256fb9d4cc7ba2fdf931bc9cbb7731660
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x27d2decb4bfc9c76f0309b8e88dec3a601fe25a8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xbfd5206962267c7b4b4a8b3d76ac2e1b2a5c4d5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x9e1028f5f1d5ede59748ffcee5532509976840e0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x3c3aa127e6ee3d2f2e432d0184dd36f2d2076b52
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xba5e6fa2f33f3955f0cef50c63dcc84861eab663
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x97c806e7665d3afd84a8fe1837921403d59f3dcc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8ee73c484a26e0a5df2ee2a4960b789967dd0415
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x00e57ec29ef2ba7df07ad10573011647b2366f6d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8f019931375454fe4ee353427eb94e2e0c9e0a8c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x93e6407554b2f02640ab806cd57bd83e848ec65d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x55d398326f99059ff775485246999027b3197955
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x2170ed0880ac9a755fd29b2688956bd959f933f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xfdc66a08b0d0dc44c17bbd471b88f49f50cdd20f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xe9e7cea3dedca5984780bafc599bd69add087d56
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xfa54ff1a158b5189ebba6ae130ced6bbd3aea76e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x570a5d26f7765ecb712c0924e4de545b89fd43df
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x47c454ca6be2f6def6f32b638c80f91c9c3c5949
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xad86d0e9764ba90ddd68747d64bffbd79879a238
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xf8a0bf9cf54bb92f17374d9e9a321e6a111a51bd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xd691d9a68c887bdf34da8c36f63487333acfd103
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x1294f4183763743c7c9519bec51773fb3acd78fd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xb04906e95ab5d797ada81508115611fee694c2b3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x111111111117dc0aa78b770fa6a738034120c302
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xcc42724c6683b7e57334c4e856f4c9965ed682bd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x90c97f71e18723b0cf0dfa30ee176ab653e89f40
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x2b72867c32cf673f7b02d208b26889fed353b1f8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x031b41e504677879370e9dbcf937283a8691fa7f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x1ce0c2827e2ef14d5c4f29a091d735a204794041
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xcf3bb6ac0f6d987a5727e2d15e39c2d6061d5bec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x8ff795a6f4d97e7887c79bea79aba5cc76444adf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x2dff88a56767223a5529ea5960da7a3f5f766406
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x003d87d02a2a01e9e8a20f507c83e15dd83a33d1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x4b0f1812e5df2a09796481ff14017e6005508003
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xbf5140a22578168fd562dccf235e5d43a02ce9b1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xca1c644704febf4ab81f85daca488d1623c28e63
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x51e72dd1f2628295cc2ef931cb64fdbdc3a0c599
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xbbca42c60b5290f2c48871a596492f93ff0ddc82
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x555296de6a86e72752e5c5dc091fe49713aa145c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x0808bf94d57c905f1236212654268ef82e1e594e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x8457ca5040ad67fdebbcc8edce889a335bc0fbfb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xcebef3df1f3c5bfd90fde603e71f31a53b11944d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x90ed8f1dc86388f14b64ba8fb4bbd23099f18240
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x9840652dc04fb9db2c43853633f0f62be6f00f98
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xba2ae424d960c26247dd6c32edc70b295c744c43
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x0782b6d8c4551b9760e74c0545a9bcd90bdc41e5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xbe2b6c5e31f292009f495ddbda88e28391c9815e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x8f0528ce5ef7b51152a59745befdd91d97091d2f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xffeecbf8d7267757c2dc3d13d730e97e15bfdf7f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x0eb3a705fc54725037cc9e008bdede697f62f335
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xf21768ccbc73ea5b6fd3c687208a7c2def2d966e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x0000028a2eb8346cd5c0267856ab7594b7a55308
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x76a797a59ba2c17726896976b7b3747bfd1d220f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xc79d1fd14f514cd713b5ca43d288a782ae53eab2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xad29abb318791d579433d831ed122afeaf29dcfe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x3203c9e46ca618c8c1ce5dc67e7e9d75f5da2377
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xdb021b1b247fe2f1fa57e0a87c748cc1e321f07f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x7083609fce4d1d8dc0c979aab8c869ea2c873402
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xc5f0f7b66764f6ec8c8dff7ba683102295e16409
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xe29142e14e52bdfbb8108076f66f49661f10ec10
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xb0d502e938ed5f4df2e681fe6e419ff29631d62b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x6730f7a6bbb7b9c8e60843948f7feb4b6a17b7f7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x1613957159e9b0ac6c80e824f7eea748a32a0ae2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0x471ece3750da237f93b8e339c536989b8978a438
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0x765de816845861e75a25fca122bb6898b8b1282a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0x66803fb87abd4aac3cbb3fad7c3aa01f6f3fb207
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0xd8763cba276a3738e6de85b4b3bf5fded6d6ca73
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0x37f750b7cc259a2f741af45294f6a16572cf5cad
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0xd71ffd0940c920786ec4dbb5a12306669b5b81ef
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0xe8537a3d056da446677b9e9d6c5db704eaab4787
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0x4f604735c1cf31399c6e711d5962b2b3e0225ad3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0x02de4766c272abc10bc88c220d214a26960a7e92
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0xceba9300f2b948710d2653dd7b07f33a8b32118c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0xc16b81af351ba9e64c1a069e3ab18c244a1e3049
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x728f30fa2f100742c7949d1961804fa8e0b1387d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x41ea5d41eeacc2d5c4072260945118a13bb7ebce
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf21661d0d1d76d3ecb8e1b9f1c923dbfffae4097
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xb0ecc6ac0073c063dcfc026ccdc9039cae2998e1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x00f932f0fe257456b32deda4758922e56a4f4b42
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xa4af354d466e8a68090dd9eb2cb7caf162f4c8c2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xba50933c268f567bdc86e1ac131be072c6b0b71a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd29da236dd4aac627346e1bba06a619e8c22d7c5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1bfce574deff725a3f483c334b790e25c8fa9779
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x9e18d5bab2fa94a6a95f509ecb38f8f68322abd3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xbf5495efe5db9ce00f80364c8b423567e58d2110
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x065b4e5dfd50ac12a81722fd0a0de81d78ddf7fb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x57e114b691db790c35207b2e685d4a43181e6061
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x0b7f0e51cd1739d6c96982d55ad8fa634dd43a9c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xc56c7a0eaa804f854b536a5f3d5f49d2ec4b12b8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x594daad7d77592a2b97b725a7ad59d7e188b5bfa
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x8355dbe8b0e275abad27eb843f3eaf3fc855e525
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x2a961d752eaa791cbff05991e4613290aec0d9ac
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x38e68a37e401f7271568cecaac63c6b1e19130b4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1131d427ecd794714ed00733ac0f851e904c8398
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x1495bc9e44af1f8bcb62278d2bec4540cf0c05ea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x808507121b80c02388fad14726482e061b8da827
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x44971abf0251958492fee97da3e5c5ada88b9185
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x320623b8e4ff03373931769a31fc52a4e78b5d70
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x6e5970dbd6fc7eb1f29c6d2edf2bc4c36124c0c1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd40c688da9df74e03566eaf0a7c754ed98fbb8cc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x8afe4055ebc86bd2afb3940c0095c9aca511d852
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x9ce84f6a69986a83d92c324df10bc8e64771030f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xbe4d9c8c638b5f0864017d7f6a04b66c42953847
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x68bbed6a47194eff1cf514b50ea91895597fc91e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x69420e3a3aa9e17dea102bb3a9b3b73dcddb9528
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x7420b4b9a0110cdc71fb720908340c03f9bc03ec
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x03aa6298f1370642642415edc0db8b957783e8d6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd533a949740bb3306d119cc777fa900ba034cd52
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf14dd7b286ce197019cba54b189d2b883e70f761
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xa35923162c49cf95e6bf26623385eb431ad920d3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x8cefbeb2172a9382753de431a493e21ba9694004
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x120a3879da835a5af037bb2d1456bebd6b54d4ba
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x69457a1c9ec492419344da01daf0df0e0369d5d0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf6ce4be313ead51511215f1874c898239a331e37
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x73d7c860998ca3c01ce8c808f5577d94d545d1b4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xeff49b0f56a97c7fd3b51f0ecd2ce999a7861420
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x236501327e701692a281934230af0b6be8df3353
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x5026f006b85729a8b14553fae6af249ad16c9aab
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x66761fa41377003622aee3c7675fc7b5c1c2fac5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x9f9c8ec3534c3ce16f928381372bfbfbfb9f4d24
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xd8c978de79e12728e38aa952a6cb4166f891790f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x7122985656e38bdc0302db86685bb972b145bd3c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x582d872a1b094fc48f5de31d3b73f2d9be47def1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x504624040e0642921c2c266a9ac37cafbd8cda4e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xc548e90589b166e1364de744e6d35d8748996fe8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x4c11249814f11b9346808179cf06e71ac328c1b5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x423f4e6138e475d85cf7ea071ac92097ed631eea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0x8390a1da07e376ef7add4be859ba74fb83aa02d5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xf94e7d0710709388bce3161c32b4eea56d3f91cc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/ethereum/0xaa95f26e30001251fb905d264aa7b00ee9df6c18
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x2416092f143378750bb29b79ed961ab195cceea5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x6c84a8f1c29108f47a79964b5fe888d4f4d0de40
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x71eeba415a523f5c952cc2f06361d5443545ad28
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x88a269df8fe7f53e590c561954c52fccc8ec0cfb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x429fed88f10285e61b12bdf00848315fbdfcc341
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xb299751b088336e165da313c33e3195b8c6663a6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xf0a479c9c3378638ec603b8b6b0d75903902550b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xb59c8912c83157a955f9d715e556257f432c35d7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xba0dda8762c24da9487f5fa026a9b64b695a07ea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xc24a365a870821eb83fd216c9596edd89479d8d7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xa586b3b80d7e3e8d439e25fbc16bc5bcee3e2c85
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xef04804e1e474d3f9b73184d7ef5d786f3fce930
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x2e9a6df78e42a30712c10a9dc4b1c8656f8f2879
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x13a7dedb7169a17be92b0e3c7c2315b46f4772b3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0x1dd6b5f9281c6b4f043c02a83a46c2772024636c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xf525e73bdeb4ac1b0e741af3ed8a8cbb43ab0756
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xe4177c1400a8eee1799835dcde2489c6f0d5d616
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xed5740209fcf6974d6f3a5f11e295b5e468ac27c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/arbitrum/0xe10d4a4255d2d35c9e23e2c4790e073046fbaf5c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x10398abc267496e49106b07dd6be13364d10dc71
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x2218a117083f5b482b0bb821d27056ba9c04b1d3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x395ae52bb17aef68c2888d941736a71dc6d4e125
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/optimism/0x9a601c5bb360811d96a23689066af316a30c3027
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xbac3368b5110f3a3dda8b5a0f7b66edb37c47afe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x1d3c629ca5c1d0ab3bdf74600e81b4145615df8e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xe9c21de62c5c5d0ceacce2762bf655afdceb7ab3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x658cda444ac43b0a7da13d638700931319b64014
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x3d2bd0e15829aa5c362a4144fdf4a1112fa29b5c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x3fb83a9a2c4408909c058b0bfe5b4823f54fafe2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x00e5646f60ac6fb446f621d146b6e1886f002905
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x12a4cebf81f8671faf1ab0acea4e3429e42869e7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x9ff62d1fc52a907b6dcba8077c2ddca6e6a9d3e1
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0xc61f39418cd27820b5d4e9ba4a7197eefaeb8b05
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x15b7c0c907e4c6b9adaaaabc300c08991d6cea05
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x7f67639ffc8c93dd558d452b8920b28815638c44
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/polygon/0x276c9cbaa4bdf57d7109a41e67bd09699536fa3d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x041fdf3f472d2c8a7ecc458fc3b7f543e6c57ef7
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x3c281a39944a2319aa653d81cfd93ca10983d234
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x96419929d7949d6a801a6909c145c8eef6a40431
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xfea9dcdc9e23a9068bf557ad5b186675c61d33ea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xdb6e0e5094a25a052ab6845a9f1e486b9a9b3dde
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xcde172dc5ffc46d228838446c57c1227e0b82049
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xff0c532fdb8cd566ae169c1cb157ff2bdc83e105
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x9a26f5433671751c3276a065f57e5a02d2817973
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x3636a7734b669ce352e97780df361ce1f809c58c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x50c5725949a6f0c72e6c4a641f24049a917db0cb
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xe3086852a4b125803c815a158249ae468a3254ca
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xbeb0fd48c2ba0f1aacad2814605f09e08a96b94e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xbc45647ea894030a4e9801ec03479739fa2485f0
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x768be13e1680b5ebe0024c42c896e3db59ec0149
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x928a6a9fc62b2c94baf2992a6fba4715f5bb0066
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xbf4db8b7a679f89ef38125d5f84dd1446af2ea3b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xed899bfdb28c8ad65307fa40f4acab113ae2e14c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x1b6a569dd61edce3c383f6d565e2f79ec3a12980
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x76734b57dfe834f102fb61e1ebf844adf8dd931e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x4621b7a9c75199271f773ebd9a499dbd165c3191
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xaf07d812d1dcec20bf741075bc18660738d226dd
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x7f12d13b34f5f4f0a9449c16bcd42f0da47af200
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x55a6f6cb50db03259f6ab17979a4891313be2f45
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x968d6a288d7b024d5012c0b25d67a889e4e3ec19
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x7a8a5012022bccbf3ea4b03cd2bb5583d915fb1a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xcde90558fc317c69580deeaf3efc509428df9080
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x0028e1e60167b48a938b785aa5292917e7eaca8b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x76e7447bafa3f0acafc9692629b1d1bc937ca15d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x15ac90165f8b45a80534228bdcb124a011f62fee
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x4045b33f339a3027af80013fb5451fdbb01a4492
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xddf98aad8180c3e368467782cd07ae2e3e8d36a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x698dc45e4f10966f6d1d98e3bfd7071d8144c233
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x3c8665472ec5af30981b06b4e0143663ebedcc1e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x18a8bd1fe17a1bb9ffb39ecd83e9489cfd17a022
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xba0dda8762c24da9487f5fa026a9b64b695a07ea
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x13741c5df9ab03e7aa9fb3bf1f714551dd5a5f8a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xebff2db643cf955247339c8c6bcd8406308ca437
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xfadb26be94c1f959f900bf88cd396b3e803481d6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x52c2b317eb0bb61e650683d2f287f56c413e4cf6
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x38d513ec43dda20f323f26c7bef74c5cf80b6477
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x33ad778e6c76237d843c52d7cafc972bb7cf8729
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x290814ad0fbd2b935f34d7b40306102313d4c63e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x5e432eecd01c12ee7071ee9219c2477a347da192
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xbdf5bafee1291eec45ae3aadac89be8152d4e673
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xff62ddfa80e513114c3a0bf4d6ffff1c1d17aadf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8c81b4c816d66d36c4bf348bdec01dbcbc70e987
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x6b82297c6f1f9c3b1f501450d2ee7c37667ab70d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x42069babe14fb1802c5cb0f50bb9d2ad6fef55e2
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x72499bddb67f4ca150e1f522ca82c87bc9fb18c8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x0578d8a44db98b23bf096a382e016e29a5ce0ffe
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8fe815417913a93ea99049fc0718ee1647a2a07c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x7d12aeb5d96d221071d176980d23c213d88d9998
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xb166e8b140d35d9d8226e40c09f757bac5a4d87d
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8853f0c059c27527d33d02378e5e4f6d5afb574a
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xf3c052f2baab885c610a748eb01dfbb643ba835b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xcd1cffa8ebc66f1a2cf7675b48ba955ffcb82d8e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xde7a416ac821c77478340eebaa21b68297025ef3
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x2da56acb9ea78330f947bd57c54119debda7af71
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8972ab69d499b5537a31576725f0af8f67203d38
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x88faea256f789f8dd50de54f9c807eef24f71b16
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x42069de48741db40aef864f8764432bbccbd0b69
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x9a27c6759a6de0f26ac41264f0856617dec6bc3f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xfaa4f3bcfc87d791e9305951275e0f62a98bcb10
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xfd9fa4f785331ce88b5af8994a047ba087c705d8
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x21eceaf3bf88ef0797e3927d855ca5bb569a47fc
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x7d9ce55d54ff3feddb611fc63ff63ec01f26d15f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x4229c271c19ca5f319fb67b4bc8a40761a6d6299
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x80f45eacf6537498ecc660e4e4a2d2f99e195cf4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x1a475d06d967aeb686c98de80d079d72097aeacf
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x4fb9b20dafe45d91ae287f2e07b2e79709308178
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xd3741ac9b3f280b0819191e4b30be4ecd990771e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x09579452bc3872727a5d105f342645792bb8a82b
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x8a24d7260cd02d3dfd8eefb66bc17ad4b17d494c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xd88611a629265c9af294ffdd2e7fa4546612273e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x9a86980d3625b4a6e69d8a4606d51cbc019e2002
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x1c7a460413dd4e964f96d8dfc56e7223ce88cd85
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x776aaef8d8760129a0398cf8674ee28cefc0eab9
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x28e29ec91db66733a94ee8e3b86a6199117baf99
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xb9898511bd2bad8bfc23eba641ef97a08f27e730
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x76baa16ff15d61d32e6b3576c3a8c83a25c2f180
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x2816a491dd0b7a88d84cbded842a618e59016888
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0xa7ea9d5d4d4c7cf7dbde5871e6d108603c6942a5
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/base/0x586e10db93630a4d2da6c6a34ba715305b556f04
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xf486ad071f3bee968384d2e39e2d8af0fcf6fd46
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x76d36d44dc4595e8d2eb3ad745f175eda134284f
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x1fa4a73a3f0133f0025378af00236f3abdee5d63
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xb3ed0a426155b79b898849803e3b36552f7ed507
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x0ef4a107b48163ab4b57fca36e1352151a587be4
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x62694d43ccb9b64e76e38385d15e325c7712a735
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xa2b726b1145a4773f68593cf171187d8ebe4d495
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0xf275e1ac303a4c9d987a2c48b8e555a77fec3f1c
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/bnb/0x11a31b833d43853f8869c9eec17f60e3b4d2a753
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
0.8
https://app.uniswap.org/explore/tokens/celo/0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e
- 2024-05-20T17:20:52.753Z
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbadff0ef41d2a68f22de21eabca8a59aaf495cf0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1fdd61ef9a5c31b9a2abc7d39c139c779e8412af
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4ade2b180f65ed752b6f1296d0418ad21eb578c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0c5cb676e38d6973837b9496f6524835208145a2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb69753c06bb5c366be51e73bfc0cc2e3dc07e371
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8143182a775c54578c8b7b3ef77982498866945d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x76e222b07c53d28b89b0bac18602810fc22b49a8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x18aaa7115705e8be94bffebde57af9bfc265b998
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7d8146cf21e8d7cbe46054e01588207b51198729
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfe0c30065b384f05761f15d0cc899d4f9f9cc0eb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1ce270557c1f68cfb577b856766310bf8b47fd9c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x793a5d8b30aab326f83d20a9370c827fea8fdc51
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xff836a5821e69066c87e268bc51b849fab94240c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf4d2888d29d722226fafa5d9b24f9164c092421e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8ed97a637a790be1feff5e888d43629dc05408f6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x31c8eacbffdd875c74b94b077895bd78cf1e64a3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc55126051b22ebb829d00368f4b12bde432de5da
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xe0f63a424a4439cbe457d80e4f4b51ad25b2c56c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8881562783028f5c1bcb985d2283d5e170d88888
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x67466be17df832165f8c80a5a120ccc652bd7e69
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd939212f16560447ed82ce46ca40a63db62419b5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x88417754ff7062c10f4e3a4ab7e9f9d9cbda6023
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5afe3855358e112b5647b952709e6165e1c1eeee
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x02e7f808990638e9e67e1f00313037ede2362361
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd2bdaaf2b9cc6981fd273dcb7c04023bfbe0a7fe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x112b08621e27e10773ec95d250604a041f36c582
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x32b053f2cba79f80ada5078cb6b305da92bde6e1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5ac34c53a04b9aaa0bf047e7291fb4e8a48f2a18
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x26ebb8213fb8d66156f1af8908d43f7e3e367c1d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xe3b9cfb8ea8a4f1279fbc28d3e15b4d2d86f18a0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8207c1ffc5b6804f6024322ccf34f29c3541ae26
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x255f1b39172f65dc6406b8bee8b08155c45fe1b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x092baadb7def4c3981454dd9c0a0d7ff07bcfc86
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x53bcf6698c911b2a7409a740eacddb901fc2a2c6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x2ac2b254bc18cd4999f64773a966e4f4869c34ee
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x17fc002b466eec40dae837fc4be5c67993ddbd6f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xc8a4eea31e9b6b61c406df013dd4fec76f21e279
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x498bf2b1e120fed3ad3d42ea2165e9b73f99c1e5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xe4dddfe67e7164b0fe14e218d80dc4c08edc01cb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x7c8a1a80fdd00c9cccd6ebd573e9ecb49bfa2a59
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x1debd73e752beaf79865fd6446b0c970eae7732f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xaf5db6e1cc585ca312e8c8f7c499033590cf5c98
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x65559aa14915a70190438ef90104769e5e890a00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x7fb688ccf682d58f86d7e38e03f9d22e7705448b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x73cb180bf0521828d8849bc8cf2b920918e23032
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x2e3d870790dc77a83dd1d18184acc7439a53f475
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0xa00e3a3511aac35ca78530c85007afcd31753819
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x528cdc92eab044e1e39fe43b9514bfdab4412b98
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x4f604735c1cf31399c6e711d5962b2b3e0225ad3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x1c954e8fe737f99f68fa1ccda3e51ebdb291948c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xf50d05a1402d0adafa880d36050736f9f6ee7dee
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xab0b2ddb9c7e440fac8e140a89c0dbcbf2d7bbff
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x8bc3ec2e7973e64be582a90b08cadd13457160fe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x64060ab139feaae7f06ca4e63189d86adeb51691
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x5ec03c1f7fa7ff05ec476d19e34a22eddb48acdc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x9627a3d6872be48410fcece9b1ddd344bf08c53e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x1ed02954d60ba14e26c230eec40cbac55fa3aeea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8d3419b9a18651f3926a205ee0b1acea1e7192de
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb56d0839998fd79efcd15c27cf966250aa58d6d3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x81f91fe59ee415735d59bd5be5cca91a0ea4fa69
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x87c211144b1d9bdaa5a791b8099ea4123dc31d21
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf4210f93bc68d63df3286c73eba08c6414f40c0d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xece7b98bd817ee5b1f2f536daf34d0b6af8bb542
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4c96a67b0577358894407af7bc3158fc1dffbeb5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x70737489dfdf1a29b7584d40500d3561bd4fe196
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x39353a32eceafe4979a8606512c046c3b6398cc4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x92fb1b7d9730b2f1bd4e2e91368c1eb6fdd2a009
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x174e33ef2effa0a4893d97dda5db4044cc7993a3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xfdc944fb59201fb163596ee5e209ebc8fa4dcdc5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x388e543a5a491e7b42e3fbcd127dd6812ea02d0d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x56a38e7216304108e841579041249feb236c887b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1804e3db872eed4141e482ff74c56862f2791103
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9de16c805a3227b9b92e39a446f9d56cf59fe640
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb8d98a102b0079b69ffbc760c8d857a31653e56e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x5d6812722c3693078e4a0dbe3e9affc27a0b2768
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x255f1b39172f65dc6406b8bee8b08155c45fe1b6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc2fe011c3885277c7f0e7ffd45ff90cadc8ecd12
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc1ffaef4e7d553bbaf13926e258a1a555a363a07
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4e73420dcc85702ea134d91a262c8ffc0a72aa70
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xecaf81eb42cd30014eb44130b89bcd6d4ad98b92
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x4eae52907dba9c370e9ee99f0ce810602a4f2c63
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x25d887ce7a35172c62febfd67a1856f20faebb00
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x382ea807a61a418479318efd96f1efbc5c1f2c21
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6468e79a80c0eab0f9a2b574c8d5bc374af59414
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3106a0a076bedae847652f42ef07fd58589e001f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd015422879a1308ba557510345e944b912b9ab73
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5de8ab7e27f6e7a1fff3e5b337584aa43961beef
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcf078da6e85389de507ceede0e3d217e457b9d49
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1bbf25e71ec48b84d773809b4ba55b6f4be946fb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7039cd6d7966672f194e8139074c3d5c4e6dcf65
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x943af17c37207c9d7a27d12cb5055542a0b7afa8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6d68015171eaa7af9a5a0a103664cf1e506ff699
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6942806d1b2d5886d95ce2f04314ece8eb825833
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x949d48eca67b17269629c7194f4b727d4ef9e5d6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9361adf2b72f413d96f81ff40d794b47ce13b331
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3bb1be077f3f96722ae92ec985ab37fd0a0c4c51
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xdbb7a34bf10169d6d2d0d02a6cbb436cf4381bfa
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x66bff695f3b16a824869a8018a3a6e3685241269
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x85d19fb57ca7da715695fcf347ca2169144523a7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x069d89974f4edabde69450f9cf5cf7d8cbd2568d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0fe13ffe64b28a172c58505e24c0c111d149bd47
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x111111111117dc0aa78b770fa6a738034120c302
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xdc7ac5d5d4a9c3b5d8f3183058a92776dc12f4f3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x482702745260ffd69fc19943f70cffe2cacd70e9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc555d625828c4527d477e595ff1dd5801b4a600e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9eec1a4814323a7396c938bc86aec46b97f1bd82
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x87d73e916d7057945c9bcd8cdd94e42a6f47f776
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x067def80d66fb69c276e53b641f37ff7525162f6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xdd157bd06c1840fa886da18a138c983a7d74c1d7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xe80772eaf6e2e18b651f160bc9158b2a5cafca65
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xb6093b61544572ab42a0e43af08abafd41bf25a6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x35ca1e5a9b1c09fa542fa18d1ba4d61c8edff852
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x83e60b9f7f4db5cdb0877659b1740e73c662c55b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x4d01397994aa636bdcc65c9e8024bc497498c3bb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xc3abc47863524ced8daf3ef98d74dd881e131c38
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x4d15a3a2286d883af0aa1b3f21367843fac63e07
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xfb7f8a2c0526d01bfb00192781b7a7761841b16c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x3809dcdd5dde24b37abe64a5a339784c3323c44f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x85955046df4668e1dd369d2de9f3aeb98dd2a369
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x554cd6bdd03214b10aafa3e0d4d42de0c5d2937b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x4318cb63a2b8edf2de971e2f17f77097e499459d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xab9cb20a28f97e189ca0b666b8087803ad636b3c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x6a8ec2d9bfbdd20a7f5a4e89d640f7e7ceba4499
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x385eeac5cb85a38a9a07a70c73e0a3271cfb54a7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x0169ec1f8f639b32eec6d923e24c2a2ff45b9dd6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xe161be4a74ab8fa8706a2d03e67c02318d0a0ad6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4d58608eff50b691a3b76189af2a7a123df1e9ba
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x420b0fa3de2efcf2b2fd04152eb1df36a09717cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1cd38856ee0fdfd65c757e530e3b1de3061008d3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xfad8cb754230dbfd249db0e8eccb5142dd675a0d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xda761a290e01c69325d12d82ac402e5a73d62e81
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xafb5d4d474693e68df500c9c682e6a2841f9661a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0b3e328455c4059eeb9e3f84b5543f74e24e7e1b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xfc5462143a3178cf044e97c491f6bcb5e38f173e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xed1978d01d4a8a9d6a43ac79403d5b8dfbed739b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xba71cb8ef2d59de7399745793657838829e0b147
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x10c1b6f768e13c624a4a23337f1a5ba5c9be0e4b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1b1514c76c54ce8807d7fdedf85c664eee734ece
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x58cd93c4a91c3940109fa27d700f5013b18b5dc2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xea6f7e7e0f46a9e0f4e2048eb129d879f609d632
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x30d19fb77c3ee5cfa97f73d72c6a1e509fa06aef
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xe2dca969624795985f2f083bcd0b674337ba130a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xbb7d61d2511fd2e63f02178ca9b663458af9fc63
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x59f4f336bf3d0c49dbfba4a74ebd2a6ace40539a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x62d0a8458ed7719fdaf978fe5929c6d342b0bfce
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb8fda5aee55120247f16225feff266dfdb381d4c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xca530408c3e552b020a2300debc7bd18820fb42f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3ffeea07a27fab7ad1df5297fa75e77a43cb5790
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcfeb09c3c5f0f78ad72166d55f9e6e9a60e96eec
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x467bccd9d29f223bce8043b84e8c8b282827790f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2077d81d0c5258230d5a195233941547cb5f0989
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa0bbbe391b0d0957f1d013381b643041d2ca4022
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd1b89856d82f978d049116eba8b7f9df2f342ff3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x62f03b52c377fea3eb71d451a95ad86c818755d1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3927fb89f34bbee63351a6340558eebf51a19fb8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xacd2c239012d17beb128b0944d49015104113650
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x86b69f38bea3e02f68ff88534bc61ec60e772b19
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6873c95307e13beb58fb8fcddf9a99667655c9e4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x18084fba666a33d37592fa2633fd49a74dd93a88
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6e79b51959cf968d87826592f46f819f92466615
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x80ee5c641a8ffc607545219a3856562f56427fe9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0414d8c87b271266a5864329fb4932bbe19c0c49
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf57e7e7c23978c3caec3c3548e3d615c346e79ff
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x1c986661170c1834db49c3830130d4038eeeb866
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x9ed7e4b1bff939ad473da5e7a218c771d1569456
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x7f9a7db853ca816b9a138aee3380ef34c437dee0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x371c7ec6d8039ff7933a2aa28eb827ffe1f52f07
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xb1bc21f748ae2be95674876710bc6d78235480e0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xadf5dd3e51bf28ab4f07e684ecf5d00691818790
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x1eba7a6a72c894026cd654ac5cdcf83a46445b08
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x38022a157b95c52d43abcac9bd09f028a1079105
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xd2507e7b5794179380673870d88b22f94da6abe0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xc708d6f2153933daa50b2d0758955be0a93a8fec
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x0052074d3eb1429f39e5ea529b54a650c21f5aa4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x4e78011ce80ee02d2c3e649fb657e45898257815
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x7583feddbcefa813dc18259940f76a02710a8905
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xe78aee6ccb05471a69677fb74da80f5d251c042b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x04f177fcacf6fb4d2f95d41d7d3fee8e565ca1d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xa6da8c8999c094432c77e7d318951d34019af24b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x6d3b8c76c5396642960243febf736c6be8b60562
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7cf7132ede0ca592a236b6198a681bb7b42dd5ae
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x3afeae00a594fbf2e4049f924e3c6ac93296b6e8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0a93a7be7e7e426fc046e204c44d6b03a302b631
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc9b6ef062fab19d3f1eabc36b1f2e852af1acd18
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1754e5aadce9567a95f545b146a616ce34eead53
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xdb173587d459ddb1b9b0f2d6d88febef039304a2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x10a7a84c91988138f8dbbc82a23b02c8639e2552
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x92af6f53febd6b4c6f5293840b6076a1b82c4bc2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xeb9e49fb4c33d9f6aefb1b03f9133435e24c0ec6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1b2c141479757b8643a519be4692904088d860b2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4d25e94291fe8dcfbfa572cbb2aaa7b755087c91
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8e0e798966382e53bfb145d474254cbe065c17dc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4b6f82a4ed0b9e3767f53309b87819a78d041a7f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x004aa1586011f3454f487eac8d0d5c647d646c69
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x741777f6b6d8145041f73a0bddd35ae81f55a40f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xc6c58f600917de512cd02d2b6ed595ab54b4c30f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x03aa6298f1370642642415edc0db8b957783e8d6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x3ee2200efb3400fabb9aacf31297cbdd1d435d47
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x0d8ce2a99bb6e3b7db580ed848240e4a0f9ae153
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xa697e272a73744b343528c3bc4702f2565b2f422
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x301af3eff0c904dc5ddd06faa808f653474f7fcc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x776f9987d9deed90eed791cbd824d971fd5ccf09
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xf7de7e8a6bd59ed41a4b5fe50278b3b7f31384df
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x19e6bfc1a6e4b042fb20531244d47e252445df01
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x4338665cbb7b2485a8855a139b75d5e34ab0db94
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x2940566eb50f15129238f4dc599adc4f742d7d8e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xbb73bb2505ac4643d5c0a99c2a1f34b3dfd09d11
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x4ea98c1999575aaadfb38237dd015c5e773f75a2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/celo/0x1d18d0386f51ab03e7e84e71bda1681eba865f1f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x57b96d4af698605563a4653d882635da59bf11af
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd33526068d116ce69f19a9ee46f0bd304f21a51f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2a5fa016ffb20c70e2ef36058c08547f344677aa
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbe0ed4138121ecfc5c0e56b40517da27e6c5226b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9fd9278f04f01c6a39a9d1c1cd79f7782c6ade08
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x054c9d4c6f4ea4e14391addd1812106c97d05690
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7613c48e0cd50e42dd9bf0f6c235063145f6f8dc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x614da3b37b6f66f7ce69b4bbbcf9a55ce6168707
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x069e4aa272d17d9625aa3b6f863c7ef6cfb96713
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x24da31e7bb182cb2cabfef1d88db19c2ae1f5572
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7d4a23832fad83258b32ce4fd3109ceef4332af4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb58e61c3098d85632df34eecfb899a1ed80921cb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x67c4d14861f9c975d004cfb3ac305bee673e996e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x69babe9811cc86dcfc3b8f9a14de6470dd18eda4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x32f0d04b48427a14fb3cbc73db869e691a9fec6f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4cff49d0a19ed6ff845a9122fa912abcfb1f68a6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x51cb253744189f11241becb29bedd3f1b5384fdb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcf4c91ecafc43c9f382db723ba20b82efa852821
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6968676661ac9851c38907bdfcc22d5dd77b564d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0d438f3b5175bebc262bf23753c1e53d03432bde
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb98d4c97425d9908e66e53a6fdf673acca0be986
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x68a47fe1cf42eba4a030a10cd4d6a1031ca3ca0a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8a370c951f34e295b2655b47bb0985dd08d8f718
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x525574c899a7c877a11865339e57376092168258
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd9a442856c234a39a81a089c06451ebaa4306a72
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x1c43d05be7e5b54d506e3ddb6f0305e8a66cd04e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xb766039cc6db368759c1e56b79affe831d0cc507
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x18c14c2d707b2212e17d1579789fc06010cfca23
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xe0ee18eacafddaeb38f8907c74347c44385578ab
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x56659245931cb6920e39c189d2a0e7dd0da2d57b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xb6a5ae40e79891e4deadad06c8a7ca47396df21c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x04565fe9aa3ae571ada8e1bebf8282c4e5247b2a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf8a99f2bf2ce5bb6ce4aafcf070d8723bc904aa2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x3b9728bd65ca2c11a817ce39a6e91808cceef6fd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x6797b6244fa75f2e78cdffc3a4eb169332b730cc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xe2c86869216ac578bd62a4b8313770d9ee359a05
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x47b464edb8dc9bc67b5cd4c9310bb87b773845bd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x28a730de97dc62a8c88363e0b1049056f1274a70
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xba5ede8d98ab88cea9f0d69918dde28dc23c2553
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8319767a7b602f88e376368dca1b92d38869b9b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x461ee40928677644b8195662ab91bcdaae6ef105
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x24569d33653c404f90af10a2b98d6e0030d3d267
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x22222bd682745cf032006394750739684e45a5f8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9124577428c5bd73ad7636cbc5014081384f29d6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xaa6cccdce193698d33deb9ffd4be74eaa74c4898
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xe095780ba2a64a4efa7a74830f0b71656f0b0ad4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb59c8912c83157a955f9d715e556257f432c35d7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7771450ece9c61430953d2646f995e33a06c91f5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc48823ec67720a04a9dfd8c7d109b2c3d6622094
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x9ec02756a559700d8d9e79ece56809f7bcc5dc27
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3593d125a4f7849a1b059e64f4517a86dd60c95d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6985884c4392d348587b19cb9eaaf157f13271cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa045fe936e26e1e1e1fb27c1f2ae3643acde0171
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbeef698bd78139829e540622d5863e723e8715f1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x426a688ee72811773eb64f5717a32981b56f10c1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x873259322be8e50d80a4b868d186cc5ab148543a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x661c70333aa1850ccdbae82776bb436a0fcfeefb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0a2c375553e6965b42c135bb8b15a8914b08de0c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6fba952443be1de22232c824eb8d976b426b3c38
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1abaea1f7c830bd89acc67ec4af516284b1bc33c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb62132e35a6c13ee1ee0f84dc5d40bad8d815206
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb60fdf036f2ad584f79525b5da76c5c531283a1b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5a3e6a77ba2f983ec0d371ea3b475f8bc0811ad5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x55296f69f40ea6d20e478533c15a6b08b654e758
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1a7e4e63778b4f12a199c062f3efdd288afcbce8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x45804880de22913dafe09f4980848ece6ecbaf78
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xe5018913f2fdf33971864804ddb5fca25c539032
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x6985884c4392d348587b19cb9eaaf157f13271cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x2c650dab03a59332e2e0c0c4a7f726913e5028c1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x9aee3c99934c88832399d6c6e08ad802112ebeab
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x439c0cf1038f8002a4cad489b427e217ba4b42ad
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x6985884c4392d348587b19cb9eaaf157f13271cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x6985884c4392d348587b19cb9eaaf157f13271cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x6985884c4392d348587b19cb9eaaf157f13271cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb79dd08ea68a908a97220c76d19a6aa9cbde4376
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4b61e2f1bbdee6d746209a693156952936f1702c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7480527815ccae421400da01e052b120cc4255e9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7466de7bb8b5e41ee572f4167de6be782a7fa75d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x298d411511a05dc1b559ed8f79c56bee06687b14
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8e16d46cb2da01cdd49601ec73d7b0344969ae33
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x18dd5b087bca9920562aff7a0199b96b9230438b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x37f0c2915cecc7e977183b8543fc0864d03e064c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x37f24b26bcefbfac7f261b97f8036da98f81a299
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xacb5b33ce55ba7729e38b2b59677e71c0112f0d9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x6985884c4392d348587b19cb9eaaf157f13271cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xc71b5f631354be6853efe9c3ab6b9590f8302e81
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7e744bbb1a49a44dfcc795014a4ba618e418fbbe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4e3fbd56cd56c3e72c1403e103b45db9da5b9d2b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0c04ff41b11065eed8c9eda4d461ba6611591395
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x636bd98fc13908e475f56d8a38a6e03616ec5563
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x590246bfbf89b113d8ac36faeea12b7589f7fe5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x80034f803afb1c6864e3ca481ef1362c54d094b9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x73fbd93bfda83b111ddc092aa3a4ca77fd30d380
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xff33a6b3dc0127862eedd3978609404b22298a54
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc770eefad204b5180df6a14ee197d99d808ee52d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa0385e7283c83e2871e9af49eec0966088421ddd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb2617246d0c6c0087f18703d576831899ca94f01
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xba386a4ca26b85fd057ab1ef86e3dc7bdeb5ce70
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9ebb0895bd9c7c9dfab0d8d877c66ba613ac98ea
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd12a99dbc40036cec6f1b776dccd2d36f5953b94
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8ab2ff0116a279a99950c66a12298962d152b83c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x420698cfdeddea6bc78d59bc17798113ad278f9d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa8c8cfb141a3bb59fea1e2ea6b79b5ecbcd7b6ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd8e8438cf7beed13cfabc82f300fb6573962c9e3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb1c9d42fa4ba691efe21656a7e6953d999b990c4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xdadeca1167fe47499e53eb50f261103630974905
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xa05245ade25cc1063ee50cf7c083b4524c1c4302
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x4fafad147c8cd0e52f83830484d164e960bdc6c3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4dd9077269dd08899f2a9e73507125962b5bc87f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8931ee05ec111325c1700b68e5ef7b887e00661d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x26f1bb40ea88b46ceb21557dc0ffac7b7c0ad40f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x642e993fa91ffe9fb24d39a8eb0e0663145f8e92
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0c41f1fc9022feb69af6dc666abfe73c9ffda7ce
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf7ccb8a6e3400eb8eb0c47619134f7516e025215
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x2416092f143378750bb29b79ed961ab195cceea5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf0268c5f9aa95baf5c25d646aabb900ac12f0800
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0c067fc190cde145b0c537765a78d4e19873a5cc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xbe5614875952b1683cb0a2c20e6509be46d353a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x87a0233a8cb4392ec3eb8fa467817fc0b6a326dd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xdfbea88c4842d30c26669602888d746d30f9d60d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb6fe221fe9eef5aba221c348ba20a1bf5e73624c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x80b3455e1db60b4cba46aba12e8b1e256dd64979
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x747747e47a48c669be384e0dfb248eee6ba04039
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/celo/0x50e85c754929840b58614f48e29c64bc78c58345
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x02f92800f57bcd74066f5709f1daa1a4302df875
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x967da4048cd07ab37855c090aaf366e4ce1b9f48
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x729031b3995538ddf6b6bce6e68d5d6fdeb3ccb5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6dea81c8171d0ba574754ef6f8b412f2ed88c54d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x97a9a15168c22b3c137e6381037e1499c8ad0978
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5faa989af96af85384b8a938c2ede4a7378d9875
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4691937a7508860f876c9c0a2a617e7d9e945d4b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x037a54aab062628c9bbae1fdb1583c195585fe41
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xcb8b5cd20bdcaea9a010ac1f8d835824f5c87a04
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xdfb8be6f8c87f74295a87de951974362cedcfa30
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x354a6da3fcde098f8389cad84b0182725c6c91de
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x3f56e0c36d275367b8c502090edf38289b3dea0d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x6f9590958ce2beaf9c92a3a8fca6d1ddf310e052
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x3e5d9d8a63cc8a88748f229999cf59487e90721e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0xecc68d0451e20292406967fe7c04280e5238ac7d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xf1c1a3c2481a3a8a3f173a9ab5ade275292a6fa3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xb5e0cfe1b4db501ac003b740665bf43192cc7853
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xffa188493c15dfaf2c206c97d8633377847b6a52
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xb5c064f955d8e7f38fe0460c556a72987494ee17
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x4f604735c1cf31399c6e711d5962b2b3e0225ad3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xf0949dd87d2531d665010d6274f06a357669457a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x14e5386f47466a463f85d151653e1736c0c50fc3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xadac33f543267c4d59a8c299cf804c303bc3e4ac
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xcfa3ef56d303ae4faaba0592388f19d7c3399fb4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x67ce18961c3269ca03c2e5632f1938cc53e614a1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x48164ea5df090e80a0eaee1147e466ea28669221
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x3054e8f8fba3055a42e5f5228a2a4e2ab1326933
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x42069d11a2cc72388a2e06210921e839cfbd3280
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x74ff3cbf86f95fea386f79633d7bc4460d415f34
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x2d6a3893966dda77749cc7e4003ab15f5cfa3cc1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x51b75da3da2e413ea1b8ed3eb078dc712304761c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8ad5b9007556749de59e088c88801a3aaa87134b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xbd97693278f1948c59f65f130fd87e7ff7c61d11
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x3992b27da26848c2b19cea6fd25ad5568b68ab98
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x34980c35353a8d7b1a1ba02e02e387a8383e004a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xdebd6e2da378784a69dc6ec99fe254223b312287
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/celo/0x456a3d042c0dbd3db53d5489e98dfb038553b0d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/celo/0x9995cc8f20db5896943afc8ee0ba463259c931ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x30d20208d987713f46dfd34ef128bb16c404d10f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x19848077f45356b21164c412eff3d3e4ff6ebc31
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x53206bf5b6b8872c1bb0b3c533e06fde2f7e22e4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x07ddacf367f0d40bd68b4b80b4709a37bdc9f847
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbdbe9f26918918bd3f43a0219d54e5fda9ce1bb3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb9d09bc374577dac1ab853de412a903408204ea8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xe72b141df173b999ae7c1adcbf60cc9833ce56a8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x214549b0317564de15770561221433fb3e8c995c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc82e3db60a52cf7529253b4ec688f631aad9e7c2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf3dcbc6d72a4e1892f7917b7c43b74131df8480e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x62e3b3c557c792c4a70765b3cdb5b56b1879f82d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2598c30330d5771ae9f983979209486ae26de875
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd4f4d0a10bcae123bb6655e8fe93a30d01eebd04
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xa0995d43901551601060447f9abf93ebc277cec2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x40379a439d4f6795b6fc9aa5687db461677a2dba
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x433cde5a82b5e0658da3543b47a375dffd126eb6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x619c4bbbd65f836b78b36cbe781513861d57f39d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1e0bb24ed6c806c01ef2f880a4b91adb90099ea7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0dd7913197bfb6d2b1f03f9772ced06298f1a644
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xfbb75a59193a3525a8825bebe7d4b56899e2f7e1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc3de830ea07524a0761646a6a4e4be0e114a3c83
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x3792dbdd07e87413247df995e692806aa13d3299
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x527856315a4bcd2f428ea7fa05ea251f7e96a50a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x292fcdd1b104de5a00250febba9bc6a5092a0076
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd749b369d361396286f8cc28a99dd3425ac05619
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfe3e6a25e6b192a42a44ecddcd13796471735acf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa1faa113cbe53436df28ff0aee54275c13b40975
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8802269d1283cdb2a5a329649e5cb4cdcee91ab6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0000bdaa645097ef80f9d475f341d0d107a45b3a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x683a4ac99e65200921f556a19dadf4b0214b5938
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x36c7188d64c44301272db3293899507eabb8ed43
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8a2279d4a90b6fe1c4b30fa660cc9f926797baa2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf418588522d5dd018b425e472991e52ebbeeeeee
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6135177a17e02658df99a07a2841464deb5b8589
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcf91b70017eabde82c9671e30e5502d312ea6eb2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x45080a6531d671ddff20db42f93792a489685e32
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x790814cd782983fab4d7b92cf155187a865d9f18
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9e6be44cc1236eef7e1f197418592d363bedcd5a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xaa7a9ca87d3694b5755f213b5d04094b8d0f0a6f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x69ee720c120ec7c9c52a625c04414459b3185f23
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x408e41876cccdc0f92210600ef50372656052a38
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5cf04716ba20127f1e2297addcf4b5035000c9eb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8290333cef9e6d528dd5618fb97a76f268f3edd4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1929761e87667283f087ea9ab8370c174681b4e9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x888888848b652b3e3a0f34c96e00eec0f3a23f72
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf944e35f95e819e752f3ccb5faf40957d311e8c5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1f70300bce8c2302780bd0a153ebb75b8ca7efcb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x3de81ce90f5a27c5e6a5adb04b54aba488a6d14e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xc87b37a581ec3257b734886d9d3a581f5a9d056c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x1a6b3a62391eccaaa992ade44cd4afe6bec8cff1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x65c936f008bc34fe819bce9fa5afd9dc2d49977f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x07d65c18cecba423298c0aeb5d2beded4dfd5736
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x51fc0f6660482ea73330e414efd7808811a57fa2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xcbe94d75ec713b7ead84f55620dc3174beeb1cfe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xd3144ff5f388d36c0a445686c08540296d8b209b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x433e39ce74aef8f409182541269e417ad9b56011
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb1a03eda10342529bbf8eb700a06c60441fef25d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x6b9bb36519538e0c073894e964e90172e1c0b41f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x689644b86075ed61c647596862c7403e1c474dbf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9a6d24c02ec35ad970287ee8296d4d6552a31dbe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x506beb7965fc7053059006c7ab4c62c02c2d989f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x31b28012f61fc3600e1c076bafc9fd997fb2da90
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xd7d919ea0c33a97ad6e7bd4f510498e2ec98cb78
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xef553b6914dbd17567393f7e55fbd773fff7d0cb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xe642657e4f43e6dcf0bd73ef24008394574dee28
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf8b1b47aa748f5c7b5d0e80c726a843913eb573a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xd064c53f043d5aee2ac9503b13ee012bf2def1d0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xfc60aa1ffca50ce08b3cdec9626c0bb9e9b09bec
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x82c8f48ac694841360de84d649a0d48d239b61f8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7d89e05c0b93b24b5cb23a073e60d008fed1acf9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7546e0d4d947a15f914e33de6616ffed826f45ef
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x9a5350edf28c1f93bb36d6e94b5c425fde8e222d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xaa076b62efc6f357882e07665157a271ab46a063
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6a6aa13393b7d1100c00a57c76c39e8b6c835041
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x07040971246a73ebda9cf29ea1306bb47c7c4e76
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6df0e641fc9847c0c6fde39be6253045440c14d3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2b640a99991dea2916205ecdc9f9c58f80017ed8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x38e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x42069cc15f5befb510430d22ff1c9a1b3ae22cfe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x89fd2d8fd8d937f55c89b7da3ceed44fa27e4a81
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x76bc677d444f1e9d57daf5187ee2b7dc852745ae
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa0084063ea01d5f09e56ef3ff6232a9e18b0bacd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4abd5745f326932b1b673bfa592a20d7bb6bc455
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xe53ec727dbdeb9e2d5456c3be40cff031ab40a55
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf43f21384d03b5cbbddd58d2de64071e4ce76ab0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x33349b282065b0284d756f0577fb39c158f935e6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x33c88d4cac6ac34f77020915a2a88cd0417dc069
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xdce765f021410b3266aa0053c93cb4535f1e12e0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xb50a8e92cb9782c9b8f3c88e4ee8a1d0aa2221d7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x0a84edf70f30325151631ce7a61307d1f4d619a3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xc11158c5da9db1d553ed28f0c2ba1cbedd42cfcb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0xb0b195aefa3650a6908f15cdac7d92f8a5791b0b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xdc4f4ed9872571d5ec8986a502a0d88f3a175f1e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9beec80e62aa257ced8b0edd8692f79ee8783777
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf95e1c0a67492720ca22842122fe7fa63d5519e5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xca8e8d244f0d219a6fc9e4793c635cea98d0399c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x6a4f69da1e2fb2a9b11d1aad60d03163fe567732
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0718f45bbf4781ce891e4e18182f025725f0fc95
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x132bbda4a40d4d6288be49b637ec2c113b5d7600
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9aaae745cf2830fb8ddc6248b17436dc3a5e701c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x24fcfc492c1393274b6bcd568ac9e225bec93584
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x21fd16cd0ef24a49d28429921e335bb0c1bfadb3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa469b7ee9ee773642b3e93e842e5d9b5baa10067
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8c19f7854b27758ddffdcdc8908f22bf55e00736
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xf2ae0038696774d65e67892c9d301c5f2cbbda58
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x6bc40d4099f9057b23af309c08d935b890d7adc0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xee2a03aa6dacf51c18679c516ad5283d8e7c2637
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7f911119435d8ded9f018194b4b6661331379a3d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x777be1c6075c20184c4fd76344b7b0b7c858fe6b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x812ba41e071c7b7fa4ebcfb62df5f45f6fa853ee
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x881d4c8618d68872fa404518b2460ea839a02a6a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xba2ae4e0a9c6ecaf172015aa2cdd70a21f5a290b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1caf237d7a2d103e3e9b1855988c01ac10344600
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7d4a7be025652995364e0e232063abd9e8d65e6e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x620aa20875ec1144126ea47fb27ecfe6e10d0c56
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfae103dc9cf190ed75350761e95403b7b8afa6c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xae7ab96520de3a18e5e111b5eaab095312d7fe84
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x04c154b66cb340f3ae24111cc767e0184ed00cc6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x70e8de73ce538da2beed35d14187f6959a8eca96
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfb7b4564402e5500db5bb6d63ae671302777c75a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6810e776880c02933d47db1b9fc05908e5386b96
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x11e969e9b3f89cb16d686a03cd8508c9fc0361af
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x8b5d1d8b3466ec21f8ee33ce63f319642c026142
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x3ed03e95dd894235090b3d4a49e0c3239edce59e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xb3f13b0c61d65d67d7d6215d70c89533ee567a91
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xfea31d704deb0975da8e77bf13e04239e70d7c28
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x66e535e8d2ebf13f49f3d49e5c50395a97c137b1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x9a06db14d639796b25a6cec6a1bf614fd98815ec
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7fdd7419428955dbf36d4176af5a8f09ad29d1f3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8c9037d1ef5c6d1f6816278c7aaf5491d24cd527
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xa9f5031b54c44c3603b4300fde9b8f5cd18ad06f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x57f5fbd3de65dfc0bd3630f732969e5fb97e6d37
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9ef1139e6b420cc929dd912a5a7adeced6f12e91
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x120edc8e391ba4c94cb98bb65d8856ae6ec1525f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xd7ea82d19f1f59ff1ae95f1945ee6e6d86a25b96
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x2c9ab600d71967ff259c491ad51f517886740cbc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xf4c8e32eadec4bfe97e0f595add0f4450a863a11
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x8c49a510756224e887b3d99d00d959f2d86dda1c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7777cec341e7434126864195adef9b05dcc3489c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x19af07b52e5faa0c2b1e11721c52aa23172fe2f5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb7109df1a93f8fe2b8162c6207c9b846c1c68090
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbbc2ae13b23d715c30720f079fcd9b4a74093505
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x595832f8fc6bf59c85c527fec3740a1b7a361269
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7316d973b0269863bbfed87302e11334e25ea565
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa0b73e1ff0b80914ab6fe0444e65848c4c34450b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2be8e422cb4a5a7f217a8f1b0658952a79132f28
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x83e6f1e41cdd28eaceb20cb649155049fac3d5aa
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbabe3ce7835665464228df00b03246115c30730a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2e6a60492fb5b58f5b5d08c7cafc75e740e6dc8e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc08e7e23c235073c6807c2efe7021304cb7c2815
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x955d5c14c8d4944da1ea7836bd44d54a8ec35ba1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3540abe4f288b280a0740ad5121aec337c404d15
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfe8526a77a2c3590e5973ba81308b90bea21fbff
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd807f7e2818db8eda0d28b5be74866338eaedb86
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x4186bfc76e2e237523cbc30fd220fe055156b41f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xd5d3aa404d7562d09a848f96a8a8d5d65977bf90
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xa3f751662e282e83ec3cbc387d225ca56dd63d3a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xd24157aa1097486dc9d7cf094a7e15026e566b5d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xbed0b9240bdbcc8e33f66d2ca650a5ef60a5bab0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x5d559ea7bb2dae4b694a079cb8328a2145fd32f6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x97b959385dfdcaf252223838746beb232ac601aa
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x18e692c03de43972fe81058f322fa542ae1a5e2c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x38029c62dfa30d9fd3cadf4c64e9b2ab21dbda17
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x4507cef57c46789ef8d1a19ea45f4216bae2b528
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/celo/0x73f93dcc49cb8a239e2032663e9475dd5ef29a08
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x9e523234d36973f9e38642886197d023c88e307e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5de758bba013e58dae2693aea3f0b12b31a3023d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1001271083c249bd771e1bb76c22d935809a61ee
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9d39a5de30e57443bff2a8307a4256c8797a3497
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf3768d6e78e65fc64b8f12ffc824452130bd5394
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf2ec4a773ef90c58d98ea734c0ebdb538519b988
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0f2d719407fdbeff09d87557abb7232601fd9f29
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x180000dda70eb7fb7f3e10e52e88ce88f46e3b3a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xed89fc0f41d8be2c98b13b7e3cd3e876d73f1d30
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x17c50d62e6e8d20d2dc18e9ad79c43263d0720d9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3b50805453023a91a8bf641e279401a0b23fa6f9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfd03723a9a3abe0562451496a9a394d2c4bad4ab
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfe67a4450907459c3e1fff623aa927dd4e28c67a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc5fb36dd2fb59d3b98deff88425a3f425ee469ed
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x6b021b3f68491974be6d4009fee61a4e3c708fd6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x7ae9ab13fc8945323b778b3f8678145e80ec2efb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xbc4c97fb9befaa8b41448e1dfcc5236da543217f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x93919784c523f39cacaa98ee0a9d96c3f32b593e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xd55fce7cdab84d84f2ef3f99816d765a2a94a509
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x32e0f9d26d1e33625742a52620cc76c1130efde6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9b700b043e9587dde9a0c29a9483e2f8fa450d54
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0b1594b0e896bf165d925956e0df733b8443af6a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x891502ba08132653151f822a3a430198f1844115
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc702b80a1bebac118cab22ce6f2978ef59563b3f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1287a235474e0331c0975e373bdd066444d1bd35
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xab36452dbac151be02b16ca17d8919826072f64a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xcc7ff230365bd730ee4b352cc2492cedac49383e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xa9b038285f43cd6fe9e16b4c80b4b9bccd3c161b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x77be1ba1cd2d7a63bffc772d361168cc327dd8bc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x00000000efe302beaa2b3e6e1b18d08d69a9012a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd101dcc414f310268c37eeb4cd376ccfa507f571
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd09eb9099fac55edcbf4965e0a866779ca365a0c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7b0df1cd724ec34ec9bc4bd19749b01afb490761
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x71297312753ea7a2570a5a3278ed70d9a75f4f44
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9e32b13ce7f2e80a01932b42553652e053d6ed8e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6942040b6d25d6207e98f8e26c6101755d67ac89
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3301ee63fb29f863f2333bd4466acb46cd8323e6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfefe157c9d0ae025213092ff9a5cb56ab492bab8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x44108f0223a3c3028f5fe7aec7f9bb2e66bef82f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1121acc14c63f3c872bfca497d10926a6098aac5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf1376bcef0f78459c0ed0ba5ddce976f1ddf51f4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xce722f60f35c37ab295adc4e6ba45bcc7ca89dd6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x614577036f0a024dbc1c88ba616b394dd65d105a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x93fa0b88c0c78e45980fa74cdd87469311b7b3e4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xe22c452bd2ade15dfc8ad98286bc6bdf0c9219b7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x00000000000451f49c692bfc24971cacea2db678
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x00000000702749f73e5210b08b0a3d440078f888
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x86f65121804d2cdbef79f9f072d4e0c2eebabc08
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x127e47aba094a9a87d084a3a93732909ff031419
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x52b492a33e447cdb854c7fc19f1e57e8bfa1777d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x55027a5b06f4340cc4c82dcc74c90ca93dcb173e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x32b133add6d99d085ff23f522662b546b70d54a1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x2ad3d80c917ddbf08acc04277f379e00e4d75395
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc73dc7ae7a4fa40517aafa941ae1ee436b91a12c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9f235d23354857efe6c541db92a9ef1877689bcb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0c90c756350fb803a7d5d9f9ee5ac29e77369973
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xac12f930318be4f9d37f602cbf89cd33e99aa9d4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x1c45366641014069114c78962bdc371f534bc81c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc328a59e7321747aebbc49fd28d1b32c1af8d3b2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x90edf25b14393350f0c1b5b12b6cb3cd3781fb4a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x590f820444fa3638e022776752c5eef34e2f89a6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1fdb29ad49330b07ae5a87483f598aa6b292039e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4a220e6096b25eadb88358cb44068a3248254675
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xabd4c63d2616a5201454168269031355f4764337
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4c1b1302220d7de5c22b495e78b72f2dd2457d45
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x050c24dbf1eec17babe5fc585f06116a259cc77a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x57211299bc356319ba5ca36873eb06896173f8bc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xfde4c96c8593536e31f229ea8f37b2ada2699bb2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf9b738c2e7adc4f299c57afd0890b925a5efea6f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x04c0599ae5a44757c0af6f9ec3b93da8976c150a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x99b2b1a2adb02b38222adcd057783d7e5d1fcc7d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf9569cfb8fd265e91aa478d86ae8c78b8af55df4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xa3d1a8deb97b111454b294e2324efad13a9d8396
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xd85eff20288ca72ea9eecffb428f89ee5066ca5c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x13f4196cc779275888440b3000ae533bbbbc3166
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x160452f95612699d1a561a70eeeeede67c6812af
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x5ce12f6d9f2fcaf0b11494a1c39e09eeb16ca7e8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x6894cde390a3f51155ea41ed24a33a4827d3063d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6db6fdb5182053eecec778afec95e0814172a474
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc0cfbe1602dd586349f60e4681bf4badca584ec9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x289ff00235d2b98b0145ff5d4435d3e92f9540a6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcb76314c2540199f4b844d4ebbc7998c604880ca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd7cfdb3cdc33dbeb9e9a4c95b61953cf12a008b3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xce176825afc335d9759cb4e323ee8b31891de747
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8f2bf2f59cdf7be4aee71500b9419623202b8636
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x744d70fdbe2ba4cf95131626614a1763df805b9e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x52e6654aee5d59e13ae30b48f8f5dbeb97f708cd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x38f9bf9dce51833ec7f03c9dc218197999999999
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x7189fb5b6504bbff6a852b13b7b82a3c118fdc27
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x38f9bf9dce51833ec7f03c9dc218197999999999
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x8349314651ede274f8c5fef01aa65ff8da75e57c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x38f9bf9dce51833ec7f03c9dc218197999999999
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x1adcef5c780d8895ac77e6ee9239b4b3ecb76da2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x38f9bf9dce51833ec7f03c9dc218197999999999
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x917f39bb33b2483dd19546b1e8d2f09ce481ee44
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x60a3e35cc302bfa44cb288bc5a4f316fdb1adb42
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x8b67f2e56139ca052a7ec49cbcd1aa9c83f2752a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x029c58a909fbe3d4be85a24f414dda923a3fde0f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x655a51e6803faf50d4ace80fa501af2f29c856cf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x9ca5dfa3b0b187d7f53f4ef83ca435a2ec2e4070
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xb68a20b9e9b06fde873897e12ab3372ce48f1a8a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x0203d275d2a65030889af45ed91d472be3948b92
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa00453052a36d43a99ac1ca145dfe4a952ca33b8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8236a87084f8b84306f72007f36f2618a5634494
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbc5ca3c518c8a2930947661237b1b562e34f22b7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfd0205066521550d7d7ab19da8f72bb004b4c341
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x880226cbcce551eeafd18c9a9e883c85811b82fc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfc21540d6b89667d167d42086e1feb04da3e9b21
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x41d06390b935356b46ad6750bda30148ad2044a4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8149745670881d99700078ede5903a1a7bebe262
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcf01a5c02c9b9dd5bf73a5a56bcdbc9dca483d43
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xae0fe8474cf5b1b412b3e4327a1c535ea12b77b7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc98d64da73a6616c42117b582e832812e7b8d57f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x70c0b83501a3989d4f8a8693581bb7010194abb5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x80122c6a83c8202ea365233363d3f4837d13e888
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x455e53cbb86018ac2b8092fdcd39d8444affc3f6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x58aea10748a00d1781d6651f9d78a414ea32ca46
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x406d59819bc2aef682f4ff2769085c98a264f97b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xc4ce1d6f5d98d65ee25cf85e9f2e9dcfee6cb5d6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x94025780a1ab58868d9b2dbbb775f44b32e8e6e5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xf33687811f3ad0cd6b48dd4b39f9f977bd7165a2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xa88594d404727625a9437c3f886c7643872296ae
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7e72d6410803c40e73806f2a72e3eade5d075cc0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x31ea904a7eca45122890deb8da3473a2081bc9d1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x48c6740bcf807d6c47c864faeea15ed4da3910ab
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc5fecc3a29fb57b5024eec8a2239d4621e111cbe
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x184cff0e719826b966025f93e05d8c8b0a79b3f9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0c2e08e459fc43ddd1e2718c122f566473f59665
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1a3a8cf347b2bf5890d3d6a1b981c4f4432c8661
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8baf5d75cae25c7df6d1e0d26c52d19ee848301a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x28561b8a2360f463011c16b6cc0b0cbef8dbbcad
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0fd10b9899882a6f2fcb5c371e17e70fdee00c38
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7a58c0be72be218b41c608b7fe7c5bb630736c71
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xddaf27167929cd045a7d97d09a4fa1046ece3d89
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x375e104af98872e5b4fe951919e504a47db1757c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5408d3883ec28c2de205064ae9690142b035fed2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1bb4afbf2ce0c9ec86e6414ad4ba4d9aab1c0de4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7391425ca7cee3ee03e09794b819291a572af83e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x38e382f74dfb84608f3c1f10187f6bef5951de93
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xbea269038eb75bdab47a9c04d0f5c572d94b93d5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf41a7b7c79840775f70a085c1fc5a762bbc6b180
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x13654df31871b5d01e5fba8e6c21a5d0344820f5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x4d840b741bc05fde325d4ec0b4cfcd0cea237e4e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x49b1be61a8ca3f9a9f178d6550e41e00d9162159
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf5bc3439f53a45607ccad667abc7daf5a583633f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0a953dd9fc813fefaf6015b804c9dfa0624690c0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x44ec807ce2f4a6f2737a92e985f318d035883e47
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xfb6115445bff7b52feb98650c87f44907e58f802
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x117a123ded97cd125837d9ac19592b77d806fa88
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd9fcd98c322942075a5c3860693e9f4f03aae07b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x240cd7b53d364a208ed41f8ced4965d11f571b7a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb8d6196d71cdd7d90a053a7769a077772aaac464
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xcbde0453d4e7d748077c1b0ac2216c011dd2f406
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x786f112c9a6bc840cdc07cfd840105efd6ef2d4b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0bffdd787c83235f6f0afa0faed42061a4619b7a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1c43cd666f22878ee902769fccda61f401814efb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1b54a6fa1360bd71a0f28f77a1d6fba215d498c3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb528edbef013aff855ac3c50b381f253af13b997
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x888888ae2c4a298efd66d162ffc53b3f2a869888
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4cd27e18757baa3a4fe7b0ab7db083002637a6c5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x240d6faf8c3b1a7394e371792a3bf9d28dd65515
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x41b1f9dcd5923c9542b6957b9b72169595acbc5c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd1f2586790a5bd6da1e443441df53af6ec213d83
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8de5b80a0c1b02fe4976851d030b36122dbb8624
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x391cf4b21f557c935c7f670218ef42c21bd8d686
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8bd35250918ed056304fa8641e083be2c42308bb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc3960227e41c3f54e9b399ce216149dea5315c34
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x59062301fb510f4ea2417b67404cb16d31e604ba
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x75ec618a817eb0a4a7e44ac3dfc64c963daf921a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x7e7a7c916c19a45769f6bdaf91087f93c6c12f78
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x21ccbc5e7f353ec43b2f5b1fb12c3e9d89d30dca
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x87eee96d50fb761ad85b1c982d28a042169d61b1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x3c720206bfacb2d16fa3ac0ed87d2048dbc401fc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x8d60fb5886497851aac8c5195006ecf07647ba0d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xcb327b99ff831bf8223cced12b1338ff3aa322ff
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf544251d25f3d243a36b07e7e7962a678f952691
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xa7296cefae8477a81e23230ca5d3a3d6f49d3764
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x051fb509e4a775fabd257611eea1efaed8f91359
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xae2bddbcc932c2d2cf286bad0028c6f5074c77b5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1dd2d631c92b1acdfcdd51a0f7145a50130050c4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xd3c68968137317a57a9babeacc7707ec433548b4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7f6f6720a73c0f54f95ab343d7efeb1fa991f4f7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xf3527ef8de265eaa3716fb312c12847bfba66cef
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x8888888888f004100c0353d657be6300587a6ccd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xe2a59d5e33c6540e18aaa46bf98917ac3158db0d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xfa2ad87e35fc8d3c9f57d73c4667a4651ce6ad2f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xec53bf9167f50cdeb3ae105f56099aaab9061f83
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb3912b20b3abc78c15e85e13ec0bf334fbb924f7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x16a3543fa6b32cac3b0a755f64a729e84f89a75c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf1c9acdc66974dfb6decb12aa385b9cd01190e38
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x0da2082905583cedfffd4847879d0f1cf3d25c36
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xec9333e7dadeebf82d290d6cb12e66cc30ce46b0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x898843fb909e3562c82f2b96f4e3d0693af041df
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xaf05ce8a2cef336006e933c02fc89887f5b3c726
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x13e4b8cffe704d3de6f19e52b201d92c21ec18bd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xaeb3607ec434454ceb308f5cd540875efb54309a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2a3bff78b79a009976eea096a51a948a3dc00e34
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4298e4ad48be89bf63a6fdc470a4b4fe9ce633b1
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa117000000f279d81a1d3cc75430faa017fa5a2e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x339058ca41e17b55b6dd295373c5d3cbe8000cd9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa3d4bee77b05d4a0c943877558ce21a763c4fa29
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x362bc847a3a9637d3af6624eec853618a43ed7d2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7a65cb87f596caf31a4932f074c59c0592be77d7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa21af1050f7b26e0cff45ee51548254c41ed6b5c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x284b25d8f199125da962abc9ee6e6b1b6715cae3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8fac8031e079f409135766c7d5de29cf22ef897c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf280b16ef293d8e534e370794ef26bf312694126
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x69af81e73a73b40adf4f3d4223cd9b1ece623074
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x888c1a341ce9d9ae9c2d2a75a72a7f0d2551a2dc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x465dbc39f46f9d43c581a5d90a43e4a0f2a6ff2d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x44e18207b6e98f4a786957954e462ed46b8c95be
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x70c29e99ca32592c0e88bb571b87444bb0e08e33
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8c7ac134ed985367eadc6f727d79e8295e11435c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6aa56e1d98b3805921c170eb4b3fe7d4fda6d89b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x81db1949d0e888557bc632f7c0f6698b1f8c9106
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2de1218c31a04e1040fc5501b89e3a58793b3ddf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x30ae41d5f9988d359c733232c6c693c0e645c77e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x1fc01117e196800f416a577350cb1938d10501c2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x3212dc0f8c834e4de893532d27cc9b6001684db0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0xd0cf4de352ac8dcce00bd6b93ee73d3cb272edc3
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x75e6b648c91d222b2f6318e8ceeed4b691d5323f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x2a06a17cbc6d0032cac2c6696da90f29d39a1a29
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x6668d4a6605a27e5ee51eda040581155eddc6666
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x2dc90fa3a0f178ba4bee16cac5d6c9a5a7b4c6cb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x9c7beba8f6ef6643abd725e45a4e8387ef260649
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0x0cf8e180350253271f4b917ccfb0accc4862f262
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x42069026eac8eee0fd9b5f7adfa4f6e6d69a2b39
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x340d2bde5eb28c1eed91b2f790723e3b160613b7
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xec21890967a8ceb3e55a3f79dac4e90673ba3c2e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6900f7b42fb4abb615c938db6a26d73a9afbed69
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4c44a8b7823b80161eb5e6d80c014024752607f2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x103143acf2e717acf8f021823e86a1dbfe944fb5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x6969f3a3754ab674b48b7829a8572360e98132ba
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x562e362876c8aee4744fc2c6aac8394c312d215d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd0ebfe04adb5ef449ec5874e450810501dc53ed5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2597342ff387b63846eb456419590781c4bfcdaf
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4e6221c07dae8d3460a46fa01779cf17fdd72ad8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb612bfc5ce2fb1337bd29f5af24ca85dbb181ce2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc0e10854ab40b2e59a5519c481161a090f1162a0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xa7f4195f10f1a62b102bd683eab131d657a6c6e4
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x7e7ef0ee0305c1c195fcae22fd7b207a813eef86
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xb6212b633c941e9be168c4b9c2d9e785f1cd42fb
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0x139052115f8b1773cf7dcba6a553f922a2e54f69
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x3f94618ad346f34f43e27f0cf46decbb0d396b1b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf56b3b3972f2f154555a0b62ff5a22b7b2a3c90b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc08cd26474722ce93f4d0c34d16201461c10aa8c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x080c169cd58122f8e1d36713bf8bcbca45176905
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x50da645f148798f68ef2d7db7c1cb22a6819bb2c
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xea1d649ddc8e2a6e6ee40b89b2997518476cafa5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xa4080f1778e69467e905b8d6f72f6e441f9e9484
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb60acd2057067dc9ed8c083f5aa227a244044fd6
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd0dfca0b404e866dc9a3038bd2a545c6735d9fa9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x18a8d75f70eaead79b5a55903d036ce337f623a5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xebb66a88cedd12bfe3a289df6dfee377f2963f12
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9343e24716659a3551eb10aff9472a2dcad5db2d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xfa3e941d1f6b7b10ed84a0c211bfa8aee907965e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x85bea4ee627b795a79583fcede229e198aa57055
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0c03ce270b4826ec62e7dd007f0b716068639f7b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x19706c142d33376240e418d6385f05691a5fa8e2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb3e41d6e0ea14b43bc5de3c314a408af171b03dd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x634769eb87542eaf41c0008c05d5d8f5d8bec3a5
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xd3c5bdbc6de5ea3899a28f6cd419f29c09fa749f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9dfad1b7102d46b1b197b90095b5c4e9f5845bba
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xc8f69a9b46b235de8d0b77c355fff7994f1b090f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5200b34e6a519f289f5258de4554ebd3db12e822
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x69fd9281a920717ee54193a1c130b689ef341933
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5d56b6581d2e7e7574adce2dc593f499a53d7505
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x168168db04def453b7e8bfaff1e0102a3e810485
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x1f19d846d99a0e75581913b64510fe0e18bbc31f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x571d9b73dc04ed88b4e273e048c8d4848f83b779
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xca5ca9083702c56b481d1eec86f1776fdbd2e594
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x99f40b01ba9c469193b360f72740e416b17ac332
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0xc6bdfc4f2e90196738873e824a9efa03f7c64176
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x06480acaae64bcfa6da8fd176f60982584385090
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0c5142bc58f9a61ab8c3d2085dd2f4e550c5ce0b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xc734635cd30e882037c3f3de1ebccf9fa9d27d9f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x65e570b560027f493f2b1907e8e8e3b9546053bd
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xd1917629b3e6a72e6772aab5dbe58eb7fa3c2f33
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9e81f6495ba29a6b4d48bddd042c0598fa8abc9f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x2075f6e2147d4ac26036c9b4084f8e28b324397d
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x01aac2b594f7bdbec740f0f1aa22910ebb4b74ab
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/bnb/0xef433ebb8ba7a486ce21b854f093b9a3f4e696bc
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x2bb84fd8f7ed0ffae3da36ad60d4d7840bdeeada
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xad86b91a1d1db15a4cd34d0634bbd4ecacb5b61a
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x4d224452801aced8b2f0aebe155379bb5d594381
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xf63e309818e4ea13782678ce6c31c1234fa61809
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xe0151763455a8a021e64880c238ba1cff3787ff0
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x44ff8620b8ca30902395a7bd3f2407e1a091bf73
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x5640e0560e6afd6a9f4ddb41230d0201d181fea7
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x88ee7a3537667958d040216d9dc1752d1274d838
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x39d5313c3750140e5042887413ba8aa6145a9bd2
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xba2a3dad197d6fee75471215efd5c30c8c854e11
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x3dd77d53f4fa9b3435b3a2ff6bb408771e6800e6
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xf929de51d91c77e42f5090069e0ad7a09e513c73
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0x74885b4d524d497261259b38900f54e6dbad2210
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/optimism/0xc55e93c62874d8100dbd2dfe307edc1036ad5434
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x9c9e5fd8bbc25984b178fdce6117defa39d2db39
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0xaa53b93608c88ee55fad8db4c504fa20e52642ad
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x55cd6469f597452b5a7536e2cd98fde4c1247ee4
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xfe550bffb51eb645ea3b324d772a19ac449e92c5
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x314d7f9e2f55b430ef656fbb98a7635d43a2261e
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x3b54eb78fc8103462f86976b06916fa46078b124
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x1d4731111bd2a50ab3dd5178574e6f3698270ffc
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7a2c5e7788e55ec0a7ba4aeec5b3da322718fb5e
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x814fe70e85025bec87d4ad3f3b713bdcaac0579b
+ 2024-10-25T19:36:47.010Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9b69667f602f15ef2d09a9a18489c788e327461e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x8808434a831efea81170a56a9ddc57cc9e6de1d8
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xe0c8b298db4cffe05d1bea0bb1ba414522b33c1b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x230ea9aed5d08afdb22cd3c06c47cf24ad501301
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x35d8949372d46b7a3d5a56006ae77b215fc69bc0
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x535887989b9edffb63b1fd5c6b99a4d45443b49a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0x9ee8c380e1926730ad89e91665ff27063b13c90a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xb8a914a00664e9361eae187468eff94905dfbc15
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/ethereum/0xda2e903b0b67f30bf26bd3464f9ee1a383bbbe5f
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/arbitrum/0xd6cf874e24a9f5f43075142101a6b13735cdd424
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/polygon/0x8c92e38eca8210f4fcbf17f0951b198dd7668292
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x9a33406165f562e16c3abd82fd1185482e01b49a
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x7f65323e468939073ef3b5287c73f13951b0ff5b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x5597ce42b315f29e42071d231dcd0158da35b77b
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0a14ef61afb32e5ca672e021784f71705ac14908
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x0f1cfd0bb452db90a3bfc0848349463010419ab2
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xf3708859c178709d5319ad5405bc81511b72b9e9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xadf734e8d910d01e6528240898d895af6c22e2de
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x78a087d713be963bf307b18f2ff8122ef9a63ae9
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x4287105ffac106eb98a71cab46586906181e35ff
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0xb8e564b206032bbcda2c3978bc371da52152f72e
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/base/0x3ecced5b416e58664f04a39dd18935eb71d33b15
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/celo/0x71e26d0e519d14591b9de9a0fe9513a398101490
+ 2024-11-01T19:06:09.419Z
+ 0.8
+
+
+ https://app.uniswap.org/explore/tokens/celo/0x105d4a9306d2e55a71d2eb95b81553ae1dc20d7b
+ 2024-11-01T19:06:09.419Z
0.8
\ No newline at end of file
diff --git a/apps/web/src/assets/svg/search.svg b/apps/web/src/assets/svg/search.svg
index fb9275b80ed..e1413b57684 100644
--- a/apps/web/src/assets/svg/search.svg
+++ b/apps/web/src/assets/svg/search.svg
@@ -1,3 +1,3 @@
-
\ No newline at end of file
+
diff --git a/apps/web/src/components/AccountDrawer/AuthenticatedHeader.tsx b/apps/web/src/components/AccountDrawer/AuthenticatedHeader.tsx
index 7dd75f26458..4ba244318be 100644
--- a/apps/web/src/components/AccountDrawer/AuthenticatedHeader.tsx
+++ b/apps/web/src/components/AccountDrawer/AuthenticatedHeader.tsx
@@ -30,7 +30,7 @@ import { useUserHasAvailableClaim, useUserUnclaimedAmount } from 'state/claim/ho
import { ThemedText } from 'theme/components'
import { ArrowDownCircleFilled } from 'ui/src/components/icons/ArrowDownCircleFilled'
import { TestnetModeBanner } from 'uniswap/src/components/banners/TestnetModeBanner'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { setIsTestnetModeEnabled } from 'uniswap/src/features/settings/slice'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { useUnitagByAddress } from 'uniswap/src/features/unitags/hooks'
diff --git a/apps/web/src/components/AccountDrawer/LanguageMenu.tsx b/apps/web/src/components/AccountDrawer/LanguageMenu.tsx
index e0bfb8f0922..297f3b79f95 100644
--- a/apps/web/src/components/AccountDrawer/LanguageMenu.tsx
+++ b/apps/web/src/components/AccountDrawer/LanguageMenu.tsx
@@ -1,17 +1,16 @@
import { InterfaceEventName } from '@uniswap/analytics-events'
import { SlideOutMenu } from 'components/AccountDrawer/SlideOutMenu'
import { MenuColumn, MenuItem } from 'components/AccountDrawer/shared'
-import { useActiveLanguage } from 'hooks/useActiveLocale'
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
import { useDispatch } from 'react-redux'
import { Language, WEB_SUPPORTED_LANGUAGES } from 'uniswap/src/features/language/constants'
-import { useLanguageInfo } from 'uniswap/src/features/language/hooks'
+import { useCurrentLanguage, useLanguageInfo } from 'uniswap/src/features/language/hooks'
import { setCurrentLanguage } from 'uniswap/src/features/settings/slice'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans } from 'uniswap/src/i18n'
function LanguageMenuItem({ language }: { language: Language }) {
- const currentLanguage = useActiveLanguage()
+ const currentLanguage = useCurrentLanguage()
const languageInfo = useLanguageInfo(language)
const dispatch = useDispatch()
diff --git a/apps/web/src/components/AccountDrawer/LocalCurrencyMenu.tsx b/apps/web/src/components/AccountDrawer/LocalCurrencyMenu.tsx
index 12708638e9c..16925b4e515 100644
--- a/apps/web/src/components/AccountDrawer/LocalCurrencyMenu.tsx
+++ b/apps/web/src/components/AccountDrawer/LocalCurrencyMenu.tsx
@@ -1,11 +1,11 @@
import { SlideOutMenu } from 'components/AccountDrawer/SlideOutMenu'
import { MenuColumn, MenuItem } from 'components/AccountDrawer/shared'
import { getLocalCurrencyIcon } from 'constants/localCurrencies'
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
import { useLocalCurrencyLinkProps } from 'hooks/useLocalCurrencyLinkProps'
import styled from 'lib/styled-components'
import { useMemo } from 'react'
import { FiatCurrency, ORDERED_CURRENCIES } from 'uniswap/src/features/fiatCurrency/constants'
+import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
import { Trans } from 'uniswap/src/i18n'
const StyledLocalCurrencyIcon = styled.div`
@@ -39,7 +39,7 @@ function LocalCurrencyMenuItem({ localCurrency, isActive }: { localCurrency: Fia
}
export function LocalCurrencyMenuItems() {
- const activeLocalCurrency = useActiveLocalCurrency()
+ const activeLocalCurrency = useAppFiatCurrency()
return (
<>
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.test.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.test.tsx
index 0ee8b6a99cf..64ef1ad1973 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.test.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.test.tsx
@@ -7,7 +7,7 @@ import { SignatureType, UniswapXOrderDetails } from 'state/signatures/types'
import { render, screen } from 'test-utils/render'
import { UniswapXOrderStatus } from 'types/uniswapx'
import { DAI } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const mockOrderDetails: UniswapXOrderDetails = {
type: SignatureType.SIGN_UNISWAPX_ORDER,
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.tsx
index 252862b6007..c7ad30682c4 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/CancelOrdersDialog.tsx
@@ -14,8 +14,8 @@ import { Slash } from 'react-feather'
import { SignatureType, UniswapXOrderDetails } from 'state/signatures/types'
import { ExternalLink, ThemedText } from 'theme/components'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Plural, Trans, t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { NumberType, useFormatter } from 'utils/formatNumbers'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.test.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.test.tsx
index 504ca9eaa7e..59ec734ac41 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.test.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.test.tsx
@@ -8,7 +8,7 @@ import { mocked } from 'test-utils/mocked'
import { render } from 'test-utils/render'
import { UniswapXOrderStatus } from 'types/uniswapx'
import { DAI } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('components/AccountDrawer/MiniPortfolio/formatTimestamp', () => ({
formatTimestamp: jest.fn(),
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.tsx
index 39163bb93dc..a80989086a2 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal.tsx
@@ -33,10 +33,10 @@ import { useOrder } from 'state/signatures/hooks'
import { SignatureType, UniswapXOrderDetails } from 'state/signatures/types'
import { Divider, ThemedText } from 'theme/components'
import { UniswapXOrderStatus } from 'types/uniswapx'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { InterfaceEventNameLocal } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { CurrencyField } from 'uniswap/src/types/currency'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { logger } from 'utilities/src/logger/logger'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainOrderLineItem.test.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainOrderLineItem.test.tsx
index 657dee7d18e..f6caf5077bf 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainOrderLineItem.test.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/OffchainOrderLineItem.test.tsx
@@ -7,7 +7,7 @@ import { SignatureType } from 'state/signatures/types'
import { render, screen } from 'test-utils/render'
import { UniswapXOrderStatus } from 'types/uniswapx'
import { DAI, USDC_MAINNET } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
describe('OffchainOrderLineItem', () => {
it('should render type EXCHANGE_RATE', () => {
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/fixtures/activity.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/fixtures/activity.ts
index 31d51ef695c..ef9a46e2ec1 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/fixtures/activity.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/fixtures/activity.ts
@@ -18,7 +18,7 @@ import {
TransactionStatus,
TransactionType,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const MockOrderTimestamp = 10000
const MockRecipientAddress = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/getCurrency.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/getCurrency.ts
index fe490fc4972..d7159808778 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/getCurrency.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/getCurrency.ts
@@ -1,5 +1,4 @@
import { Currency } from '@uniswap/sdk-core'
-import { chainIdToBackendChain } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { apolloClient } from 'graphql/data/apollo/client'
import { gqlTokenToCurrencyInfo } from 'graphql/data/types'
@@ -10,7 +9,8 @@ import {
TokenDocument,
TokenQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { isSameAddress } from 'utilities/src/addresses'
export async function getCurrency(currencyId: string, chainId: UniverseChainId): Promise {
@@ -29,7 +29,7 @@ export async function getCurrency(currencyId: string, chainId: UniverseChainId):
query: TokenDocument,
variables: {
address: currencyId,
- chain: chainIdToBackendChain({ chainId }),
+ chain: toGraphQLChain(chainId),
},
})
return gqlTokenToCurrencyInfo(data?.token as Token)?.currency
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.test.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.test.ts
index 0f4dd0de702..83ab9e22b81 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.test.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.test.ts
@@ -26,7 +26,7 @@ import {
nativeOnChain,
} from 'uniswap/src/constants/tokens'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { useFormatter } from 'utils/formatNumbers'
function mockSwapInfo(
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.ts
index fb8b46db406..0b95c5f9042 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseLocal.ts
@@ -35,9 +35,9 @@ import {
import { isConfirmedTx } from 'state/transactions/utils'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { isAddress } from 'utilities/src/addresses'
import { logger } from 'utilities/src/logger/logger'
import { NumberType, useFormatter } from 'utils/formatNumbers'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseRemote.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseRemote.tsx
index fd04d360a25..693a7cb5d78 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseRemote.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/parseRemote.tsx
@@ -36,8 +36,8 @@ import {
TransactionDetailsPartsFragment,
TransactionType,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { isAddress, isSameAddress } from 'utilities/src/addresses'
import { logger } from 'utilities/src/logger/logger'
import { NumberType, useFormatter } from 'utils/formatNumbers'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/types.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/types.ts
index b3025eb6ec6..fb51891be9a 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/types.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/types.ts
@@ -4,7 +4,7 @@ import {
TransactionStatus,
TransactionType,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
/**
* TODO: refactor parsing / Activity so that all Activity Types can have a detail sheet.
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/utils.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/utils.ts
index 7264cdc2808..2dde36d985c 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/utils.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/utils.ts
@@ -17,10 +17,10 @@ import { UniswapXOrderStatus } from 'types/uniswapx'
import PERMIT2_ABI from 'uniswap/src/abis/permit2.json'
import { Permit2 } from 'uniswap/src/abis/types'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { InterfaceEventNameLocal } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { getContract } from 'utilities/src/contracts/getContract'
import { logger } from 'utilities/src/logger/logger'
import { useAsyncData } from 'utilities/src/react/hooks'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/ExtensionDeeplinks.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/ExtensionDeeplinks.tsx
index 9bfd096b10e..8b545ed1744 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/ExtensionDeeplinks.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/ExtensionDeeplinks.tsx
@@ -1,7 +1,7 @@
+// eslint-disable-next-line no-restricted-imports
+import { PositionStatus } from '@uniswap/client-pools/dist/pools/v1/types_pb'
import { MenuState, miniPortfolioMenuStateAtom } from 'components/AccountDrawer'
import { useOpenLimitOrders, usePendingActivity } from 'components/AccountDrawer/MiniPortfolio/Activity/hooks'
-import { useFilterPossiblyMaliciousPositionInfo } from 'components/AccountDrawer/MiniPortfolio/Pools/PoolsTab'
-import useMultiChainPositions from 'components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions'
import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks'
import { Pool } from 'components/Icons/Pool'
import { ExtensionRequestMethods, useUniswapExtensionConnector } from 'components/WalletModal/useOrderedConnections'
@@ -15,6 +15,7 @@ import { RotatableChevron } from 'ui/src/components/icons/RotatableChevron'
import { TimePast } from 'ui/src/components/icons/TimePast'
import { iconSizes } from 'ui/src/theme/iconSizes'
+import { useGetPositionsQuery } from 'uniswap/src/data/rest/getPositions'
import { t } from 'uniswap/src/i18n'
const UnreadIndicator = () => {
@@ -66,8 +67,10 @@ export function ExtensionDeeplinks({ account }: { account: string }) {
}
}, [hasPendingActivity])
- const { positions } = useMultiChainPositions(account)
- const filteredPositions = useFilterPossiblyMaliciousPositionInfo(positions)
+ const { data } = useGetPositionsQuery({
+ address: account,
+ positionStatuses: [PositionStatus.IN_RANGE, PositionStatus.OUT_OF_RANGE, PositionStatus.CLOSED],
+ })
if (!uniswapExtensionConnector) {
return null
@@ -97,7 +100,7 @@ export function ExtensionDeeplinks({ account }: { account: string }) {
setActivityUnread(false)
}}
/>
- {filteredPositions.length > 0 && (
+ {data && data?.positions.length > 0 && (
}
Label={t('common.pools')}
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitDetailActivityRow.test.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitDetailActivityRow.test.tsx
index 7ec503a3ae7..f69f3ac9f8f 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitDetailActivityRow.test.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitDetailActivityRow.test.tsx
@@ -8,7 +8,7 @@ import { render, screen } from 'test-utils/render'
import { UniswapXOrderStatus } from 'types/uniswapx'
import { DAI } from 'uniswap/src/constants/tokens'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('components/AccountDrawer/MiniPortfolio/formatTimestamp', () => {
return {
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitsMenu.test.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitsMenu.test.tsx
index 95ff48fd06a..b1b9d29af55 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitsMenu.test.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/LimitsMenu.test.tsx
@@ -10,7 +10,7 @@ import { act, fireEvent, render, screen } from 'test-utils/render'
import { UniswapXOrderStatus } from 'types/uniswapx'
import { DAI } from 'uniswap/src/constants/tokens'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('components/AccountDrawer/MiniPortfolio/Activity/hooks', () => ({
...jest.requireActual('components/AccountDrawer/MiniPortfolio/Activity/hooks'),
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/OpenLimitOrdersButton.test.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/OpenLimitOrdersButton.test.tsx
index 8bed1c2b3c3..7badaa3a271 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/OpenLimitOrdersButton.test.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/OpenLimitOrdersButton.test.tsx
@@ -3,7 +3,7 @@ import { OpenLimitOrdersButton } from 'components/AccountDrawer/MiniPortfolio/Li
import { mocked } from 'test-utils/mocked'
import { act, fireEvent, render, screen } from 'test-utils/render'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('components/AccountDrawer/MiniPortfolio/Activity/hooks', () => ({
...jest.requireActual('components/AccountDrawer/MiniPortfolio/Activity/hooks'),
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/__snapshots__/LimitDetailActivityRow.test.tsx.snap b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/__snapshots__/LimitDetailActivityRow.test.tsx.snap
index fe53b6716e1..ae8204833a1 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/__snapshots__/LimitDetailActivityRow.test.tsx.snap
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Limits/__snapshots__/LimitDetailActivityRow.test.tsx.snap
@@ -205,8 +205,7 @@ exports[`LimitDetailActivityRow should render with valid details 1`] = `
{
if (enabled) {
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/NFTs/NFTTab.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/NFTs/NFTTab.tsx
index e99d5db4fc2..62d21d21f23 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/NFTs/NFTTab.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/NFTs/NFTTab.tsx
@@ -13,9 +13,9 @@ import InfiniteScroll from 'react-infinite-scroll-component'
import { useNavigate } from 'react-router-dom'
import { Gallery } from 'ui/src/components/icons/Gallery'
import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
import { t } from 'uniswap/src/i18n'
const StyledTabButton = styled(TabButton)`
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/PoolsTab.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/PoolsTab.tsx
index ff549dfce27..dd9730c5947 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/PoolsTab.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/PoolsTab.tsx
@@ -1,19 +1,21 @@
import { InterfaceElementName } from '@uniswap/analytics-events'
-import { Position } from '@uniswap/v3-sdk'
+// eslint-disable-next-line no-restricted-imports
+import { PositionStatus, ProtocolVersion } from '@uniswap/client-pools/dist/pools/v1/types_pb'
+import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { ExpandoRow } from 'components/AccountDrawer/MiniPortfolio/ExpandoRow'
-import { PositionInfo } from 'components/AccountDrawer/MiniPortfolio/Pools/cache'
-import { useFeeValues } from 'components/AccountDrawer/MiniPortfolio/Pools/hooks'
-import useMultiChainPositions from 'components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions'
import { PortfolioLogo } from 'components/AccountDrawer/MiniPortfolio/PortfolioLogo'
import PortfolioRow, {
PortfolioSkeleton,
PortfolioTabWrapper,
} from 'components/AccountDrawer/MiniPortfolio/PortfolioRow'
import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks'
+import { useV3OrV4PositionDerivedInfo } from 'components/Liquidity/hooks'
+import { PositionInfo } from 'components/Liquidity/types'
+import { getPositionUrl, parseRestPosition } from 'components/Liquidity/utils'
import { MouseoverTooltip } from 'components/Tooltip'
import Row from 'components/deprecated/Row'
+import { ZERO_ADDRESS } from 'constants/misc'
import { useAccount } from 'hooks/useAccount'
-import { useFilterPossiblyMaliciousPositions } from 'hooks/useFilterPossiblyMaliciousPositions'
import { useSwitchChain } from 'hooks/useSwitchChain'
import styled from 'lib/styled-components'
import { EmptyWalletModule } from 'nft/components/profile/view/EmptyWalletContent'
@@ -21,83 +23,82 @@ import { useCallback, useMemo, useReducer } from 'react'
import { useNavigate } from 'react-router-dom'
import { ThemedText } from 'theme/components'
import { BIPS_BASE } from 'uniswap/src/constants/misc'
+import { useGetPositionsQuery } from 'uniswap/src/data/rest/getPositions'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext'
import Trace from 'uniswap/src/features/telemetry/Trace'
+import { useUSDCValue } from 'uniswap/src/features/transactions/swap/hooks/useUSDCPrice'
import { t } from 'uniswap/src/i18n'
-import { NumberType, useFormatter } from 'utils/formatNumbers'
-
-/**
- * Takes an array of PositionInfo objects (format used by the Uniswap Labs gql API).
- * The hook access PositionInfo.details (format used by the NFT position contract),
- * filters the PositionDetails data for malicious content,
- * and then returns the original data in its original format.
- */
-export function useFilterPossiblyMaliciousPositionInfo(positions: PositionInfo[] | undefined): PositionInfo[] {
- const tokenIdsToPositionInfo: Record
= useMemo(
- () =>
- positions
- ? positions.reduce((acc, position) => ({ ...acc, [position.details.tokenId.toString()]: position }), {})
- : {},
- [positions],
- )
- const positionDetails = useMemo(() => positions?.map((position) => position.details) ?? [], [positions])
- const filteredPositionDetails = useFilterPossiblyMaliciousPositions(positionDetails)
+import { NumberType } from 'utilities/src/format/types'
- return useMemo(
- () => filteredPositionDetails.map((positionDetails) => tokenIdsToPositionInfo[positionDetails.tokenId.toString()]),
- [filteredPositionDetails, tokenIdsToPositionInfo],
- )
+function isPositionInfo(position: PositionInfo | undefined): position is PositionInfo {
+ return !!position
+}
+
+function getPositionKey(position: PositionInfo) {
+ const { chainId } = position
+ if (position.version === ProtocolVersion.V2) {
+ return `${position.liquidityToken.address}-${chainId}`
+ }
+
+ return `${position.tokenId}-${chainId}`
}
export default function Pools({ account }: { account: string }) {
- const { positions, loading } = useMultiChainPositions(account)
- const filteredPositions = useFilterPossiblyMaliciousPositionInfo(positions)
- const [showClosed, toggleShowClosed] = useReducer((showClosed) => !showClosed, false)
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+
+ const { data, isLoading } = useGetPositionsQuery({
+ address: account,
+ positionStatuses: [PositionStatus.IN_RANGE, PositionStatus.OUT_OF_RANGE],
+ protocolVersions: isV4EverywhereEnabled
+ ? [ProtocolVersion.V2, ProtocolVersion.V3, ProtocolVersion.V4]
+ : [ProtocolVersion.V2, ProtocolVersion.V3],
+ })
+
+ const { data: closedData } = useGetPositionsQuery({
+ address: account,
+ positionStatuses: [PositionStatus.CLOSED],
+ protocolVersions: isV4EverywhereEnabled
+ ? [ProtocolVersion.V2, ProtocolVersion.V3, ProtocolVersion.V4]
+ : [ProtocolVersion.V2, ProtocolVersion.V3],
+ })
+
+ const openPositions = useMemo(() => data?.positions.map(parseRestPosition).filter(isPositionInfo), [data?.positions])
+ const closedPositions = useMemo(
+ () => closedData?.positions.map(parseRestPosition).filter(isPositionInfo),
+ [closedData?.positions],
+ )
- const [openPositions, closedPositions] = useMemo(() => {
- const openPositions: PositionInfo[] = []
- const closedPositions: PositionInfo[] = []
- for (let i = 0; i < filteredPositions.length; i++) {
- const position = filteredPositions[i]
- if (position.closed) {
- closedPositions.push(position)
- } else {
- openPositions.push(position)
- }
- }
- return [openPositions, closedPositions]
- }, [filteredPositions])
+ const [showClosed, toggleShowClosed] = useReducer((showClosed) => !showClosed, false)
const accountDrawer = useAccountDrawer()
- if (!filteredPositions || loading) {
+ if (!openPositions && isLoading) {
return
}
- if (filteredPositions.length === 0) {
+ if (!openPositions || (openPositions?.length === 0 && closedPositions?.length === 0)) {
return
}
return (
{openPositions.map((positionInfo) => (
-
+
))}
-
- {closedPositions.map((positionInfo) => (
-
- ))}
-
+ {closedPositions && closedPositions.length > 0 && (
+
+ {closedPositions.map((positionInfo) => (
+
+ ))}
+
+ )}
)
}
@@ -112,23 +113,46 @@ const ActiveDot = styled.span<{ closed: boolean; outOfRange: boolean }>`
margin-top: 1px;
`
-function calculateLiquidityValue(price0: number | undefined, price1: number | undefined, position: Position) {
- if (!price0 || !price1) {
- return undefined
- }
+function useDerivedPositionInfo(positionInfo: PositionInfo): {
+ liquidityValue?: CurrencyAmount
+ feeValue?: CurrencyAmount
+ totalValue?: CurrencyAmount
+ formattedFeeTier?: string
+} {
+ const { feeTier, currency0Amount, currency1Amount } = positionInfo
+ const fiatValue0 = useUSDCValue(currency0Amount)
+ const fiatValue1 = useUSDCValue(currency1Amount)
+
+ const { fiatFeeValue0, fiatFeeValue1 } = useV3OrV4PositionDerivedInfo(positionInfo)
+
+ return useMemo(() => {
+ const liquidityValue = fiatValue0 && fiatValue1 ? fiatValue0.add(fiatValue1) : undefined
+
+ if (positionInfo.version === ProtocolVersion.V3 || positionInfo.version === ProtocolVersion.V4) {
+ const feeValue = fiatFeeValue0 && fiatFeeValue1 && fiatFeeValue0.add(fiatFeeValue1)
+ const totalValue = liquidityValue && feeValue ? liquidityValue.add(feeValue) : undefined
+ const formattedFeeTier = feeTier ? `${Number(feeTier) / BIPS_BASE}%` : undefined // TODO(WEB-5452): support dynamic fee tiers
+ return {
+ liquidityValue,
+ feeValue,
+ totalValue,
+ formattedFeeTier,
+ }
+ }
- const value0 = parseFloat(position.amount0.toExact()) * price0
- const value1 = parseFloat(position.amount1.toExact()) * price1
- return value0 + value1
+ // V2 has no fee value so the total value and the liquidity value is the same
+ return { liquidityValue, totalValue: liquidityValue }
+ }, [feeTier, fiatFeeValue0, fiatFeeValue1, fiatValue0, fiatValue1, positionInfo.version])
}
function PositionListItem({ positionInfo }: { positionInfo: PositionInfo }) {
- const { formatNumber } = useFormatter()
-
- const { chainId, position, pool, details, inRange, closed } = positionInfo
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+ const { formatCurrencyAmount } = useLocalizationContext()
- const { priceA, priceB, fees: feeValue } = useFeeValues(positionInfo)
- const liquidityValue = calculateLiquidityValue(priceA, priceB, position)
+ const { tokenId, status, chainId, currency0Amount, currency1Amount } = positionInfo
+ const { liquidityValue, feeValue, totalValue, formattedFeeTier } = useDerivedPositionInfo(positionInfo)
+ const token0 = currency0Amount.currency
+ const token1 = currency1Amount.currency
const navigate = useNavigate()
const accountDrawer = useAccountDrawer()
@@ -138,52 +162,59 @@ function PositionListItem({ positionInfo }: { positionInfo: PositionInfo }) {
if (account.chainId !== chainId) {
await switchChain(chainId)
}
+
accountDrawer.close()
- navigate('/pool/' + details.tokenId)
- }, [account.chainId, chainId, switchChain, accountDrawer, navigate, details.tokenId])
+
+ const positionUrl = isV4EverywhereEnabled
+ ? getPositionUrl(positionInfo)
+ : positionInfo.version === ProtocolVersion.V3
+ ? '/pool/' + tokenId
+ : '/pools/v2'
+ navigate(positionUrl)
+ }, [account.chainId, chainId, switchChain, accountDrawer, navigate, tokenId, isV4EverywhereEnabled, positionInfo])
const analyticsEventProperties = useMemo(
() => ({
chain_id: chainId,
- pool_token_0_symbol: pool.token0.symbol,
- pool_token_1_symbol: pool.token1.symbol,
- pool_token_0_address: pool.token0.address,
- pool_token_1_address: pool.token1.address,
+ pool_token_0_symbol: token0.symbol,
+ pool_token_1_symbol: token1.symbol,
+ pool_token_0_address: token0.isToken ? token0.wrapped.address : ZERO_ADDRESS,
+ pool_token_1_address: token1.isToken ? token1.wrapped.address : ZERO_ADDRESS,
}),
- [chainId, pool.token0.address, pool.token0.symbol, pool.token1.address, pool.token1.symbol],
+ [chainId, token0, token1],
)
return (
}
+ left={}
title={
- {pool.token0.symbol} / {pool.token1?.symbol}
+ {token0.symbol} / {token1?.symbol}
}
- descriptor={{`${pool.fee / BIPS_BASE}%`}}
+ descriptor={{formattedFeeTier}}
right={
<>
- {`${formatNumber({
- input: liquidityValue,
+ {`${formatCurrencyAmount({
+ value: liquidityValue,
type: NumberType.PortfolioBalance,
- })} (liquidity) + ${formatNumber({
- input: feeValue,
+ })} (liquidity) + ${formatCurrencyAmount({
+ value: feeValue,
type: NumberType.PortfolioBalance,
})} (fees)`}
}
>
- {formatNumber({
- input: (liquidityValue ?? 0) + (feeValue ?? 0),
+ {formatCurrencyAmount({
+ value: totalValue,
type: NumberType.PortfolioBalance,
})}
@@ -191,9 +222,16 @@ function PositionListItem({ positionInfo }: { positionInfo: PositionInfo }) {
- {closed ? t('common.closed') : inRange ? t('common.withinRange') : t('common.outOfRange')}
+ {status === PositionStatus.CLOSED
+ ? t('common.closed')
+ : status === PositionStatus.IN_RANGE
+ ? t('common.withinRange')
+ : t('common.outOfRange')}
-
+
>
}
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/cache.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/cache.ts
index b92f8be40ad..6e7c4e444fb 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/cache.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/cache.ts
@@ -7,8 +7,8 @@ import { atomWithStorage } from 'jotai/utils'
import ms from 'ms'
import { useCallback } from 'react'
import { PositionDetails } from 'types/position'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { SerializedToken } from 'uniswap/src/features/tokens/slice/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { deserializeToken, serializeToken } from 'uniswap/src/utils/currency'
import { buildCurrencyKey, currencyKey } from 'utils/currencyKey'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/getTokensAsync.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/getTokensAsync.ts
index c141bf98669..5813bd48454 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/getTokensAsync.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/getTokensAsync.ts
@@ -4,7 +4,7 @@ import ERC20_ABI from 'uniswap/src/abis/erc20.json'
import { Erc20Interface } from 'uniswap/src/abis/types/Erc20'
import { Erc20Bytes32Interface } from 'uniswap/src/abis/types/Erc20Bytes32'
import { UniswapInterfaceMulticall } from 'uniswap/src/abis/types/v3'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { isAddress } from 'utilities/src/addresses'
import { logger } from 'utilities/src/logger/logger'
import { DEFAULT_ERC20_DECIMALS } from 'utilities/src/tokens/constants'
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/hooks.ts b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/hooks.ts
index b08d4cb607b..de41ee698a6 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/hooks.ts
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/hooks.ts
@@ -1,26 +1,21 @@
-import {
- MULTICALL_ADDRESSES,
- Token,
- NONFUNGIBLE_POSITION_MANAGER_ADDRESSES as V3NFT_ADDRESSES,
-} from '@uniswap/sdk-core'
+import { MULTICALL_ADDRESSES, NONFUNGIBLE_POSITION_MANAGER_ADDRESSES as V3NFT_ADDRESSES } from '@uniswap/sdk-core'
import type { AddressMap } from '@uniswap/smart-order-router'
import NFTPositionManagerJSON from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import MulticallJSON from '@uniswap/v3-periphery/artifacts/contracts/lens/UniswapInterfaceMulticall.sol/UniswapInterfaceMulticall.json'
import { useWeb3React } from '@web3-react/core'
import { PositionInfo } from 'components/AccountDrawer/MiniPortfolio/Pools/cache'
-import { useIsSupportedChainIdCallback } from 'constants/chains'
import { RPC_PROVIDERS } from 'constants/providers'
import { BaseContract } from 'ethers/lib/ethers'
import { toContractInput } from 'graphql/data/util'
import { useAccount } from 'hooks/useAccount'
-import useStablecoinPrice from 'hooks/useStablecoinPrice'
import { useMemo } from 'react'
import { NonfungiblePositionManager, UniswapInterfaceMulticall } from 'uniswap/src/abis/types/v3'
import {
ContractInput,
useUniswapPricesQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains, useIsSupportedChainIdCallback } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { getContract } from 'utilities/src/contracts/getContract'
import { CurrencyKey, currencyKey, currencyKeyFromGraphQL } from 'utils/currencyKey'
@@ -68,18 +63,19 @@ export function useInterfaceMulticallContracts(chainIds: UniverseChainId[]): Con
type PriceMap = { [key: CurrencyKey]: number | undefined }
export function usePoolPriceMap(positions: PositionInfo[] | undefined) {
+ const { defaultChainId } = useEnabledChains()
const contracts = useMemo(() => {
if (!positions || !positions.length) {
return []
}
// Avoids fetching duplicate tokens by placing in map
const contractMap = positions.reduce((acc: { [key: string]: ContractInput }, { pool: { token0, token1 } }) => {
- acc[currencyKey(token0)] = toContractInput(token0)
- acc[currencyKey(token1)] = toContractInput(token1)
+ acc[currencyKey(token0)] = toContractInput(token0, defaultChainId)
+ acc[currencyKey(token1)] = toContractInput(token1, defaultChainId)
return acc
}, {})
return Object.values(contractMap)
- }, [positions])
+ }, [defaultChainId, positions])
const { data, loading } = useUniswapPricesQuery({ variables: { contracts }, skip: !contracts.length })
@@ -96,21 +92,3 @@ export function usePoolPriceMap(positions: PositionInfo[] | undefined) {
return { priceMap, pricesLoading: loading && !data }
}
-
-function useFeeValue(token: Token, fee: number | undefined, queriedPrice: number | undefined) {
- const { price: stablecoinPrice } = useStablecoinPrice(!queriedPrice ? token : undefined)
- return useMemo(() => {
- // Prefers gql price, as fetching stablecoinPrice will trigger multiple infura calls for each pool position
- const price = queriedPrice ?? (stablecoinPrice ? parseFloat(stablecoinPrice.toSignificant()) : undefined)
- const feeValue = fee && price ? fee * price : undefined
-
- return [price, feeValue]
- }, [fee, queriedPrice, stablecoinPrice])
-}
-
-export function useFeeValues(position: PositionInfo) {
- const [priceA, feeValueA] = useFeeValue(position.pool.token0, position.fees?.[0], position.prices?.[0])
- const [priceB, feeValueB] = useFeeValue(position.pool.token1, position.fees?.[1], position.prices?.[1])
-
- return { priceA, priceB, fees: (feeValueA || 0) + (feeValueB || 0) }
-}
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions.tsx
index 57a59cc0e12..b585c1566f0 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions.tsx
@@ -19,9 +19,9 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { PositionDetails } from 'types/position'
import { NonfungiblePositionManager, UniswapInterfaceMulticall } from 'uniswap/src/abis/types/v3'
import { UniswapV3PoolInterface } from 'uniswap/src/abis/types/v3/UniswapV3Pool'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { logger } from 'utilities/src/logger/logger'
import { DEFAULT_ERC20_DECIMALS } from 'utilities/src/tokens/constants'
import { currencyKey } from 'utils/currencyKey'
@@ -145,7 +145,7 @@ export default function useMultiChainPositions(account: string): UseMultiChainPo
tokenA,
tokenB,
fee: details.fee,
- chainId: UNIVERSE_CHAIN_INFO[chainId].sdkId,
+ chainId: getChainInfo(chainId).sdkId,
})
poolAddressCache.set(details, chainId, poolAddress)
}
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.test.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.test.tsx
index 01a3b34973c..7005f1396de 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.test.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.test.tsx
@@ -3,7 +3,7 @@ import 'test-utils/tokens/mocks'
import { PortfolioLogo } from 'components/AccountDrawer/MiniPortfolio/PortfolioLogo'
import { render } from 'test-utils/render'
import { DAI, DAI_ARBITRUM_ONE, USDC_ARBITRUM, USDC_MAINNET } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
describe('PortfolioLogo', () => {
it('renders without L2 icon', () => {
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.tsx
index 846031a3071..04c26e10476 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/PortfolioLogo.tsx
@@ -11,11 +11,10 @@ import {
L2LogoContainer,
SingleLogoContainer,
} from 'components/Logo/DoubleLogo'
-import { TESTNET_CHAIN_IDS } from 'constants/chains'
import styled from 'lib/styled-components'
import React, { memo } from 'react'
import { Flex, SpinningLoader, styled as TamaguiStyled } from 'ui/src'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { SUPPORTED_TESTNET_CHAIN_IDS, UniverseChainId } from 'uniswap/src/features/chains/types'
const UnknownContract = styled(UnknownStatus)`
color: ${({ theme }) => theme.neutral2};
@@ -67,7 +66,7 @@ const AbsoluteCenteredElement = TamaguiStyled(Flex, {
* Renders an image by prioritizing a list of sources, and then eventually a fallback contract icon
*/
export const PortfolioLogo = memo(function PortfolioLogo(props: PortfolioLogoProps) {
- if (TESTNET_CHAIN_IDS.includes(props.chainId)) {
+ if (SUPPORTED_TESTNET_CHAIN_IDS.includes(props.chainId)) {
return
}
diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Tokens/TokensTab.tsx b/apps/web/src/components/AccountDrawer/MiniPortfolio/Tokens/TokensTab.tsx
index 49ba0b49473..ece508a6229 100644
--- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Tokens/TokensTab.tsx
+++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Tokens/TokensTab.tsx
@@ -17,11 +17,8 @@ import { useCallback, useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { EllipsisStyle, ThemedText } from 'theme/components'
import { Text, Tooltip } from 'ui/src'
-import {
- useEnabledChains,
- useHideSmallBalancesSetting,
- useHideSpamTokensSetting,
-} from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { useHideSmallBalancesSetting, useHideSpamTokensSetting } from 'uniswap/src/features/settings/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { useTranslation } from 'uniswap/src/i18n'
import { logger } from 'utilities/src/logger/logger'
diff --git a/apps/web/src/components/AccountDrawer/SettingsMenu.tsx b/apps/web/src/components/AccountDrawer/SettingsMenu.tsx
index aa3c2ddcb9d..75f96b9323d 100644
--- a/apps/web/src/components/AccountDrawer/SettingsMenu.tsx
+++ b/apps/web/src/components/AccountDrawer/SettingsMenu.tsx
@@ -6,16 +6,13 @@ import { SpamToggle } from 'components/AccountDrawer/SpamToggle'
import { TestnetsToggle } from 'components/AccountDrawer/TestnetsToggle'
import Column from 'components/deprecated/Column'
import Row from 'components/deprecated/Row'
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
-import { useActiveLanguage } from 'hooks/useActiveLocale'
import styled from 'lib/styled-components'
import { ReactNode } from 'react'
import { ChevronRight } from 'react-feather'
import { ClickableStyle, ThemedText } from 'theme/components'
import ThemeToggle from 'theme/components/ThemeToggle'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { useLanguageInfo } from 'uniswap/src/features/language/hooks'
+import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
+import { useCurrentLanguage, useLanguageInfo } from 'uniswap/src/features/language/hooks'
import { Trans } from 'uniswap/src/i18n'
const Container = styled(Column)`
@@ -72,10 +69,9 @@ export default function SettingsMenu({
openLanguageSettings: () => void
openLocalCurrencySettings: () => void
}) {
- const activeLanguage = useActiveLanguage()
- const activeLocalCurrency = useActiveLocalCurrency()
+ const activeLanguage = useCurrentLanguage()
+ const activeLocalCurrency = useAppFiatCurrency()
const languageInfo = useLanguageInfo(activeLanguage)
- const isTestnetFeatureFlagOn = useFeatureFlag(FeatureFlags.TestnetMode)
return (
} onClose={onClose}>
@@ -86,7 +82,7 @@ export default function SettingsMenu({
- {isTestnetFeatureFlagOn &&
}
+
diff --git a/apps/web/src/components/AccountDrawer/SmallBalanceToggle.tsx b/apps/web/src/components/AccountDrawer/SmallBalanceToggle.tsx
index 3bf664c6075..96150ddfde7 100644
--- a/apps/web/src/components/AccountDrawer/SmallBalanceToggle.tsx
+++ b/apps/web/src/components/AccountDrawer/SmallBalanceToggle.tsx
@@ -1,6 +1,7 @@
import { SettingsToggle } from 'components/AccountDrawer/SettingsToggle'
import { useDispatch } from 'react-redux'
-import { useEnabledChains, useHideSmallBalancesSetting } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { useHideSmallBalancesSetting } from 'uniswap/src/features/settings/hooks'
import { setHideSmallBalances } from 'uniswap/src/features/settings/slice'
import { t } from 'uniswap/src/i18n'
diff --git a/apps/web/src/components/AccountDrawer/TestnetsToggle.tsx b/apps/web/src/components/AccountDrawer/TestnetsToggle.tsx
index 3a5d6196f70..a12a405cfff 100644
--- a/apps/web/src/components/AccountDrawer/TestnetsToggle.tsx
+++ b/apps/web/src/components/AccountDrawer/TestnetsToggle.tsx
@@ -1,7 +1,7 @@
import { SettingsToggle } from 'components/AccountDrawer/SettingsToggle'
import { useDispatch } from 'react-redux'
import { useOpenModal } from 'state/application/hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { setIsTestnetModeEnabled } from 'uniswap/src/features/settings/slice'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { t } from 'uniswap/src/i18n'
diff --git a/apps/web/src/components/AddressQRModal.tsx b/apps/web/src/components/AddressQRModal.tsx
index 6e0232f7e70..35aa53a0418 100644
--- a/apps/web/src/components/AddressQRModal.tsx
+++ b/apps/web/src/components/AddressQRModal.tsx
@@ -2,7 +2,6 @@ import { AddressDisplay } from 'components/AccountDetails/AddressDisplay'
import { SecondaryIdentifiers } from 'components/AccountDrawer/Status'
import Identicon from 'components/Identicon'
import { GetHelpHeader } from 'components/Modal/GetHelpHeader'
-import { PRODUCTION_CHAIN_IDS } from 'constants/chains'
import useENSName from 'hooks/useENSName'
import { useCallback } from 'react'
import { useModalIsOpen, useOpenModal, useToggleModal } from 'state/application/hooks'
@@ -11,6 +10,7 @@ import { ThemedText } from 'theme/components'
import { AdaptiveWebModal, Flex, QRCodeDisplay, Text, useSporeColors } from 'ui/src'
import { NetworkLogos } from 'uniswap/src/components/network/NetworkLogos'
import { useAddressColorProps } from 'uniswap/src/features/address/color'
+import { SUPPORTED_CHAIN_IDS } from 'uniswap/src/features/chains/types'
import { useUnitagByAddress } from 'uniswap/src/features/unitags/hooks'
import { Trans } from 'uniswap/src/i18n'
@@ -72,10 +72,10 @@ export function AddressQRModal({ accountAddress }: { accountAddress: Address })
-
+
diff --git a/apps/web/src/components/Banner/Outage/OutageBanner.tsx b/apps/web/src/components/Banner/Outage/OutageBanner.tsx
index a25c0a4512d..2a460f9828c 100644
--- a/apps/web/src/components/Banner/Outage/OutageBanner.tsx
+++ b/apps/web/src/components/Banner/Outage/OutageBanner.tsx
@@ -1,13 +1,14 @@
import { Container, PopupContainer, StyledXButton, TextContainer } from 'components/Banner/shared/styled'
-import { chainIdToBackendChain } from 'constants/chains'
import { ChainOutageData } from 'featureFlags/flags/outageBanner'
import styled, { useTheme } from 'lib/styled-components'
import { useState } from 'react'
import { Globe } from 'react-feather'
import { ExternalLink, ThemedText } from 'theme/components'
import { capitalize } from 'tsafe'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
const IconContainer = styled.div`
height: 100%;
@@ -43,7 +44,8 @@ export function OutageBanner({ chainId, version }: ChainOutageData) {
const [hidden, setHidden] = useState(false)
const theme = useTheme()
const versionName = version ? version.toString().toLowerCase() + ' data' : 'Data'
- const chainName = capitalize(chainIdToBackendChain({ chainId, withFallback: true }).toLowerCase())
+ const { defaultChainId } = useEnabledChains()
+ const chainName = capitalize(toGraphQLChain(chainId ?? defaultChainId).toLowerCase())
const versionDescription = version ? ' ' + version.toString().toLowerCase() : ''
return (
diff --git a/apps/web/src/components/Banner/shared/Banners.tsx b/apps/web/src/components/Banner/shared/Banners.tsx
index 2b7d497db27..d8535f0d5f6 100644
--- a/apps/web/src/components/Banner/shared/Banners.tsx
+++ b/apps/web/src/components/Banner/shared/Banners.tsx
@@ -1,11 +1,11 @@
import { InterfacePageName } from '@uniswap/analytics-events'
import { OutageBanner, getOutageBannerSessionStorageKey } from 'components/Banner/Outage/OutageBanner'
-import { getChainFromChainUrlParam, isChainUrlParam } from 'constants/chains'
import { manualChainOutageAtom, useOutageBanners } from 'featureFlags/flags/outageBanner'
import { useAtomValue } from 'jotai/utils'
import { useMemo } from 'react'
import { useLocation } from 'react-router-dom'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { getChainIdFromChainUrlParam, isChainUrlParam } from 'utils/chainParams'
import { getCurrentPageFromLocation } from 'utils/urlRoutes'
export function Banners() {
@@ -18,7 +18,7 @@ export function Banners() {
// Calculate the chainId for the current page's contextual chain (e.g. /tokens/ethereum or /tokens/arbitrum), if it exists.
const pageChainId = useMemo(() => {
const chainUrlParam = pathname.split('/').find(isChainUrlParam)
- return chainUrlParam ? getChainFromChainUrlParam(chainUrlParam)?.id : UniverseChainId.Mainnet
+ return chainUrlParam ? getChainIdFromChainUrlParam(chainUrlParam) : UniverseChainId.Mainnet
}, [pathname])
const currentPageHasManualOutage = manualOutage?.chainId === pageChainId
diff --git a/apps/web/src/components/BreadcrumbNav/index.test.tsx b/apps/web/src/components/BreadcrumbNav/index.test.tsx
index 2b433eb0b95..867e602094a 100644
--- a/apps/web/src/components/BreadcrumbNav/index.test.tsx
+++ b/apps/web/src/components/BreadcrumbNav/index.test.tsx
@@ -4,7 +4,7 @@ import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { TokenFromList } from 'state/lists/tokenFromList'
import { act, render, screen } from 'test-utils/render'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
describe('BreadcrumbNav', () => {
it('renders hover components correctly', async () => {
diff --git a/apps/web/src/components/Button/LoaderButton.tsx b/apps/web/src/components/Button/LoaderButton.tsx
new file mode 100644
index 00000000000..83bec13c5c4
--- /dev/null
+++ b/apps/web/src/components/Button/LoaderButton.tsx
@@ -0,0 +1,38 @@
+import { PropsWithChildren } from 'react'
+import { Button, ColorTokens, Flex, SpinningLoader, WidthAnimator } from 'ui/src'
+import { ButtonProps } from 'ui/src/components/button/Button'
+import { iconSizes } from 'ui/src/theme'
+
+type LoaderButtonProps = ButtonProps & {
+ buttonKey: string
+ loading: boolean
+ loaderColor?: ColorTokens
+}
+
+export function LoaderButton({
+ buttonKey,
+ loading,
+ size,
+ animation,
+ children,
+ loaderColor,
+ ...rest
+}: PropsWithChildren) {
+ return (
+
+ )
+}
diff --git a/apps/web/src/components/ChainConnectivityWarning.tsx b/apps/web/src/components/ChainConnectivityWarning.tsx
index 9e5460cb77f..a6531da5ac9 100644
--- a/apps/web/src/components/ChainConnectivityWarning.tsx
+++ b/apps/web/src/components/ChainConnectivityWarning.tsx
@@ -1,4 +1,3 @@
-import { AVERAGE_L1_BLOCK_TIME, getChain } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import { useIsLandingPage } from 'hooks/useIsLandingPage'
@@ -8,9 +7,11 @@ import styled from 'lib/styled-components'
import { useMemo } from 'react'
import { AlertTriangle } from 'react-feather'
import { ExternalLink } from 'theme/components'
-import { DEFAULT_MS_BEFORE_WARNING, UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { DEFAULT_MS_BEFORE_WARNING, getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { AVERAGE_L1_BLOCK_TIME_MS } from 'uniswap/src/features/transactions/swap/hooks/usePollingIntervalByChain'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
const BodyRow = styled.div`
color: ${({ theme }) => theme.neutral1};
@@ -53,22 +54,22 @@ const Wrapper = styled.div`
export function ChainConnectivityWarning() {
const { chainId } = useAccount()
- const info = getChain({ chainId, withFallback: true })
+ const { defaultChainId } = useEnabledChains()
+ const info = getChainInfo(chainId ?? defaultChainId)
const label = info.label
const isNftPage = useIsNftPage()
const isLandingPage = useIsLandingPage()
const waitMsBeforeWarning = useMemo(
- () => (chainId ? UNIVERSE_CHAIN_INFO[chainId]?.blockWaitMsBeforeWarning : undefined) ?? DEFAULT_MS_BEFORE_WARNING,
+ () => (chainId ? getChainInfo(chainId)?.blockWaitMsBeforeWarning : undefined) ?? DEFAULT_MS_BEFORE_WARNING,
[chainId],
)
- const machineTime = useMachineTimeMs(AVERAGE_L1_BLOCK_TIME)
+ const machineTime = useMachineTimeMs(AVERAGE_L1_BLOCK_TIME_MS)
const blockTime = useCurrentBlockTimestamp(
useMemo(
() => ({
- blocksPerFetch:
- /* 5m / 12s = */ 25 * (chainId ? UNIVERSE_CHAIN_INFO[chainId].blockPerMainnetEpochForChainId : 1),
+ blocksPerFetch: /* 5m / 12s = */ 25 * (chainId ? getChainInfo(chainId).blockPerMainnetEpochForChainId : 1),
}),
[chainId],
),
diff --git a/apps/web/src/components/Charts/ChartHeader.tsx b/apps/web/src/components/Charts/ChartHeader.tsx
index 3206ace161e..6901215a52e 100644
--- a/apps/web/src/components/Charts/ChartHeader.tsx
+++ b/apps/web/src/components/Charts/ChartHeader.tsx
@@ -8,8 +8,6 @@ import { EllipsisTamaguiStyle } from 'theme/components'
import { ThemedText } from 'theme/components/text'
import { Flex, Text, styled } from 'ui/src'
import { PriceSource } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import { NumberType, useFormatter } from 'utils/formatNumbers'
export type ChartHeaderProtocolInfo = { protocol: PriceSource; value?: number }
@@ -22,7 +20,7 @@ const ProtocolLegendWrapper = styled(Flex, {
gap: '$gap12',
pointerEvents: 'none',
variants: {
- isMultichainExploreEnabled: {
+ hover: {
true: {
right: 'unset',
p: '$spacing8',
@@ -41,49 +39,28 @@ const ProtocolLegendWrapper = styled(Flex, {
function ProtocolLegend({ protocolData }: { protocolData?: ChartHeaderProtocolInfo[] }) {
const { formatFiatPrice } = useFormatter()
const theme = useTheme()
- const isMultichainExploreEnabled = useFeatureFlag(FeatureFlags.MultichainExplore)
return (
-
+
{protocolData
?.map(({ value, protocol }) => {
- const display = value
- ? formatFiatPrice({ price: value, type: NumberType.ChartFiatValue })
- : isMultichainExploreEnabled
- ? null
- : getProtocolName(protocol)
+ const display = value ? formatFiatPrice({ price: value, type: NumberType.ChartFiatValue }) : null
return (
!!display && (
-
- {isMultichainExploreEnabled ? (
-
- {getProtocolName(protocol)}
-
- ) : (
-
- {display}
-
- )}
+
+
+ {getProtocolName(protocol)}
+
+
- {isMultichainExploreEnabled && (
-
- {display}
-
- )}
+
+ {display}
+
)
)
@@ -141,7 +118,6 @@ export function ChartHeader({
additionalFields,
}: ChartHeaderProps) {
const isHovered = !!time
- const isMultichainExploreEnabled = useFeatureFlag(FeatureFlags.MultichainExplore)
return (
- {((isHovered && protocolData) || !isMultichainExploreEnabled) && }
+ {isHovered && protocolData && }
)
}
diff --git a/apps/web/src/components/Charts/ChartModel.tsx b/apps/web/src/components/Charts/ChartModel.tsx
index bfa95bf8cda..d4d4f2fe762 100644
--- a/apps/web/src/components/Charts/ChartModel.tsx
+++ b/apps/web/src/components/Charts/ChartModel.tsx
@@ -2,7 +2,6 @@ import { PROTOCOL_LEGEND_ELEMENT_ID, SeriesDataItemType } from 'components/Chart
import { formatTickMarks } from 'components/Charts/utils'
import { MissingDataBars } from 'components/Table/icons'
import { useScreenSize } from 'hooks/screenSize/useScreenSize'
-import { useActiveLocale } from 'hooks/useActiveLocale'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { atom } from 'jotai'
import { useUpdateAtom } from 'jotai/utils'
@@ -21,6 +20,7 @@ import {
import { ReactElement, useEffect, useMemo, useRef, useState } from 'react'
import { ThemedText } from 'theme/components'
import { Flex, TamaguiElement, assertWebElement, styled } from 'ui/src'
+import { useCurrentLocale } from 'uniswap/src/features/language/hooks'
import { Trans } from 'uniswap/src/i18n'
import { useFormatter } from 'utils/formatNumbers'
import { v4 as uuidv4 } from 'uuid'
@@ -265,7 +265,7 @@ export function Chart, TDataType e
const [crosshairData, setCrosshairData] = useState(undefined)
const format = useFormatter()
const theme = useTheme()
- const locale = useActiveLocale()
+ const locale = useCurrentLocale()
const { md: isLargeScreen } = useScreenSize()
const modelParams = useMemo(
() => ({ ...params, format, theme, locale, isLargeScreen, onCrosshairMove: setCrosshairData }),
diff --git a/apps/web/src/components/Charts/LiquidityChart/index.tsx b/apps/web/src/components/Charts/LiquidityChart/index.tsx
index 8ee96b70ed9..967027e04b8 100644
--- a/apps/web/src/components/Charts/LiquidityChart/index.tsx
+++ b/apps/web/src/components/Charts/LiquidityChart/index.tsx
@@ -12,7 +12,7 @@ import { TickProcessed, usePoolActiveLiquidity } from 'hooks/usePoolTickData'
import JSBI from 'jsbi'
import { ISeriesApi, UTCTimestamp } from 'lightweight-charts'
import { useEffect, useState } from 'react'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { NumberType, useFormatter } from 'utils/formatNumbers'
interface LiquidityBarChartModelParams extends ChartModelParams, LiquidityBarProps {}
diff --git a/apps/web/src/components/Charts/SparklineChart/index.tsx b/apps/web/src/components/Charts/SparklineChart/index.tsx
index b12f22e4c54..15554814d55 100644
--- a/apps/web/src/components/Charts/SparklineChart/index.tsx
+++ b/apps/web/src/components/Charts/SparklineChart/index.tsx
@@ -1,16 +1,16 @@
import { getPriceBounds } from 'components/Charts/PriceChart/utils'
import LineChart from 'components/Charts/SparklineChart/LineChart'
import { LoadingBubble } from 'components/Tokens/loading'
-import { getChainFromChainUrlParam } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { curveCardinal, scaleLinear } from 'd3'
-import { SparklineMap, TopToken } from 'graphql/data/TopTokens'
+import { SparklineMap, TopToken } from 'graphql/data/types'
import { PricePoint } from 'graphql/data/util'
import styled, { useTheme } from 'lib/styled-components'
import { memo } from 'react'
import { TokenStat } from 'state/explore/types'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
import { addressesAreEquivalent } from 'utils/addressesAreEquivalent'
+import { getChainIdFromChainUrlParam } from 'utils/chainParams'
const LoadingContainer = styled.div`
height: 100%;
@@ -38,8 +38,8 @@ interface SparklineChartProps {
function _SparklineChart({ width, height, tokenData, pricePercentChange, sparklineMap }: SparklineChartProps) {
const theme = useTheme()
// for sparkline
- const chainId = getChainFromChainUrlParam(tokenData?.chain.toLowerCase())?.id
- const chainInfo = chainId && UNIVERSE_CHAIN_INFO[chainId]
+ const chainId = getChainIdFromChainUrlParam(tokenData?.chain.toLowerCase())
+ const chainInfo = chainId && getChainInfo(chainId)
const isNative = addressesAreEquivalent(tokenData?.address, chainInfo?.wrappedNativeCurrency.address)
const pricePoints = tokenData?.address
? sparklineMap[isNative ? NATIVE_CHAIN_ID : tokenData.address.toLowerCase()]
diff --git a/apps/web/src/components/Charts/StackedLineChart/stacked-area-series/renderer.ts b/apps/web/src/components/Charts/StackedLineChart/stacked-area-series/renderer.ts
index beca9f26631..ef270c9168c 100644
--- a/apps/web/src/components/Charts/StackedLineChart/stacked-area-series/renderer.ts
+++ b/apps/web/src/components/Charts/StackedLineChart/stacked-area-series/renderer.ts
@@ -72,29 +72,28 @@ export class StackedAreaSeriesRenderer implements
}
})
const zeroY = priceToCoordinate(0) ?? 0
+ const colorsCount = options.colors.length
+ const isV4EverywhereEnabled = options.colors.length === 3
const { linesMeshed, hoverInfo } = this._createLinePaths(
bars,
this._data.visibleRange,
renderingScope,
zeroY * renderingScope.verticalPixelRatio,
options.hoveredLogicalIndex,
+ isV4EverywhereEnabled,
)
- const fullLinesMeshed = linesMeshed.slice(0, 3)
- const highlightLinesMeshed = options.hoveredLogicalIndex ? linesMeshed.slice(3) : []
+ const fullLinesMeshed = linesMeshed.slice(0, colorsCount + 1)
+ const highlightLinesMeshed = options.hoveredLogicalIndex ? linesMeshed.slice(colorsCount + 1) : []
const areaPaths = this._createAreas(fullLinesMeshed)
- const colorsCount = options.colors.length
const isHovered = options.hoveredLogicalIndex && options.hoveredLogicalIndex !== -1
- const isMultichainExploreEnabled = !!options.gradients
areaPaths.forEach((areaPath, index) => {
// Modification: determine area fill opacity based on number of lines and hover state
if (areaPaths.length === 1) {
ctx.globalAlpha = 0.12 // single-line charts have low opacity fill
- } else if (!isMultichainExploreEnabled) {
- ctx.globalAlpha = isHovered ? 0.24 : 1
}
const gradient = options.gradients
@@ -109,51 +108,47 @@ export class StackedAreaSeriesRenderer implements
ctx.fill(areaPath)
})
- ctx.lineWidth = options.lineWidth * (isMultichainExploreEnabled ? 1 : renderingScope.verticalPixelRatio)
+ ctx.lineWidth = options.lineWidth
ctx.lineJoin = 'round'
fullLinesMeshed.toReversed().forEach((linePath, index) => {
- const unreversedIndex = fullLinesMeshed.length - index
- const color = options.colors[unreversedIndex % colorsCount]
+ const color = options.colors[colorsCount - (index + 1)]
ctx.strokeStyle = color
ctx.fillStyle = color
- ctx.globalAlpha = isHovered && isMultichainExploreEnabled ? 0.24 : 1
+ ctx.globalAlpha = isHovered ? 0.24 : 1
// Bottom line is just the x-axis, which should not be drawn
if (index !== fullLinesMeshed.length - 1) {
// Line rendering:
ctx.beginPath()
- ctx.strokeStyle = color
ctx.stroke(linePath.path)
- }
-
- // Modification: Draws a glyph where lines intersect with the crosshair
- const hoverY = hoverInfo.points[index - 1]
- // Reset the global alpha to 1 after filling in the area under the graph and before drawing the glyph
- ctx.globalAlpha = 1
-
- // Glyph rendering:
- ctx.globalCompositeOperation = 'destination-out' // This mode allows removing a portion of the drawn line from the canvas
- ctx.beginPath()
- ctx.arc(hoverInfo.x, hoverY, 5 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
- ctx.fill() // Cuts a hole out of the line where part of the glyph should be rendered
+ // Modification: Draws a glyph where lines intersect with the crosshair
+ const hoverY = hoverInfo.points.toReversed()[index]
+ // Reset the global alpha to 1 after filling in the area under the graph and before drawing the glyph
+ ctx.globalAlpha = 1
- ctx.globalCompositeOperation = 'source-over' // Resets to default mode
+ // Glyph rendering:
+ ctx.globalCompositeOperation = 'destination-out' // This mode allows removing a portion of the drawn line from the canvas
+ ctx.beginPath()
+ ctx.arc(hoverInfo.x, hoverY, 5 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
+ ctx.fill() // Cuts a hole out of the line where part of the glyph should be rendered
- ctx.beginPath()
+ ctx.globalCompositeOperation = 'source-over' // Resets to default mode
+ ctx.beginPath()
- ctx.arc(hoverInfo.x, hoverY, 3 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
- ctx.fill() // Draws innermost portion of glyph
+ ctx.arc(hoverInfo.x, hoverY, 3 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
+ ctx.fill() // Draws innermost portion of glyph
- ctx.globalAlpha = 0.2
- ctx.beginPath()
- ctx.arc(hoverInfo.x, hoverY, 8 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
- ctx.fill() // Draws middle portion of glyph
+ ctx.globalAlpha = 0.2
+ ctx.beginPath()
+ ctx.arc(hoverInfo.x, hoverY, 8 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
+ ctx.fill() // Draws middle portion of glyph
- ctx.globalAlpha = 0.3
- ctx.beginPath()
- ctx.arc(hoverInfo.x, hoverY, 12 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
- ctx.fill() // Draws outer portion of glyph
+ ctx.globalAlpha = 0.3
+ ctx.beginPath()
+ ctx.arc(hoverInfo.x, hoverY, 12 * renderingScope.verticalPixelRatio, 0, 2 * Math.PI)
+ ctx.fill() // Draws outer portion of glyph
+ }
ctx.globalAlpha = 1
})
@@ -163,19 +158,14 @@ export class StackedAreaSeriesRenderer implements
ctx.globalAlpha = 1
return
}
- const unreversedIndex = fullLinesMeshed.length - index
- const color = options.colors[unreversedIndex % colorsCount]
+ const color = options.colors[colorsCount - (index + 1)]
ctx.strokeStyle = color
ctx.fillStyle = color
ctx.globalAlpha = 1
- // Bottom line is just the x-axis, which should not be drawn
- if (index !== fullLinesMeshed.length - 1) {
- // Line rendering:
- ctx.beginPath()
- ctx.strokeStyle = color
- ctx.stroke(linePath.path)
- }
+ // Line rendering:
+ ctx.beginPath()
+ ctx.stroke(linePath.path)
})
}
@@ -186,17 +176,22 @@ export class StackedAreaSeriesRenderer implements
renderingScope: BitmapCoordinatesRenderingScope,
zeroY: number,
hoveredIndex?: number | null,
+ isV4EverywhereEnabled?: boolean,
) {
const { horizontalPixelRatio, verticalPixelRatio } = renderingScope
- const oddLines: LinePathData[] = []
- const evenLines: LinePathData[] = []
- const oddHighlightLines: LinePathData[] = []
- const evenHighlightLines: LinePathData[] = []
+ const v2Lines: LinePathData[] = []
+ const v3Lines: LinePathData[] = []
+ const v4Lines: LinePathData[] = []
+ const v2HighlightLines: LinePathData[] = []
+ const v3HighlightLines: LinePathData[] = []
+ const v4HighlightLines: LinePathData[] = []
+
let firstBar = true
// Modification: tracks and returns coordinates of where a glyph should be rendered for each line when a crosshair is drawn
const hoverInfo = { points: new Array(), x: 0 }
+ const numLines = isV4EverywhereEnabled ? 3 : 2
// Modification: updated loop to include one point above and below the visible range to ensure the line is drawn to edges of chart
for (let i = visibleRange.from - 1; i < visibleRange.to + 1; i++) {
if (i >= bars.length || i < 0) {
@@ -206,8 +201,8 @@ export class StackedAreaSeriesRenderer implements
const stack = bars[i]
let lineIndex = 0
stack.ys.forEach((yMedia, index) => {
- if (index % 2 !== 0) {
- return // only doing odd at the moment
+ if (index % numLines !== 0) {
+ return
}
const x = stack.x * horizontalPixelRatio
@@ -219,34 +214,86 @@ export class StackedAreaSeriesRenderer implements
}
if (firstBar) {
- oddLines[lineIndex] = {
+ v2Lines[lineIndex] = {
path: new Path2D(),
first: { x, y },
last: { x, y },
}
- oddLines[lineIndex].path.moveTo(x, y)
+ v2Lines[lineIndex].path.moveTo(x, y)
} else {
- oddLines[lineIndex].path.lineTo(x, y)
- oddLines[lineIndex].last.x = x
- oddLines[lineIndex].last.y = y
+ v2Lines[lineIndex].path.lineTo(x, y)
+ v2Lines[lineIndex].last.x = x
+ v2Lines[lineIndex].last.y = y
}
if (firstBar && hoveredIndex && i <= hoveredIndex) {
- oddHighlightLines[lineIndex] = {
+ v2HighlightLines[lineIndex] = {
+ path: new Path2D(),
+ first: { x, y },
+ last: { x, y },
+ }
+ v2HighlightLines[lineIndex].path.moveTo(x, y)
+ } else if (hoveredIndex && i <= hoveredIndex) {
+ v2HighlightLines[lineIndex].path.lineTo(x, y)
+ v2HighlightLines[lineIndex].last.x = x
+ v2HighlightLines[lineIndex].last.y = y
+ }
+ lineIndex += 1
+ })
+ firstBar = false
+ }
+ firstBar = true
+ // Modification: updated loop to include one point above and below the visible range to ensure the line is drawn to edges of chart
+ for (let i = visibleRange.to + 1; i >= visibleRange.from - 1; i--) {
+ if (i >= bars.length || i < 0) {
+ continue
+ }
+ const stack = bars[i]
+ let lineIndex = 0
+ stack.ys.forEach((yMedia, index) => {
+ if (index % numLines !== 1) {
+ return
+ }
+
+ const x = stack.x * horizontalPixelRatio
+ const y = yMedia * verticalPixelRatio
+
+ if (i === hoveredIndex) {
+ hoverInfo.points[index] = y
+ hoverInfo.x = x
+ }
+
+ if (firstBar) {
+ v3Lines[lineIndex] = {
+ path: new Path2D(),
+ first: { x, y },
+ last: { x, y },
+ }
+ v3Lines[lineIndex].path.moveTo(x, y)
+ } else {
+ v3Lines[lineIndex].path.lineTo(x, y)
+ v3Lines[lineIndex].last.x = x
+ v3Lines[lineIndex].last.y = y
+ }
+
+ if (v3HighlightLines.length <= lineIndex && hoveredIndex && i <= hoveredIndex) {
+ v3HighlightLines[lineIndex] = {
path: new Path2D(),
first: { x, y },
last: { x, y },
}
- oddHighlightLines[lineIndex].path.moveTo(x, y)
+ v3HighlightLines[lineIndex].path.moveTo(x, y)
} else if (hoveredIndex && i <= hoveredIndex) {
- oddHighlightLines[lineIndex].path.lineTo(x, y)
- oddHighlightLines[lineIndex].last.x = x
- oddHighlightLines[lineIndex].last.y = y
+ v3HighlightLines[lineIndex].path.lineTo(x, y)
+ v3HighlightLines[lineIndex].last.x = x
+ v3HighlightLines[lineIndex].last.y = y
}
+
lineIndex += 1
})
firstBar = false
}
firstBar = true
+
// Modification: updated loop to include one point above and below the visible range to ensure the line is drawn to edges of chart
for (let i = visibleRange.to + 1; i >= visibleRange.from - 1; i--) {
if (i >= bars.length || i < 0) {
@@ -255,8 +302,8 @@ export class StackedAreaSeriesRenderer implements
const stack = bars[i]
let lineIndex = 0
stack.ys.forEach((yMedia, index) => {
- if (index % 2 === 0) {
- return // only doing even at the moment
+ if (index % numLines !== 2 || !isV4EverywhereEnabled) {
+ return
}
const x = stack.x * horizontalPixelRatio
@@ -268,29 +315,29 @@ export class StackedAreaSeriesRenderer implements
}
if (firstBar) {
- evenLines[lineIndex] = {
+ v4Lines[lineIndex] = {
path: new Path2D(),
first: { x, y },
last: { x, y },
}
- evenLines[lineIndex].path.moveTo(x, y)
+ v4Lines[lineIndex].path.moveTo(x, y)
} else {
- evenLines[lineIndex].path.lineTo(x, y)
- evenLines[lineIndex].last.x = x
- evenLines[lineIndex].last.y = y
+ v4Lines[lineIndex].path.lineTo(x, y)
+ v4Lines[lineIndex].last.x = x
+ v4Lines[lineIndex].last.y = y
}
- if (evenHighlightLines.length <= lineIndex && hoveredIndex && i <= hoveredIndex) {
- evenHighlightLines[lineIndex] = {
+ if (v4HighlightLines.length <= lineIndex && hoveredIndex && i <= hoveredIndex) {
+ v4HighlightLines[lineIndex] = {
path: new Path2D(),
first: { x, y },
last: { x, y },
}
- evenHighlightLines[lineIndex].path.moveTo(x, y)
+ v4HighlightLines[lineIndex].path.moveTo(x, y)
} else if (hoveredIndex && i <= hoveredIndex) {
- evenHighlightLines[lineIndex].path.lineTo(x, y)
- evenHighlightLines[lineIndex].last.x = x
- evenHighlightLines[lineIndex].last.y = y
+ v4HighlightLines[lineIndex].path.lineTo(x, y)
+ v4HighlightLines[lineIndex].last.x = x
+ v4HighlightLines[lineIndex].last.y = y
}
lineIndex += 1
@@ -300,20 +347,24 @@ export class StackedAreaSeriesRenderer implements
const baseLine = {
path: new Path2D(),
- first: { x: oddLines[0].last.x, y: zeroY },
- last: { x: oddLines[0].first.x, y: zeroY },
+ first: { x: v2Lines[0].last.x, y: zeroY },
+ last: { x: v2Lines[0].first.x, y: zeroY },
}
- baseLine.path.moveTo(oddLines[0].last.x, zeroY)
- baseLine.path.lineTo(oddLines[0].first.x, zeroY)
+ baseLine.path.moveTo(v2Lines[0].last.x, zeroY)
+ baseLine.path.lineTo(v2Lines[0].first.x, zeroY)
const linesMeshed: LinePathData[] = [baseLine]
- for (let i = 0; i < oddLines.length; i++) {
- linesMeshed.push(oddLines[i])
- if (i < evenLines.length) {
- linesMeshed.push(evenLines[i])
+ for (let i = 0; i < v2Lines.length; i++) {
+ linesMeshed.push(v2Lines[i])
+ if (i < v3Lines.length) {
+ linesMeshed.push(v3Lines[i])
+ }
+ if (i < v4Lines.length && isV4EverywhereEnabled) {
+ linesMeshed.push(v4Lines[i])
}
if (hoveredIndex) {
- linesMeshed.push(oddHighlightLines[i])
- linesMeshed.push(evenHighlightLines[i])
+ linesMeshed.push(v2HighlightLines[i])
+ linesMeshed.push(v3HighlightLines[i])
+ isV4EverywhereEnabled && linesMeshed.push(v4HighlightLines[i])
}
}
@@ -324,10 +375,13 @@ export class StackedAreaSeriesRenderer implements
_createAreas(linesMeshed: LinePathData[]): Path2D[] {
const areas: Path2D[] = []
for (let i = 1; i < linesMeshed.length; i++) {
- const areaPath = new Path2D(linesMeshed[i - 1].path)
+ // The first area must reference the base line, aka index 0
+ // All other areas need to reference the first area to fully fill the bottom of the graph
+ const baseReferenceIndex = Math.min(i - 1, 1)
+ const areaPath = new Path2D(linesMeshed[baseReferenceIndex].path)
areaPath.lineTo(linesMeshed[i].first.x, linesMeshed[i].first.y)
areaPath.addPath(linesMeshed[i].path)
- areaPath.lineTo(linesMeshed[i - 1].first.x, linesMeshed[i - 1].first.y)
+ areaPath.lineTo(linesMeshed[baseReferenceIndex].first.x, linesMeshed[baseReferenceIndex].first.y)
areaPath.closePath()
areas.push(areaPath)
}
diff --git a/apps/web/src/components/Charts/VolumeChart/CustomVolumeChartModel.tsx b/apps/web/src/components/Charts/VolumeChart/CustomVolumeChartModel.tsx
index fb1c359563e..df171ed5924 100644
--- a/apps/web/src/components/Charts/VolumeChart/CustomVolumeChartModel.tsx
+++ b/apps/web/src/components/Charts/VolumeChart/CustomVolumeChartModel.tsx
@@ -9,7 +9,6 @@ export type CustomVolumeChartModelParams = {
colors: string[]
headerHeight: number
useThinCrosshair?: boolean
- isMultichainExploreEnabled?: boolean
background?: string
}
@@ -26,7 +25,6 @@ export class CustomVolumeChartModel exten
this.series = this.api.addCustomSeries(
new CustomHistogramSeries({
colors: params.colors,
- isMultichainExploreEnabled: params.isMultichainExploreEnabled,
background: params.background,
}),
)
diff --git a/apps/web/src/components/Charts/VolumeChart/custom-histogram-series.tsx b/apps/web/src/components/Charts/VolumeChart/custom-histogram-series.tsx
index 53e04c96173..9fd4870124d 100644
--- a/apps/web/src/components/Charts/VolumeChart/custom-histogram-series.tsx
+++ b/apps/web/src/components/Charts/VolumeChart/custom-histogram-series.tsx
@@ -23,13 +23,11 @@ export class CustomHistogramSeries
{
_renderer: CustomHistogramSeriesRenderer
_colors: string[]
- _isMultichainExploreEnabled?: boolean
_background?: string
constructor(props: CustomHistogramProps) {
this._renderer = new CustomHistogramSeriesRenderer(props)
this._colors = props.colors
- this._isMultichainExploreEnabled = props.isMultichainExploreEnabled
this._background = props.background
}
diff --git a/apps/web/src/components/Charts/VolumeChart/renderer.tsx b/apps/web/src/components/Charts/VolumeChart/renderer.tsx
index 6c38d88911c..1540dfd57a2 100644
--- a/apps/web/src/components/Charts/VolumeChart/renderer.tsx
+++ b/apps/web/src/components/Charts/VolumeChart/renderer.tsx
@@ -57,7 +57,6 @@ function cumulativeBuildUp(data: StackedHistogramData): number[] {
export interface CustomHistogramProps {
colors: string[]
- isMultichainExploreEnabled?: boolean
background?: string
}
@@ -65,12 +64,10 @@ export class CustomHistogramSeriesRenderer im
_data: PaneRendererCustomData
- {protocolVersion === ProtocolVersion.V2 && v2}
- {!!feePercent && {feePercent}}
+
+
+ {protocolVersion?.toLowerCase()}
+
+ {/* TODO(WEB-5364): add hook badge when data available, it should have a hover state and link out to the explorer */}
+ {!!feePercent && (
+
+ {feePercent}
+
+ )}
+
{
beforeEach(() => {
diff --git a/apps/web/src/components/Pools/PoolDetails/PoolDetailsLink.tsx b/apps/web/src/components/Pools/PoolDetails/PoolDetailsLink.tsx
index d7456ec8928..a2e0a9f7144 100644
--- a/apps/web/src/components/Pools/PoolDetails/PoolDetailsLink.tsx
+++ b/apps/web/src/components/Pools/PoolDetails/PoolDetailsLink.tsx
@@ -5,7 +5,6 @@ import { DoubleCurrencyAndChainLogo } from 'components/Logo/DoubleLogo'
import { DetailBubble, SmallDetailBubble } from 'components/Pools/PoolDetails/shared'
import Tooltip, { TooltipSize } from 'components/Tooltip'
import Row from 'components/deprecated/Row'
-import { chainIdToBackendChain } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { getTokenDetailsURL, gqlToCurrency } from 'graphql/data/util'
import useCopyClipboard from 'hooks/useCopyClipboard'
@@ -16,8 +15,10 @@ import { useNavigate } from 'react-router-dom'
import { BREAKPOINTS } from 'theme'
import { ClickableStyle, EllipsisStyle, ExternalLink, ThemedText } from 'theme/components'
import { Token } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { Trans, t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { isAddress, shortenAddress } from 'utilities/src/addresses'
@@ -107,7 +108,8 @@ export function PoolDetailsLink({ address, chainId, tokens, loading }: PoolDetai
)
const navigate = useNavigate()
- const chainName = chainIdToBackendChain({ chainId, withFallback: true })
+ const { defaultChainId } = useEnabledChains()
+ const chainName = toGraphQLChain(chainId ?? defaultChainId)
const handleTokenTextClick = useCallback(() => {
if (!isPool) {
navigate(getTokenDetailsURL({ address: tokens[0]?.address, chain: chainName }))
diff --git a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.tsx b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.tsx
index 2e781da625b..44b07e10bad 100644
--- a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.tsx
+++ b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.tsx
@@ -5,7 +5,6 @@ import { DeltaArrow } from 'components/Tokens/TokenDetails/Delta'
import { LoadingBubble } from 'components/Tokens/loading'
import Column from 'components/deprecated/Column'
import Row from 'components/deprecated/Row'
-import { chainIdToBackendChain } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { PoolData } from 'graphql/data/pools/usePoolData'
import { getTokenDetailsURL, unwrapToken } from 'graphql/data/util'
@@ -19,8 +18,10 @@ import { BREAKPOINTS } from 'theme'
import { ClickableStyle, ThemedText } from 'theme/components'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { Token } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const HeaderText = styled(Text)`
@@ -133,6 +134,7 @@ const PoolBalanceTokenNames = ({ token, chainId }: { token: TokenFullData; chain
const unwrappedToken = chainId ? unwrapToken(chainId, token) : token
const isNative = unwrappedToken?.address === NATIVE_CHAIN_ID
const currency = isNative && chainId ? nativeOnChain(chainId) : token.currency
+ const { defaultChainId } = useEnabledChains()
return (
{!screenIsNotLarge && }
@@ -144,7 +146,7 @@ const PoolBalanceTokenNames = ({ token, chainId }: { token: TokenFullData; chain
{screenIsNotLarge && (
diff --git a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.test.tsx b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.test.tsx
index b4bb448ad68..8e0285fec30 100644
--- a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.test.tsx
+++ b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.test.tsx
@@ -10,8 +10,8 @@ import { mocked } from 'test-utils/mocked'
import { useMultiChainPositionsReturnValue, validBEPoolToken0, validBEPoolToken1 } from 'test-utils/pools/fixtures'
import { act, render, screen } from 'test-utils/render'
import { useUniswapContext } from 'uniswap/src/contexts/UniswapContext'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { dismissTokenWarning } from 'uniswap/src/features/tokens/slice/slice'
-import { UniverseChainId } from 'uniswap/src/types/chains'
jest.mock('components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions')
diff --git a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.tsx b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.tsx
index e5267373ee3..13e1a3826b5 100644
--- a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.tsx
+++ b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStatsButtons.tsx
@@ -6,9 +6,9 @@ import Column from 'components/deprecated/Column'
import Row from 'components/deprecated/Row'
import { SwapWrapperOuter } from 'components/swap/styled'
import { LoadingBubble } from 'components/Tokens/loading'
-import TokenSafetyMessage from 'components/TokenSafety/TokenSafetyMessage'
-import { chainIdToBackendChain } from 'constants/chains'
+import TokenSafetyMessage from 'components/TokenSafety/DeprecatedTokenSafetyMessage'
import { getPriorityWarning, StrongWarning, useTokenWarning } from 'constants/deprecatedTokenSafety'
+import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { useTokenBalancesQuery } from 'graphql/data/apollo/AdaptiveTokenBalancesProvider'
import { gqlToCurrency } from 'graphql/data/util'
import { useScreenSize } from 'hooks/screenSize/useScreenSize'
@@ -16,7 +16,7 @@ import { useAccount } from 'hooks/useAccount'
import { useSwitchChain } from 'hooks/useSwitchChain'
import styled from 'lib/styled-components'
import { Swap } from 'pages/Swap'
-import { useMemo, useReducer } from 'react'
+import { useCallback, useMemo, useReducer, useState } from 'react'
import { Plus, X } from 'react-feather'
import { useLocation, useNavigate } from 'react-router-dom'
import { BREAKPOINTS } from 'theme'
@@ -25,9 +25,17 @@ import { opacify } from 'theme/utils'
import { Z_INDEX } from 'theme/zIndex'
import { ArrowUpDown } from 'ui/src/components/icons/ArrowUpDown'
import { Token } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
+import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+import { TokenWarningCard } from 'uniswap/src/features/tokens/TokenWarningCard'
+import TokenWarningModal from 'uniswap/src/features/tokens/TokenWarningModal'
+import { useCurrencyInfo } from 'uniswap/src/features/tokens/useCurrencyInfo'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
-import { currencyId } from 'utils/currencyId'
+import { currencyId } from 'uniswap/src/utils/currencyId'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const PoolDetailsStatsButtonsRow = styled(Row)`
@@ -154,16 +162,19 @@ export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier, load
const position = userOwnedPositions && findMatchingPosition(userOwnedPositions, token0, token1, feeTier)
const tokenId = position?.details.tokenId
const switchChain = useSwitchChain()
+ const { defaultChainId } = useEnabledChains()
const navigate = useNavigate()
const location = useLocation()
const currency0 = token0 && gqlToCurrency(token0)
const currency1 = token1 && gqlToCurrency(token1)
+ const currencyInfo0 = useCurrencyInfo(currency0 && currencyId(currency0))
+ const currencyInfo1 = useCurrencyInfo(currency1 && currencyId(currency1))
// Mobile Balance Data
const { data: balanceQuery } = useTokenBalancesQuery()
const { balance0, balance1, balance0Fiat, balance1Fiat } = useMemo(() => {
const filteredBalances = balanceQuery?.portfolios?.[0]?.tokenBalances?.filter(
- (tokenBalance) => tokenBalance?.token?.chain === chainIdToBackendChain({ chainId, withFallback: true }),
+ (tokenBalance) => tokenBalance?.token?.chain === toGraphQLChain(chainId ?? defaultChainId),
)
const tokenBalance0 = filteredBalances?.find((tokenBalance) => tokenBalance?.token?.address === token0?.address)
const tokenBalance1 = filteredBalances?.find((tokenBalance) => tokenBalance?.token?.address === token1?.address)
@@ -173,7 +184,7 @@ export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier, load
balance0Fiat: tokenBalance0?.denominatedValue?.value ?? 0,
balance1Fiat: tokenBalance1?.denominatedValue?.value ?? 0,
}
- }, [balanceQuery?.portfolios, chainId, token0?.address, token1?.address])
+ }, [balanceQuery?.portfolios, chainId, defaultChainId, token0?.address, token1?.address])
const { formatNumber } = useFormatter()
const formattedBalance0 = formatNumber({
input: balance0,
@@ -194,7 +205,9 @@ export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier, load
if (account.chainId !== chainId && chainId) {
await switchChain(chainId)
}
- navigate(`/add/${currencyId(currency0)}/${currencyId(currency1)}/${feeTier}${tokenId ? `/${tokenId}` : ''}`, {
+ const currency0Address = currency0.isNative ? NATIVE_CHAIN_ID : currency0.address
+ const currency1Address = currency1.isNative ? NATIVE_CHAIN_ID : currency1.address
+ navigate(`/add/${currency0Address}/${currency1Address}/${feeTier}${tokenId ? `/${tokenId}` : ''}`, {
state: { from: location.pathname },
})
}
@@ -207,6 +220,15 @@ export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier, load
const token1Warning = useTokenWarning(token1?.address, chainId)
const priorityWarning = getPriorityWarning(token0Warning, token1Warning)
+ const tokenProtectionEnabled = useFeatureFlag(FeatureFlags.TokenProtection)
+ const [showWarningModal, setShowWarningModal] = useState(false)
+ const closeWarningModal = useCallback(() => setShowWarningModal(false), [])
+ const [warningModalCurrencyInfo, setWarningModalCurrencyInfo] = useState>()
+ const onWarningCardCtaPressed = useCallback((currencyInfo: Maybe) => {
+ setWarningModalCurrencyInfo(currencyInfo)
+ setShowWarningModal(true)
+ }, [])
+
if (loading || !currency0 || !currency1) {
return (
@@ -282,13 +304,30 @@ export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier, load
compact
disableTokenInputs={chainId !== account.chainId}
/>
- {Boolean(priorityWarning) && (
-
+ {tokenProtectionEnabled ? (
+ <>
+ onWarningCardCtaPressed(currencyInfo0)} />
+ onWarningCardCtaPressed(currencyInfo1)} />
+ {warningModalCurrencyInfo && (
+ // Intentionally duplicative with the TokenWarningModal in the swap component; this one only displays when user clicks "i" Info button on the TokenWarningCard
+
+ )}
+ >
+ ) : (
+ Boolean(priorityWarning) && (
+
+ )
)}
!s, false)
const filterAnchorRef = useRef(null)
@@ -83,7 +84,7 @@ export function PoolDetailsTransactionsTable({
const { transactions, loading, loadMore, error } = usePoolTransactions(
poolAddress,
- chain.id,
+ chainId,
filter,
token0,
protocolVersion,
@@ -113,7 +114,7 @@ export function PoolDetailsTransactionsTable({
>
),
@@ -266,7 +267,7 @@ export function PoolDetailsTransactionsTable({
justifyContent="flex-end"
grow
>
-
+
{shortenAddress(makerAddress.getValue?.(), 0)}
@@ -275,7 +276,7 @@ export function PoolDetailsTransactionsTable({
]
}, [
activeLocalCurrency,
- chain.id,
+ chainId,
filter,
filterModalIsOpen,
formatFiatPrice,
diff --git a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap
index fef3b3d892b..8a5bd4f0403 100644
--- a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap
+++ b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap
@@ -284,7 +284,7 @@ exports[`PoolDetailsHeader renders header text correctly 1`] = `
min-width: 0;
}
-.c12 {
+.c10 {
box-sizing: border-box;
margin: 0;
min-width: 0;
@@ -311,7 +311,7 @@ exports[`PoolDetailsHeader renders header text correctly 1`] = `
gap: 12px;
}
-.c13 {
+.c11 {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
@@ -331,7 +331,7 @@ exports[`PoolDetailsHeader renders header text correctly 1`] = `
gap: 8px;
}
-.c14 {
+.c12 {
display: inline-block;
height: inherit;
}
@@ -344,14 +344,6 @@ exports[`PoolDetailsHeader renders header text correctly 1`] = `
letter-spacing: -0.01em;
}
-.c10 {
- color: #7D7D7D;
- -webkit-letter-spacing: -0.01em;
- -moz-letter-spacing: -0.01em;
- -ms-letter-spacing: -0.01em;
- letter-spacing: -0.01em;
-}
-
.c4 {
display: -webkit-box;
display: -webkit-flex;
@@ -411,12 +403,6 @@ exports[`PoolDetailsHeader renders header text correctly 1`] = `
animation-duration: 250ms;
}
-.c11 {
- background: #F9F9F9;
- padding: 2px 6px;
- border-radius: 4px;
-}
-
.c6 {
display: -webkit-box;
display: -webkit-flex;
@@ -523,9 +509,18 @@ exports[`PoolDetailsHeader renders header text correctly 1`] = `
- 0.05%
+
+
+ 0.05%
+
@@ -605,7 +600,7 @@ exports[`PoolDetailsHeader renders header text correctly 1`] = `
id="Dropdown"
>
diff --git a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStatsButtons.test.tsx.snap b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStatsButtons.test.tsx.snap
index 3c563591913..1bfa640becf 100644
--- a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStatsButtons.test.tsx.snap
+++ b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStatsButtons.test.tsx.snap
@@ -425,7 +425,7 @@ exports[`PoolDetailsStatsButton renders both buttons correctly 1`] = `
transition: opacity 250ms ease-in-out;
}
-.c52 {
+.c53 {
z-index: 1020;
overflow: hidden;
top: 0;
@@ -941,8 +941,14 @@ exports[`PoolDetailsStatsButton renders both buttons correctly 1`] = `
}
}
-@media only screen and (max-width:1024px) {
+@media (max-width:720px) {
.c52 {
+ display: none;
+ }
+}
+
+@media only screen and (max-width:1024px) {
+ .c53 {
opacity: 0;
pointer-events: none;
-webkit-transition: opacity 250ms ease-in-out;
@@ -1439,10 +1445,94 @@ exports[`PoolDetailsStatsButton renders both buttons correctly 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+ Swapping across networks
+
+
+
+
+
+ Move ETH, USDC, and more across 8+ networks.
+
+
+
+
+
+
+
diff --git a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap
index 5bd7b641b20..5d92908a1ee 100644
--- a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap
+++ b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap
@@ -2,31 +2,7 @@
exports[`PoolDetailsTransactionsTable renders data filled state 1`] = `
- .c1 {
- box-sizing: border-box;
- margin: 0;
- min-width: 0;
-}
-
-.c2 {
- width: 100%;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- padding: 0;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: start;
- -webkit-justify-content: flex-start;
- -ms-flex-pack: start;
- justify-content: flex-start;
- gap: 4px;
-}
-
-.c5 {
+ .c5 {
color: #7D7D7D;
-webkit-letter-spacing: -0.01em;
-moz-letter-spacing: -0.01em;
@@ -69,6 +45,30 @@ exports[`PoolDetailsTransactionsTable renders data filled state 1`] = `
opacity: 0.4;
}
+.c1 {
+ box-sizing: border-box;
+ margin: 0;
+ min-width: 0;
+}
+
+.c2 {
+ width: 100%;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ padding: 0;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: start;
+ -webkit-justify-content: flex-start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ gap: 4px;
+}
+
.c8 {
display: inline-block;
height: inherit;
@@ -417,31 +417,7 @@ exports[`PoolDetailsTransactionsTable renders data filled state 1`] = `
exports[`PoolDetailsTransactionsTable renders error state 1`] = `
- .c1 {
- box-sizing: border-box;
- margin: 0;
- min-width: 0;
-}
-
-.c2 {
- width: 100%;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- padding: 0;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: start;
- -webkit-justify-content: flex-start;
- -ms-flex-pack: start;
- justify-content: flex-start;
- gap: 4px;
-}
-
-.c9 {
+ .c9 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@@ -501,6 +477,30 @@ exports[`PoolDetailsTransactionsTable renders error state 1`] = `
border-radius: 20px;
}
+.c1 {
+ box-sizing: border-box;
+ margin: 0;
+ min-width: 0;
+}
+
+.c2 {
+ width: 100%;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ padding: 0;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: start;
+ -webkit-justify-content: flex-start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ gap: 4px;
+}
+
.c3 {
height: 16px;
width: 16px;
@@ -1285,7 +1285,15 @@ exports[`PoolDetailsTransactionsTable renders error state 1`] = `
exports[`PoolDetailsTransactionsTable renders loading state 1`] = `
- .c1 {
+ .c5 {
+ color: #7D7D7D;
+ -webkit-letter-spacing: -0.01em;
+ -moz-letter-spacing: -0.01em;
+ -ms-letter-spacing: -0.01em;
+ letter-spacing: -0.01em;
+}
+
+.c1 {
box-sizing: border-box;
margin: 0;
min-width: 0;
@@ -1309,14 +1317,6 @@ exports[`PoolDetailsTransactionsTable renders loading state 1`] = `
gap: 4px;
}
-.c5 {
- color: #7D7D7D;
- -webkit-letter-spacing: -0.01em;
- -moz-letter-spacing: -0.01em;
- -ms-letter-spacing: -0.01em;
- letter-spacing: -0.01em;
-}
-
.c3 {
height: 16px;
width: 16px;
diff --git a/apps/web/src/components/Pools/PoolTable/PoolTable.test.tsx b/apps/web/src/components/Pools/PoolTable/PoolTable.test.tsx
index 5e63dd478a8..1b4c34ad143 100644
--- a/apps/web/src/components/Pools/PoolTable/PoolTable.test.tsx
+++ b/apps/web/src/components/Pools/PoolTable/PoolTable.test.tsx
@@ -1,16 +1,15 @@
import 'test-utils/tokens/mocks'
-import { ApolloError } from '@apollo/client'
import { Percent } from '@uniswap/sdk-core'
import { TopPoolTable } from 'components/Pools/PoolTable/PoolTable'
-import { useTopPools } from 'graphql/data/pools/useTopPools'
import Router from 'react-router-dom'
+import { useTopPools } from 'state/explore/topPools'
import { mocked } from 'test-utils/mocked'
-import { validBEPoolToken0, validBEPoolToken1, validParams } from 'test-utils/pools/fixtures'
+import { validParams, validRestPoolToken0, validRestPoolToken1 } from 'test-utils/pools/fixtures'
import { render, screen } from 'test-utils/render'
import { ProtocolVersion } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-jest.mock('graphql/data/pools/useTopPools')
+jest.mock('state/explore/topPools')
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: jest.fn(),
@@ -23,9 +22,8 @@ describe('PoolTable', () => {
it('renders loading state', () => {
mocked(useTopPools).mockReturnValue({
- loading: true,
- errorV3: undefined,
- errorV2: undefined,
+ isLoading: true,
+ isError: false,
topPools: [],
})
@@ -36,9 +34,8 @@ describe('PoolTable', () => {
it('renders error state', () => {
mocked(useTopPools).mockReturnValue({
- loading: false,
- errorV3: new ApolloError({ errorMessage: 'error fetching data' }),
- errorV2: new ApolloError({ errorMessage: 'error fetching data' }),
+ isLoading: false,
+ isError: true,
topPools: [],
})
@@ -50,8 +47,10 @@ describe('PoolTable', () => {
it('renders data filled state', () => {
const mockData = [
{
- token0: validBEPoolToken0,
- token1: validBEPoolToken1,
+ id: '1',
+ chain: 'mainnet',
+ token0: validRestPoolToken0,
+ token1: validRestPoolToken1,
feeTier: 10000,
hash: '0x123',
txCount: 200,
@@ -65,9 +64,8 @@ describe('PoolTable', () => {
]
mocked(useTopPools).mockReturnValue({
topPools: mockData,
- loading: false,
- errorV3: undefined,
- errorV2: undefined,
+ isLoading: false,
+ isError: false,
})
const { asFragment } = render()
diff --git a/apps/web/src/components/Pools/PoolTable/PoolTable.tsx b/apps/web/src/components/Pools/PoolTable/PoolTable.tsx
index e71193e25f6..d415cc5d605 100644
--- a/apps/web/src/components/Pools/PoolTable/PoolTable.tsx
+++ b/apps/web/src/components/Pools/PoolTable/PoolTable.tsx
@@ -12,16 +12,8 @@ import { EllipsisText } from 'components/Tokens/TokenTable'
import { MAX_WIDTH_MEDIA_BREAKPOINT } from 'components/Tokens/constants'
import { exploreSearchStringAtom } from 'components/Tokens/state'
import { MouseoverTooltip, TooltipSize } from 'components/Tooltip'
-import { chainIdToBackendChain, useChainFromUrlParam } from 'constants/chains'
-import { useUpdateManualOutage } from 'featureFlags/flags/outageBanner'
-import { PoolSortFields, TablePool, useTopPools } from 'graphql/data/pools/useTopPools'
-import {
- OrderDirection,
- getSupportedGraphQlChain,
- gqlToCurrency,
- supportedChainIdFromGQLChain,
- unwrapToken,
-} from 'graphql/data/util'
+import { PoolSortFields, TablePool } from 'graphql/data/pools/useTopPools'
+import { OrderDirection, gqlToCurrency, supportedChainIdFromGQLChain, unwrapToken } from 'graphql/data/util'
import { useCurrencyInfo } from 'hooks/Tokens'
import useSimplePagination from 'hooks/useSimplePagination'
import { useAtom } from 'jotai'
@@ -33,10 +25,10 @@ import { PoolStat } from 'state/explore/types'
import { Flex, Text, styled } from 'ui/src'
import { BIPS_BASE } from 'uniswap/src/constants/misc'
import { Chain, ProtocolVersion, Token } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const HEADER_DESCRIPTIONS: Record = {
@@ -52,13 +44,23 @@ const TableWrapper = styled(Flex, {
maxWidth: MAX_WIDTH_MEDIA_BREAKPOINT,
})
-const Badge = styled(Text, {
+export const PoolDetailsBadge = styled(Text, {
py: 2,
px: 6,
backgroundColor: '$surface2',
- borderRadius: '$rounded6',
- variant: 'body4',
color: '$neutral2',
+ variants: {
+ $position: {
+ right: {
+ borderTopRightRadius: 4,
+ borderBottomRightRadius: 4,
+ },
+ left: {
+ borderTopLeftRadius: 4,
+ borderBottomLeftRadius: 4,
+ },
+ },
+ },
})
interface PoolTableValues {
@@ -93,24 +95,31 @@ function PoolDescription({
chainId: UniverseChainId
protocolVersion?: ProtocolVersion | string
}) {
- const isRestExploreEnabled = useFeatureFlag(FeatureFlags.RestExplore)
+ const isRestPool = token0 && !('id' in token0)
const currencies = [token0 ? gqlToCurrency(token0) : undefined, token1 ? gqlToCurrency(token1) : undefined]
- // skip is isRestExploreEnabled
const currencyLogos = [
- useCurrencyInfo(currencies?.[0], chainId, isRestExploreEnabled)?.logoUrl,
- useCurrencyInfo(currencies?.[1], chainId, isRestExploreEnabled)?.logoUrl,
+ useCurrencyInfo(currencies?.[0], chainId, isRestPool)?.logoUrl,
+ useCurrencyInfo(currencies?.[1], chainId, isRestPool)?.logoUrl,
]
- const images = isRestExploreEnabled
- ? [getRestTokenLogo(token0, currencyLogos[0]), getRestTokenLogo(token1, currencyLogos[1])]
- : undefined
+ const images = [getRestTokenLogo(token0, currencyLogos[0]), getRestTokenLogo(token1, currencyLogos[1])]
+
return (
{token0?.symbol}/{token1?.symbol}
- {protocolVersion === ProtocolVersion.V2 && {protocolVersion.toLowerCase()}}
- {feeTier && {feeTier / BIPS_BASE}%}
+
+
+ {protocolVersion.toLowerCase()}
+
+ {/* TODO(WEB-5364): add hook badge when data available, it should have a hover state and link out to the explorer */}
+ {feeTier && (
+
+ {feeTier / BIPS_BASE}%
+
+ )}
+
)
}
@@ -168,7 +177,6 @@ function PoolTableHeader({
}
export const TopPoolTable = memo(function TopPoolTable() {
- const chain = getSupportedGraphQlChain(useChainFromUrlParam(), { fallbackToEthereum: true })
const sortMethod = useAtomValue(sortMethodAtom)
const sortAscending = useAtomValue(sortAscendingAtom)
@@ -179,38 +187,22 @@ export const TopPoolTable = memo(function TopPoolTable() {
resetSortAscending()
}, [resetSortAscending, resetSortMethod])
- const {
- topPools: gqlTopPools,
- loading: gqlLoading,
- errorV3,
- errorV2,
- } = useTopPools(
- { sortBy: sortMethod, sortDirection: sortAscending ? OrderDirection.Asc : OrderDirection.Desc },
- chain.id,
- )
- const combinedError =
- errorV2 && errorV3
- ? new ApolloError({ errorMessage: `Could not retrieve V2 and V3 Top Pools on chain: ${chain.id}` })
- : undefined
- const allDataStillLoading = gqlLoading && !gqlTopPools.length
- useUpdateManualOutage({ chainId: chain.id, errorV3, errorV2 })
-
- const {
- topPools: restTopPools,
- isLoading: restIsLoading,
- isError: restIsError,
- } = useRestTopPools({ sortBy: sortMethod, sortDirection: sortAscending ? OrderDirection.Asc : OrderDirection.Desc })
+ const { topPools, isLoading, isError } = useRestTopPools({
+ sortBy: sortMethod,
+ sortDirection: sortAscending ? OrderDirection.Asc : OrderDirection.Desc,
+ })
const { page, loadMore } = useSimplePagination()
- const isRestExploreEnabled = useFeatureFlag(FeatureFlags.RestExplore)
- const { topPools, loading, error } = isRestExploreEnabled
- ? { topPools: restTopPools?.slice(0, page * TABLE_PAGE_SIZE), loading: restIsLoading, error: restIsError }
- : { topPools: gqlTopPools, loading: allDataStillLoading, error: combinedError }
-
return (
-
+
)
})
@@ -237,13 +229,14 @@ export function PoolsTable({
const orderDirection = sortAscending ? OrderDirection.Asc : OrderDirection.Desc
const sortMethod = useAtomValue(sortMethodAtom)
const filterString = useAtomValue(exploreSearchStringAtom)
+ const { defaultChainId } = useEnabledChains()
const poolTableValues: PoolTableValues[] | undefined = useMemo(
() =>
pools?.map((pool, index) => {
const poolSortRank = index + 1
const isGqlPool = 'hash' in pool
- const chainId = supportedChainIdFromGQLChain(pool.token0?.chain as Chain) ?? UniverseChainId.Mainnet
+ const chainId = supportedChainIdFromGQLChain(pool.token0?.chain as Chain) ?? defaultChainId
return {
index: poolSortRank,
poolDescription: (
@@ -260,7 +253,7 @@ export function PoolsTable({
volumeWeek: isGqlPool ? pool.volumeWeek : giveExploreStatDefaultValue(pool.volume1Week?.value),
volOverTvl: pool.volOverTvl,
apr: pool.apr,
- link: `/explore/pools/${chainIdToBackendChain({ chainId, withFallback: true }).toLowerCase()}/${isGqlPool ? pool.hash : pool.id}`,
+ link: `/explore/pools/${toGraphQLChain(chainId ?? defaultChainId).toLowerCase()}/${isGqlPool ? pool.hash : pool.id}`,
analytics: {
elementName: InterfaceElementName.POOLS_TABLE_ROW,
properties: {
@@ -278,7 +271,7 @@ export function PoolsTable({
},
}
}) ?? [],
- [filterString, pools],
+ [defaultChainId, filterString, pools],
)
const showLoadingSkeleton = loading || !!error
diff --git a/apps/web/src/components/Pools/PoolTable/__snapshots__/PoolTable.test.tsx.snap b/apps/web/src/components/Pools/PoolTable/__snapshots__/PoolTable.test.tsx.snap
index 4bb1bc3b514..cd6098987b8 100644
--- a/apps/web/src/components/Pools/PoolTable/__snapshots__/PoolTable.test.tsx.snap
+++ b/apps/web/src/components/Pools/PoolTable/__snapshots__/PoolTable.test.tsx.snap
@@ -332,12 +332,22 @@ exports[`PoolTable renders data filled state 1`] = `
>
USDC/ETH
-
- 1%
-
+
+ v3
+
+
+ 1%
+
+
diff --git a/apps/web/src/components/Popups/PopupContent.tsx b/apps/web/src/components/Popups/PopupContent.tsx
index 08c6cf3825d..11ca59e7b8b 100644
--- a/apps/web/src/components/Popups/PopupContent.tsx
+++ b/apps/web/src/components/Popups/PopupContent.tsx
@@ -11,7 +11,6 @@ import AlertTriangleFilled from 'components/Icons/AlertTriangleFilled'
import { LoaderV3 } from 'components/Icons/LoadingSpinner'
import Column, { AutoColumn } from 'components/deprecated/Column'
import { AutoRow } from 'components/deprecated/Row'
-import { useIsSupportedChainId } from 'constants/chains'
import styled from 'lib/styled-components'
import { X } from 'react-feather'
import { useOrder } from 'state/signatures/hooks'
@@ -19,10 +18,11 @@ import { useTransaction } from 'state/transactions/hooks'
import { EllipsisStyle, ThemedText } from 'theme/components'
import { Flex, useSporeColors } from 'ui/src'
import { BridgeIcon } from 'uniswap/src/components/CurrencyLogo/SplitLogo'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { useFormatter } from 'utils/formatNumbers'
@@ -73,7 +73,7 @@ const PopupAlertTriangle = styled(AlertTriangleFilled)`
export function FailedNetworkSwitchPopup({ chainId, onClose }: { chainId: UniverseChainId; onClose: () => void }) {
const isSupportedChain = useIsSupportedChainId(chainId)
- const chainInfo = isSupportedChain ? UNIVERSE_CHAIN_INFO[chainId] : undefined
+ const chainInfo = isSupportedChain ? getChainInfo(chainId) : undefined
if (!chainInfo) {
return null
diff --git a/apps/web/src/components/Popups/PopupItem.tsx b/apps/web/src/components/Popups/PopupItem.tsx
index 347d79f87f5..9eebd20c3a3 100644
--- a/apps/web/src/components/Popups/PopupItem.tsx
+++ b/apps/web/src/components/Popups/PopupItem.tsx
@@ -4,7 +4,6 @@ import {
UniswapXOrderPopupContent,
} from 'components/Popups/PopupContent'
import { ToastRegularSimple } from 'components/Popups/ToastRegularSimple'
-import { useSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { useEffect } from 'react'
import { useRemovePopup } from 'state/application/hooks'
@@ -12,9 +11,10 @@ import { PopupContent, PopupType } from 'state/application/reducer'
import { Flex, Text } from 'ui/src'
import { Shuffle } from 'ui/src/components/icons/Shuffle'
import { NetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { SwapTab } from 'uniswap/src/types/screens/interface'
export default function PopupItem({
@@ -79,7 +79,7 @@ export default function PopupItem({
}
function getSwitchNetworkTitle(action: SwapTab, chainId: UniverseChainId) {
- const { label } = UNIVERSE_CHAIN_INFO[chainId]
+ const { label } = getChainInfo(chainId)
switch (action) {
case SwapTab.Swap:
@@ -98,8 +98,8 @@ function BridgeToast({
inputChainId: UniverseChainId
outputChainId: UniverseChainId
}): JSX.Element {
- const originChain = UNIVERSE_CHAIN_INFO[inputChainId]
- const targetChain = UNIVERSE_CHAIN_INFO[outputChainId]
+ const originChain = getChainInfo(inputChainId)
+ const targetChain = getChainInfo(outputChainId)
return (
diff --git a/apps/web/src/components/PositionCard/index.tsx b/apps/web/src/components/PositionCard/index.tsx
index e02c2023f0b..077b1115636 100644
--- a/apps/web/src/components/PositionCard/index.tsx
+++ b/apps/web/src/components/PositionCard/index.tsx
@@ -8,7 +8,6 @@ import { AutoColumn } from 'components/deprecated/Column'
import { AutoRow, RowBetween, RowFixed } from 'components/deprecated/Row'
import { CardNoise } from 'components/earn/styled'
import { Dots } from 'components/swap/styled'
-import { chainIdToBackendChain } from 'constants/chains'
import { BIG_INT_ZERO } from 'constants/misc'
import { useAccount } from 'hooks/useAccount'
import { useColor } from 'hooks/useColor'
@@ -22,6 +21,8 @@ import { Link } from 'react-router-dom'
import { Text } from 'rebass'
import { useTokenBalance } from 'state/connection/hooks'
import { StyledInternalLink, ThemedText } from 'theme/components'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { Trans } from 'uniswap/src/i18n'
import { currencyId } from 'utils/currencyId'
import { unwrappedToken } from 'utils/unwrappedToken'
@@ -157,6 +158,8 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
export default function FullPositionCard({ pair, border, stakedBalance }: PositionCardProps) {
const account = useAccount()
+ const { defaultChainId } = useEnabledChains()
+
const currency0 = unwrappedToken(pair.token0)
const currency1 = unwrappedToken(pair.token1)
@@ -293,7 +296,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
↗
diff --git a/apps/web/src/components/PositionListItem/PositionListItem.test.tsx b/apps/web/src/components/PositionListItem/PositionListItem.test.tsx
index 50c1219f374..c0333210e75 100644
--- a/apps/web/src/components/PositionListItem/PositionListItem.test.tsx
+++ b/apps/web/src/components/PositionListItem/PositionListItem.test.tsx
@@ -7,7 +7,7 @@ import { PoolState, usePool } from 'hooks/usePools'
import { mocked } from 'test-utils/mocked'
import { render } from 'test-utils/render'
import { USDC_MAINNET } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('components/Logo/DoubleLogo')
jest.mock('hooks/Tokens')
diff --git a/apps/web/src/components/PositionPreview.tsx b/apps/web/src/components/PositionPreview.tsx
index 16798088d63..935dba80417 100644
--- a/apps/web/src/components/PositionPreview.tsx
+++ b/apps/web/src/components/PositionPreview.tsx
@@ -9,7 +9,7 @@ import { AutoColumn } from 'components/deprecated/Column'
import { RowBetween, RowFixed } from 'components/deprecated/Row'
import { Break } from 'components/earn/styled'
import JSBI from 'jsbi'
-import { BlastRebasingAlert } from 'pages/AddLiquidity/blastAlerts'
+import { BlastRebasingAlert } from 'pages/AddLiquidityV3/blastAlerts'
import { ReactNode, useCallback, useState } from 'react'
import { Bound } from 'state/mint/v3/actions'
import { ThemedText } from 'theme/components'
diff --git a/apps/web/src/components/RemoveLiquidity/RemoveLiquidityModalContext.tsx b/apps/web/src/components/RemoveLiquidity/RemoveLiquidityModalContext.tsx
index 0f74baafcab..5dec68189fa 100644
--- a/apps/web/src/components/RemoveLiquidity/RemoveLiquidityModalContext.tsx
+++ b/apps/web/src/components/RemoveLiquidity/RemoveLiquidityModalContext.tsx
@@ -1,4 +1,4 @@
-import { useModalLiquidityPositionInfo } from 'components/Liquidity/hooks'
+import { useModalLiquidityInitialState } from 'components/Liquidity/hooks'
import { PositionInfo } from 'components/Liquidity/types'
import { Dispatch, PropsWithChildren, SetStateAction, createContext, useContext, useState } from 'react'
@@ -27,7 +27,7 @@ const RemoveLiquidityModalContext = createContext({
export function RemoveLiquidityModalContextProvider({ children }: PropsWithChildren): JSX.Element {
const [step, setStep] = useState(DecreaseLiquidityStep.Input)
const [percent, setPercent] = useState('')
- const positionInfo = useModalLiquidityPositionInfo()
+ const positionInfo = useModalLiquidityInitialState()
const percentInvalid = percent === '0' || percent === '' || !percent
return (
@@ -37,7 +37,7 @@ export function RemoveLiquidityModalContextProvider({ children }: PropsWithChild
)
}
-export function useLiquidityModalContext() {
+export function useRemoveLiquidityModalContext() {
const removeModalContext = useContext(RemoveLiquidityModalContext)
if (removeModalContext === undefined) {
diff --git a/apps/web/src/components/RemoveLiquidity/RemoveLiquidityReview.tsx b/apps/web/src/components/RemoveLiquidity/RemoveLiquidityReview.tsx
index ed33411ebc1..48148862d3f 100644
--- a/apps/web/src/components/RemoveLiquidity/RemoveLiquidityReview.tsx
+++ b/apps/web/src/components/RemoveLiquidity/RemoveLiquidityReview.tsx
@@ -1,10 +1,12 @@
+// eslint-disable-next-line no-restricted-imports
+import { ProtocolVersion } from '@uniswap/client-pools/dist/pools/v1/types_pb'
import { TokenInfo } from 'components/Liquidity/TokenInfo'
import {
useGetPoolTokenPercentage,
usePositionCurrentPrice,
useV3OrV4PositionDerivedInfo,
} from 'components/Liquidity/hooks'
-import { useLiquidityModalContext } from 'components/RemoveLiquidity/RemoveLiquidityModalContext'
+import { useRemoveLiquidityModalContext } from 'components/RemoveLiquidity/RemoveLiquidityModalContext'
import { useRemoveLiquidityTxContext } from 'components/RemoveLiquidity/RemoveLiquidityTxContext'
import { DetailLineItem } from 'components/swap/DetailLineItem'
import { useCurrencyInfo } from 'hooks/Tokens'
@@ -29,7 +31,7 @@ import { NumberType } from 'utilities/src/format/types'
export function RemoveLiquidityReview({ onClose }: { onClose: () => void }) {
const { t } = useTranslation()
const [steps, setSteps] = useState([])
- const { percent, positionInfo } = useLiquidityModalContext()
+ const { percent, positionInfo } = useRemoveLiquidityModalContext()
const removeLiquidityTxContext = useRemoveLiquidityTxContext()
const { formatCurrencyAmount, formatPercent } = useLocalizationContext()
const [currentStep, setCurrentStep] = useState<{ step: TransactionStep; accepted: boolean } | undefined>()
@@ -42,6 +44,12 @@ export function RemoveLiquidityReview({ onClose }: { onClose: () => void }) {
const { txContext, gasFeeEstimateUSD } = removeLiquidityTxContext
+ const onSuccess = () => {
+ setSteps([])
+ setCurrentStep(undefined)
+ onClose()
+ }
+
const onFailure = () => {
setCurrentStep(undefined)
}
@@ -59,7 +67,7 @@ export function RemoveLiquidityReview({ onClose }: { onClose: () => void }) {
liquidityTxContext: txContext,
setCurrentStep,
setSteps,
- onSuccess: onClose,
+ onSuccess,
onFailure,
}),
)
@@ -103,37 +111,39 @@ export function RemoveLiquidityReview({ onClose }: { onClose: () => void }) {
currencyAmount={currency1AmountToRemove}
currencyUSDAmount={currency1FiatAmount?.multiply(percent).divide(100)}
/>
-
-
- Includes accrued fees:
-
-
-
-
-
- {currency0Amount.currency.symbol} fees
+ {positionInfo.version !== ProtocolVersion.V2 && (
+
+
+ {t('fee.accrued')}
+
+
+
+
+
+ {currency0Amount.currency.symbol} fees
+
+
+ {formatCurrencyAmount({ value: feeValue0 })}{' '}
+
+ ({formatCurrencyAmount({ value: fiatFeeValue0, type: NumberType.FiatTokenPrice })})
+
+
-
- {formatCurrencyAmount({ value: feeValue0 })}{' '}
-
- ({formatCurrencyAmount({ value: fiatFeeValue0, type: NumberType.FiatTokenPrice })})
-
-
-
-
-
-
- {currency1Amount.currency.symbol} fees
-
-
- {formatCurrencyAmount({ value: feeValue1 })}{' '}
-
- ({formatCurrencyAmount({ value: fiatFeeValue1, type: NumberType.FiatTokenPrice })})
-
+
+
+
+ {currency1Amount.currency.symbol} fees
+
+
+ {formatCurrencyAmount({ value: feeValue1 })}{' '}
+
+ ({formatCurrencyAmount({ value: fiatFeeValue1, type: NumberType.FiatTokenPrice })})
+
+
-
+ )}
{currentStep ? (
diff --git a/apps/web/src/components/RemoveLiquidity/RemoveLiquidityTxContext.tsx b/apps/web/src/components/RemoveLiquidity/RemoveLiquidityTxContext.tsx
index 8a5138daa34..0de27743910 100644
--- a/apps/web/src/components/RemoveLiquidity/RemoveLiquidityTxContext.tsx
+++ b/apps/web/src/components/RemoveLiquidity/RemoveLiquidityTxContext.tsx
@@ -1,5 +1,5 @@
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
-import { useLiquidityModalContext } from 'components/RemoveLiquidity/RemoveLiquidityModalContext'
+import { useRemoveLiquidityModalContext } from 'components/RemoveLiquidity/RemoveLiquidityModalContext'
import { useRemoveLiquidityTxAndGasInfo } from 'components/RemoveLiquidity/hooks'
import { PropsWithChildren, createContext, useContext, useEffect, useMemo } from 'react'
import { useAccountMeta } from 'uniswap/src/contexts/UniswapContext'
@@ -23,7 +23,7 @@ const RemoveLiquidityTxContext = createContext ({
+ useEnabledChains: jest.fn(),
+ useIsSupportedChainId: jest.fn(),
+}))
jest.mock('hooks/useAccount')
describe('Settings Tab', () => {
@@ -16,6 +21,12 @@ describe('Settings Tab', () => {
mocked(useAccount).mockReturnValue({
chainId: UniverseChainId.Mainnet,
} as unknown as ReturnType)
+ mocked(useEnabledChains).mockReturnValue({
+ isTestnetModeEnabled: false,
+ chains: [],
+ gqlChains: [],
+ defaultChainId: UniverseChainId.Mainnet,
+ })
mocked(useIsSupportedChainId).mockReturnValue(true)
})
diff --git a/apps/web/src/components/Settings/index.tsx b/apps/web/src/components/Settings/index.tsx
index 5acb587d56a..7ea5b60ff3c 100644
--- a/apps/web/src/components/Settings/index.tsx
+++ b/apps/web/src/components/Settings/index.tsx
@@ -8,9 +8,9 @@ import MenuButton from 'components/Settings/MenuButton'
import MultipleRoutingOptions from 'components/Settings/MultipleRoutingOptions'
import RouterPreferenceSettings from 'components/Settings/RouterPreferenceSettings'
import TransactionDeadlineSettings from 'components/Settings/TransactionDeadlineSettings'
-import { useIsSupportedChainId, useIsUniswapXSupportedChain } from 'constants/chains'
import { useIsMobile } from 'hooks/screenSize/useIsMobile'
import useDisableScrolling from 'hooks/useDisableScrolling'
+import { useIsUniswapXSupportedChain } from 'hooks/useIsUniswapXSupportedChain'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import styled from 'lib/styled-components'
import { Portal } from 'nft/components/common/Portal'
@@ -22,6 +22,7 @@ import { InterfaceTrade } from 'state/routing/types'
import { isUniswapXTrade } from 'state/routing/utils'
import { Divider, ThemedText } from 'theme/components'
import { Z_INDEX } from 'theme/zIndex'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
import { isL2ChainId } from 'uniswap/src/features/chains/utils'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
diff --git a/apps/web/src/components/SwapBottomCard.tsx b/apps/web/src/components/SwapBottomCard.tsx
index 56173e22da0..4c54f88a910 100644
--- a/apps/web/src/components/SwapBottomCard.tsx
+++ b/apps/web/src/components/SwapBottomCard.tsx
@@ -1,5 +1,4 @@
import { getChainUI } from 'components/Logo/ChainLogo'
-import { getChain, useIsSupportedChainId } from 'constants/chains'
import { useIsSendPage } from 'hooks/useIsSendPage'
import { useIsSwapPage } from 'hooks/useIsSwapPage'
import { useCallback } from 'react'
@@ -19,10 +18,10 @@ import { useUniswapContext } from 'uniswap/src/contexts/UniswapContext'
import { selectHasViewedBridgingBanner } from 'uniswap/src/features/behaviorHistory/selectors'
import { setHasViewedBridgingBanner } from 'uniswap/src/features/behaviorHistory/slice'
import { useIsBridgingChain, useNumBridgingChains } from 'uniswap/src/features/bridging/hooks/chains'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ONE_SECOND_MS } from 'utilities/src/time/time'
export function SwapBottomCard() {
@@ -36,8 +35,7 @@ export function SwapBottomCard() {
const isSupportedChain = useIsSupportedChainId(chainId)
const hasViewedBridgingBanner = useSelector(selectHasViewedBridgingBanner)
- const bridgingEnabled = useFeatureFlag(FeatureFlags.Bridging)
- const isBridgingSupported = useIsBridgingChain(chainId ?? UniverseChainId.Mainnet)
+ const isBridgingSupportedChain = useIsBridgingChain(chainId ?? UniverseChainId.Mainnet)
const numBridgingChains = useNumBridgingChains()
const handleBridgingDismiss = useCallback(
(shouldNavigate: boolean) => {
@@ -61,9 +59,8 @@ export function SwapBottomCard() {
return null
}
- const shouldShowBridgingBanner = bridgingEnabled && !hasViewedBridgingBanner && isBridgingSupported
-
- const shouldShowLegacyTreatment = !bridgingEnabled
+ const isBridgingBannerChain = chainId === null || chainId === UniverseChainId.Mainnet || isBridgingSupportedChain
+ const shouldShowBridgingBanner = !hasViewedBridgingBanner && isBridgingBannerChain
if (shouldShowBridgingBanner) {
return (
@@ -84,7 +81,7 @@ export function SwapBottomCard() {
/>
)
- } else if (shouldShowLegacyTreatment || !isBridgingSupported) {
+ } else if (!isBridgingSupportedChain) {
return
} else {
return null
@@ -96,7 +93,7 @@ function NetworkAlert({ chainId }: { chainId: UniverseChainId }) {
const { t } = useTranslation()
const { symbol, bgColor, textColor } = getChainUI(chainId, darkMode)
- const chainInfo = getChain({ chainId })
+ const chainInfo = getChainInfo(chainId)
return chainInfo.bridge ? (
diff --git a/apps/web/src/components/SwitchLocaleLink.tsx b/apps/web/src/components/SwitchLocaleLink.tsx
index de6c8158e21..0e870c47f0b 100644
--- a/apps/web/src/components/SwitchLocaleLink.tsx
+++ b/apps/web/src/components/SwitchLocaleLink.tsx
@@ -1,11 +1,10 @@
-import { navigatorLocale, useActiveLocale } from 'hooks/useActiveLocale'
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
import { useMemo } from 'react'
import { useAppDispatch } from 'state/hooks'
import { StyledInternalLink } from 'theme/components'
import { Text } from 'ui/src'
import { DEFAULT_LOCALE, Language, Locale, mapLocaleToLanguage } from 'uniswap/src/features/language/constants'
-import { useLanguageInfo } from 'uniswap/src/features/language/hooks'
+import { navigatorLocale, useCurrentLocale, useLanguageInfo } from 'uniswap/src/features/language/hooks'
import { setCurrentLanguage } from 'uniswap/src/features/settings/slice'
import { Trans } from 'uniswap/src/i18n'
@@ -23,7 +22,7 @@ const useTargetLocale = (activeLocale: Locale) => {
}
export function SwitchLocaleLink() {
- const activeLocale = useActiveLocale()
+ const activeLocale = useCurrentLocale()
const targetLocale = useTargetLocale(activeLocale)
const targetLanguageInfo = useLanguageInfo(targetLocale ? mapLocaleToLanguage[targetLocale] : Language.English)
const dispatch = useAppDispatch()
diff --git a/apps/web/src/components/Table/styled.tsx b/apps/web/src/components/Table/styled.tsx
index a74146c7198..a9de95e74c7 100644
--- a/apps/web/src/components/Table/styled.tsx
+++ b/apps/web/src/components/Table/styled.tsx
@@ -3,9 +3,8 @@ import { ButtonLight } from 'components/Button/buttons'
import { useAbbreviatedTimeString } from 'components/Table/utils'
import { MouseoverTooltip, TooltipSize } from 'components/Tooltip'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
-import { OrderDirection, getTokenDetailsURL, supportedChainIdFromGQLChain, unwrapToken } from 'graphql/data/util'
+import { OrderDirection, getTokenDetailsURL, unwrapToken } from 'graphql/data/util'
import { useCurrency } from 'hooks/Tokens'
-import { useActiveLocale } from 'hooks/useActiveLocale'
import deprecatedStyled from 'lib/styled-components'
import { PropsWithChildren } from 'react'
import { ArrowDown, CornerLeftUp, ExternalLink as ExternalLinkIcon } from 'react-feather'
@@ -14,8 +13,10 @@ import { ClickableStyle, ClickableTamaguiStyle, EllipsisTamaguiStyle, ThemedText
import { Z_INDEX } from 'theme/zIndex'
import { Anchor, Flex, Text, View, styled } from 'ui/src'
import { Token } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { fromGraphQLChain } from 'uniswap/src/features/chains/utils'
+import { useCurrentLocale } from 'uniswap/src/features/language/hooks'
import { useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
export const SHOW_RETURN_TO_TOP_OFFSET = 500
export const LOAD_MORE_BOTTOM_OFFSET = 50
@@ -260,7 +261,7 @@ const StyledExternalLinkIcon = deprecatedStyled(ExternalLinkIcon)`
* @returns JSX.Element containing the formatted timestamp
*/
export const TimestampCell = ({ timestamp, link }: { timestamp: number; link: string }) => {
- const locale = useActiveLocale()
+ const locale = useCurrentLocale()
const options: Intl.DateTimeFormatOptions = {
year: '2-digit',
month: '2-digit',
@@ -298,7 +299,8 @@ const TokenSymbolText = styled(Text, {
*/
export const TokenLinkCell = ({ token }: { token: Token }) => {
const { t } = useTranslation()
- const chainId = supportedChainIdFromGQLChain(token.chain) ?? UniverseChainId.Mainnet
+ const { defaultChainId } = useEnabledChains()
+ const chainId = fromGraphQLChain(token.chain) ?? defaultChainId
const unwrappedToken = unwrapToken(chainId, token)
const isNative = unwrappedToken.address === NATIVE_CHAIN_ID
const nativeCurrency = useCurrency(NATIVE_CHAIN_ID, chainId)
diff --git a/apps/web/src/components/TokenSafety/TokenSafetyMessage.tsx b/apps/web/src/components/TokenSafety/DeprecatedTokenSafetyMessage.tsx
similarity index 97%
rename from apps/web/src/components/TokenSafety/TokenSafetyMessage.tsx
rename to apps/web/src/components/TokenSafety/DeprecatedTokenSafetyMessage.tsx
index 147738a452a..d1f628ebb1e 100644
--- a/apps/web/src/components/TokenSafety/TokenSafetyMessage.tsx
+++ b/apps/web/src/components/TokenSafety/DeprecatedTokenSafetyMessage.tsx
@@ -47,6 +47,7 @@ type TokenSafetyMessageProps = {
tokenSymbol?: string
}
+/** @deprecated Use TokenWarningCard from packages/uniswap instead */
export default function TokenSafetyMessage({
warning,
tokenAddress,
diff --git a/apps/web/src/components/TokenSafety/TokenSafetyIcon.tsx b/apps/web/src/components/TokenSafety/TokenSafetyIcon.tsx
index 41748470fc5..9eae29bae6c 100644
--- a/apps/web/src/components/TokenSafety/TokenSafetyIcon.tsx
+++ b/apps/web/src/components/TokenSafety/TokenSafetyIcon.tsx
@@ -8,6 +8,7 @@ const WarningContainer = styled(Flex, {
justifyContent: 'center',
})
+/** @deprecated use WarningIcon from packages/uniswap instead */
export default function TokenSafetyIcon({ warning }: { warning?: Warning }) {
const colors = useSporeColors()
switch (warning?.level) {
diff --git a/apps/web/src/components/TokenSafety/index.tsx b/apps/web/src/components/TokenSafety/index.tsx
index 68cd68f3241..6a26bdc9dc4 100644
--- a/apps/web/src/components/TokenSafety/index.tsx
+++ b/apps/web/src/components/TokenSafety/index.tsx
@@ -14,7 +14,7 @@ import {
import styled from 'lib/styled-components'
import { Text } from 'rebass'
import { ButtonText, ExternalLink } from 'theme/components'
-import { ExplorerView } from 'uniswap/src/features/address/ExplorerView'
+import { TokenAddressView } from 'uniswap/src/features/address/TokenAddressView'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { useDismissedTokenWarnings } from 'uniswap/src/features/tokens/slice/hooks'
import { Trans } from 'uniswap/src/i18n'
@@ -156,11 +156,11 @@ export default function TokenSafety({
// Logic for only showing the 'unsupported' warning if one is supported and other isn't
if (token0 && token0Warning && (token0Unsupported || !(token1Warning && token1Unsupported))) {
logos.push()
- urls.push()
+ urls.push()
}
if (token1 && token1Warning && (token1Unsupported || !(token0Warning && token0Unsupported))) {
logos.push()
- urls.push()
+ urls.push()
}
const plural = logos.length > 1
diff --git a/apps/web/src/components/Tokens/TokenDetails/BalanceSummary.tsx b/apps/web/src/components/Tokens/TokenDetails/BalanceSummary.tsx
index 8c4a3d620f1..22b9f9b0a06 100644
--- a/apps/web/src/components/Tokens/TokenDetails/BalanceSummary.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/BalanceSummary.tsx
@@ -10,8 +10,9 @@ import { useNavigate } from 'react-router-dom'
import { BREAKPOINTS } from 'theme'
import { ThemedText } from 'theme/components'
import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const BalancesCard = styled.div`
@@ -131,6 +132,7 @@ const OtherChainsBalanceSummary = ({
hasPageChainBalance: boolean
}) => {
const navigate = useNavigate()
+ const { defaultChainId } = useEnabledChains()
if (!otherChainBalances.length) {
return null
@@ -148,7 +150,7 @@ const OtherChainsBalanceSummary = ({
)}
{otherChainBalances.map((balance) => {
const currency = balance.token && gqlToCurrency(balance.token)
- const chainId = (balance.token && supportedChainIdFromGQLChain(balance.token.chain)) ?? UniverseChainId.Mainnet
+ const chainId = (balance.token && supportedChainIdFromGQLChain(balance.token.chain)) ?? defaultChainId
return (
@@ -82,7 +82,7 @@ export default function InvalidTokenDetails({
diff --git a/apps/web/src/components/Tokens/TokenDetails/Skeleton.test.tsx b/apps/web/src/components/Tokens/TokenDetails/Skeleton.test.tsx
index 82055b5d03c..e3644cc7ead 100644
--- a/apps/web/src/components/Tokens/TokenDetails/Skeleton.test.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/Skeleton.test.tsx
@@ -1,7 +1,7 @@
import { getLoadingTitle, TokenDetailsPageSkeleton } from 'components/Tokens/TokenDetails/Skeleton'
import { render } from 'test-utils/render'
import { USDC_MAINNET } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
describe('TDP Skeleton', () => {
it('should render correctly', () => {
diff --git a/apps/web/src/components/Tokens/TokenDetails/Skeleton.tsx b/apps/web/src/components/Tokens/TokenDetails/Skeleton.tsx
index 5feb16f65d6..4713415f2aa 100644
--- a/apps/web/src/components/Tokens/TokenDetails/Skeleton.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/Skeleton.tsx
@@ -8,9 +8,7 @@ import { StatPair, StatWrapper, StatsWrapper } from 'components/Tokens/TokenDeta
import { Hr } from 'components/Tokens/TokenDetails/shared'
import { LoadingBubble } from 'components/Tokens/loading'
import { SwapSkeleton } from 'components/swap/SwapSkeleton'
-import { useChainFromUrlParam } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
-import { getSupportedGraphQlChain } from 'graphql/data/util'
import { useCurrency } from 'hooks/Tokens'
import deprecatedStyled from 'lib/styled-components'
import { ReactNode } from 'react'
@@ -19,8 +17,11 @@ import { useParams } from 'react-router-dom'
import { ClickableTamaguiStyle } from 'theme/components'
import { capitalize } from 'tsafe'
import { Anchor, Flex, Text, TextProps, styled } from 'ui/src'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans } from 'uniswap/src/i18n'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
const SWAP_COMPONENT_WIDTH = 360
@@ -268,17 +269,17 @@ function LoadingStats() {
/* Loading State: row component with loading bubbles */
function TokenDetailsSkeleton() {
- const chain = getSupportedGraphQlChain(useChainFromUrlParam(), { fallbackToEthereum: true })
+ const { id: chainId, urlParam } = getChainInfo(useChainIdFromUrlParam() ?? UniverseChainId.Mainnet)
const { tokenAddress } = useParams<{ tokenAddress?: string }>()
- const token = useCurrency(tokenAddress === NATIVE_CHAIN_ID ? 'ETH' : tokenAddress, chain.id)
+ const token = useCurrency(tokenAddress === NATIVE_CHAIN_ID ? 'ETH' : tokenAddress, chainId)
return (
-
+
-
+
@@ -313,7 +314,7 @@ function TokenDetailsSkeleton() {
{tokenAddress && (
- {getLoadingTitle(token, tokenAddress, chain.id, chain.urlParam)}
+ {getLoadingTitle(token, tokenAddress, chainId, urlParam)}
)}
diff --git a/apps/web/src/components/Tokens/TokenDetails/StatsSection.tsx b/apps/web/src/components/Tokens/TokenDetails/StatsSection.tsx
index 2b750967050..0ad811b8704 100644
--- a/apps/web/src/components/Tokens/TokenDetails/StatsSection.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/StatsSection.tsx
@@ -2,15 +2,15 @@ import { HEADER_DESCRIPTIONS } from 'components/Tokens/TokenTable'
import { UNSUPPORTED_METADATA_CHAINS } from 'components/Tokens/constants'
import { TokenSortMethod } from 'components/Tokens/state'
import { MouseoverTooltip } from 'components/Tooltip'
-import { useIsSupportedChainId } from 'constants/chains'
import { TokenQueryData } from 'graphql/data/Token'
import styled from 'lib/styled-components'
import { ReactNode } from 'react'
import { ExternalLink, ThemedText } from 'theme/components'
import { textFadeIn } from 'theme/styles'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { NumberType, useFormatter } from 'utils/formatNumbers'
export const StatWrapper = styled.div`
@@ -92,9 +92,7 @@ type StatsSectionProps = {
export default function StatsSection(props: StatsSectionProps) {
const { chainId, address, tokenQueryData } = props
const isSupportedChain = useIsSupportedChainId(chainId)
- const { label, infoLink } = isSupportedChain
- ? UNIVERSE_CHAIN_INFO[chainId]
- : { label: undefined, infoLink: undefined }
+ const { label, infoLink } = isSupportedChain ? getChainInfo(chainId) : { label: undefined, infoLink: undefined }
const tokenMarketInfo = tokenQueryData?.market
const tokenProjectMarketInfo = tokenQueryData?.project?.markets?.[0] // aggregated market price from CoinGecko
diff --git a/apps/web/src/components/Tokens/TokenDetails/TokenDescription.tsx b/apps/web/src/components/Tokens/TokenDetails/TokenDescription.tsx
index a46fef79834..b670e144532 100644
--- a/apps/web/src/components/Tokens/TokenDetails/TokenDescription.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/TokenDescription.tsx
@@ -12,8 +12,8 @@ import { useCallback, useReducer } from 'react'
import { Copy } from 'react-feather'
import { ClickableTamaguiStyle, EllipsisTamaguiStyle, ExternalLink, ThemedText } from 'theme/components'
import { Flex, Paragraph, styled, Text } from 'ui/src'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { t, Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { shortenAddress } from 'utilities/src/addresses'
import { useFormatter } from 'utils/formatNumbers'
diff --git a/apps/web/src/components/Tokens/TokenDetails/TokenDetailsHeader.tsx b/apps/web/src/components/Tokens/TokenDetails/TokenDetailsHeader.tsx
index 45148295b41..d120462dc26 100644
--- a/apps/web/src/components/Tokens/TokenDetails/TokenDetailsHeader.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/TokenDetailsHeader.tsx
@@ -17,8 +17,8 @@ import { EllipsisTamaguiStyle } from 'theme/components'
import { Flex, Text, WebBottomSheet, useMedia, useSporeColors } from 'ui/src'
import { Check } from 'ui/src/components/icons/Check'
import { iconSizes } from 'ui/src/theme'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { isMobileWeb } from 'utilities/src/platform'
diff --git a/apps/web/src/components/Tokens/TokenDetails/index.tsx b/apps/web/src/components/Tokens/TokenDetails/index.tsx
index 12e3c0df714..67d0ca9d3da 100644
--- a/apps/web/src/components/Tokens/TokenDetails/index.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/index.tsx
@@ -2,7 +2,7 @@ import { InterfacePageName } from '@uniswap/analytics-events'
import { Currency } from '@uniswap/sdk-core'
import { BreadcrumbNavContainer, BreadcrumbNavLink, CurrentPageBreadcrumb } from 'components/BreadcrumbNav'
import { MobileBottomBar, TDPActionTabs } from 'components/NavBar/MobileBottomBar'
-import TokenSafetyMessage from 'components/TokenSafety/TokenSafetyMessage'
+import TokenSafetyMessage from 'components/TokenSafety/DeprecatedTokenSafetyMessage'
import { ActivitySection } from 'components/Tokens/TokenDetails/ActivitySection'
import BalanceSummary, { PageChainBalanceSummary } from 'components/Tokens/TokenDetails/BalanceSummary'
import ChartSection from 'components/Tokens/TokenDetails/ChartSection'
@@ -11,23 +11,30 @@ import StatsSection from 'components/Tokens/TokenDetails/StatsSection'
import { TokenDescription } from 'components/Tokens/TokenDetails/TokenDescription'
import { TokenDetailsHeader } from 'components/Tokens/TokenDetails/TokenDetailsHeader'
import { Hr } from 'components/Tokens/TokenDetails/shared'
-import { CHAIN_ID_TO_BACKEND_NAME, isSupportedChainId } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { getTokenDetailsURL } from 'graphql/data/util'
import { useCurrency } from 'hooks/Tokens'
import { useScreenSize } from 'hooks/screenSize/useScreenSize'
-import useParsedQueryString from 'hooks/useParsedQueryString'
import { ScrollDirection, useScroll } from 'hooks/useScroll'
import deprecatedStyled from 'lib/styled-components'
import { Swap } from 'pages/Swap'
import { useTDPContext } from 'pages/TokenDetails/TDPContext'
-import { PropsWithChildren, useCallback, useMemo } from 'react'
+import { PropsWithChildren, useCallback, useMemo, useState } from 'react'
import { ChevronRight } from 'react-feather'
import { useNavigate } from 'react-router-dom'
import { CurrencyState } from 'state/swap/types'
import { Flex, useIsTouchDevice } from 'ui/src'
+import { useUrlContext } from 'uniswap/src/contexts/UrlContext'
+import { isUniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
+import { TokenWarningCard } from 'uniswap/src/features/tokens/TokenWarningCard'
+import TokenWarningModal from 'uniswap/src/features/tokens/TokenWarningModal'
+import { useCurrencyInfo } from 'uniswap/src/features/tokens/useCurrencyInfo'
import { Trans } from 'uniswap/src/i18n'
+import { currencyId } from 'uniswap/src/utils/currencyId'
import { addressesAreEquivalent } from 'utils/addressesAreEquivalent'
import { getInitialLogoUrl } from 'utils/getInitialLogoURL'
@@ -69,6 +76,7 @@ function getCurrencyURLAddress(currency?: Currency): string {
function useSwapInitialInputCurrency() {
const { currency } = useTDPContext()
+ const { useParsedQueryString } = useUrlContext()
const parsedQs = useParsedQueryString()
const inputTokenAddress = useMemo(() => {
@@ -80,8 +88,11 @@ function useSwapInitialInputCurrency() {
function TDPSwapComponent() {
const { address, currency, currencyChainId, warning } = useTDPContext()
+ const tokenProtectionEnabled = useFeatureFlag(FeatureFlags.TokenProtection)
const navigate = useNavigate()
+ const currencyInfo = useCurrencyInfo(currencyId(currency))
+
const handleCurrencyChange = useCallback(
(tokens: CurrencyState) => {
const inputCurrencyURLAddress = getCurrencyURLAddress(tokens.inputCurrency)
@@ -107,10 +118,7 @@ function TDPSwapComponent() {
const url = getTokenDetailsURL({
// The function falls back to "NATIVE" if the address is null
address: newDefaultToken.isNative ? null : newDefaultToken.address,
- chain:
- CHAIN_ID_TO_BACKEND_NAME[
- isSupportedChainId(newDefaultToken.chainId) ? newDefaultToken.chainId : currencyChainId
- ],
+ chain: toGraphQLChain(isUniverseChainId(newDefaultToken.chainId) ? newDefaultToken.chainId : currencyChainId),
inputAddress:
// If only one token was selected before we navigate, then it was the default token and it's being replaced.
// On the new page, the *new* default token becomes the output, and we don't have another option to set as the input token.
@@ -124,6 +132,9 @@ function TDPSwapComponent() {
// Other token to prefill the swap form with
const initialInputCurrency = useSwapInitialInputCurrency()
+ const [showWarningModal, setShowWarningModal] = useState(false)
+ const closeWarningModal = useCallback(() => setShowWarningModal(false), [])
+
return (
<>
- {warning && }
+ {tokenProtectionEnabled ? (
+ <>
+ setShowWarningModal(true)} />
+ {currencyInfo && (
+ // Intentionally duplicative with the TokenWarningModal in the swap component; this one only displays when user clicks "i" Info button on the TokenWarningCard
+
+ )}
+ >
+ ) : (
+ warning &&
+ )}
>
)
}
diff --git a/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.test.tsx b/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.test.tsx
index b1d1b3233d1..7caf33a42ee 100644
--- a/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.test.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.test.tsx
@@ -9,7 +9,7 @@ import { mocked } from 'test-utils/mocked'
import { validBEPoolToken0, validBEPoolToken1, validParams } from 'test-utils/pools/fixtures'
import { render, screen } from 'test-utils/render'
import { ProtocolVersion } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('graphql/data/pools/usePoolsFromTokenAddress')
jest.mock('react-router-dom', () => ({
diff --git a/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.tsx b/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.tsx
index de2790a1fce..05b794b2407 100644
--- a/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/tables/TokenDetailsPoolsTable.tsx
@@ -7,7 +7,7 @@ import { PoolSortFields } from 'graphql/data/pools/useTopPools'
import { OrderDirection } from 'graphql/data/util'
import { useAtomValue, useResetAtom } from 'jotai/utils'
import { useEffect, useMemo } from 'react'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const HIDDEN_COLUMNS = [PoolSortFields.VolOverTvl]
diff --git a/apps/web/src/components/Tokens/TokenDetails/tables/TransactionsTable.tsx b/apps/web/src/components/Tokens/TokenDetails/tables/TransactionsTable.tsx
index 47577dfd613..43781e8ac75 100644
--- a/apps/web/src/components/Tokens/TokenDetails/tables/TransactionsTable.tsx
+++ b/apps/web/src/components/Tokens/TokenDetails/tables/TransactionsTable.tsx
@@ -15,13 +15,13 @@ import {
import { useUpdateManualOutage } from 'featureFlags/flags/outageBanner'
import { TokenTransactionType, useTokenTransactions } from 'graphql/data/useTokenTransactions'
import { OrderDirection, unwrapToken } from 'graphql/data/util'
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
import { useMemo, useReducer, useRef, useState } from 'react'
import { EllipsisTamaguiStyle } from 'theme/components'
import { Flex, Text, styled } from 'ui/src'
import { Token as GQLToken } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { shortenAddress } from 'utilities/src/addresses'
import { useFormatter } from 'utils/formatNumbers'
@@ -56,7 +56,7 @@ interface SwapLeg {
}
export function TransactionsTable({ chainId, referenceToken }: { chainId: UniverseChainId; referenceToken: Token }) {
- const activeLocalCurrency = useActiveLocalCurrency()
+ const activeLocalCurrency = useAppFiatCurrency()
const { formatNumber, formatFiatPrice } = useFormatter()
const [filterModalIsOpen, toggleFilterModal] = useReducer((s) => !s, false)
const filterAnchorRef = useRef(null)
diff --git a/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap b/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap
index 10efb1ca8bb..c51b03407d4 100644
--- a/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap
+++ b/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap
@@ -304,12 +304,22 @@ exports[`TDPPoolTable renders data filled state 1`] = `
>
USDC/ETH
-
- 1%
-
+
+ v3
+
+
+ 1%
+
+
diff --git a/apps/web/src/components/Tokens/TokenTable/NetworkFilter.tsx b/apps/web/src/components/Tokens/TokenTable/NetworkFilter.tsx
index 23c25849529..014dc936317 100644
--- a/apps/web/src/components/Tokens/TokenTable/NetworkFilter.tsx
+++ b/apps/web/src/components/Tokens/TokenTable/NetworkFilter.tsx
@@ -3,29 +3,22 @@ import Badge from 'components/Badge/Badge'
import { DropdownSelector, InternalMenuItem } from 'components/DropdownSelector'
import { ChainLogo } from 'components/Logo/ChainLogo'
import { AllNetworksIcon } from 'components/Tokens/TokenTable/icons'
-import {
- BACKEND_NOT_YET_SUPPORTED_CHAIN_IDS,
- BACKEND_SUPPORTED_CHAINS,
- InterfaceGqlChain,
- useChainFromUrlParam,
- useIsSupportedChainIdCallback,
-} from 'constants/chains'
-import { getSupportedGraphQlChain, supportedChainIdFromGQLChain } from 'graphql/data/util'
import deprecatedStyled, { useTheme } from 'lib/styled-components'
import { ExploreTab } from 'pages/Explore'
import { useExploreParams } from 'pages/Explore/redirects'
-import { Dispatch, SetStateAction, memo, useState } from 'react'
+import { Dispatch, SetStateAction, memo, useCallback, useState } from 'react'
import { Check } from 'react-feather'
import { useNavigate } from 'react-router-dom'
import { EllipsisTamaguiStyle } from 'theme/components'
import { Flex, FlexProps, ScrollView, Text, styled } from 'ui/src'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useEnabledChains, useIsSupportedChainIdCallback } from 'uniswap/src/features/chains/hooks'
+import { ALL_CHAIN_IDS, GqlChainId, UniverseChainId, UniverseChainInfo } from 'uniswap/src/features/chains/types'
+import { isBackendSupportedChainId, isTestnetChain, toGraphQLChain } from 'uniswap/src/features/chains/utils'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId, UniverseChainInfo } from 'uniswap/src/types/chains'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
const NetworkLabel = styled(Flex, {
flexDirection: 'row',
@@ -54,14 +47,33 @@ const StyledDropdown = {
export default function TableNetworkFilter() {
const [isMenuOpen, toggleMenu] = useState(false)
const isSupportedChainCallback = useIsSupportedChainIdCallback()
- const isMultichainExploreEnabled = useFeatureFlag(FeatureFlags.MultichainExplore)
+ const { isTestnetModeEnabled } = useEnabledChains()
const exploreParams = useExploreParams()
- const currentChain = getSupportedGraphQlChain(useChainFromUrlParam(), {
- fallbackToEthereum: !isMultichainExploreEnabled,
- })
+ const currentChainId = useChainIdFromUrlParam()
const tab = exploreParams.tab
+ const tableNetworkItemRenderer = useCallback(
+ (chainId: UniverseChainId) => {
+ if (!isSupportedChainCallback(chainId)) {
+ return null
+ }
+ const chainInfo = getChainInfo(chainId)
+ const supported = isBackendSupportedChainId(chainId)
+ return (
+
+ )
+ },
+ [isSupportedChainCallback, tab],
+ )
+
return (
@@ -70,46 +82,28 @@ export default function TableNetworkFilter() {
toggleOpen={toggleMenu}
menuLabel={
- {!currentChain ? (
+ {!currentChainId ? (
) : (
-
+
)}
}
internalMenuItems={
- {isMultichainExploreEnabled && (
-
+
+ {/* non-testnet backend supported chains */}
+ {ALL_CHAIN_IDS.filter(isBackendSupportedChainId)
+ .filter((c) => !isTestnetChain(c))
+ .map(tableNetworkItemRenderer)}
+ {/* Testnet backend supported chains */}
+ {isTestnetModeEnabled
+ ? ALL_CHAIN_IDS.filter(isBackendSupportedChainId).filter(isTestnetChain).map(tableNetworkItemRenderer)
+ : null}
+ {/* Unsupported non-testnet backend supported chains */}
+ {ALL_CHAIN_IDS.filter((c) => !isBackendSupportedChainId(c) && !isTestnetChain(c)).map(
+ tableNetworkItemRenderer,
)}
- {BACKEND_SUPPORTED_CHAINS.map((network) => {
- const chainId = supportedChainIdFromGQLChain(network)
- const isSupportedChain = isSupportedChainCallback(chainId)
- const chainInfo = isSupportedChain ? UNIVERSE_CHAIN_INFO[chainId] : undefined
- return chainInfo ? (
-
- ) : null
- })}
- {BACKEND_NOT_YET_SUPPORTED_CHAIN_IDS.map((network) => {
- const isSupportedChain = isSupportedChainCallback(network)
- const chainInfo = isSupportedChain ? UNIVERSE_CHAIN_INFO[network] : undefined
- return chainInfo ? (
-
- ) : null
- })}
}
buttonStyle={{ height: 40 }}
@@ -127,7 +121,7 @@ const TableNetworkItem = memo(function TableNetworkItem({
tab,
unsupported,
}: {
- display: 'All networks' | InterfaceGqlChain
+ display: 'All networks' | GqlChainId
chainInfo?: UniverseChainInfo
toggleMenu: Dispatch>
tab?: ExploreTab
@@ -136,17 +130,15 @@ const TableNetworkItem = memo(function TableNetworkItem({
const navigate = useNavigate()
const theme = useTheme()
const { t } = useTranslation()
- const isMultichainExploreEnabled = useFeatureFlag(FeatureFlags.MultichainExplore)
const chainId = chainInfo?.id
const exploreParams = useExploreParams()
- const currentChain = getSupportedGraphQlChain(
- useChainFromUrlParam(),
- isMultichainExploreEnabled ? undefined : { fallbackToEthereum: true },
- )
- const isAllNetworks = display === 'All networks' && isMultichainExploreEnabled
+ const urlChainId = useChainIdFromUrlParam()
+ const currentChainInfo = urlChainId ? getChainInfo(urlChainId) : undefined
+
+ const isAllNetworks = display === 'All networks'
const isCurrentChain = isAllNetworks
- ? !currentChain
- : currentChain?.backendChain.chain === display && exploreParams.chainName
+ ? !currentChainInfo
+ : currentChainInfo?.backendChain.chain === display && exploreParams.chainName
return (
{
- return isRestExploreEnabled
- ? {
- tokens: restTopTokens?.slice(0, page * TABLE_PAGE_SIZE),
- tokenSortRank: restTokenSortRank,
- loading: restIsLoading,
- sparklines: restSparklines,
- error: restError,
- }
- : {
- tokens: gqlTokens,
- tokenSortRank: gqlTokenSortRank,
- loading: gqlLoadingTokens,
- sparklines: gqlSparklines,
- error: gqlError,
- }
- }, [
- isRestExploreEnabled,
- restTopTokens,
- page,
- restTokenSortRank,
- restIsLoading,
- restSparklines,
- restError,
- gqlTokens,
- gqlTokenSortRank,
- gqlLoadingTokens,
- gqlSparklines,
- gqlError,
- ])
-
return (
)
@@ -206,6 +160,7 @@ function TokenTable({
loadMore?: ({ onComplete }: { onComplete?: () => void }) => void
}) {
const { formatFiatPrice, formatNumber, formatDelta } = useFormatter()
+ const { defaultChainId } = useEnabledChains()
const sortAscending = useAtomValue(sortAscendingAtom)
const orderDirection = sortAscending ? OrderDirection.Asc : OrderDirection.Desc
const sortMethod = useAtomValue(sortMethodAtom)
@@ -221,14 +176,14 @@ function TokenTable({
: token?.pricePercentChange1Hour?.value
const delta1d = isGqlToken ? token?.market?.pricePercentChange1Day?.value : token?.pricePercentChange1Day?.value
const tokenSortIndex = tokenSortRank[token?.address ?? NATIVE_CHAIN_ID]
- const chainId = getChainFromChainUrlParam(token?.chain.toLowerCase())?.id
+ const chainId = getChainIdFromChainUrlParam(token?.chain.toLowerCase())
const unwrappedToken = chainId ? unwrapToken(chainId, token) : token
return {
index: tokenSortIndex,
tokenDescription: ,
price: isGqlToken ? token?.market?.price?.value ?? 0 : giveExploreStatDefaultValue(token?.price?.value),
- testId: `token-table-row-${token?.address}`,
+ testId: `token-table-row-${unwrappedToken?.address ?? NATIVE_CHAIN_ID}`,
percentChange1hr: (
<>
@@ -266,7 +221,7 @@ function TokenTable({
),
link: getTokenDetailsURL({
address: unwrappedToken?.address,
- chain: chainIdToBackendChain({ chainId, withFallback: true }),
+ chain: toGraphQLChain(chainId ?? defaultChainId),
}),
analytics: {
elementName: InterfaceElementName.TOKENS_TABLE_ROW,
@@ -284,7 +239,7 @@ function TokenTable({
linkState: { preloadedLogoSrc: isGqlToken ? token?.project?.logoUrl : token?.logo },
}
}) ?? [],
- [filterString, formatDelta, sparklines, timePeriod, tokenSortRank, tokens],
+ [defaultChainId, filterString, formatDelta, sparklines, timePeriod, tokenSortRank, tokens],
)
const showLoadingSkeleton = loading || !!error
diff --git a/apps/web/src/components/Tokens/constants.ts b/apps/web/src/components/Tokens/constants.ts
index 3b8f4500cf5..fa0c5e3d082 100644
--- a/apps/web/src/components/Tokens/constants.ts
+++ b/apps/web/src/components/Tokens/constants.ts
@@ -1,6 +1,6 @@
// Breakpoints specifically for the token pages
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
// TODO(WEB-2968): Deprecate these in the new .info project
export const MAX_WIDTH_MEDIA_BREAKPOINT = '1200px'
diff --git a/apps/web/src/components/TopLevelModals/LaunchModal.tsx b/apps/web/src/components/TopLevelModals/LaunchModal.tsx
index 177a6e9f067..779c5a45075 100644
--- a/apps/web/src/components/TopLevelModals/LaunchModal.tsx
+++ b/apps/web/src/components/TopLevelModals/LaunchModal.tsx
@@ -81,12 +81,19 @@ export function LaunchModal({
-
- openUri(learnMoreUrl)}>
+ openUri(learnMoreUrl)}>
{t('common.button.learn')}
diff --git a/apps/web/src/components/TopLevelModals/index.tsx b/apps/web/src/components/TopLevelModals/index.tsx
index 1a4b6be722e..78ca7094bab 100644
--- a/apps/web/src/components/TopLevelModals/index.tsx
+++ b/apps/web/src/components/TopLevelModals/index.tsx
@@ -17,6 +17,7 @@ import useAccountRiskCheck from 'hooks/useAccountRiskCheck'
import Bag from 'nft/components/bag/Bag'
import TransactionCompleteModal from 'nft/components/collection/TransactionCompleteModal'
import { IncreaseLiquidityModal } from 'pages/IncreaseLiquidity/IncreaseLiquidityModal'
+import { ClaimFeeModal } from 'pages/Pool/Positions/ClaimFeeModal'
import { RemoveLiquidityModal } from 'pages/RemoveLiquidity/RemoveLiquidityModal'
import { useCloseModal, useModalIsOpen, useToggleModal } from 'state/application/hooks'
import { ApplicationModal } from 'state/application/reducer'
@@ -32,6 +33,7 @@ export default function TopLevelModals() {
const blockedAccountModalOpen = useModalIsOpen(ApplicationModal.BLOCKED_ACCOUNT)
const isAddLiquidityModalOpen = useModalIsOpen(ModalName.AddLiquidity)
const isRemoveLiquidityModalOpen = useModalIsOpen(ModalName.RemoveLiquidity)
+ const isClaimFeeModalOpen = useModalIsOpen(ModalName.ClaimFee)
const isTestnetModeModalOpen = useModalIsOpen(ModalName.TestnetMode)
const closeTestnetModeModal = useCloseModal(ModalName.TestnetMode)
@@ -65,6 +67,7 @@ export default function TopLevelModals() {
{isAddLiquidityModalOpen && }
{isRemoveLiquidityModalOpen && }
+ {isClaimFeeModalOpen && }
>
)
}
diff --git a/apps/web/src/components/TransactionConfirmationModal/index.tsx b/apps/web/src/components/TransactionConfirmationModal/index.tsx
index e81ef32ca7b..aeff239ef2c 100644
--- a/apps/web/src/components/TransactionConfirmationModal/index.tsx
+++ b/apps/web/src/components/TransactionConfirmationModal/index.tsx
@@ -9,7 +9,6 @@ import Modal from 'components/Modal'
import AnimatedConfirmation from 'components/TransactionConfirmationModal/AnimatedConfirmation'
import { AutoColumn, ColumnCenter } from 'components/deprecated/Column'
import Row, { RowBetween, RowFixed } from 'components/deprecated/Row'
-import { useIsSupportedChainId } from 'constants/chains'
import { useCurrencyInfo } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
import styled, { useTheme } from 'lib/styled-components'
@@ -18,11 +17,12 @@ import { AlertCircle, ArrowUpCircle, CheckCircle } from 'react-feather'
import { useTransaction } from 'state/transactions/hooks'
import { isConfirmedTx } from 'state/transactions/utils'
import { CloseIcon, CustomLightSpinner, ExternalLink, ThemedText } from 'theme/components'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { isL2ChainId } from 'uniswap/src/features/chains/utils'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
const Wrapper = styled.div`
@@ -236,7 +236,7 @@ function L2Content({
const secondsToConfirm =
confirmed && transaction.confirmedTime ? (transaction.confirmedTime - transaction.addedTime) / 1000 : undefined
- const info = UNIVERSE_CHAIN_INFO[chainId]
+ const info = getChainInfo(chainId)
return (
diff --git a/apps/web/src/components/Web3Provider/WebUniswapContext.tsx b/apps/web/src/components/Web3Provider/WebUniswapContext.tsx
index a0b1cdab3a1..909c2b31141 100644
--- a/apps/web/src/components/Web3Provider/WebUniswapContext.tsx
+++ b/apps/web/src/components/Web3Provider/WebUniswapContext.tsx
@@ -7,32 +7,38 @@ import { PropsWithChildren, useCallback, useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import { UniswapProvider } from 'uniswap/src/contexts/UniswapContext'
import { AccountMeta, AccountType } from 'uniswap/src/features/accounts/types'
+import { Connector } from 'wagmi'
// Adapts useEthersProvider to fit uniswap context hook shape
function useWebProvider(chainId: number) {
return useEthersProvider({ chainId })
}
-function useWagmiAccount(): AccountMeta | undefined {
+function useWagmiAccount(): { account?: AccountMeta; connector?: Connector } {
const account = useAccount()
return useMemo(() => {
if (!account.address) {
- return undefined
+ return {
+ account: undefined,
+ connector: account.connector,
+ }
}
return {
- address: account.address,
- type: AccountType.SignerMnemonic,
+ account: {
+ address: account.address,
+ type: AccountType.SignerMnemonic,
+ },
+ connector: account.connector,
}
- }, [account.address])
+ }, [account.address, account.connector])
}
// Abstracts web-specific transaction flow objects for usage in cross-platform flows in the `uniswap` package.
export function WebUniswapProvider({ children }: PropsWithChildren) {
- const account = useWagmiAccount()
+ const { account, connector } = useWagmiAccount()
const signer = useEthersSigner()
- const { connector } = useAccount()
const showSwapNetworkNotification = useShowSwapNetworkNotification()
const navigate = useNavigate()
const navigateToFiatOnRamp = useCallback(() => navigate(`/buy`, { replace: true }), [navigate])
diff --git a/apps/web/src/components/Web3Provider/index.tsx b/apps/web/src/components/Web3Provider/index.tsx
index f5bb1f7f5ff..063ed5988bf 100644
--- a/apps/web/src/components/Web3Provider/index.tsx
+++ b/apps/web/src/components/Web3Provider/index.tsx
@@ -4,7 +4,6 @@ import { CustomUserProperties, InterfaceEventName, WalletConnectionResult } from
import { recentConnectorIdAtom } from 'components/Web3Provider/constants'
import { queryClient, wagmiConfig } from 'components/Web3Provider/wagmiConfig'
import { walletTypeToAmplitudeWalletType } from 'components/Web3Provider/walletConnect'
-import { useIsSupportedChainId } from 'constants/chains'
import { RPC_PROVIDERS } from 'constants/providers'
import { useAccount } from 'hooks/useAccount'
import { ConnectionProvider } from 'hooks/useConnect'
@@ -14,6 +13,7 @@ import { useUpdateAtom } from 'jotai/utils'
import { ReactNode, useEffect } from 'react'
import { useLocation } from 'react-router-dom'
import { useConnectedWallets } from 'state/wallets/hooks'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
@@ -28,17 +28,14 @@ export default function Web3Provider({ children }: { children: ReactNode }) {
return (
-
-
- {children}
-
+ {children}
)
}
/** A component to run hooks under the Web3ReactProvider context. */
-function Updater() {
+export function Web3ProviderUpdater() {
const account = useAccount()
const provider = useEthersWeb3Provider()
diff --git a/apps/web/src/components/Web3Provider/wagmiConfig.ts b/apps/web/src/components/Web3Provider/wagmiConfig.ts
index 9e02df6d2ab..73c116df417 100644
--- a/apps/web/src/components/Web3Provider/wagmiConfig.ts
+++ b/apps/web/src/components/Web3Provider/wagmiConfig.ts
@@ -2,9 +2,9 @@ import { QueryClient } from '@tanstack/react-query'
import { injectedWithFallback } from 'components/Web3Provider/injectedWithFallback'
import { WC_PARAMS, uniswapWalletConnect } from 'components/Web3Provider/walletConnect'
import { UNISWAP_LOGO } from 'ui/src/assets'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { UNISWAP_WEB_URL } from 'uniswap/src/constants/urls'
-import { COMBINED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { ALL_CHAIN_IDS, UniverseChainId } from 'uniswap/src/features/chains/types'
import { createClient } from 'viem'
import { createConfig, http } from 'wagmi'
import { connect } from 'wagmi/actions'
@@ -17,10 +17,7 @@ declare module 'wagmi' {
}
export const wagmiConfig = createConfig({
- chains: [
- UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet],
- ...COMBINED_CHAIN_IDS.map((chainId) => UNIVERSE_CHAIN_INFO[chainId]),
- ],
+ chains: [getChainInfo(UniverseChainId.Mainnet), ...ALL_CHAIN_IDS.map(getChainInfo)],
connectors: [
injectedWithFallback(),
walletConnect(WC_PARAMS),
@@ -40,7 +37,7 @@ export const wagmiConfig = createConfig({
chain,
batch: { multicall: true },
pollingInterval: 12_000,
- transport: http(chain.rpcUrls.appOnly.http[0]),
+ transport: http(chain.rpcUrls.interface.http[0]),
})
},
})
diff --git a/apps/web/src/components/swap/GasBreakdownTooltip.tsx b/apps/web/src/components/swap/GasBreakdownTooltip.tsx
index a0ef2ff1ebd..1a8345780aa 100644
--- a/apps/web/src/components/swap/GasBreakdownTooltip.tsx
+++ b/apps/web/src/components/swap/GasBreakdownTooltip.tsx
@@ -2,7 +2,6 @@ import { Currency } from '@uniswap/sdk-core'
import UniswapXRouterLabel, { UniswapXGradient } from 'components/RouterLabel/UniswapXRouterLabel'
import { AutoColumn } from 'components/deprecated/Column'
import Row from 'components/deprecated/Row'
-import { chainIdToBackendChain, useSupportedChainId } from 'constants/chains'
import styled from 'lib/styled-components'
import { ReactNode } from 'react'
import { InterfaceTrade } from 'state/routing/types'
@@ -10,6 +9,8 @@ import { isPreviewTrade, isUniswapXTrade } from 'state/routing/utils'
import { Divider, ExternalLink, ThemedText } from 'theme/components'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { uniswapUrls } from 'uniswap/src/constants/urls'
+import { useEnabledChains, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { Trans } from 'uniswap/src/i18n'
import { NumberType, useFormatter } from 'utils/formatNumbers'
@@ -84,7 +85,8 @@ export function GasBreakdownTooltip({ trade }: GasBreakdownTooltipProps) {
function NetworkCostDescription({ native }: { native: Currency }) {
const supportedChain = useSupportedChainId(native.chainId)
- const chainName = chainIdToBackendChain({ chainId: supportedChain, withFallback: true })
+ const { defaultChainId } = useEnabledChains()
+ const chainName = toGraphQLChain(supportedChain ?? defaultChainId)
return (
diff --git a/apps/web/src/components/swap/GasEstimateTooltip.tsx b/apps/web/src/components/swap/GasEstimateTooltip.tsx
index ad80dc1d731..450c87add97 100644
--- a/apps/web/src/components/swap/GasEstimateTooltip.tsx
+++ b/apps/web/src/components/swap/GasEstimateTooltip.tsx
@@ -5,12 +5,12 @@ import { UniswapXGradient, UniswapXRouterIcon } from 'components/RouterLabel/Uni
import { MouseoverTooltip, TooltipSize } from 'components/Tooltip'
import Row, { RowFixed } from 'components/deprecated/Row'
import { GasBreakdownTooltip } from 'components/swap/GasBreakdownTooltip'
-import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import styled from 'lib/styled-components'
import { SubmittableTrade } from 'state/routing/types'
import { isUniswapXTrade } from 'state/routing/utils'
import { useSwapAndLimitContext } from 'state/swap/useSwapContext'
import { ThemedText } from 'theme/components'
+import { chainSupportsGasEstimates } from 'uniswap/src/features/chains/utils'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { NumberType, useFormatter } from 'utils/formatNumbers'
@@ -27,7 +27,7 @@ export default function GasEstimateTooltip({ trade, loading }: { trade?: Submitt
const { chainId } = useSwapAndLimitContext()
const { formatNumber } = useFormatter()
- if (!trade || !chainId || !SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId)) {
+ if (!trade || !chainId || !chainSupportsGasEstimates(chainId)) {
return null
}
diff --git a/apps/web/src/components/swap/SwapHeader.test.tsx b/apps/web/src/components/swap/SwapHeader.test.tsx
index 19ce3d9769e..1429e1f69bb 100644
--- a/apps/web/src/components/swap/SwapHeader.test.tsx
+++ b/apps/web/src/components/swap/SwapHeader.test.tsx
@@ -2,7 +2,7 @@ import SwapHeader from 'components/swap/SwapHeader'
import { Dispatch, PropsWithChildren, SetStateAction } from 'react'
import { CurrencyState, EMPTY_DERIVED_SWAP_INFO, SwapAndLimitContext, SwapContext } from 'state/swap/types'
import { act, render, screen } from 'test-utils/render'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyField } from 'uniswap/src/types/currency'
import { SwapTab } from 'uniswap/src/types/screens/interface'
diff --git a/apps/web/src/components/swap/SwapLineItem.tsx b/apps/web/src/components/swap/SwapLineItem.tsx
index 3691bef360c..bafbcbc3ab8 100644
--- a/apps/web/src/components/swap/SwapLineItem.tsx
+++ b/apps/web/src/components/swap/SwapLineItem.tsx
@@ -9,7 +9,6 @@ import { GasBreakdownTooltip, UniswapXDescription } from 'components/swap/GasBre
import GasEstimateTooltip from 'components/swap/GasEstimateTooltip'
import { RoutingTooltip, SwapRoute } from 'components/swap/SwapRoute'
import TradePrice from 'components/swap/TradePrice'
-import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import { useUSDPrice } from 'hooks/useUSDPrice'
import styled, { DefaultTheme } from 'lib/styled-components'
import React, { ReactNode, useEffect, useState } from 'react'
@@ -19,6 +18,7 @@ import { isLimitTrade, isPreviewTrade, isUniswapXTrade, isUniswapXTradeType } fr
import { useUserSlippageTolerance } from 'state/user/hooks'
import { SlippageTolerance } from 'state/user/types'
import { ExternalLink, ThemedText } from 'theme/components'
+import { chainSupportsGasEstimates } from 'uniswap/src/features/chains/utils'
import { Trans, t } from 'uniswap/src/i18n'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { getPriceImpactColor } from 'utils/prices'
@@ -157,7 +157,7 @@ function useLineItem(props: SwapLineItemProps): LineItemData | undefined {
tooltipSize: isUniswapX ? TooltipSize.Small : TooltipSize.Large,
}
case SwapLineItemType.NETWORK_COST:
- if (!SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId)) {
+ if (!chainSupportsGasEstimates(chainId)) {
return undefined
}
return {
diff --git a/apps/web/src/components/swap/SwapRoute.tsx b/apps/web/src/components/swap/SwapRoute.tsx
index ee1a649f82d..f082e4319ef 100644
--- a/apps/web/src/components/swap/SwapRoute.tsx
+++ b/apps/web/src/components/swap/SwapRoute.tsx
@@ -2,20 +2,20 @@ import RouterLabel from 'components/RouterLabel'
import Column from 'components/deprecated/Column'
import { RowBetween } from 'components/deprecated/Row'
import { UniswapXDescription } from 'components/swap/GasBreakdownTooltip'
-import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import { ClassicTrade, SubmittableTrade } from 'state/routing/types'
import { isClassicTrade } from 'state/routing/utils'
import { Separator, ThemedText } from 'theme/components'
import RoutingDiagram from 'uniswap/src/components/RoutingDiagram/RoutingDiagram'
+import { chainSupportsGasEstimates } from 'uniswap/src/features/chains/utils'
import { Trans } from 'uniswap/src/i18n'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import getRoutingDiagramEntries from 'utils/getRoutingDiagramEntries'
// TODO(WEB-2022)
-// Can `trade.gasUseEstimateUSD` be defined when `chainId` is not in `SUPPORTED_GAS_ESTIMATE_CHAIN_IDS`?
+// Can `trade.gasUseEstimateUSD` be defined when `chainId` doesn't support gas estimates?
function useGasPrice({ gasUseEstimateUSD, inputAmount }: ClassicTrade) {
const { formatNumber } = useFormatter()
- if (!gasUseEstimateUSD || !SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(inputAmount.currency.chainId)) {
+ if (!gasUseEstimateUSD || !chainSupportsGasEstimates(inputAmount.currency.chainId)) {
return undefined
}
diff --git a/apps/web/src/components/swap/UnsupportedCurrencyFooter.tsx b/apps/web/src/components/swap/UnsupportedCurrencyFooter.tsx
index f28f8d8b0a9..f010a603c15 100644
--- a/apps/web/src/components/swap/UnsupportedCurrencyFooter.tsx
+++ b/apps/web/src/components/swap/UnsupportedCurrencyFooter.tsx
@@ -13,8 +13,8 @@ import { CloseIcon, ExternalLink, ThemedText } from 'theme/components'
import { Z_INDEX } from 'theme/zIndex'
import { Text } from 'ui/src'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
const DetailsFooter = styled.div<{ show: boolean }>`
diff --git a/apps/web/src/connection/web3reactShim.ts b/apps/web/src/connection/web3reactShim.ts
index 52ca2978221..d56b9d2d144 100644
--- a/apps/web/src/connection/web3reactShim.ts
+++ b/apps/web/src/connection/web3reactShim.ts
@@ -1,7 +1,7 @@
import { useAccount } from 'hooks/useAccount'
import { useEthersProvider } from 'hooks/useEthersProvider'
import { useMemo } from 'react'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
// eslint-disable-next-line import/no-unused-modules -- shim is used via a build alias in craco.config.cjs
export function useWeb3React() {
diff --git a/apps/web/src/constants/chains.test.ts b/apps/web/src/constants/chains.test.ts
index 083879b10e7..19c387c7dda 100644
--- a/apps/web/src/constants/chains.test.ts
+++ b/apps/web/src/constants/chains.test.ts
@@ -1,112 +1,20 @@
-import {
- BACKEND_NOT_YET_SUPPORTED_CHAIN_IDS,
- BACKEND_SUPPORTED_CHAINS,
- CHAIN_IDS_TO_NAMES,
- CHAIN_ID_TO_BACKEND_NAME,
- CHAIN_NAME_TO_CHAIN_ID,
- ChainSlug,
- INFURA_PREFIX_TO_CHAIN_ID,
- InterfaceGqlChain,
- SUPPORTED_GAS_ESTIMATE_CHAIN_IDS,
- TESTNET_CHAIN_IDS,
- UX_SUPPORTED_GQL_CHAINS,
- getChainFromChainUrlParam,
- getChainPriority,
-} from 'constants/chains'
-import { GQL_MAINNET_CHAINS, GQL_TESTNET_CHAINS, UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { SUPPORTED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/types/chains'
+import { ALL_GQL_CHAINS, GQL_MAINNET_CHAINS } from 'uniswap/src/features/chains/chainInfo'
+import { GqlChainId, UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
+import { getChainIdFromChainUrlParam } from 'utils/chainParams'
-// Define an array of test cases with chainId and expected priority
-const chainPriorityTestCases: [UniverseChainId, number][] = [
- [UniverseChainId.Mainnet, 0],
- [UniverseChainId.Sepolia, 0],
- [UniverseChainId.ArbitrumOne, 1],
- [UniverseChainId.Optimism, 2],
- [UniverseChainId.Polygon, 3],
- [UniverseChainId.Base, 4],
- [UniverseChainId.Bnb, 5],
- [UniverseChainId.Avalanche, 6],
- [UniverseChainId.Celo, 7],
- [UniverseChainId.Blast, 8],
- [UniverseChainId.Zora, 9],
- [UniverseChainId.Zksync, 10],
-]
-
-test.each(chainPriorityTestCases)(
- 'getChainPriority returns expected priority for a given ChainId %O',
- (chainId: UniverseChainId, expectedPriority: number) => {
- const priority = getChainPriority(chainId)
- expect(priority).toBe(expectedPriority)
- },
-)
-
-const chainIdNames: { [chainId in UniverseChainId]: string } = {
- [UniverseChainId.Mainnet]: 'mainnet',
- [UniverseChainId.Sepolia]: 'sepolia',
- [UniverseChainId.Polygon]: 'polygon',
- [UniverseChainId.Celo]: 'celo',
- [UniverseChainId.ArbitrumOne]: 'arbitrum',
- [UniverseChainId.Optimism]: 'optimism',
- [UniverseChainId.Bnb]: 'bnb',
- [UniverseChainId.Avalanche]: 'avalanche',
- [UniverseChainId.Base]: 'base',
- [UniverseChainId.Blast]: 'blast',
- [UniverseChainId.WorldChain]: 'worldchain',
- [UniverseChainId.Zora]: 'zora',
- [UniverseChainId.Zksync]: 'zksync',
- [UniverseChainId.AstrochainSepolia]: 'astrochain',
-} as const
-
-test.each(Object.keys(chainIdNames).map((key) => parseInt(key) as UniverseChainId))(
- 'CHAIN_IDS_TO_NAMES generates the correct chainIds',
- (chainId: UniverseChainId) => {
- const name = CHAIN_IDS_TO_NAMES[chainId]
- expect(name).toBe(chainIdNames[chainId])
- },
-)
-
-const supportedGasEstimateChains = [
- UniverseChainId.Mainnet,
- UniverseChainId.Polygon,
- UniverseChainId.Celo,
- UniverseChainId.Optimism,
- UniverseChainId.ArbitrumOne,
- UniverseChainId.Bnb,
- UniverseChainId.Avalanche,
- UniverseChainId.Base,
- UniverseChainId.Blast,
- UniverseChainId.Zora,
-] as const
-
-test.each(supportedGasEstimateChains)(
- 'SUPPORTED_GAS_ESTIMATE_CHAIN_IDS generates the correct chainIds',
- (chainId: UniverseChainId) => {
- expect(SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId)).toBe(true)
- expect(SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.length).toEqual(supportedGasEstimateChains.length)
- },
-)
-
-const testnetChainIds = [UniverseChainId.Sepolia, UniverseChainId.AstrochainSepolia] as const
-
-test.each(testnetChainIds)('TESTNET_CHAIN_IDS generates the correct chainIds', (chainId: UniverseChainId) => {
- expect(TESTNET_CHAIN_IDS.includes(chainId)).toBe(true)
- expect(TESTNET_CHAIN_IDS.length).toEqual(testnetChainIds.length)
-})
-
-const uxSupportedGQLChains = [...GQL_MAINNET_CHAINS, ...GQL_TESTNET_CHAINS] as const
-
-test.each(GQL_MAINNET_CHAINS)('GQL_MAINNET_CHAINS generates the correct chains', (chain: InterfaceGqlChain) => {
+test.each(GQL_MAINNET_CHAINS)('GQL_MAINNET_CHAINS generates the correct chains', (chain: GqlChainId) => {
expect(GQL_MAINNET_CHAINS.includes(chain)).toBe(true)
expect(GQL_MAINNET_CHAINS.length).toEqual(GQL_MAINNET_CHAINS.length)
})
-test.each(uxSupportedGQLChains)('UX_SUPPORTED_GQL_CHAINS generates the correct chains', (chain: InterfaceGqlChain) => {
- expect(UX_SUPPORTED_GQL_CHAINS.includes(chain)).toBe(true)
- expect(UX_SUPPORTED_GQL_CHAINS.length).toEqual(uxSupportedGQLChains.length)
+test.each(ALL_GQL_CHAINS)('UX_SUPPORTED_GQL_CHAINS generates the correct chains', (chain: GqlChainId) => {
+ expect(ALL_GQL_CHAINS.includes(chain)).toBe(true)
+ expect(ALL_GQL_CHAINS.length).toEqual(ALL_GQL_CHAINS.length)
})
-const chainIdToBackendName: { [key: number]: InterfaceGqlChain } = {
+const chainIdToBackendName: { [key: number]: GqlChainId } = {
[UniverseChainId.Mainnet]: Chain.Ethereum,
[UniverseChainId.Sepolia]: Chain.EthereumSepolia,
[UniverseChainId.Polygon]: Chain.Polygon,
@@ -123,133 +31,29 @@ const chainIdToBackendName: { [key: number]: InterfaceGqlChain } = {
test.each(Object.keys(chainIdToBackendName).map((key) => parseInt(key) as UniverseChainId))(
'CHAIN_IDS_TO_BACKEND_NAME generates the correct chains',
(chainId: UniverseChainId) => {
- const name = CHAIN_ID_TO_BACKEND_NAME[chainId]
+ const name = toGraphQLChain(chainId)
expect(name).toBe(chainIdToBackendName[chainId])
},
)
-const chainToChainId = {
- [Chain.Ethereum]: UniverseChainId.Mainnet,
- [Chain.EthereumSepolia]: UniverseChainId.Sepolia,
- [Chain.Polygon]: UniverseChainId.Polygon,
- [Chain.Celo]: UniverseChainId.Celo,
- [Chain.Optimism]: UniverseChainId.Optimism,
- [Chain.Arbitrum]: UniverseChainId.ArbitrumOne,
- [Chain.Bnb]: UniverseChainId.Bnb,
- [Chain.Avalanche]: UniverseChainId.Avalanche,
- [Chain.Base]: UniverseChainId.Base,
- [Chain.Blast]: UniverseChainId.Blast,
- [Chain.Worldchain]: UniverseChainId.WorldChain,
- [Chain.Zora]: UniverseChainId.Zora,
- [Chain.Zksync]: UniverseChainId.Zksync,
-} as const
-
-test.each(Object.keys(chainToChainId).map((key) => key as InterfaceGqlChain))(
- 'CHAIN_NAME_TO_CHAIN_ID generates the correct chains',
- (chain) => {
- const chainId = CHAIN_NAME_TO_CHAIN_ID[chain]
- expect(chainId).toBe(chainToChainId[chain as Exclude]) // will remove this after AstrochainSepolia is added
- },
-)
-
-const backendSupportedChains = [
- Chain.Ethereum,
- Chain.Arbitrum,
- Chain.Optimism,
- Chain.Polygon,
- Chain.Base,
- Chain.Bnb,
- Chain.Celo,
- Chain.Blast,
- Chain.Avalanche,
- Chain.Worldchain,
- Chain.Zksync,
- Chain.Zora,
-] as const
-
-test.each(backendSupportedChains)(
- 'BACKEND_SUPPORTED_CHAINS generates the correct chains',
- (chain: InterfaceGqlChain) => {
- expect(BACKEND_SUPPORTED_CHAINS.includes(chain)).toBe(true)
- expect(BACKEND_SUPPORTED_CHAINS.length).toEqual(backendSupportedChains.length)
- },
-)
-
-const backendNotyetSupportedChainIds = [] as const
-
-test('BACKEND_NOT_YET_SUPPORTED_CHAIN_IDS array is empty', () => {
- expect(backendNotyetSupportedChainIds).toEqual(BACKEND_NOT_YET_SUPPORTED_CHAIN_IDS)
-})
-
-const infuraPrefixToChainId: { [prefix: string]: UniverseChainId } = {
- mainnet: UniverseChainId.Mainnet,
- sepolia: UniverseChainId.Sepolia,
- 'optimism-mainnet': UniverseChainId.Optimism,
- 'arbitrum-mainnet': UniverseChainId.ArbitrumOne,
- 'polygon-mainnet': UniverseChainId.Polygon,
- 'avalanche-mainnet': UniverseChainId.Avalanche,
- 'base-mainnet': UniverseChainId.Base,
- 'blast-mainnet': UniverseChainId.Blast,
-}
-
-test.each(Object.keys(infuraPrefixToChainId))('INFURA_PREFIX_TO_CHAIN_ID generates the correct chains', (chainName) => {
- const chain = INFURA_PREFIX_TO_CHAIN_ID[chainName]
- expect(chain).toEqual(infuraPrefixToChainId[chainName])
- expect(Object.keys(infuraPrefixToChainId).length).toEqual(Object.keys(infuraPrefixToChainId).length)
-})
-
-function getBlocksPerMainnetEpochForChainId(chainId: number | undefined): number {
- // Average block times were pulled from https://dune.com/jacobdcastro/avg-block-times on 2024-03-14,
- // and corroborated with that chain's documentation/explorer.
- // Blocks per mainnet epoch is computed as `Math.floor(12s / AVG_BLOCK_TIME)` and hard-coded.
- switch (chainId) {
- case UniverseChainId.ArbitrumOne:
- return 46
- case UniverseChainId.Optimism:
- return 6
- case UniverseChainId.Polygon:
- return 5
- case UniverseChainId.Base:
- return 6
- case UniverseChainId.Bnb:
- return 4
- case UniverseChainId.Avalanche:
- return 6
- case UniverseChainId.Celo:
- return 2
- case UniverseChainId.Zksync:
- return 12
- default:
- return 1
- }
-}
-
-test.each(SUPPORTED_CHAIN_IDS)(
- 'CHAIN_INFO maps the correct blocks per mainnet epoch for chainId',
- (chainId: UniverseChainId) => {
- const block = UNIVERSE_CHAIN_INFO[chainId].blockPerMainnetEpochForChainId
- expect(block).toEqual(getBlocksPerMainnetEpochForChainId(chainId))
- },
-)
-
describe('getChainFromChainUrlParam', () => {
it('should return true for valid chain slug', () => {
const validChainName = 'ethereum'
- expect(getChainFromChainUrlParam(validChainName)?.id).toBe(UniverseChainId.Mainnet)
+ expect(getChainIdFromChainUrlParam(validChainName)).toBe(UniverseChainId.Mainnet)
})
it('should return false for undefined chain slug', () => {
const undefinedChainName = undefined
- expect(getChainFromChainUrlParam(undefinedChainName)?.id).toBe(undefined)
+ expect(getChainIdFromChainUrlParam(undefinedChainName)).toBe(undefined)
})
it('should return false for invalid chain slug', () => {
const invalidChainName = 'invalidchain'
- expect(getChainFromChainUrlParam(invalidChainName as ChainSlug)?.id).toBe(undefined)
+ expect(getChainIdFromChainUrlParam(invalidChainName)).toBe(undefined)
})
it('should return false for a misconfigured chain slug', () => {
const invalidChainName = 'eThErEuM'
- expect(getChainFromChainUrlParam(invalidChainName as ChainSlug)?.id).toBe(undefined)
+ expect(getChainIdFromChainUrlParam(invalidChainName)).toBe(undefined)
})
})
diff --git a/apps/web/src/constants/chains.ts b/apps/web/src/constants/chains.ts
deleted file mode 100644
index 5c263661f53..00000000000
--- a/apps/web/src/constants/chains.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-/* eslint-disable rulesdir/no-undefined-or */
-import { Currency, V2_ROUTER_ADDRESSES } from '@uniswap/sdk-core'
-import ms from 'ms'
-import { useCallback } from 'react'
-import { useParams } from 'react-router-dom'
-import { GQL_MAINNET_CHAINS, GQL_TESTNET_CHAINS, UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { Chain as BackendChainId } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { useFeatureFlaggedChainIds } from 'uniswap/src/features/chains/utils'
-import { ArbitrumXV2ExperimentGroup, Experiments } from 'uniswap/src/features/gating/experiments'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useExperimentGroupName, useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { COMBINED_CHAIN_IDS, UniverseChainId, UniverseChainInfo } from 'uniswap/src/types/chains'
-
-export const AVERAGE_L1_BLOCK_TIME = ms(`12s`)
-
-export function isSupportedChainId(chainId?: number | UniverseChainId | null): chainId is UniverseChainId {
- return !!chainId && COMBINED_CHAIN_IDS.includes(chainId as UniverseChainId)
-}
-
-export function useIsSupportedChainId(chainId?: number | UniverseChainId): chainId is UniverseChainId {
- const featureFlaggedChains = useFeatureFlaggedChainIds()
-
- const chainIsNotEnabled = !featureFlaggedChains.includes(chainId as UniverseChainId)
- return chainIsNotEnabled ? false : isSupportedChainId(chainId)
-}
-
-export function useIsSupportedChainIdCallback() {
- const featureFlaggedChains = useFeatureFlaggedChainIds()
-
- return useCallback(
- (chainId?: number | UniverseChainId): chainId is UniverseChainId => {
- const chainIsNotEnabled = !featureFlaggedChains.includes(chainId as UniverseChainId)
- return chainIsNotEnabled ? false : isSupportedChainId(chainId)
- },
- [featureFlaggedChains],
- )
-}
-
-export function useSupportedChainId(chainId?: number): UniverseChainId | undefined {
- const featureFlaggedChains = useFeatureFlaggedChainIds()
- if (!chainId || COMBINED_CHAIN_IDS.indexOf(chainId) === -1) {
- return undefined
- }
-
- const chainDisabled = !featureFlaggedChains.includes(chainId as UniverseChainId)
- return chainDisabled ? undefined : (chainId as UniverseChainId)
-}
-
-export type InterfaceGqlChain = Exclude
-
-export type ChainSlug = UniverseChainInfo['urlParam']
-export const isChainUrlParam = (str?: string): str is ChainSlug =>
- !!str && Object.values(UNIVERSE_CHAIN_INFO).some((chain) => chain.urlParam === str)
-export const getChainUrlParam = (str?: string): ChainSlug | undefined => (isChainUrlParam(str) ? str : undefined)
-
-export function getChain(options: { chainId: UniverseChainId }): UniverseChainInfo
-export function getChain(options: { chainId?: UniverseChainId; withFallback: true }): UniverseChainInfo
-export function getChain(options: { chainId?: UniverseChainId; withFallback?: boolean }): UniverseChainInfo | undefined
-export function getChain({
- chainId,
- withFallback,
-}: {
- chainId?: UniverseChainId
- withFallback?: boolean
-}): UniverseChainInfo | undefined {
- return chainId
- ? UNIVERSE_CHAIN_INFO[chainId]
- : withFallback
- ? UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet]
- : undefined
-}
-
-export const CHAIN_IDS_TO_NAMES = Object.fromEntries(
- Object.entries(UNIVERSE_CHAIN_INFO).map(([key, value]) => [key, value.interfaceName]),
-) as { [chainId in UniverseChainId]: string }
-
-export const UX_SUPPORTED_GQL_CHAINS = [...GQL_MAINNET_CHAINS, ...GQL_TESTNET_CHAINS]
-
-export const CHAIN_ID_TO_BACKEND_NAME = Object.fromEntries(
- Object.entries(UNIVERSE_CHAIN_INFO).map(([key, value]) => [key, value.backendChain.chain]),
-) as { [chainId in UniverseChainId]: InterfaceGqlChain }
-
-export function chainIdToBackendChain(options: { chainId: UniverseChainId }): InterfaceGqlChain
-export function chainIdToBackendChain(options: { chainId?: UniverseChainId; withFallback: true }): InterfaceGqlChain
-export function chainIdToBackendChain(options: {
- chainId?: UniverseChainId
- withFallback?: boolean
-}): InterfaceGqlChain | undefined
-export function chainIdToBackendChain({
- chainId,
- withFallback,
-}: {
- chainId?: UniverseChainId
- withFallback?: boolean
-}): InterfaceGqlChain | undefined {
- return chainId
- ? CHAIN_ID_TO_BACKEND_NAME[chainId]
- : withFallback
- ? CHAIN_ID_TO_BACKEND_NAME[UniverseChainId.Mainnet]
- : undefined
-}
-
-export const CHAIN_NAME_TO_CHAIN_ID = Object.fromEntries(
- Object.entries(UNIVERSE_CHAIN_INFO)
- .filter(([, value]) => !value.backendChain.isSecondaryChain)
- .map(([key, value]) => [value.backendChain.chain, parseInt(key) as UniverseChainId]),
-) as { [chain in InterfaceGqlChain]: UniverseChainId }
-
-export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = Object.keys(UNIVERSE_CHAIN_INFO)
- .filter((key) => UNIVERSE_CHAIN_INFO[parseInt(key) as UniverseChainId].supportsGasEstimates)
- .map((key) => parseInt(key) as UniverseChainId)
-
-export const PRODUCTION_CHAIN_IDS: UniverseChainId[] = Object.values(UNIVERSE_CHAIN_INFO)
- .filter((chain) => !chain.testnet)
- .map((chain) => chain.id)
-
-export const TESTNET_CHAIN_IDS = Object.keys(UNIVERSE_CHAIN_INFO)
- .filter((key) => UNIVERSE_CHAIN_INFO[parseInt(key) as UniverseChainId].testnet)
- .map((key) => parseInt(key) as UniverseChainId)
-
-/**
- * @deprecated when v2 pools are enabled on chains supported through sdk-core
- */
-export const SUPPORTED_V2POOL_CHAIN_IDS = Object.keys(V2_ROUTER_ADDRESSES).map((chainId) => parseInt(chainId))
-
-export const BACKEND_SUPPORTED_CHAINS = Object.keys(UNIVERSE_CHAIN_INFO)
- .filter((key) => {
- const chainId = parseInt(key) as UniverseChainId
- return (
- UNIVERSE_CHAIN_INFO[chainId].backendChain.backendSupported &&
- !UNIVERSE_CHAIN_INFO[chainId].backendChain.isSecondaryChain &&
- !UNIVERSE_CHAIN_INFO[chainId].testnet
- )
- })
- .map((key) => UNIVERSE_CHAIN_INFO[parseInt(key) as UniverseChainId].backendChain.chain as InterfaceGqlChain)
-
-export const BACKEND_NOT_YET_SUPPORTED_CHAIN_IDS = GQL_MAINNET_CHAINS.filter(
- (chain) => !BACKEND_SUPPORTED_CHAINS.includes(chain),
-).map((chain) => CHAIN_NAME_TO_CHAIN_ID[chain]) as [UniverseChainId]
-
-export const INFURA_PREFIX_TO_CHAIN_ID: { [prefix: string]: UniverseChainId } = Object.fromEntries(
- Object.entries(UNIVERSE_CHAIN_INFO)
- .filter(([, value]) => !!value.infuraPrefix)
- .map(([key, value]) => [value.infuraPrefix, parseInt(key) as UniverseChainId]),
-)
-
-/**
- * Get the priority of a chainId based on its relevance to the user.
- * @param {ChainId} chainId - The chainId to determine the priority for.
- * @returns {number} The priority of the chainId, the lower the priority, the earlier it should be displayed, with base of MAINNET=0.
- */
-export function getChainPriority(chainId: UniverseChainId): number {
- if (isSupportedChainId(chainId)) {
- return UNIVERSE_CHAIN_INFO[chainId].chainPriority
- }
-
- return Infinity
-}
-
-export function useIsUniswapXSupportedChain(chainId?: number) {
- const xv2ArbitrumEnabled =
- useExperimentGroupName(Experiments.ArbitrumXV2OpenOrders) === ArbitrumXV2ExperimentGroup.Test
- const isPriorityOrdersEnabled = useFeatureFlag(FeatureFlags.UniswapXPriorityOrders)
-
- return (
- chainId === UniverseChainId.Mainnet ||
- (xv2ArbitrumEnabled && chainId === UniverseChainId.ArbitrumOne) ||
- (isPriorityOrdersEnabled && chainId === UniverseChainId.Base) // UniswapX priority orders are only available on Base for now
- )
-}
-
-export function isStablecoin(currency?: Currency): boolean {
- if (!currency) {
- return false
- }
-
- return getChain({ chainId: currency.chainId as UniverseChainId }).stablecoins.some((stablecoin) =>
- stablecoin.equals(currency),
- )
-}
-
-export function getChainFromChainUrlParam(chainUrlParam?: ChainSlug): UniverseChainInfo | undefined {
- return chainUrlParam !== undefined
- ? Object.values(UNIVERSE_CHAIN_INFO).find((chain) => chainUrlParam === chain.urlParam)
- : undefined
-}
-
-export function useChainFromUrlParam(): UniverseChainInfo | undefined {
- const chainName = useParams<{ chainName?: string }>().chainName
- // In the case where /explore/:chainName is used, the chainName is passed as a tab param
- const tab = useParams<{ tab?: string }>().tab
- return getChainFromChainUrlParam(getChainUrlParam(chainName ?? tab))
-}
diff --git a/apps/web/src/constants/deprecatedTokenSafety.tsx b/apps/web/src/constants/deprecatedTokenSafety.tsx
index 3ea0eaa1d25..c9a76a838bc 100644
--- a/apps/web/src/constants/deprecatedTokenSafety.tsx
+++ b/apps/web/src/constants/deprecatedTokenSafety.tsx
@@ -5,8 +5,8 @@
*/
import { useCurrencyInfo } from 'hooks/Tokens'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans, t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
export const TOKEN_SAFETY_ARTICLE = 'https://support.uniswap.org/hc/en-us/articles/8723118437133'
diff --git a/apps/web/src/constants/providers.ts b/apps/web/src/constants/providers.ts
index 8aeaa777396..7f2359ed25e 100644
--- a/apps/web/src/constants/providers.ts
+++ b/apps/web/src/constants/providers.ts
@@ -1,15 +1,12 @@
-import { CHAIN_IDS_TO_NAMES } from 'constants/chains'
import AppJsonRpcProvider from 'rpc/AppJsonRpcProvider'
import ConfiguredJsonRpcProvider from 'rpc/ConfiguredJsonRpcProvider'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { SUPPORTED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { SUPPORTED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/features/chains/types'
function getAppProvider(chainId: UniverseChainId) {
- const info = UNIVERSE_CHAIN_INFO[chainId]
+ const info = getChainInfo(chainId)
return new AppJsonRpcProvider(
- info.rpcUrls.appOnly.http.map(
- (url) => new ConfiguredJsonRpcProvider(url, { chainId, name: CHAIN_IDS_TO_NAMES[chainId] }),
- ),
+ info.rpcUrls.interface.http.map((url) => new ConfiguredJsonRpcProvider(url, { chainId, name: info.interfaceName })),
)
}
diff --git a/apps/web/src/constants/routing.test.ts b/apps/web/src/constants/routing.test.ts
index 44d686c6142..94583f60e08 100644
--- a/apps/web/src/constants/routing.test.ts
+++ b/apps/web/src/constants/routing.test.ts
@@ -1,5 +1,5 @@
import { COMMON_BASES } from 'uniswap/src/constants/routing'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
describe('Routing', () => {
describe('COMMON_BASES', () => {
diff --git a/apps/web/src/constants/routing.ts b/apps/web/src/constants/routing.ts
index 9e07460a298..e678c6336e1 100644
--- a/apps/web/src/constants/routing.ts
+++ b/apps/web/src/constants/routing.ts
@@ -16,7 +16,7 @@ import {
WETH_AVALANCHE,
WRAPPED_NATIVE_CURRENCY,
} from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
type ChainTokenList = {
readonly [chainId: number]: Token[]
diff --git a/apps/web/src/featureFlags/dynamicConfig/quickRouteChains.ts b/apps/web/src/featureFlags/dynamicConfig/quickRouteChains.ts
index 4ee3118beea..02ddefb7ddb 100644
--- a/apps/web/src/featureFlags/dynamicConfig/quickRouteChains.ts
+++ b/apps/web/src/featureFlags/dynamicConfig/quickRouteChains.ts
@@ -1,6 +1,6 @@
+import { SUPPORTED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/features/chains/types'
import { DynamicConfigs, QuickRouteChainsConfigKey } from 'uniswap/src/features/gating/configs'
import { useDynamicConfigValue } from 'uniswap/src/features/gating/hooks'
-import { SUPPORTED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/types/chains'
import { logger } from 'utilities/src/logger/logger'
export function useQuickRouteChains(): UniverseChainId[] {
diff --git a/apps/web/src/featureFlags/flags/outageBanner.ts b/apps/web/src/featureFlags/flags/outageBanner.ts
index 77ba15a4d48..e9f5b7cd3e2 100644
--- a/apps/web/src/featureFlags/flags/outageBanner.ts
+++ b/apps/web/src/featureFlags/flags/outageBanner.ts
@@ -1,9 +1,9 @@
import { ApolloError } from '@apollo/client'
import { atomWithReset, useResetAtom, useUpdateAtom } from 'jotai/utils'
import { ProtocolVersion } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
export type ChainOutageData = {
chainId: UniverseChainId
diff --git a/apps/web/src/featureFlags/useFeatureFlagUrlOverrides.tsx b/apps/web/src/featureFlags/useFeatureFlagUrlOverrides.tsx
index 1e54108df99..8101771179a 100644
--- a/apps/web/src/featureFlags/useFeatureFlagUrlOverrides.tsx
+++ b/apps/web/src/featureFlags/useFeatureFlagUrlOverrides.tsx
@@ -1,12 +1,13 @@
-import useParsedQueryString from 'hooks/useParsedQueryString'
import { useContext, useEffect } from 'react'
+import { useUrlContext } from 'uniswap/src/contexts/UrlContext'
import { Statsig, StatsigContext } from 'uniswap/src/features/gating/sdk/statsig'
import { isProdEnv } from 'utilities/src/environment/env'
export function useFeatureFlagUrlOverrides() {
+ const { useParsedQueryString } = useUrlContext()
const parsedQs = useParsedQueryString()
const statsigContext = useContext(StatsigContext)
- const isProduction = isProdEnv()
+ const isProduction = isProdEnv() && window.location.hostname !== 'localhost'
useEffect(() => {
// Override on
diff --git a/apps/web/src/graphql/data/RecentTokenTransfers.ts b/apps/web/src/graphql/data/RecentTokenTransfers.ts
index b2231c8de1c..2a5d8aa5f3f 100644
--- a/apps/web/src/graphql/data/RecentTokenTransfers.ts
+++ b/apps/web/src/graphql/data/RecentTokenTransfers.ts
@@ -5,7 +5,7 @@ import {
TransactionType,
useRecentTokenTransfersQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
export function useRecentTokenTransfers(address?: string) {
const { gqlChains } = useEnabledChains()
diff --git a/apps/web/src/graphql/data/SearchTokens.ts b/apps/web/src/graphql/data/SearchTokens.ts
index 186415e17cd..743ede5bb11 100644
--- a/apps/web/src/graphql/data/SearchTokens.ts
+++ b/apps/web/src/graphql/data/SearchTokens.ts
@@ -1,15 +1,14 @@
-import { BACKEND_SUPPORTED_CHAINS } from 'constants/chains'
import { useMemo } from 'react'
import {
- Chain,
SearchTokensWebQuery,
Token,
useSearchTokensWebQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { isBackendSupportedChain } from 'uniswap/src/features/chains/utils'
// Filters out results that are undefined, or where the token's chain is not supported in explore.
function isExploreSupportedToken(token: GqlSearchToken | undefined): token is Token {
- return token !== undefined && (BACKEND_SUPPORTED_CHAINS as ReadonlyArray).includes(token.chain)
+ return token !== undefined && isBackendSupportedChain(token.chain)
}
export function useSearchTokens(searchQuery: string = '') {
diff --git a/apps/web/src/graphql/data/TopTokens.ts b/apps/web/src/graphql/data/TopTokens.ts
deleted file mode 100644
index 68a41be69b2..00000000000
--- a/apps/web/src/graphql/data/TopTokens.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import { ApolloError } from '@apollo/client'
-import {
- exploreSearchStringAtom,
- filterTimeAtom,
- sortAscendingAtom,
- sortMethodAtom,
- TokenSortMethod,
-} from 'components/Tokens/state'
-import {
- isPricePoint,
- PollingInterval,
- PricePoint,
- supportedChainIdFromGQLChain,
- toHistoryDuration,
- unwrapToken,
- usePollQueryWhileMounted,
-} from 'graphql/data/util'
-import useIsWindowVisible from 'hooks/useIsWindowVisible'
-import { useAtomValue } from 'jotai/utils'
-import { useMemo } from 'react'
-import {
- Chain,
- TopTokens100Query,
- useTopTokens100Query,
- useTopTokensSparklineQuery,
-} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-
-const TokenSortMethods = {
- [TokenSortMethod.PRICE]: (a: TopToken, b: TopToken) =>
- (b?.market?.price?.value ?? 0) - (a?.market?.price?.value ?? 0),
- [TokenSortMethod.DAY_CHANGE]: (a: TopToken, b: TopToken) =>
- (b?.market?.pricePercentChange1Day?.value ?? 0) - (a?.market?.pricePercentChange1Day?.value ?? 0),
- [TokenSortMethod.HOUR_CHANGE]: (a: TopToken, b: TopToken) =>
- (b?.market?.pricePercentChange1Hour?.value ?? 0) - (a?.market?.pricePercentChange1Hour?.value ?? 0),
- [TokenSortMethod.VOLUME]: (a: TopToken, b: TopToken) =>
- (b?.market?.volume?.value ?? 0) - (a?.market?.volume?.value ?? 0),
- [TokenSortMethod.FULLY_DILUTED_VALUATION]: (a: TopToken, b: TopToken) =>
- (b?.project?.markets?.[0]?.fullyDilutedValuation?.value ?? 0) -
- (a?.project?.markets?.[0]?.fullyDilutedValuation?.value ?? 0),
-}
-
-function useSortedTokens(tokens: TopTokens100Query['topTokens']) {
- const sortMethod = useAtomValue(sortMethodAtom)
- const sortAscending = useAtomValue(sortAscendingAtom)
-
- return useMemo(() => {
- if (!tokens) {
- return undefined
- }
- const tokenArray = Array.from(tokens).sort(TokenSortMethods[sortMethod])
-
- return sortAscending ? tokenArray.reverse() : tokenArray
- }, [tokens, sortMethod, sortAscending])
-}
-
-function useFilteredTokens(tokens: TopTokens100Query['topTokens']) {
- const filterString = useAtomValue(exploreSearchStringAtom)
-
- const lowercaseFilterString = useMemo(() => filterString.toLowerCase(), [filterString])
-
- return useMemo(() => {
- if (!tokens) {
- return undefined
- }
- let returnTokens = tokens
- if (lowercaseFilterString) {
- returnTokens = returnTokens?.filter((token) => {
- const addressIncludesFilterString = token?.address?.toLowerCase().includes(lowercaseFilterString)
- const projectNameIncludesFilterString = token?.project?.name?.toLowerCase().includes(lowercaseFilterString)
- const nameIncludesFilterString = token?.name?.toLowerCase().includes(lowercaseFilterString)
- const symbolIncludesFilterString = token?.symbol?.toLowerCase().includes(lowercaseFilterString)
- return (
- projectNameIncludesFilterString ||
- nameIncludesFilterString ||
- symbolIncludesFilterString ||
- addressIncludesFilterString
- )
- })
- }
- return returnTokens
- }, [tokens, lowercaseFilterString])
-}
-
-export type SparklineMap = { [key: string]: PricePoint[] | undefined }
-export type TopToken = NonNullable['topTokens']>[number]
-
-interface UseTopTokensReturnValue {
- tokens?: readonly TopToken[]
- tokenSortRank: Record
- loadingTokens: boolean
- sparklines: SparklineMap
- error?: ApolloError
-}
-
-export function useTopTokens(chain: Chain, skip?: boolean): UseTopTokensReturnValue {
- const chainId = supportedChainIdFromGQLChain(chain)
- const duration = toHistoryDuration(useAtomValue(filterTimeAtom))
- const isWindowVisible = useIsWindowVisible()
-
- const { data: sparklineQuery } = usePollQueryWhileMounted(
- useTopTokensSparklineQuery({
- variables: { duration, chain },
- skip: !isWindowVisible || skip,
- }),
- PollingInterval.Slow,
- )
-
- const sparklines = useMemo(() => {
- const unwrappedTokens = chainId && sparklineQuery?.topTokens?.map((topToken) => unwrapToken(chainId, topToken))
- const map: SparklineMap = {}
- unwrappedTokens?.forEach((current) => {
- if (current?.address !== undefined) {
- map[current.address] = current?.market?.priceHistory?.filter(isPricePoint) as PricePoint[]
- }
- })
- return map
- }, [chainId, sparklineQuery?.topTokens])
-
- const {
- data,
- loading: loadingTokens,
- error,
- } = usePollQueryWhileMounted(
- useTopTokens100Query({
- variables: { duration, chain },
- skip: !isWindowVisible || skip,
- }),
- PollingInterval.Fast,
- )
-
- const unwrappedTokens = useMemo(
- () => chainId && data?.topTokens?.map((token) => unwrapToken(chainId, token)),
- [chainId, data],
- )
- const sortedTokens = useSortedTokens(unwrappedTokens)
- const tokenSortRank = useMemo(
- () =>
- sortedTokens?.reduce((acc, cur, i) => {
- if (!cur?.address) {
- return acc
- }
- return {
- ...acc,
- [cur.address]: i + 1,
- }
- }, {}) ?? {},
- [sortedTokens],
- )
- const filteredTokens = useFilteredTokens(sortedTokens)
- return useMemo(
- () => ({ tokens: filteredTokens, tokenSortRank, loadingTokens, sparklines, error }),
- [filteredTokens, tokenSortRank, loadingTokens, sparklines, error],
- )
-}
diff --git a/apps/web/src/graphql/data/TrendingTokens.ts b/apps/web/src/graphql/data/TrendingTokens.ts
index e5e28a858ff..2a71563288e 100644
--- a/apps/web/src/graphql/data/TrendingTokens.ts
+++ b/apps/web/src/graphql/data/TrendingTokens.ts
@@ -1,11 +1,13 @@
-import { chainIdToBackendChain } from 'constants/chains'
import { unwrapToken } from 'graphql/data/util'
import { useMemo } from 'react'
import { useTrendingTokensQuery } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
export default function useTrendingTokens(chainId?: UniverseChainId) {
- const chain = chainIdToBackendChain({ chainId, withFallback: true })
+ const { defaultChainId } = useEnabledChains()
+ const chain = toGraphQLChain(chainId ?? defaultChainId)
const { data, loading } = useTrendingTokensQuery({ variables: { chain } })
return useMemo(
diff --git a/apps/web/src/graphql/data/apollo/AssetActivityProvider.tsx b/apps/web/src/graphql/data/apollo/AssetActivityProvider.tsx
index 555b52c92a0..0fe57edba21 100644
--- a/apps/web/src/graphql/data/apollo/AssetActivityProvider.tsx
+++ b/apps/web/src/graphql/data/apollo/AssetActivityProvider.tsx
@@ -22,9 +22,9 @@ import {
useActivityWebLazyQuery,
useOnAssetActivitySubscription,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
import { logger } from 'utilities/src/logger/logger'
import { useInterval } from 'utilities/src/time/timing'
import { v4 as uuidV4 } from 'uuid'
diff --git a/apps/web/src/graphql/data/apollo/TokenBalancesProvider.test.tsx b/apps/web/src/graphql/data/apollo/TokenBalancesProvider.test.tsx
index b4f02e14ec4..4134d5a09ec 100644
--- a/apps/web/src/graphql/data/apollo/TokenBalancesProvider.test.tsx
+++ b/apps/web/src/graphql/data/apollo/TokenBalancesProvider.test.tsx
@@ -1,4 +1,4 @@
-import { fireEvent, screen } from '@testing-library/react'
+import { fireEvent, screen, waitFor } from '@testing-library/react'
import { PrefetchBalancesWrapper, useTokenBalancesQuery } from 'graphql/data/apollo/AdaptiveTokenBalancesProvider'
import { useAccount } from 'hooks/useAccount'
import { mocked } from 'test-utils/mocked'
@@ -7,6 +7,8 @@ import { useOnAssetActivitySubscription } from 'uniswap/src/data/graphql/uniswap
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+// TODO(WEB-5370): Remove this delay + waitFor once we've integrated wallet's refetch logic
+jest.setTimeout(10000)
const mockLazyFetch = jest.fn()
const mockBalanceQueryResponse = [
mockLazyFetch,
@@ -45,17 +47,17 @@ describe('TokenBalancesProvider', () => {
mocked(useAccount).mockReturnValue({ address: '0xaddress1', chainId: 1 } as any)
})
- it('TokenBalancesProvider should not fetch balances without calls to useOnAssetActivitySubscription', () => {
+ it('TokenBalancesProvider should not fetch balances without calls to useOnAssetActivitySubscription', async () => {
render()
- expect(mockLazyFetch).toHaveBeenCalledTimes(0)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(0), { timeout: 3500 })
})
describe('useTokenBalancesQuery', () => {
- it('should only refetch balances when stale', () => {
+ it('should only refetch balances when stale', async () => {
const { rerender, unmount } = renderHook(() => useTokenBalancesQuery())
// Rendering useTokenBalancesQuery should trigger a fetch
- expect(mockLazyFetch).toHaveBeenCalledTimes(1)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(1), { timeout: 3500 })
// Rerender to clear staleness
rerender()
@@ -63,31 +65,31 @@ describe('TokenBalancesProvider', () => {
// Receiving a new value from subscription should trigger a fetch while useTokenBalancesQuery hooks are mounted
triggerSubscriptionUpdate()
rerender()
- expect(mockLazyFetch).toHaveBeenCalledTimes(2)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(2), { timeout: 3500 })
// Unmounting the hooks should not trigger any fetches
unmount()
- expect(mockLazyFetch).toHaveBeenCalledTimes(2)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(2), { timeout: 3500 })
// Receiving a new value from subscription should NOT trigger a fetch if no useTokenBalancesQuery hooks are mounted
triggerSubscriptionUpdate()
- expect(mockLazyFetch).toHaveBeenCalledTimes(2)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(2), { timeout: 3500 })
})
- it('should use cached balances across multiple hook calls', () => {
+ it('should use cached balances across multiple hook calls', async () => {
renderHook(() => ({
hook1: useTokenBalancesQuery(),
hook2: useTokenBalancesQuery(),
}))
// Rendering useTokenBalancesQuery twice should only trigger one fetch
- expect(mockLazyFetch).toHaveBeenCalledTimes(1)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(1), { timeout: 3500 })
})
- it('should refetch when account changes', () => {
+ it('should refetch when account changes', async () => {
const { rerender } = renderHook(() => useTokenBalancesQuery())
- expect(mockLazyFetch).toHaveBeenCalledTimes(1)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(1), { timeout: 3500 })
// Rerender to clear staleness
rerender()
@@ -96,12 +98,12 @@ describe('TokenBalancesProvider', () => {
mocked(useAccount).mockReturnValue({ address: '0xaddress2', chainId: 1 } as any)
rerender()
- expect(mockLazyFetch).toHaveBeenCalledTimes(2)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(2), { timeout: 3500 })
})
})
describe('PrefetchBalancesWrapper', () => {
- it('should fetch balances when a PrefetchBalancesWrapper is hovered', () => {
+ it('should fetch balances when a PrefetchBalancesWrapper is hovered', async () => {
const { rerender } = render(
hi
@@ -117,17 +119,17 @@ describe('TokenBalancesProvider', () => {
)
// Should not fetch balances before hover
- expect(mockLazyFetch).toHaveBeenCalledTimes(0)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(0), { timeout: 3500 })
// Hovering component should trigger a fetch
fireEvent.mouseEnter(wrappedComponent)
fireEvent.mouseLeave(wrappedComponent)
- expect(mockLazyFetch).toHaveBeenCalledTimes(1)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(1), { timeout: 4000 })
// Subsequent hover should not trigger a fetch
fireEvent.mouseEnter(wrappedComponent)
fireEvent.mouseLeave(wrappedComponent)
- expect(mockLazyFetch).toHaveBeenCalledTimes(1)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(1), { timeout: 4000 })
// Subsequent hover should trigger a fetch if the subscription has updated
triggerSubscriptionUpdate()
@@ -136,10 +138,10 @@ describe('TokenBalancesProvider', () => {
hi
,
)
- expect(mockLazyFetch).toHaveBeenCalledTimes(1)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(1), { timeout: 4000 })
fireEvent.mouseEnter(wrappedComponent)
fireEvent.mouseLeave(wrappedComponent)
- expect(mockLazyFetch).toHaveBeenCalledTimes(2)
+ await waitFor(() => expect(mockLazyFetch).toHaveBeenCalledTimes(2), { timeout: 4000 })
})
})
})
diff --git a/apps/web/src/graphql/data/apollo/TokenBalancesProvider.tsx b/apps/web/src/graphql/data/apollo/TokenBalancesProvider.tsx
index 2747a311fc6..92af65a096d 100644
--- a/apps/web/src/graphql/data/apollo/TokenBalancesProvider.tsx
+++ b/apps/web/src/graphql/data/apollo/TokenBalancesProvider.tsx
@@ -8,14 +8,11 @@ import {
SwapOrderStatus,
usePortfolioBalancesLazyQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import {
- useEnabledChains,
- useHideSmallBalancesSetting,
- useHideSpamTokensSetting,
-} from 'uniswap/src/features/settings/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useHideSmallBalancesSetting, useHideSpamTokensSetting } from 'uniswap/src/features/settings/hooks'
import { SUBSCRIPTION_CHAINIDS } from 'utilities/src/apollo/constants'
import { usePrevious } from 'utilities/src/react/hooks'
@@ -102,22 +99,37 @@ export function TokenBalancesProvider({ children }: PropsWithChildren) {
if (!account.address) {
return
}
- lazyFetch({
- variables: {
- ownerAddress: account.address,
- chains: gqlChains,
- valueModifiers: [
- {
- ownerAddress: account.address,
- includeSpamTokens: valueModifiers.includeSpamTokens,
- includeSmallBalances: valueModifiers.includeSmallBalances,
- tokenExcludeOverrides: [],
- tokenIncludeOverrides: [],
- },
- ],
+ // adds a 3 second delay to account for dependency latency after an account update
+ // TODO(WEB-5370): Remove this delay once we've integrated wallet's refetch logic
+ setTimeout(
+ () => {
+ account.address &&
+ lazyFetch({
+ variables: {
+ ownerAddress: account.address,
+ chains: gqlChains,
+ valueModifiers: [
+ {
+ ownerAddress: account.address,
+ includeSpamTokens: valueModifiers.includeSpamTokens,
+ includeSmallBalances: valueModifiers.includeSmallBalances,
+ tokenExcludeOverrides: [],
+ tokenIncludeOverrides: [],
+ },
+ ],
+ },
+ })
},
- })
- }, [account.address, lazyFetch, valueModifiers, gqlChains])
+ hasAccountUpdate ? 3000 : 0,
+ )
+ }, [
+ account.address,
+ hasAccountUpdate,
+ lazyFetch,
+ gqlChains,
+ valueModifiers.includeSpamTokens,
+ valueModifiers.includeSmallBalances,
+ ])
return (
, Record>,
+): Reference | StoreObject {
+ if (existing && !incoming) {
+ return existing
+ }
+ return mergeObjects(existing, incoming)
+}
diff --git a/apps/web/src/graphql/data/nft/NftUniversalRouterAddress.ts b/apps/web/src/graphql/data/nft/NftUniversalRouterAddress.ts
index 535e10cb760..c414120ec55 100644
--- a/apps/web/src/graphql/data/nft/NftUniversalRouterAddress.ts
+++ b/apps/web/src/graphql/data/nft/NftUniversalRouterAddress.ts
@@ -1,6 +1,6 @@
import { UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion } from '@uniswap/universal-router-sdk'
import { useNftUniversalRouterAddressQuery } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export function getURAddress(chainId?: UniverseChainId, nftURAddress?: string): string | undefined {
if (!chainId) {
diff --git a/apps/web/src/graphql/data/pools/usePoolData.ts b/apps/web/src/graphql/data/pools/usePoolData.ts
index a9d77524bd4..4481699b7ce 100644
--- a/apps/web/src/graphql/data/pools/usePoolData.ts
+++ b/apps/web/src/graphql/data/pools/usePoolData.ts
@@ -1,4 +1,3 @@
-import { chainIdToBackendChain } from 'constants/chains'
import { V2_BIPS } from 'graphql/data/pools/useTopPools'
import ms from 'ms'
import { useMemo } from 'react'
@@ -8,7 +7,9 @@ import {
useV2PairQuery,
useV3PoolQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
export interface PoolData {
// basic pool info
@@ -74,12 +75,14 @@ export function usePoolData(
error: boolean
data?: PoolData
} {
+ const { defaultChainId } = useEnabledChains()
+ const variables = { chain: toGraphQLChain(chainId ?? defaultChainId), address: poolAddress }
const {
loading: loadingV3,
error: errorV3,
data: dataV3,
} = useV3PoolQuery({
- variables: { chain: chainIdToBackendChain({ chainId, withFallback: true }), address: poolAddress },
+ variables,
errorPolicy: 'all',
})
const {
@@ -87,7 +90,7 @@ export function usePoolData(
error: errorV2,
data: dataV2,
} = useV2PairQuery({
- variables: { chain: chainIdToBackendChain({ chainId, withFallback: true }), address: poolAddress },
+ variables,
skip: !chainId,
errorPolicy: 'all',
})
diff --git a/apps/web/src/graphql/data/pools/usePoolTransactions.ts b/apps/web/src/graphql/data/pools/usePoolTransactions.ts
index 0b6ff5f5917..9e217b7b093 100644
--- a/apps/web/src/graphql/data/pools/usePoolTransactions.ts
+++ b/apps/web/src/graphql/data/pools/usePoolTransactions.ts
@@ -1,4 +1,3 @@
-import { chainIdToBackendChain } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { useCallback, useMemo, useRef } from 'react'
import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
@@ -11,7 +10,9 @@ import {
useV2PairTransactionsQuery,
useV3PoolTransactionsQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
export enum PoolTableTransactionType {
BUY = 'Buy',
@@ -56,13 +57,15 @@ export function usePoolTransactions(
protocolVersion: ProtocolVersion = ProtocolVersion.V3,
first = PoolTransactionDefaultQuerySize,
) {
+ const { defaultChainId } = useEnabledChains()
+ const variables = { first, chain: toGraphQLChain(chainId ?? defaultChainId), address }
const {
loading: loadingV3,
error: errorV3,
data: dataV3,
fetchMore: fetchMoreV3,
} = useV3PoolTransactionsQuery({
- variables: { first, chain: chainIdToBackendChain({ chainId, withFallback: true }), address },
+ variables,
skip: protocolVersion !== ProtocolVersion.V3,
})
const {
@@ -71,7 +74,7 @@ export function usePoolTransactions(
data: dataV2,
fetchMore: fetchMoreV2,
} = useV2PairTransactionsQuery({
- variables: { first, chain: chainIdToBackendChain({ chainId, withFallback: true }), address },
+ variables,
skip: !chainId || protocolVersion !== ProtocolVersion.V2,
})
const loadingMore = useRef(false)
diff --git a/apps/web/src/graphql/data/pools/usePoolsFromTokenAddress.ts b/apps/web/src/graphql/data/pools/usePoolsFromTokenAddress.ts
index d2c872e9a72..9172d7cce04 100644
--- a/apps/web/src/graphql/data/pools/usePoolsFromTokenAddress.ts
+++ b/apps/web/src/graphql/data/pools/usePoolsFromTokenAddress.ts
@@ -1,4 +1,3 @@
-import { chainIdToBackendChain } from 'constants/chains'
import {
PoolTableSortState,
TablePool,
@@ -12,7 +11,9 @@ import {
useTopV2PairsQuery,
useTopV3PoolsQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
const DEFAULT_QUERY_SIZE = 20
@@ -21,6 +22,8 @@ export function usePoolsFromTokenAddress(
sortState: PoolTableSortState,
chainId?: UniverseChainId,
) {
+ const { defaultChainId } = useEnabledChains()
+ const chain = toGraphQLChain(chainId ?? defaultChainId)
const {
loading: loadingV3,
error: errorV3,
@@ -30,7 +33,7 @@ export function usePoolsFromTokenAddress(
variables: {
first: DEFAULT_QUERY_SIZE,
tokenAddress,
- chain: chainIdToBackendChain({ chainId, withFallback: true }),
+ chain,
},
})
@@ -43,7 +46,7 @@ export function usePoolsFromTokenAddress(
variables: {
first: DEFAULT_QUERY_SIZE,
tokenAddress,
- chain: chainIdToBackendChain({ chainId, withFallback: true }),
+ chain,
},
skip: !chainId,
})
diff --git a/apps/web/src/graphql/data/pools/useTopPools.ts b/apps/web/src/graphql/data/pools/useTopPools.ts
index 5fc3cbd0929..10456cbde86 100644
--- a/apps/web/src/graphql/data/pools/useTopPools.ts
+++ b/apps/web/src/graphql/data/pools/useTopPools.ts
@@ -1,20 +1,7 @@
import { Percent } from '@uniswap/sdk-core'
-import { exploreSearchStringAtom } from 'components/Tokens/state'
-import { chainIdToBackendChain } from 'constants/chains'
import { OrderDirection } from 'graphql/data/util'
-import useIsWindowVisible from 'hooks/useIsWindowVisible'
-import { useAtomValue } from 'jotai/utils'
-import { useMemo } from 'react'
import { BIPS_BASE } from 'uniswap/src/constants/misc'
-import {
- ProtocolVersion,
- Token,
- useTopV2PairsQuery,
- useTopV3PoolsQuery,
-} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { ProtocolVersion, Token } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
export function sortPools(pools: TablePool[], sortState: PoolTableSortState) {
return pools.sort((a, b) => {
@@ -93,92 +80,3 @@ export type PoolTableSortState = {
sortBy: PoolSortFields
sortDirection: OrderDirection
}
-
-function useFilteredPools(pools: TablePool[]) {
- const filterString = useAtomValue(exploreSearchStringAtom)
-
- const lowercaseFilterString = useMemo(() => filterString.toLowerCase(), [filterString])
-
- return useMemo(
- () =>
- pools.filter((pool) => {
- const addressIncludesFilterString = pool.hash.toLowerCase().includes(lowercaseFilterString)
- const token0IncludesFilterString = pool.token0?.symbol?.toLowerCase().includes(lowercaseFilterString)
- const token1IncludesFilterString = pool.token1?.symbol?.toLowerCase().includes(lowercaseFilterString)
- const token0HashIncludesFilterString = pool.token0?.address?.toLowerCase().includes(lowercaseFilterString)
- const token1HashIncludesFilterString = pool.token1?.address?.toLowerCase().includes(lowercaseFilterString)
- const poolName = `${pool.token0?.symbol}/${pool.token1?.symbol}`.toLowerCase()
- const poolNameIncludesFilterString = poolName.includes(lowercaseFilterString)
- return (
- token0IncludesFilterString ||
- token1IncludesFilterString ||
- addressIncludesFilterString ||
- token0HashIncludesFilterString ||
- token1HashIncludesFilterString ||
- poolNameIncludesFilterString
- )
- }),
- [lowercaseFilterString, pools],
- )
-}
-
-export function useTopPools(sortState: PoolTableSortState, chainId?: UniverseChainId) {
- const isWindowVisible = useIsWindowVisible()
- const isRestExploreEnabled = useFeatureFlag(FeatureFlags.RestExplore)
- const {
- loading: loadingV3,
- error: errorV3,
- data: dataV3,
- } = useTopV3PoolsQuery({
- variables: { first: 100, chain: chainIdToBackendChain({ chainId, withFallback: true }) },
- skip: !isWindowVisible || isRestExploreEnabled,
- })
- const {
- loading: loadingV2,
- error: errorV2,
- data: dataV2,
- } = useTopV2PairsQuery({
- variables: { first: 100, chain: chainIdToBackendChain({ chainId, withFallback: true }) },
- skip: !isWindowVisible || !chainId || isRestExploreEnabled,
- })
- const loading = loadingV3 || loadingV2
-
- const unfilteredPools = useMemo(() => {
- // TODO(WEB-4818): add v4 pools here
- const topV3Pools: TablePool[] =
- dataV3?.topV3Pools?.map((pool) => {
- return {
- hash: pool.address,
- token0: pool.token0,
- token1: pool.token1,
- tvl: pool.totalLiquidity?.value,
- volume24h: pool.volume24h?.value,
- volumeWeek: pool.volumeWeek?.value,
- apr: calculateApr(pool.volume24h?.value, pool.totalLiquidity?.value, pool.feeTier),
- volOverTvl: calculate1DVolOverTvl(pool.volume24h?.value, pool.totalLiquidity?.value),
- feeTier: pool.feeTier,
- protocolVersion: pool.protocolVersion,
- } as TablePool
- }) ?? []
- const topV2Pairs: TablePool[] =
- dataV2?.topV2Pairs?.map((pool) => {
- return {
- hash: pool.address,
- token0: pool.token0,
- token1: pool.token1,
- tvl: pool.totalLiquidity?.value,
- volume24h: pool.volume24h?.value,
- volumeWeek: pool.volumeWeek?.value,
- volOverTvl: calculate1DVolOverTvl(pool.volume24h?.value, pool.totalLiquidity?.value),
- apr: calculateApr(pool.volume24h?.value, pool.totalLiquidity?.value, V2_BIPS),
- feeTier: V2_BIPS,
- protocolVersion: pool.protocolVersion,
- } as TablePool
- }) ?? []
-
- return sortPools([...topV3Pools, ...topV2Pairs], sortState)
- }, [dataV2?.topV2Pairs, dataV3?.topV3Pools, sortState])
-
- const filteredPools = useFilteredPools(unfilteredPools).slice(0, 100)
- return { topPools: filteredPools, loading, errorV3, errorV2 }
-}
diff --git a/apps/web/src/graphql/data/protocolStats.ts b/apps/web/src/graphql/data/protocolStats.ts
deleted file mode 100644
index 7195dcfb580..00000000000
--- a/apps/web/src/graphql/data/protocolStats.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { StackedLineData } from 'components/Charts/StackedLineChart'
-import { StackedHistogramData } from 'components/Charts/VolumeChart/renderer'
-import { ChartType } from 'components/Charts/utils'
-import { ChartQueryResult, checkDataQuality } from 'components/Tokens/TokenDetails/ChartSection/util'
-import useIsWindowVisible from 'hooks/useIsWindowVisible'
-import { UTCTimestamp } from 'lightweight-charts'
-import { useMemo } from 'react'
-import {
- Chain,
- HistoryDuration,
- PriceSource,
- ProtocolVersion,
- TimestampedAmount,
- useDailyProtocolTvlQuery,
- useHistoricalProtocolVolumeQuery,
-} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-
-function mapDataByTimestamp(
- v2Data?: readonly TimestampedAmount[],
- v3Data?: readonly TimestampedAmount[],
-): Record> {
- const dataByTime: Record> = {}
- v2Data?.forEach((v2Point) => {
- const timestamp = v2Point.timestamp
- dataByTime[timestamp] = { [ProtocolVersion.V2]: v2Point.value, [ProtocolVersion.V3]: 0, [ProtocolVersion.V4]: 0 }
- })
- v3Data?.forEach((v3Point) => {
- const timestamp = v3Point.timestamp
- if (!dataByTime[timestamp]) {
- dataByTime[timestamp] = { [ProtocolVersion.V4]: 0, [ProtocolVersion.V2]: 0, [ProtocolVersion.V3]: v3Point.value }
- } else {
- dataByTime[timestamp][ProtocolVersion.V3] = v3Point.value
- }
- })
- return dataByTime
-}
-
-export function useHistoricalProtocolVolume(
- chain: Chain,
- duration: HistoryDuration,
-): ChartQueryResult {
- const isWindowVisible = useIsWindowVisible()
- const isRestExploreEnabled = useFeatureFlag(FeatureFlags.RestExplore)
- const { data: queryData, loading } = useHistoricalProtocolVolumeQuery({
- variables: { chain, duration },
- skip: !isWindowVisible || isRestExploreEnabled,
- })
-
- return useMemo(() => {
- const dataByTime = mapDataByTimestamp(queryData?.v2HistoricalProtocolVolume, queryData?.v3HistoricalProtocolVolume)
-
- const entries = Object.entries(dataByTime).reduce((acc, [timestamp, values]) => {
- acc.push({
- time: Number(timestamp) as UTCTimestamp,
- values: {
- [PriceSource.SubgraphV2]: values[ProtocolVersion.V2],
- [PriceSource.SubgraphV3]: values[ProtocolVersion.V3],
- [PriceSource.SubgraphV4]: values[ProtocolVersion.V4],
- },
- })
- return acc
- }, [] as StackedHistogramData[])
-
- const dataQuality = checkDataQuality(entries, ChartType.VOLUME, duration)
- return { chartType: ChartType.VOLUME, entries, loading, dataQuality }
- }, [duration, loading, queryData?.v2HistoricalProtocolVolume, queryData?.v3HistoricalProtocolVolume])
-}
-
-export function useDailyProtocolTVL(chain: Chain): ChartQueryResult {
- const isWindowVisible = useIsWindowVisible()
- const isRestExploreEnabled = useFeatureFlag(FeatureFlags.RestExplore)
- const { data: queryData, loading } = useDailyProtocolTvlQuery({
- variables: { chain },
- skip: !isWindowVisible || isRestExploreEnabled,
- })
-
- return useMemo(() => {
- const dataByTime = mapDataByTimestamp(queryData?.v2DailyProtocolTvl, queryData?.v3DailyProtocolTvl)
- const entries = Object.entries(dataByTime).map(([timestamp, values]) => ({
- time: Number(timestamp),
- values: [values[ProtocolVersion.V2], values[ProtocolVersion.V3]],
- })) as StackedLineData[]
-
- const dataQuality = checkDataQuality(entries, ChartType.TVL, HistoryDuration.Year)
- return { chartType: ChartType.TVL, entries, loading, dataQuality }
- }, [loading, queryData?.v2DailyProtocolTvl, queryData?.v3DailyProtocolTvl])
-}
diff --git a/apps/web/src/graphql/data/types.test.ts b/apps/web/src/graphql/data/types.test.ts
index 2ab76cdabb2..821da42c39f 100644
--- a/apps/web/src/graphql/data/types.test.ts
+++ b/apps/web/src/graphql/data/types.test.ts
@@ -7,8 +7,8 @@ import {
Token,
TokenStandard,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { removeSafetyInfo } from 'uniswap/src/test/fixtures'
-import { UniverseChainId } from 'uniswap/src/types/chains'
const MAINNET_NATIVE_GQL_TOKEN = {
__typename: 'Token',
diff --git a/apps/web/src/graphql/data/types.ts b/apps/web/src/graphql/data/types.ts
index c09d0ba8e13..e8daca792c5 100644
--- a/apps/web/src/graphql/data/types.ts
+++ b/apps/web/src/graphql/data/types.ts
@@ -1,16 +1,16 @@
-import { isSupportedChainId } from 'constants/chains'
-import { fiatOnRampToCurrency, gqlToCurrency } from 'graphql/data/util'
+import { PricePoint, fiatOnRampToCurrency, gqlToCurrency } from 'graphql/data/util'
import { COMMON_BASES, buildPartialCurrencyInfo } from 'uniswap/src/constants/routing'
import { USDC_OPTIMISM } from 'uniswap/src/constants/tokens'
import {
Token as GqlToken,
ProtectionResult,
SafetyLevel,
+ TopTokens100Query,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId, isUniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyInfo, TokenList } from 'uniswap/src/features/dataApi/types'
import { buildCurrencyInfo, getCurrencySafetyInfo } from 'uniswap/src/features/dataApi/utils'
import { FORSupportedToken } from 'uniswap/src/features/fiatOnRamp/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { isSameAddress } from 'utilities/src/addresses'
import { currencyId } from 'utils/currencyId'
@@ -40,7 +40,7 @@ export function gqlTokenToCurrencyInfo(token?: GqlToken): CurrencyInfo | undefin
}
export function meldSupportedCurrencyToCurrencyInfo(forCurrency: FORSupportedToken): CurrencyInfo | undefined {
- if (!isSupportedChainId(Number(forCurrency.chainId))) {
+ if (!isUniverseChainId(Number(forCurrency.chainId))) {
return undefined
}
@@ -82,3 +82,6 @@ export function meldSupportedCurrencyToCurrencyInfo(forCurrency: FORSupportedTok
isSpam: false,
})
}
+
+export type SparklineMap = { [key: string]: PricePoint[] | undefined }
+export type TopToken = NonNullable['topTokens']>[number]
diff --git a/apps/web/src/graphql/data/useTokenTransactions.ts b/apps/web/src/graphql/data/useTokenTransactions.ts
index debe193563d..7ca9ce7fe4b 100644
--- a/apps/web/src/graphql/data/useTokenTransactions.ts
+++ b/apps/web/src/graphql/data/useTokenTransactions.ts
@@ -1,4 +1,3 @@
-import { chainIdToBackendChain } from 'constants/chains'
import { useCallback, useMemo, useRef } from 'react'
import {
Chain,
@@ -7,7 +6,9 @@ import {
useV2TokenTransactionsQuery,
useV3TokenTransactionsQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
export enum TokenTransactionType {
BUY = 'Buy',
@@ -21,6 +22,7 @@ export function useTokenTransactions(
chainId: UniverseChainId,
filter: TokenTransactionType[] = [TokenTransactionType.BUY, TokenTransactionType.SELL],
) {
+ const { defaultChainId } = useEnabledChains()
const {
data: dataV3,
loading: loadingV3,
@@ -29,7 +31,7 @@ export function useTokenTransactions(
} = useV3TokenTransactionsQuery({
variables: {
address: address.toLowerCase(),
- chain: chainIdToBackendChain({ chainId, withFallback: true }),
+ chain: toGraphQLChain(chainId ?? defaultChainId),
first: TokenTransactionDefaultQuerySize,
},
})
@@ -42,7 +44,7 @@ export function useTokenTransactions(
variables: {
address: address.toLowerCase(),
first: TokenTransactionDefaultQuerySize,
- chain: chainIdToBackendChain({ chainId }),
+ chain: toGraphQLChain(chainId),
},
})
const loadingMoreV3 = useRef(false)
diff --git a/apps/web/src/graphql/data/util.test.tsx b/apps/web/src/graphql/data/util.test.tsx
index 15c076a7944..bf8ef3953b6 100644
--- a/apps/web/src/graphql/data/util.test.tsx
+++ b/apps/web/src/graphql/data/util.test.tsx
@@ -1,13 +1,14 @@
-import { isSupportedGQLChain, supportedChainIdFromGQLChain } from 'graphql/data/util'
+import { supportedChainIdFromGQLChain } from 'graphql/data/util'
import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { isBackendSupportedChain } from 'uniswap/src/features/chains/utils'
describe('fromGraphQLChain', () => {
it('should return the corresponding chain ID for supported chains', () => {
expect(supportedChainIdFromGQLChain(Chain.Ethereum)).toBe(UniverseChainId.Mainnet)
for (const chain of Object.values(Chain)) {
- if (!isSupportedGQLChain(chain)) {
+ if (!isBackendSupportedChain(chain)) {
continue
}
expect(supportedChainIdFromGQLChain(chain)).not.toBe(undefined)
@@ -17,12 +18,11 @@ describe('fromGraphQLChain', () => {
it('should return undefined for unsupported chains', () => {
expect(supportedChainIdFromGQLChain(Chain.UnknownChain)).toBe(undefined)
- for (const chain of Object.values(Chain)) {
- if (isSupportedGQLChain(chain)) {
- continue
- }
- expect(supportedChainIdFromGQLChain(chain)).toBe(undefined)
- }
+ Object.values(Chain)
+ .filter((c) => !isBackendSupportedChain(c))
+ .forEach((chain) => {
+ expect(supportedChainIdFromGQLChain(chain)).toBe(undefined)
+ })
})
it('should not crash when a new BE chain is added', () => {
@@ -32,7 +32,7 @@ describe('fromGraphQLChain', () => {
const ExpandedChainList = [...Object.values(Chain), NewChain.NewChain as unknown as Chain]
for (const chain of ExpandedChainList) {
- if (isSupportedGQLChain(chain)) {
+ if (isBackendSupportedChain(chain)) {
continue
}
expect(supportedChainIdFromGQLChain(chain)).toBe(undefined)
diff --git a/apps/web/src/graphql/data/util.tsx b/apps/web/src/graphql/data/util.tsx
index 1957b9fe1ed..52be5573f8b 100644
--- a/apps/web/src/graphql/data/util.tsx
+++ b/apps/web/src/graphql/data/util.tsx
@@ -1,25 +1,13 @@
-import { OperationVariables, QueryResult } from '@apollo/client'
import { DeepPartial } from '@apollo/client/utilities'
+import { BigNumber } from '@ethersproject/bignumber'
import { DataTag, DefaultError, QueryKey, UndefinedInitialDataOptions, queryOptions } from '@tanstack/react-query'
import { Currency, Token } from '@uniswap/sdk-core'
-import {
- AVERAGE_L1_BLOCK_TIME,
- BACKEND_SUPPORTED_CHAINS,
- CHAIN_NAME_TO_CHAIN_ID,
- InterfaceGqlChain,
- UX_SUPPORTED_GQL_CHAINS,
- chainIdToBackendChain,
- getChainFromChainUrlParam,
- isSupportedChainId,
-} from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { DefaultTheme } from 'lib/styled-components'
import ms from 'ms'
import { ExploreTab } from 'pages/Explore'
-import { useEffect } from 'react'
import { TokenStat } from 'state/explore/types'
import { ThemeColors } from 'theme/colors'
-import { GQL_MAINNET_CHAINS, UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { WRAPPED_NATIVE_CURRENCY, nativeOnChain } from 'uniswap/src/constants/tokens'
import {
Chain,
@@ -29,32 +17,26 @@ import {
PriceSource,
TokenStandard,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { GQL_MAINNET_CHAINS, getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { GqlChainId, UniverseChainId, isUniverseChainId } from 'uniswap/src/features/chains/types'
+import {
+ fromGraphQLChain,
+ isBackendSupportedChain,
+ toGraphQLChain,
+ toSupportedChainId,
+} from 'uniswap/src/features/chains/utils'
import { FORSupportedToken } from 'uniswap/src/features/fiatOnRamp/types'
-import { UniverseChainId, UniverseChainInfo } from 'uniswap/src/types/chains'
+import { AVERAGE_L1_BLOCK_TIME_MS } from 'uniswap/src/features/transactions/swap/hooks/usePollingIntervalByChain'
+import { getChainIdFromChainUrlParam } from 'utils/chainParams'
import { getNativeTokenDBAddress } from 'utils/nativeTokens'
export enum PollingInterval {
Slow = ms(`5m`),
Normal = ms(`1m`),
- Fast = AVERAGE_L1_BLOCK_TIME,
+ Fast = AVERAGE_L1_BLOCK_TIME_MS,
LightningMcQueen = ms(`3s`), // approx block interval for polygon
}
-// Polls a query only when the current component is mounted, as useQuery's pollInterval prop will continue to poll after unmount
-export function usePollQueryWhileMounted(
- queryResult: QueryResult,
- interval: PollingInterval,
-) {
- const { startPolling, stopPolling } = queryResult
-
- useEffect(() => {
- startPolling(interval)
- return stopPolling
- }, [interval, startPolling, stopPolling])
-
- return queryResult
-}
-
export enum TimePeriod {
HOUR = 'H',
DAY = 'D',
@@ -81,16 +63,13 @@ export function toHistoryDuration(timePeriod: TimePeriod): HistoryDuration {
export type PricePoint = { timestamp: number; value: number }
-export function isPricePoint(p: PricePoint | undefined): p is PricePoint {
- return p !== undefined
-}
-
export function isGqlSupportedChain(chainId?: UniverseChainId) {
- return !!chainId && GQL_MAINNET_CHAINS.includes(UNIVERSE_CHAIN_INFO[chainId].backendChain.chain)
+ return !!chainId && GQL_MAINNET_CHAINS.includes(getChainInfo(chainId).backendChain.chain)
}
-export function toContractInput(currency: Currency): ContractInput {
- const chain = chainIdToBackendChain({ chainId: currency.chainId as UniverseChainId })
+export function toContractInput(currency: Currency, fallback: UniverseChainId): ContractInput {
+ const supportedChainId = toSupportedChainId(currency.chainId)
+ const chain = toGraphQLChain(supportedChainId ?? fallback)
return { chain, address: currency.isToken ? currency.address : getNativeTokenDBAddress(chain) }
}
@@ -98,7 +77,7 @@ export function gqlToCurrency(token: DeepPartial): Currenc
if (!token.chain) {
return undefined
}
- const chainId = getChainFromChainUrlParam(token.chain.toLowerCase())?.id
+ const chainId = getChainIdFromChainUrlParam(token.chain.toLowerCase())
if (!chainId) {
return undefined
}
@@ -111,12 +90,15 @@ export function gqlToCurrency(token: DeepPartial): Currenc
token.decimals ?? 18,
token.symbol ?? undefined,
token.name ?? token.project?.name ?? undefined,
+ undefined,
+ token.feeData?.buyFeeBps ? BigNumber.from(token.feeData.buyFeeBps) : undefined,
+ token.feeData?.sellFeeBps ? BigNumber.from(token.feeData.sellFeeBps) : undefined,
)
}
}
export function fiatOnRampToCurrency(forCurrency: FORSupportedToken): Currency | undefined {
- if (!isSupportedChainId(Number(forCurrency.chainId))) {
+ if (!isUniverseChainId(Number(forCurrency.chainId))) {
return undefined
}
const supportedChainId = Number(forCurrency.chainId) as UniverseChainId
@@ -129,35 +111,10 @@ export function fiatOnRampToCurrency(forCurrency: FORSupportedToken): Currency |
}
}
-export function getSupportedGraphQlChain(
- chain: UniverseChainInfo | undefined,
- options: { fallbackToEthereum: true },
-): UniverseChainInfo
-export function getSupportedGraphQlChain(
- chain: UniverseChainInfo | undefined,
- options?: { fallbackToEthereum?: boolean },
-): UniverseChainInfo | undefined
-export function getSupportedGraphQlChain(
- chain: UniverseChainInfo | undefined,
- options?: { fallbackToEthereum?: boolean },
-): UniverseChainInfo | undefined {
- const fallbackChain = options?.fallbackToEthereum ? UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet] : undefined
- return chain?.backendChain.backendSupported ? chain : fallbackChain
-}
-
-export function isSupportedGQLChain(chain: Chain): chain is InterfaceGqlChain {
- const chains: ReadonlyArray = UX_SUPPORTED_GQL_CHAINS
- return chains.includes(chain)
-}
-
-export function supportedChainIdFromGQLChain(chain: InterfaceGqlChain): UniverseChainId
+export function supportedChainIdFromGQLChain(chain: GqlChainId): UniverseChainId
export function supportedChainIdFromGQLChain(chain: Chain): UniverseChainId | undefined
export function supportedChainIdFromGQLChain(chain: Chain): UniverseChainId | undefined {
- return isSupportedGQLChain(chain) ? CHAIN_NAME_TO_CHAIN_ID[chain] : undefined
-}
-
-export function isBackendSupportedChain(chain: Chain): chain is InterfaceGqlChain {
- return (BACKEND_SUPPORTED_CHAINS as ReadonlyArray).includes(chain)
+ return isBackendSupportedChain(chain) ? fromGraphQLChain(chain) ?? undefined : undefined
}
export function getTokenExploreURL({ tab, chain }: { tab: ExploreTab; chain?: Chain }) {
@@ -231,8 +188,8 @@ const PROTOCOL_META: { [source in PriceSource]: ProtocolMeta } = {
},
[PriceSource.SubgraphV4]: {
name: 'v4',
- color: 'accent1', // TODO(WEB-4618): update the colors when they are available
- gradient: { start: 'rgba(252, 116, 254, 0.20)', end: 'rgba(252, 116, 254, 0.00)' },
+ color: 'chain_137',
+ gradient: { start: 'rgba(96, 123, 238, 0.20)', end: 'rgba(55, 70, 136, 0.00)' },
},
/* [PriceSource.UniswapX]: { name: 'UniswapX', color: purple } */
}
diff --git a/apps/web/src/hooks/Tokens.test.ts b/apps/web/src/hooks/Tokens.test.ts
index 3c5edc0f3be..84c8fe70daa 100644
--- a/apps/web/src/hooks/Tokens.test.ts
+++ b/apps/web/src/hooks/Tokens.test.ts
@@ -3,11 +3,11 @@ import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { useCurrencyInfo } from 'hooks/Tokens'
import { TEST_TOKEN_1 } from 'test-utils/constants'
import { renderHook } from 'test-utils/render'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { DAI } from 'uniswap/src/constants/tokens'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { NativeCurrency } from 'uniswap/src/features/tokens/NativeCurrency'
import { useCurrencyInfo as useUniswapCurrencyInfo } from 'uniswap/src/features/tokens/useCurrencyInfo'
-import { UniverseChainId } from 'uniswap/src/types/chains'
jest.mock('uniswap/src/features/tokens/useCurrencyInfo', () => ({
useCurrencyInfo: jest.fn(),
@@ -50,7 +50,7 @@ describe('useCurrencyInfo', () => {
renderHook(() => useCurrencyInfo('ETH', UniverseChainId.Mainnet))
expect(useUniswapCurrencyInfo).toHaveBeenCalledWith(
- `${UniverseChainId.Mainnet}-${UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet].nativeCurrency.address}`,
+ `${UniverseChainId.Mainnet}-${getChainInfo(UniverseChainId.Mainnet).nativeCurrency.address}`,
{ skip: undefined },
)
})
@@ -59,7 +59,7 @@ describe('useCurrencyInfo', () => {
renderHook(() => useCurrencyInfo(undefined, UniverseChainId.Mainnet))
expect(useUniswapCurrencyInfo).toHaveBeenCalledWith(
- `${UniverseChainId.Mainnet}-${UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet].nativeCurrency.address}`,
+ `${UniverseChainId.Mainnet}-${getChainInfo(UniverseChainId.Mainnet).nativeCurrency.address}`,
{ skip: undefined },
)
})
@@ -69,7 +69,7 @@ describe('useCurrencyInfo', () => {
renderHook(() => useCurrencyInfo(currency))
expect(useUniswapCurrencyInfo).toHaveBeenCalledWith(
- `${UniverseChainId.Mainnet}-${UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet].nativeCurrency.address}`,
+ `${UniverseChainId.Mainnet}-${getChainInfo(UniverseChainId.Mainnet).nativeCurrency.address}`,
{ skip: undefined },
)
})
diff --git a/apps/web/src/hooks/Tokens.ts b/apps/web/src/hooks/Tokens.ts
index 7310db70a77..185a35bdcaf 100644
--- a/apps/web/src/hooks/Tokens.ts
+++ b/apps/web/src/hooks/Tokens.ts
@@ -1,12 +1,11 @@
import { Currency, Token } from '@uniswap/sdk-core'
-import { useSupportedChainId } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { useAccount } from 'hooks/useAccount'
import { useMemo } from 'react'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { COMMON_BASES } from 'uniswap/src/constants/routing'
-import { UniverseChainId } from 'uniswap/src/types/chains'
-
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
import { useCurrencyInfo as useUniswapCurrencyInfo } from 'uniswap/src/features/tokens/useCurrencyInfo'
import { buildCurrencyId } from 'uniswap/src/utils/currencyId'
@@ -32,9 +31,8 @@ export function useCurrencyInfo(
const { chainId: connectedChainId } = useAccount()
const chainIdWithFallback =
(typeof addressOrCurrency === 'string' ? chainId : addressOrCurrency?.chainId) ?? connectedChainId
- const nativeAddressWithFallback =
- UNIVERSE_CHAIN_INFO[chainIdWithFallback as UniverseChainId]?.nativeCurrency.address ??
- UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet]?.nativeCurrency.address
+ const supportedChainId = useSupportedChainId(chainIdWithFallback)
+ const nativeAddressWithFallback = getChainInfo(supportedChainId ?? UniverseChainId.Mainnet).nativeCurrency.address
const isNative = useMemo(() => checkIsNative(addressOrCurrency), [addressOrCurrency])
const address = useMemo(
@@ -42,8 +40,6 @@ export function useCurrencyInfo(
[isNative, nativeAddressWithFallback, addressOrCurrency],
)
- const supportedChainId = useSupportedChainId(chainIdWithFallback)
-
const addressWithFallback = isNative || !address ? nativeAddressWithFallback : address
const currencyId = buildCurrencyId(supportedChainId ?? UniverseChainId.Mainnet, addressWithFallback)
@@ -70,7 +66,7 @@ export function useCurrencyInfo(
}, [addressOrCurrency, currencyInfo, chainIdWithFallback, isNative, address, skip])
}
-const checkIsNative = (addressOrCurrency?: string | Currency): boolean => {
+export const checkIsNative = (addressOrCurrency?: string | Currency): boolean => {
return typeof addressOrCurrency === 'string'
? [NATIVE_CHAIN_ID, 'native', 'eth'].includes(addressOrCurrency.toLowerCase())
: addressOrCurrency?.isNative ?? false
diff --git a/apps/web/src/hooks/useAccount.ts b/apps/web/src/hooks/useAccount.ts
index f89896332bf..17a89eeedfe 100644
--- a/apps/web/src/hooks/useAccount.ts
+++ b/apps/web/src/hooks/useAccount.ts
@@ -1,7 +1,7 @@
/* eslint-disable rulesdir/no-undefined-or */
-import { useSupportedChainId } from 'constants/chains'
import { useMemo } from 'react'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useSupportedChainIdWithConnector } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { UseAccountReturnType as UseAccountReturnTypeWagmi, useAccount as useAccountWagmi, useChainId } from 'wagmi'
@@ -16,7 +16,7 @@ type UseAccountReturnType = ReplaceChainId
export function useAccount(): UseAccountReturnType {
const { chainId, ...rest } = useAccountWagmi()
const fallbackChainId = useChainId()
- const supportedChainId = useSupportedChainId(chainId ?? fallbackChainId)
+ const supportedChainId = useSupportedChainIdWithConnector(chainId ?? fallbackChainId, rest.connector)
return useMemo(
() => ({
diff --git a/apps/web/src/hooks/useActiveLocalCurrency.ts b/apps/web/src/hooks/useActiveLocalCurrency.ts
deleted file mode 100644
index 0a59ceb3438..00000000000
--- a/apps/web/src/hooks/useActiveLocalCurrency.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { useActiveLocale } from 'hooks/useActiveLocale'
-import useParsedQueryString from 'hooks/useParsedQueryString'
-import { useMemo } from 'react'
-import { FiatCurrency, ORDERED_CURRENCIES } from 'uniswap/src/features/fiatCurrency/constants'
-import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
-import { getFiatCurrencyComponents } from 'utils/formatNumbers'
-
-function useUrlLocalCurrency() {
- const parsed = useParsedQueryString()
- const parsedLocalCurrency = parsed.cur
-
- if (typeof parsedLocalCurrency !== 'string') {
- return undefined
- }
-
- const lowerCaseSupportedLocalCurrency = parsedLocalCurrency.toLowerCase()
- return ORDERED_CURRENCIES.find((localCurrency) => localCurrency.toLowerCase() === lowerCaseSupportedLocalCurrency)
-}
-
-export function useActiveLocalCurrency(): FiatCurrency {
- const activeLocalCurrency = useAppFiatCurrency()
- const urlLocalCurrency = useUrlLocalCurrency()
-
- return useMemo(() => urlLocalCurrency ?? activeLocalCurrency, [activeLocalCurrency, urlLocalCurrency])
-}
-
-export function useActiveLocalCurrencyComponents() {
- const activeLocale = useActiveLocale()
- const activeLocalCurrency = useActiveLocalCurrency()
-
- return useMemo(
- () => getFiatCurrencyComponents(activeLocale, activeLocalCurrency),
- [activeLocalCurrency, activeLocale],
- )
-}
diff --git a/apps/web/src/hooks/useActiveLocale.ts b/apps/web/src/hooks/useActiveLocale.ts
deleted file mode 100644
index 2d5811118f1..00000000000
--- a/apps/web/src/hooks/useActiveLocale.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import useParsedQueryString from 'hooks/useParsedQueryString'
-import { useMemo } from 'react'
-import store from 'state'
-import {
- DEFAULT_LOCALE,
- Language,
- Locale,
- WEB_SUPPORTED_LANGUAGES,
- mapLocaleToLanguage,
-} from 'uniswap/src/features/language/constants'
-import { getLocale, useCurrentLocale } from 'uniswap/src/features/language/hooks'
-
-/**
- * Given a locale string (e.g. from user agent), return the best match for corresponding Locale enum object
- * @param maybeSupportedLocale the fuzzy locale identifier
- */
-export function parseLocale(maybeSupportedLocale: unknown): Locale | undefined {
- if (typeof maybeSupportedLocale !== 'string') {
- return undefined
- }
- const lowerMaybeSupportedLocale = maybeSupportedLocale.toLowerCase()
- return WEB_SUPPORTED_LANGUAGES.map((lang) => getLocale(lang)).find(
- (locale) =>
- locale.toLowerCase() === lowerMaybeSupportedLocale || locale.split('-')[0] === lowerMaybeSupportedLocale,
- )
-}
-
-/**
- * Returns the supported locale read from the user agent (navigator)
- */
-export function navigatorLocale(): Locale | undefined {
- if (!navigator.language) {
- return undefined
- }
-
- const [language, region] = navigator.language.split('-')
-
- if (region) {
- return parseLocale(`${language}-${region.toUpperCase()}`) ?? parseLocale(language)
- }
-
- return parseLocale(language)
-}
-
-export function storeLocale(): Locale | undefined {
- const storeLanguage = store.getState().userSettings.currentLanguage
- return getLocale(storeLanguage)
-}
-
-function useUrlLocale() {
- const parsed = useParsedQueryString()
- return parseLocale(parsed.lng)
-}
-
-/**
- * Returns the currently active locale, from a combination of user agent, query string, and user settings stored in redux
- */
-export function useActiveLocale(): Locale {
- const urlLocale = useUrlLocale()
- const userLocale = useCurrentLocale()
- return useMemo(() => urlLocale ?? userLocale ?? navigatorLocale() ?? DEFAULT_LOCALE, [urlLocale, userLocale])
-}
-
-export function useActiveLanguage(): Language {
- const locale = useActiveLocale()
- return mapLocaleToLanguage[locale]
-}
diff --git a/apps/web/src/hooks/useAutoSlippageTolerance.ts b/apps/web/src/hooks/useAutoSlippageTolerance.ts
index d5916473179..49cd03c4f65 100644
--- a/apps/web/src/hooks/useAutoSlippageTolerance.ts
+++ b/apps/web/src/hooks/useAutoSlippageTolerance.ts
@@ -2,7 +2,6 @@ import { MixedRoute, partitionMixedRouteByProtocol, Protocol, Trade } from '@uni
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import { Pool } from '@uniswap/v3-sdk'
-import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import useGasPrice from 'hooks/useGasPrice'
import { useStablecoinAmountFromFiatValue } from 'hooks/useStablecoinPrice'
@@ -11,7 +10,7 @@ import JSBI from 'jsbi'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { useMemo } from 'react'
import { ClassicTrade } from 'state/routing/types'
-import { isL2ChainId } from 'uniswap/src/features/chains/utils'
+import { chainSupportsGasEstimates, isL2ChainId } from 'uniswap/src/features/chains/utils'
import { logger } from 'utilities/src/logger/logger'
const DEFAULT_AUTO_SLIPPAGE = new Percent(5, 1000) // 0.5%
@@ -81,7 +80,7 @@ export default function useClassicAutoSlippageTolerance(trade?: ClassicTrade): P
const outputDollarValue = useStablecoinAmountFromFiatValue(outputUSD.data)
// Prefer the USD estimate, if it is supported.
- const supportsGasEstimate = useMemo(() => chainId && SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId), [chainId])
+ const supportsGasEstimate = useMemo(() => chainId && chainSupportsGasEstimates(chainId), [chainId])
const gasEstimateUSD =
useStablecoinAmountFromFiatValue(supportsGasEstimate ? trade?.gasUseEstimateUSD : undefined) ?? null
@@ -108,9 +107,7 @@ export default function useClassicAutoSlippageTolerance(trade?: ClassicTrade): P
// NOTE - dont use gas estimate for L2s yet - need to verify accuracy
// if not, use local heuristic
const dollarCostToUse =
- chainId && SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId) && gasEstimateUSD
- ? gasEstimateUSD
- : gasCostStablecoinAmount
+ chainId && chainSupportsGasEstimates(chainId) && gasEstimateUSD ? gasEstimateUSD : gasCostStablecoinAmount
if (outputDollarValue && dollarCostToUse) {
// optimize for highest possible slippage without getting MEV'd
diff --git a/apps/web/src/hooks/useContract.ts b/apps/web/src/hooks/useContract.ts
index 386454c38ab..bc32103d1fc 100644
--- a/apps/web/src/hooks/useContract.ts
+++ b/apps/web/src/hooks/useContract.ts
@@ -2,6 +2,7 @@ import { Contract } from '@ethersproject/contracts'
import { InterfaceEventName } from '@uniswap/analytics-events'
import {
ARGENT_WALLET_DETECTOR_ADDRESS,
+ CHAIN_TO_ADDRESSES_MAP,
ENS_REGISTRAR_ADDRESSES,
MULTICALL_ADDRESSES,
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
@@ -37,8 +38,8 @@ import { NonfungiblePositionManager, UniswapInterfaceMulticall } from 'uniswap/s
import { V3Migrator } from 'uniswap/src/abis/types/v3/V3Migrator'
import WETH_ABI from 'uniswap/src/abis/weth.json'
import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { getContract } from 'utilities/src/contracts/getContract'
import { logger } from 'utilities/src/logger/logger'
@@ -204,3 +205,36 @@ export function useV3NFTPositionManagerContract(
}, [account.isConnected, chainIdToUse, contract, withSignerIfPossible])
return contract
}
+
+/**
+ * NOTE: the return type of this contract and the ABI used are just a generic ERC721,
+ * so you can only use this to call tokenURI or other Position NFT related functions.
+ */
+export function useV4NFTPositionManagerContract(
+ withSignerIfPossible?: boolean,
+ chainId?: UniverseChainId,
+): Erc721 | null {
+ const account = useAccount()
+ const chainIdToUse = chainId ?? account.chainId
+
+ const contract = useContract(
+ chainIdToUse ? CHAIN_TO_ADDRESSES_MAP[chainIdToUse].v4PositionManagerAddress : undefined,
+ NFTPositionManagerABI,
+ withSignerIfPossible,
+ chainIdToUse,
+ )
+ useEffect(() => {
+ if (contract && account.isConnected) {
+ sendAnalyticsEvent(InterfaceEventName.WALLET_PROVIDER_USED, {
+ source: 'useV4NFTPositionManagerContract',
+ contract: {
+ name: 'V4NonfungiblePositionManager',
+ address: contract.address,
+ withSignerIfPossible,
+ chainId: chainIdToUse,
+ },
+ })
+ }
+ }, [account.isConnected, chainIdToUse, contract, withSignerIfPossible])
+ return contract
+}
diff --git a/apps/web/src/hooks/useERC20Permit.ts b/apps/web/src/hooks/useERC20Permit.ts
index e17057a1271..ca1f27739f4 100644
--- a/apps/web/src/hooks/useERC20Permit.ts
+++ b/apps/web/src/hooks/useERC20Permit.ts
@@ -9,7 +9,7 @@ import JSBI from 'jsbi'
import { useSingleCallResult } from 'lib/hooks/multicall'
import { useMemo, useState } from 'react'
import { DAI, UNI, USDC_MAINNET } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export enum PermitType {
AMOUNT = 1,
diff --git a/apps/web/src/hooks/useEthersProvider.ts b/apps/web/src/hooks/useEthersProvider.ts
index 0fe25fa89ea..b2c0f099b3d 100644
--- a/apps/web/src/hooks/useEthersProvider.ts
+++ b/apps/web/src/hooks/useEthersProvider.ts
@@ -1,7 +1,7 @@
import { Web3Provider } from '@ethersproject/providers'
import { useAccount } from 'hooks/useAccount'
import { useMemo } from 'react'
-import { UniverseChainInfo } from 'uniswap/src/types/chains'
+import { UniverseChainInfo } from 'uniswap/src/features/chains/types'
import type { Client, Transport } from 'viem'
import { useClient, useConnectorClient } from 'wagmi'
diff --git a/apps/web/src/hooks/useEthersSigner.ts b/apps/web/src/hooks/useEthersSigner.ts
index 593966a50a6..e58c9271593 100644
--- a/apps/web/src/hooks/useEthersSigner.ts
+++ b/apps/web/src/hooks/useEthersSigner.ts
@@ -1,6 +1,6 @@
import { Web3Provider } from '@ethersproject/providers'
import { useMemo } from 'react'
-import { UniverseChainInfo } from 'uniswap/src/types/chains'
+import { UniverseChainInfo } from 'uniswap/src/features/chains/types'
import type { Account, Client, Transport } from 'viem'
import { useConnectorClient } from 'wagmi'
diff --git a/apps/web/src/hooks/useFeeTierDistribution.ts b/apps/web/src/hooks/useFeeTierDistribution.ts
index 5e4ca6ba970..862d4794ba9 100644
--- a/apps/web/src/hooks/useFeeTierDistribution.ts
+++ b/apps/web/src/hooks/useFeeTierDistribution.ts
@@ -1,6 +1,5 @@
import { Currency, Token } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
-import { chainIdToBackendChain } from 'constants/chains'
import { PoolState, usePool } from 'hooks/usePools'
import ms from 'ms'
import { useMemo } from 'react'
@@ -8,6 +7,8 @@ import {
useFeeTierDistributionQuery,
useIsV3SubgraphStaleQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { logger } from 'utilities/src/logger/logger'
interface FeeTierDistribution {
@@ -97,7 +98,8 @@ export function useFeeTierDistribution(
}
function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
- const chain = chainIdToBackendChain({ chainId: token0?.chainId, withFallback: true })
+ const { defaultChainId } = useEnabledChains()
+ const chain = toGraphQLChain(token0?.chainId ?? defaultChainId)
const { loading, error, data } = useFeeTierDistributionQuery({
variables: {
chain,
diff --git a/apps/web/src/hooks/useFetchListCallback.ts b/apps/web/src/hooks/useFetchListCallback.ts
index f9f993fbc03..8b865762912 100644
--- a/apps/web/src/hooks/useFetchListCallback.ts
+++ b/apps/web/src/hooks/useFetchListCallback.ts
@@ -6,7 +6,7 @@ import resolveENSContentHash from 'lib/utils/resolveENSContentHash'
import { useCallback } from 'react'
import { useAppDispatch } from 'state/hooks'
import { fetchTokenList } from 'state/lists/actions'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { logger } from 'utilities/src/logger/logger'
export function useFetchListCallback(): (listUrl: string, skipValidation?: boolean) => Promise {
diff --git a/apps/web/src/hooks/useFilterPossiblyMaliciousPositions.ts b/apps/web/src/hooks/useFilterPossiblyMaliciousPositions.ts
index 148c40d577a..9566af6d4a8 100644
--- a/apps/web/src/hooks/useFilterPossiblyMaliciousPositions.ts
+++ b/apps/web/src/hooks/useFilterPossiblyMaliciousPositions.ts
@@ -1,5 +1,4 @@
import { useQueries } from '@tanstack/react-query'
-import { chainIdToBackendChain } from 'constants/chains'
import { apolloClient } from 'graphql/data/apollo/client'
import { gqlTokenToCurrencyInfo } from 'graphql/data/types'
import { apolloQueryOptions } from 'graphql/data/util'
@@ -13,7 +12,9 @@ import {
TokenDocument,
TokenQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { hasURL } from 'utils/urlChecks'
function getUniqueAddressesFromPositions(positions: PositionDetails[]): string[] {
@@ -22,7 +23,7 @@ function getUniqueAddressesFromPositions(positions: PositionDetails[]): string[]
)
}
-function getPositionCurrencyInfosQueryOptions(position: PositionDetails, chainId?: UniverseChainId) {
+function getPositionCurrencyInfosQueryOptions(position: PositionDetails, chainId: UniverseChainId) {
return apolloQueryOptions({
queryKey: ['positionCurrencyInfo', position],
queryFn: async () => {
@@ -31,7 +32,7 @@ function getPositionCurrencyInfosQueryOptions(position: PositionDetails, chainId
query: TokenDocument,
variables: {
address: position.token0,
- chain: chainIdToBackendChain({ chainId }),
+ chain: toGraphQLChain(chainId),
},
fetchPolicy: 'cache-first',
}),
@@ -39,7 +40,7 @@ function getPositionCurrencyInfosQueryOptions(position: PositionDetails, chainId
query: TokenDocument,
variables: {
address: position.token1,
- chain: chainIdToBackendChain({ chainId }),
+ chain: toGraphQLChain(chainId),
},
fetchPolicy: 'cache-first',
}),
@@ -67,10 +68,11 @@ function getPositionCurrencyInfosQueryOptions(position: PositionDetails, chainId
*/
export function useFilterPossiblyMaliciousPositions(positions: PositionDetails[]): PositionDetails[] {
const { chainId } = useAccount()
+ const { defaultChainId } = useEnabledChains()
const nonListPositionTokenAddresses = useMemo(() => getUniqueAddressesFromPositions(positions), [positions])
const positionCurrencyInfos = useQueries({
- queries: positions.map((position) => getPositionCurrencyInfosQueryOptions(position, chainId)),
+ queries: positions.map((position) => getPositionCurrencyInfosQueryOptions(position, chainId ?? defaultChainId)),
})
const symbolCallStates = useTokenContractsConstant(nonListPositionTokenAddresses, 'symbol')
diff --git a/apps/web/src/hooks/useGlobalChainSwitch.ts b/apps/web/src/hooks/useGlobalChainSwitch.ts
index 48193f1cdc5..2e381f0b666 100644
--- a/apps/web/src/hooks/useGlobalChainSwitch.ts
+++ b/apps/web/src/hooks/useGlobalChainSwitch.ts
@@ -1,8 +1,9 @@
-import { chainIdToBackendChain, useIsSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { useEffect } from 'react'
import { useAppSelector } from 'state/hooks'
import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
export const useOnGlobalChainSwitch = (callback: (chainId: number, chain?: Chain) => void) => {
const { chainId } = useAccount()
@@ -10,7 +11,7 @@ export const useOnGlobalChainSwitch = (callback: (chainId: number, chain?: Chain
const switchingChain = useAppSelector((state) => state.wallets.switchingChain)
useEffect(() => {
if (isSupportedChain && chainId === switchingChain) {
- const chainName = chainIdToBackendChain({ chainId })
+ const chainName = toGraphQLChain(chainId)
callback(chainId, chainName)
}
}, [callback, chainId, isSupportedChain, switchingChain])
diff --git a/apps/web/src/hooks/useIsUniswapXSupportedChain.ts b/apps/web/src/hooks/useIsUniswapXSupportedChain.ts
new file mode 100644
index 00000000000..b856d785eea
--- /dev/null
+++ b/apps/web/src/hooks/useIsUniswapXSupportedChain.ts
@@ -0,0 +1,17 @@
+/* eslint-disable rulesdir/no-undefined-or */
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { ArbitrumXV2ExperimentGroup, Experiments } from 'uniswap/src/features/gating/experiments'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useExperimentGroupName, useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+
+export function useIsUniswapXSupportedChain(chainId?: number) {
+ const xv2ArbitrumEnabled =
+ useExperimentGroupName(Experiments.ArbitrumXV2OpenOrders) === ArbitrumXV2ExperimentGroup.Test
+ const isPriorityOrdersEnabled = useFeatureFlag(FeatureFlags.UniswapXPriorityOrders)
+
+ return (
+ chainId === UniverseChainId.Mainnet ||
+ (xv2ArbitrumEnabled && chainId === UniverseChainId.ArbitrumOne) ||
+ (isPriorityOrdersEnabled && chainId === UniverseChainId.Base) // UniswapX priority orders are only available on Base for now
+ )
+}
diff --git a/apps/web/src/hooks/useLocalCurrencyLinkProps.ts b/apps/web/src/hooks/useLocalCurrencyLinkProps.ts
index 06c1dac3cf4..536e370b870 100644
--- a/apps/web/src/hooks/useLocalCurrencyLinkProps.ts
+++ b/apps/web/src/hooks/useLocalCurrencyLinkProps.ts
@@ -1,11 +1,11 @@
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
-import useParsedQueryString from 'hooks/useParsedQueryString'
import { stringify } from 'qs'
import { useMemo } from 'react'
import { useDispatch } from 'react-redux'
import type { To } from 'react-router-dom'
import { useLocation } from 'react-router-dom'
+import { useUrlContext } from 'uniswap/src/contexts/UrlContext'
import { FiatCurrency } from 'uniswap/src/features/fiatCurrency/constants'
+import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
import { setCurrentFiatCurrency } from 'uniswap/src/features/settings/slice'
import { InterfaceEventNameLocal } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
@@ -16,8 +16,9 @@ export function useLocalCurrencyLinkProps(localCurrency?: FiatCurrency): {
} {
const dispatch = useDispatch()
const location = useLocation()
+ const { useParsedQueryString } = useUrlContext()
const qs = useParsedQueryString()
- const activeLocalCurrency = useActiveLocalCurrency()
+ const activeLocalCurrency = useAppFiatCurrency()
return useMemo(
() =>
diff --git a/apps/web/src/hooks/useLocationLinkProps.ts b/apps/web/src/hooks/useLocationLinkProps.ts
index bd4048703fb..87267e2e4ec 100644
--- a/apps/web/src/hooks/useLocationLinkProps.ts
+++ b/apps/web/src/hooks/useLocationLinkProps.ts
@@ -1,14 +1,15 @@
-import useParsedQueryString from 'hooks/useParsedQueryString'
import { stringify } from 'qs'
import { useMemo } from 'react'
import type { To } from 'react-router-dom'
import { useLocation } from 'react-router-dom'
+import { useUrlContext } from 'uniswap/src/contexts/UrlContext'
import { Locale } from 'uniswap/src/features/language/constants'
export function useLocationLinkProps(locale: Locale | null): {
to?: To
} {
const location = useLocation()
+ const { useParsedQueryString } = useUrlContext()
const qs = useParsedQueryString()
return useMemo(
diff --git a/apps/web/src/hooks/useNetworkSupportsV2.ts b/apps/web/src/hooks/useNetworkSupportsV2.ts
index 8a3cbcf1ea6..cbdd11b82e3 100644
--- a/apps/web/src/hooks/useNetworkSupportsV2.ts
+++ b/apps/web/src/hooks/useNetworkSupportsV2.ts
@@ -1,11 +1,13 @@
-import { SUPPORTED_V2POOL_CHAIN_IDS } from 'constants/chains'
+import { V2_ROUTER_ADDRESSES } from '@uniswap/sdk-core'
import { useAccount } from 'hooks/useAccount'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+
+/**
+ * @deprecated when v2 pools are enabled on chains supported through sdk-core
+ */
+const SUPPORTED_V2POOL_CHAIN_IDS = Object.keys(V2_ROUTER_ADDRESSES).map((chainId) => parseInt(chainId))
export function useNetworkSupportsV2() {
const { chainId } = useAccount()
- const isV2EverywhereEnabled = useFeatureFlag(FeatureFlags.V2Everywhere)
- return chainId && isV2EverywhereEnabled && SUPPORTED_V2POOL_CHAIN_IDS.includes(chainId)
+ return chainId && SUPPORTED_V2POOL_CHAIN_IDS.includes(chainId)
}
diff --git a/apps/web/src/hooks/useParsedQueryString.ts b/apps/web/src/hooks/useParsedQueryString.ts
deleted file mode 100644
index 3abd77ced3d..00000000000
--- a/apps/web/src/hooks/useParsedQueryString.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { parse, ParsedQs } from 'qs'
-import { useMemo } from 'react'
-import { useLocation } from 'react-router-dom'
-
-export default function useParsedQueryString(): ParsedQs {
- const { search } = useLocation()
- return useMemo(() => {
- const hash = window.location.hash
- const query = search || hash.substr(hash.indexOf('?'))
-
- return query && query.length > 1 ? parse(query, { parseArrays: false, ignoreQueryPrefix: true }) : {}
- }, [search])
-}
diff --git a/apps/web/src/hooks/usePermit2Allowance.ts b/apps/web/src/hooks/usePermit2Allowance.ts
index 1c67d540a7a..3e41344231c 100644
--- a/apps/web/src/hooks/usePermit2Allowance.ts
+++ b/apps/web/src/hooks/usePermit2Allowance.ts
@@ -1,6 +1,5 @@
import { permit2Address } from '@uniswap/permit2-sdk'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
-import { AVERAGE_L1_BLOCK_TIME } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { PermitSignature, usePermitAllowance, useUpdatePermitAllowance } from 'hooks/usePermitAllowance'
import { useRevokeTokenAllowance, useTokenAllowance, useUpdateTokenAllowance } from 'hooks/useTokenAllowance'
@@ -8,6 +7,7 @@ import useInterval from 'lib/hooks/useInterval'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { TradeFillType } from 'state/routing/types'
import { useHasPendingApproval, useHasPendingRevocation, useTransactionAdder } from 'state/transactions/hooks'
+import { AVERAGE_L1_BLOCK_TIME_MS } from 'uniswap/src/features/transactions/swap/hooks/usePollingIntervalByChain'
enum ApprovalState {
PENDING,
@@ -91,10 +91,10 @@ export default function usePermit2Allowance(
// Signature and PermitAllowance will expire, so they should be rechecked at an interval.
// Calculate now such that the signature will still be valid for the submitting block.
- const [now, setNow] = useState(Date.now() + AVERAGE_L1_BLOCK_TIME)
+ const [now, setNow] = useState(Date.now() + AVERAGE_L1_BLOCK_TIME_MS)
useInterval(
- useCallback(() => setNow((Date.now() + AVERAGE_L1_BLOCK_TIME) / 1000), []),
- AVERAGE_L1_BLOCK_TIME,
+ useCallback(() => setNow((Date.now() + AVERAGE_L1_BLOCK_TIME_MS) / 1000), []),
+ AVERAGE_L1_BLOCK_TIME_MS,
)
const [signature, setSignature] = useState()
diff --git a/apps/web/src/hooks/usePoolTickData.ts b/apps/web/src/hooks/usePoolTickData.ts
index b48f4b73050..7bdd9da8154 100644
--- a/apps/web/src/hooks/usePoolTickData.ts
+++ b/apps/web/src/hooks/usePoolTickData.ts
@@ -1,6 +1,5 @@
import { Currency, Price, Token, V3_CORE_FACTORY_ADDRESSES } from '@uniswap/sdk-core'
import { FeeAmount, Pool, TICK_SPACINGS, tickToPrice } from '@uniswap/v3-sdk'
-import { chainIdToBackendChain, useSupportedChainId } from 'constants/chains'
import { TickData, Ticks } from 'graphql/data/AllV3TicksQuery'
import { useAccount } from 'hooks/useAccount'
import { PoolState, usePoolMultichain } from 'hooks/usePools'
@@ -8,7 +7,9 @@ import JSBI from 'jsbi'
import ms from 'ms'
import { useEffect, useMemo, useState } from 'react'
import { useAllV3TicksQuery } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { logger } from 'utilities/src/logger/logger'
import computeSurroundingTicks from 'utils/computeSurroundingTicks'
@@ -27,13 +28,15 @@ const getActiveTick = (tickCurrent: number | undefined, feeAmount: FeeAmount | u
tickCurrent && feeAmount ? Math.floor(tickCurrent / TICK_SPACINGS[feeAmount]) * TICK_SPACINGS[feeAmount] : undefined
const MAX_TICK_FETCH_VALUE = 1000
-function useTicksFromSubgraph(
+function usePaginatedTickQuery(
currencyA: Currency | undefined,
currencyB: Currency | undefined,
feeAmount: FeeAmount | undefined,
skip = 0,
chainId: UniverseChainId,
) {
+ const { defaultChainId } = useEnabledChains()
+
const poolAddress =
currencyA && currencyB && feeAmount
? Pool.getAddress(
@@ -49,7 +52,7 @@ function useTicksFromSubgraph(
return useAllV3TicksQuery({
variables: {
address: poolAddress?.toLowerCase() ?? '',
- chain: chainIdToBackendChain({ chainId: supportedChainId, withFallback: true }),
+ chain: toGraphQLChain(supportedChainId ?? defaultChainId),
skip,
first: MAX_TICK_FETCH_VALUE,
},
@@ -70,13 +73,17 @@ function useAllV3Ticks(
ticks?: TickData[]
} {
const [skipNumber, setSkipNumber] = useState(0)
- const [subgraphTickData, setSubgraphTickData] = useState([])
- const { data, error, loading: isLoading } = useTicksFromSubgraph(currencyA, currencyB, feeAmount, skipNumber, chainId)
+ const [tickData, setTickData] = useState([])
+ const {
+ data,
+ error,
+ loading: isLoading,
+ } = usePaginatedTickQuery(currencyA, currencyB, feeAmount, skipNumber, chainId)
const ticks: Ticks = data?.v3Pool?.ticks as Ticks
useEffect(() => {
if (ticks?.length) {
- setSubgraphTickData((tickData) => [...tickData, ...ticks])
+ setTickData((tickData) => [...tickData, ...ticks])
if (ticks?.length === MAX_TICK_FETCH_VALUE) {
setSkipNumber((skipNumber) => skipNumber + MAX_TICK_FETCH_VALUE)
}
@@ -86,7 +93,7 @@ function useAllV3Ticks(
return {
isLoading: isLoading || ticks?.length === MAX_TICK_FETCH_VALUE,
error,
- ticks: subgraphTickData,
+ ticks: tickData,
}
}
diff --git a/apps/web/src/hooks/usePools.ts b/apps/web/src/hooks/usePools.ts
index a1106824f9b..894a459b16b 100644
--- a/apps/web/src/hooks/usePools.ts
+++ b/apps/web/src/hooks/usePools.ts
@@ -9,8 +9,8 @@ import { useMultipleContractSingleData } from 'lib/hooks/multicall'
import { useEffect, useMemo, useRef } from 'react'
import { IUniswapV3PoolStateInterface } from 'uniswap/src/abis/types/v3/IUniswapV3PoolState'
import { UniswapV3Pool } from 'uniswap/src/abis/types/v3/UniswapV3Pool'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { logger } from 'utilities/src/logger/logger'
const POOL_STATE_INTERFACE = new Interface(IUniswapV3PoolStateJSON.abi) as IUniswapV3PoolStateInterface
@@ -51,7 +51,7 @@ export class PoolCache {
tokenA,
tokenB,
fee,
- chainId: UNIVERSE_CHAIN_INFO[chainId].sdkId,
+ chainId: getChainInfo(chainId).sdkId,
}),
}
this.addresses.unshift(address)
diff --git a/apps/web/src/hooks/usePositionTokenURI.ts b/apps/web/src/hooks/usePositionTokenURI.ts
index 9cc44095956..d0f8ee5ff7f 100644
--- a/apps/web/src/hooks/usePositionTokenURI.ts
+++ b/apps/web/src/hooks/usePositionTokenURI.ts
@@ -1,11 +1,13 @@
import { BigNumber } from '@ethersproject/bignumber'
-import { useV3NFTPositionManagerContract } from 'hooks/useContract'
-import { useEthersProvider } from 'hooks/useEthersProvider'
+import { useQuery } from '@tanstack/react-query'
+// eslint-disable-next-line no-restricted-imports
+import { ProtocolVersion } from '@uniswap/client-pools/dist/pools/v1/types_pb'
+import { useV3NFTPositionManagerContract, useV4NFTPositionManagerContract } from 'hooks/useContract'
import JSBI from 'jsbi'
-import { NEVER_RELOAD } from 'lib/hooks/multicall'
-import multicall from 'lib/state/multicall'
import { useMemo } from 'react'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { Erc721 } from 'uniswap/src/abis/types/Erc721'
+import { NonfungiblePositionManager } from 'uniswap/src/abis/types/v3/NonfungiblePositionManager'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
type TokenId = number | JSBI | BigNumber
@@ -30,49 +32,53 @@ type UsePositionTokenURIResult =
loading: true
}
+function useNFTPositionManagerContract(
+ version: ProtocolVersion,
+ chainId?: UniverseChainId,
+): NonfungiblePositionManager | Erc721 | null {
+ const v3Contract = useV3NFTPositionManagerContract(false, chainId)
+ const v4Contract = useV4NFTPositionManagerContract(false, chainId)
+ return version === ProtocolVersion.V3 ? v3Contract : v4Contract
+}
+
export function usePositionTokenURI(
tokenId: TokenId | undefined,
chainId?: UniverseChainId,
+ version?: ProtocolVersion,
): UsePositionTokenURIResult {
- const contract = useV3NFTPositionManagerContract(false, chainId)
- const inputs = useMemo(
- () => [tokenId instanceof BigNumber ? tokenId.toHexString() : tokenId?.toString(16)],
- [tokenId],
- )
- const latestBlock = useEthersProvider({ chainId })?.blockNumber
- const { result, error, loading, valid } = multicall.hooks.useSingleCallResult(
- chainId,
- latestBlock,
- contract,
- 'tokenURI',
- inputs,
- {
- ...NEVER_RELOAD,
- gasRequired: 3_000_000,
+ const contract = useNFTPositionManagerContract(version ?? ProtocolVersion.V3, chainId)
+ const { data, isLoading, error } = useQuery({
+ queryKey: ['PositionTokenURI', tokenId, chainId, version],
+ queryFn: async () => {
+ const input = tokenId instanceof BigNumber ? tokenId.toHexString() : tokenId?.toString(16)
+ if (!input) {
+ return null
+ }
+ return await contract?.tokenURI(input)
},
- )
+ })
return useMemo(() => {
- if (error || !valid || !tokenId) {
+ if (error || !tokenId) {
return {
valid: false,
loading: false,
}
}
- if (loading) {
+ if (isLoading) {
return {
valid: true,
loading: true,
}
}
- if (!result) {
+ if (!data) {
return {
valid: false,
loading: false,
}
}
- const [tokenURI] = result as [string]
- if (!tokenURI || !tokenURI.startsWith(STARTS_WITH)) {
+
+ if (!data || !data.startsWith(STARTS_WITH)) {
return {
valid: false,
loading: false,
@@ -80,7 +86,7 @@ export function usePositionTokenURI(
}
try {
- const json = JSON.parse(atob(tokenURI.slice(STARTS_WITH.length)))
+ const json = JSON.parse(atob(data.slice(STARTS_WITH.length)))
return {
valid: true,
@@ -90,5 +96,5 @@ export function usePositionTokenURI(
} catch (error) {
return { valid: false, loading: false }
}
- }, [error, loading, result, tokenId, valid])
+ }, [error, isLoading, data, tokenId])
}
diff --git a/apps/web/src/hooks/useSelectChain.ts b/apps/web/src/hooks/useSelectChain.ts
index 488ec4567c5..0e83e02d937 100644
--- a/apps/web/src/hooks/useSelectChain.ts
+++ b/apps/web/src/hooks/useSelectChain.ts
@@ -2,7 +2,7 @@ import { useSwitchChain } from 'hooks/useSwitchChain'
import { useCallback } from 'react'
import { useDispatch } from 'react-redux'
import { PopupType, addPopup, removePopup } from 'state/application/reducer'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { logger } from 'utilities/src/logger/logger'
import { UserRejectedRequestError } from 'viem'
diff --git a/apps/web/src/hooks/useSendCallback.ts b/apps/web/src/hooks/useSendCallback.ts
index 2fa5df2621c..8158d511b70 100644
--- a/apps/web/src/hooks/useSendCallback.ts
+++ b/apps/web/src/hooks/useSendCallback.ts
@@ -1,7 +1,6 @@
import { TransactionRequest } from '@ethersproject/abstract-provider'
import { InterfaceEventName } from '@uniswap/analytics-events'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
-import { useSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { useEthersProvider } from 'hooks/useEthersProvider'
import { useSwitchChain } from 'hooks/useSwitchChain'
@@ -10,6 +9,7 @@ import { useCallback, useRef } from 'react'
import { useTransactionAdder } from 'state/transactions/hooks'
import { SendTransactionInfo, TransactionType } from 'state/transactions/types'
import { trace } from 'tracing/trace'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { currencyId } from 'utils/currencyId'
import { UserRejectedRequestError, toReadableError } from 'utils/errors'
diff --git a/apps/web/src/hooks/useSocksBalance.ts b/apps/web/src/hooks/useSocksBalance.ts
index f2913bab0b8..373720d209c 100644
--- a/apps/web/src/hooks/useSocksBalance.ts
+++ b/apps/web/src/hooks/useSocksBalance.ts
@@ -2,7 +2,7 @@ import { SOCKS_CONTROLLER_ADDRESSES, Token } from '@uniswap/sdk-core'
import { useAccount } from 'hooks/useAccount'
import { useTokenBalance } from 'lib/hooks/useCurrencyBalance'
import { useMemo } from 'react'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
// technically a 721, not an ERC20, but suffices for our purposes
const SOCKS = new Token(UniverseChainId.Mainnet, SOCKS_CONTROLLER_ADDRESSES[UniverseChainId.Mainnet], 0)
diff --git a/apps/web/src/hooks/useStablecoinPrice.ts b/apps/web/src/hooks/useStablecoinPrice.ts
index 882425a1405..831055f13c5 100644
--- a/apps/web/src/hooks/useStablecoinPrice.ts
+++ b/apps/web/src/hooks/useStablecoinPrice.ts
@@ -1,10 +1,11 @@
import { Currency, CurrencyAmount, Price, Token, TradeType } from '@uniswap/sdk-core'
-import { getChain, useSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { useMemo, useRef } from 'react'
import { ClassicTrade, INTERNAL_ROUTER_PREFERENCE_PRICE, TradeState } from 'state/routing/types'
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
/**
* Returns the price in USDC of the input currency
@@ -15,7 +16,7 @@ export default function useStablecoinPrice(currency?: Currency): {
state: TradeState
} {
const chainId = useSupportedChainId(currency?.chainId)
- const amountOut = chainId ? getChain({ chainId }).spotPriceStablecoinAmount : undefined
+ const amountOut = chainId ? getChainInfo(chainId).spotPriceStablecoinAmount : undefined
const stablecoin = amountOut?.currency
const { trade, state } = useRoutingAPITrade(
@@ -79,9 +80,7 @@ export function useStablecoinValue(currencyAmount: CurrencyAmount | un
export function useStablecoinAmountFromFiatValue(fiatValue: number | null | undefined) {
const { chainId } = useAccount()
const supportedChainId = useSupportedChainId(chainId)
- const stablecoin = supportedChainId
- ? getChain({ chainId: supportedChainId }).spotPriceStablecoinAmount.currency
- : undefined
+ const stablecoin = supportedChainId ? getChainInfo(supportedChainId).spotPriceStablecoinAmount.currency : undefined
return useMemo(() => {
if (fiatValue === null || fiatValue === undefined || !chainId || !stablecoin) {
diff --git a/apps/web/src/hooks/useSwapCallback.tsx b/apps/web/src/hooks/useSwapCallback.tsx
index 88224e9ac94..ea1d715bf2d 100644
--- a/apps/web/src/hooks/useSwapCallback.tsx
+++ b/apps/web/src/hooks/useSwapCallback.tsx
@@ -1,7 +1,6 @@
import { Percent, TradeType } from '@uniswap/sdk-core'
import { FlatFeeOptions } from '@uniswap/universal-router-sdk'
import { FeeOptions } from '@uniswap/v3-sdk'
-import { useSupportedChainId } from 'constants/chains'
import { BigNumber } from 'ethers/lib/ethers'
import { useAccount } from 'hooks/useAccount'
import { PermitSignature } from 'hooks/usePermitAllowance'
@@ -20,7 +19,8 @@ import {
ExactOutputSwapTransactionInfo,
TransactionType,
} from 'state/transactions/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { currencyId } from 'utils/currencyId'
export type SwapResult = Awaited>>
diff --git a/apps/web/src/hooks/useSwapTaxes.ts b/apps/web/src/hooks/useSwapTaxes.ts
index 29d4375b724..09155f7ea55 100644
--- a/apps/web/src/hooks/useSwapTaxes.ts
+++ b/apps/web/src/hooks/useSwapTaxes.ts
@@ -7,8 +7,8 @@ import { useContract } from 'hooks/useContract'
import { useEffect, useState } from 'react'
import FOT_DETECTOR_ABI from 'uniswap/src/abis/fee-on-transfer-detector.json'
import { FeeOnTransferDetector } from 'uniswap/src/abis/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { logger } from 'utilities/src/logger/logger'
// TODO(WEB-4058): Move all of these contract addresses into the top-level wagmi config
diff --git a/apps/web/src/hooks/useSwitchChain.ts b/apps/web/src/hooks/useSwitchChain.ts
index 2b136ae7b12..ac343b7ad05 100644
--- a/apps/web/src/hooks/useSwitchChain.ts
+++ b/apps/web/src/hooks/useSwitchChain.ts
@@ -1,10 +1,10 @@
-import { useIsSupportedChainIdCallback } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { useCallback } from 'react'
import { useDispatch } from 'react-redux'
import { endSwitchingChain, startSwitchingChain } from 'state/wallets/reducer'
import { trace } from 'tracing/trace'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useIsSupportedChainIdCallback } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { useSwitchChain as useSwitchChainWagmi } from 'wagmi'
export function useSwitchChain() {
diff --git a/apps/web/src/hooks/useTokenBalances.ts b/apps/web/src/hooks/useTokenBalances.ts
index cc244adf8a3..ee10382e314 100644
--- a/apps/web/src/hooks/useTokenBalances.ts
+++ b/apps/web/src/hooks/useTokenBalances.ts
@@ -7,7 +7,7 @@ import {
QuickTokenBalancePartsFragment,
useQuickTokenBalancesWebQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { currencyKeyFromGraphQL } from 'utils/currencyKey'
/**
diff --git a/apps/web/src/hooks/useUSDPrice.ts b/apps/web/src/hooks/useUSDPrice.ts
index 69e1dc5eddd..8e9c4470e14 100644
--- a/apps/web/src/hooks/useUSDPrice.ts
+++ b/apps/web/src/hooks/useUSDPrice.ts
@@ -1,6 +1,5 @@
import { NetworkStatus } from '@apollo/client'
import { Currency, CurrencyAmount, Price, TradeType } from '@uniswap/sdk-core'
-import { chainIdToBackendChain, useIsSupportedChainId, useSupportedChainId } from 'constants/chains'
import { PollingInterval } from 'graphql/data/util'
import useIsWindowVisible from 'hooks/useIsWindowVisible'
import useStablecoinPrice from 'hooks/useStablecoinPrice'
@@ -9,7 +8,9 @@ import { ClassicTrade, INTERNAL_ROUTER_PREFERENCE_PRICE, TradeState } from 'stat
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { Chain, useTokenSpotPriceQuery } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains, useIsSupportedChainId, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { getNativeTokenDBAddress } from 'utils/nativeTokens'
// ETH amounts used when calculating spot price for a given currency.
@@ -71,7 +72,8 @@ export function useUSDPrice(
} {
const currency = currencyAmount?.currency ?? prefetchCurrency
const chainId = useSupportedChainId(currency?.chainId)
- const chain = chainIdToBackendChain({ chainId })
+ const { defaultChainId } = useEnabledChains()
+ const chain = toGraphQLChain(chainId ?? defaultChainId)
// skip all pricing requests if the window is not focused
const isWindowVisible = useIsWindowVisible()
diff --git a/apps/web/src/hooks/useUSDTokenUpdater.ts b/apps/web/src/hooks/useUSDTokenUpdater.ts
index afd86b8ad1f..2e21baee27e 100644
--- a/apps/web/src/hooks/useUSDTokenUpdater.ts
+++ b/apps/web/src/hooks/useUSDTokenUpdater.ts
@@ -1,9 +1,10 @@
import { Currency } from '@uniswap/sdk-core'
-import { getChain, useSupportedChainId } from 'constants/chains'
import useStablecoinPrice from 'hooks/useStablecoinPrice'
import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { useMemo } from 'react'
import { TradeState } from 'state/routing/types'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const NUM_DECIMALS_USD = 2
@@ -30,10 +31,7 @@ export function useUSDTokenUpdater(
if (isFiatInput) {
const exactAmountUSD = (parseFloat(exactAmount || '0') / conversionRate).toFixed(NUM_DECIMALS_USD)
const stablecoinAmount = supportedChainId
- ? tryParseCurrencyAmount(
- exactAmountUSD,
- getChain({ chainId: supportedChainId }).spotPriceStablecoinAmount.currency,
- )
+ ? tryParseCurrencyAmount(exactAmountUSD, getChainInfo(supportedChainId).spotPriceStablecoinAmount.currency)
: undefined
const currencyAmount = stablecoinAmount ? price?.invert().quote(stablecoinAmount) : undefined
diff --git a/apps/web/src/i18n/LanguageProvider.tsx b/apps/web/src/i18n/LanguageProvider.tsx
index 2f3a5c65d26..7d2aa689db4 100644
--- a/apps/web/src/i18n/LanguageProvider.tsx
+++ b/apps/web/src/i18n/LanguageProvider.tsx
@@ -1,14 +1,19 @@
-import { navigatorLocale, parseLocale, storeLocale, useActiveLocale } from 'hooks/useActiveLocale'
import { ReactNode, useEffect } from 'react'
+import store from 'state'
import { useAppDispatch } from 'state/hooks'
-import { DEFAULT_LOCALE, mapLocaleToLanguage } from 'uniswap/src/features/language/constants'
-import { useCurrentLocale } from 'uniswap/src/features/language/hooks'
+import { DEFAULT_LOCALE, Locale, mapLocaleToLanguage } from 'uniswap/src/features/language/constants'
+import { getLocale, navigatorLocale, parseLocale, useCurrentLocale } from 'uniswap/src/features/language/hooks'
import { setCurrentLanguage } from 'uniswap/src/features/settings/slice'
import { changeLanguage } from 'uniswap/src/i18n'
+function getStoreLocale(): Locale | undefined {
+ const storeLanguage = store.getState().userSettings.currentLanguage
+ return getLocale(storeLanguage)
+}
+
function setupInitialLanguage() {
const lngQuery = typeof window !== 'undefined' ? new URL(window.location.href).searchParams.get('lng') : ''
- const initialLocale = parseLocale(lngQuery) ?? storeLocale() ?? navigatorLocale() ?? DEFAULT_LOCALE
+ const initialLocale = parseLocale(lngQuery) ?? getStoreLocale() ?? navigatorLocale() ?? DEFAULT_LOCALE
changeLanguage(initialLocale)
}
@@ -17,10 +22,8 @@ if (process.env.NODE_ENV !== 'test') {
}
export function LanguageProvider({ children }: { children: ReactNode }): JSX.Element {
- const activeLocale = useActiveLocale()
- const userLocale = useCurrentLocale()
const dispatch = useAppDispatch()
- const locale = userLocale || activeLocale
+ const locale = useCurrentLocale()
useEffect(() => {
changeLanguage(locale)
diff --git a/apps/web/src/index.tsx b/apps/web/src/index.tsx
index f7b1908aa38..4fcf67e419d 100644
--- a/apps/web/src/index.tsx
+++ b/apps/web/src/index.tsx
@@ -6,7 +6,7 @@ import { ApolloProvider } from '@apollo/client'
import { PortalProvider } from '@tamagui/portal'
import { QueryClientProvider } from '@tanstack/react-query'
import { MiniKit } from '@worldcoin/minikit-js'
-import Web3Provider from 'components/Web3Provider'
+import Web3Provider, { Web3ProviderUpdater } from 'components/Web3Provider'
import { WebUniswapProvider } from 'components/Web3Provider/WebUniswapContext'
import { AssetActivityProvider } from 'graphql/data/apollo/AssetActivityProvider'
import { TokenBalancesProvider } from 'graphql/data/apollo/TokenBalancesProvider'
@@ -33,6 +33,7 @@ import RadialGradientByChainUpdater from 'theme/components/RadialGradientByChain
import { SystemThemeUpdater, ThemeColorMetaUpdater } from 'theme/components/ThemeToggle'
import { TamaguiProvider } from 'theme/tamaguiProvider'
import { getEnvName } from 'tracing/env'
+import { ReactRouterUrlProvider } from 'uniswap/src/contexts/UrlContext'
import { SharedQueryClient } from 'uniswap/src/data/apiClients/SharedQueryClient'
import { DUMMY_STATSIG_SDK_KEY } from 'uniswap/src/features/gating/constants'
import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext'
@@ -62,6 +63,7 @@ function Updaters() {
+
>
)
}
@@ -116,39 +118,41 @@ const Router = isBrowserRouterEnabled() ? BrowserRouter : HashRouter
createRoot(container).render(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
,
)
diff --git a/apps/web/src/lib/hooks/multicall.ts b/apps/web/src/lib/hooks/multicall.ts
index d2004e74852..ea6c16185d4 100644
--- a/apps/web/src/lib/hooks/multicall.ts
+++ b/apps/web/src/lib/hooks/multicall.ts
@@ -2,7 +2,7 @@ import { useMainnetBlockNumber } from 'lib/hooks/useBlockNumber'
import { useCallContext } from 'lib/hooks/useCallContext'
import multicall from 'lib/state/multicall'
import { SkipFirst } from 'types/tuple'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export { NEVER_RELOAD } from '@uniswap/redux-multicall' // re-export for convenience
export type { CallStateResult } from '@uniswap/redux-multicall' // re-export for convenience
diff --git a/apps/web/src/lib/hooks/routing/clientSideSmartOrderRouter.ts b/apps/web/src/lib/hooks/routing/clientSideSmartOrderRouter.ts
index 6165603ab55..eaec1b186d4 100644
--- a/apps/web/src/lib/hooks/routing/clientSideSmartOrderRouter.ts
+++ b/apps/web/src/lib/hooks/routing/clientSideSmartOrderRouter.ts
@@ -2,13 +2,12 @@ import { BigintIsh, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
// This file is lazy-loaded, so the import of smart-order-router is intentional.
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { AlphaRouter, AlphaRouterConfig } from '@uniswap/smart-order-router'
-import { getChain, isSupportedChainId } from 'constants/chains'
import { RPC_PROVIDERS } from 'constants/providers'
import JSBI from 'jsbi'
import { GetQuoteArgs, QuoteResult, QuoteState, SwapRouterNativeAssets } from 'state/routing/types'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId, isUniverseChainId } from 'uniswap/src/features/chains/types'
import { transformSwapRouteToGetQuoteResult } from 'utils/transformSwapRouteToGetQuoteResult'
const routers = new Map()
@@ -18,9 +17,9 @@ export function getRouter(chainId: UniverseChainId): AlphaRouter {
return router
}
- if (isSupportedChainId(chainId) && getChain({ chainId }).supportsClientSideRouting) {
+ if (isUniverseChainId(chainId) && getChainInfo(chainId).supportsInterfaceClientSideRouting) {
const provider = RPC_PROVIDERS[chainId as UniverseChainId]
- const router = new AlphaRouter({ chainId: UNIVERSE_CHAIN_INFO[chainId].sdkId, provider })
+ const router = new AlphaRouter({ chainId: getChainInfo(chainId).sdkId, provider })
routers.set(chainId, router)
return router
}
diff --git a/apps/web/src/lib/hooks/routing/useRoutingAPIArguments.ts b/apps/web/src/lib/hooks/routing/useRoutingAPIArguments.ts
index 5a393c7fa8c..32d540f5d0e 100644
--- a/apps/web/src/lib/hooks/routing/useRoutingAPIArguments.ts
+++ b/apps/web/src/lib/hooks/routing/useRoutingAPIArguments.ts
@@ -1,10 +1,11 @@
import { SkipToken, skipToken } from '@reduxjs/toolkit/query/react'
import { Protocol } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
-import { useIsUniswapXSupportedChain } from 'constants/chains'
+import { useIsUniswapXSupportedChain } from 'hooks/useIsUniswapXSupportedChain'
import { useMemo } from 'react'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/types'
import { currencyAddressForSwapQuote } from 'state/routing/utils'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import {
ArbitrumXV2ExperimentGroup,
ArbitrumXV2OpenOrderProperties,
@@ -12,7 +13,6 @@ import {
} from 'uniswap/src/features/gating/experiments'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useExperimentGroupName, useExperimentValue, useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
/**
* Returns query arguments for the Routing API query or undefined if the
diff --git a/apps/web/src/lib/hooks/useBlockNumber.tsx b/apps/web/src/lib/hooks/useBlockNumber.tsx
index 1fc46e36d18..916e5e84a33 100644
--- a/apps/web/src/lib/hooks/useBlockNumber.tsx
+++ b/apps/web/src/lib/hooks/useBlockNumber.tsx
@@ -7,7 +7,7 @@ import useIsWindowVisible from 'hooks/useIsWindowVisible'
import { atom } from 'jotai'
import { useAtomValue } from 'jotai/utils'
import { PropsWithChildren, createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
// MulticallUpdater is outside of the SwapAndLimitContext but we still want to use the swap context chainId for swap-related multicalls
export const multicallUpdaterSwapChainIdAtom = atom(undefined)
diff --git a/apps/web/src/lib/hooks/useNativeCurrency.ts b/apps/web/src/lib/hooks/useNativeCurrency.ts
index 943b3d2c510..c918db4aae8 100644
--- a/apps/web/src/lib/hooks/useNativeCurrency.ts
+++ b/apps/web/src/lib/hooks/useNativeCurrency.ts
@@ -1,7 +1,7 @@
import { NativeCurrency, Token } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export default function useNativeCurrency(chainId: UniverseChainId | null | undefined): NativeCurrency | Token {
return useMemo(
diff --git a/apps/web/src/lib/hooks/useTokenList/sorting.test.ts b/apps/web/src/lib/hooks/useTokenList/sorting.test.ts
index ebed74f3cc1..c45dd10941d 100644
--- a/apps/web/src/lib/hooks/useTokenList/sorting.test.ts
+++ b/apps/web/src/lib/hooks/useTokenList/sorting.test.ts
@@ -8,7 +8,7 @@ import {
TokenBalance,
TokenStandard,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const nativeToken: Token = {
id: 'native-token',
diff --git a/apps/web/src/lib/hooks/useTokenList/sorting.ts b/apps/web/src/lib/hooks/useTokenList/sorting.ts
index 0cdbda776e6..924e713ebb4 100644
--- a/apps/web/src/lib/hooks/useTokenList/sorting.ts
+++ b/apps/web/src/lib/hooks/useTokenList/sorting.ts
@@ -2,7 +2,7 @@ import { Token } from '@uniswap/sdk-core'
import { PortfolioBalance } from 'graphql/data/portfolios'
import { supportedChainIdFromGQLChain } from 'graphql/data/util'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { currencyKey } from 'utils/currencyKey'
import { SplitOptions, splitHiddenTokens } from 'utils/splitHiddenTokens'
diff --git a/apps/web/src/lib/state/multicall.tsx b/apps/web/src/lib/state/multicall.tsx
index 4a26d3f87f5..d9612be4a80 100644
--- a/apps/web/src/lib/state/multicall.tsx
+++ b/apps/web/src/lib/state/multicall.tsx
@@ -4,8 +4,8 @@ import { useInterfaceMulticall, useMainnetInterfaceMulticall } from 'hooks/useCo
import { useAtomValue } from 'jotai/utils'
import useBlockNumber, { multicallUpdaterSwapChainIdAtom, useMainnetBlockNumber } from 'lib/hooks/useBlockNumber'
import { useMemo } from 'react'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const multicall = createMulticall()
@@ -20,7 +20,7 @@ export function MulticallUpdater() {
const latestBlockNumber = useBlockNumber()
const contract = useInterfaceMulticall(chainId)
const listenerOptions: ListenerOptions = useMemo(
- () => ({ blocksPerFetch: chainId ? UNIVERSE_CHAIN_INFO[chainId].blockPerMainnetEpochForChainId : 1 }),
+ () => ({ blocksPerFetch: chainId ? getChainInfo(chainId).blockPerMainnetEpochForChainId : 1 }),
[chainId],
)
diff --git a/apps/web/src/lib/utils/formatLocaleNumber.test.ts b/apps/web/src/lib/utils/formatLocaleNumber.test.ts
index 93e929537fa..d626436091b 100644
--- a/apps/web/src/lib/utils/formatLocaleNumber.test.ts
+++ b/apps/web/src/lib/utils/formatLocaleNumber.test.ts
@@ -13,7 +13,6 @@ function expectedOutput(l: Locale): string {
case 'sw-TZ':
case 'zh-Hans':
case 'ur-PK':
- case 'th-TH':
case 'es-US':
case 'es-419':
case 'ms-MY':
diff --git a/apps/web/src/lib/utils/searchBar.test.ts b/apps/web/src/lib/utils/searchBar.test.ts
index db0a3f92784..ed1077e8649 100644
--- a/apps/web/src/lib/utils/searchBar.test.ts
+++ b/apps/web/src/lib/utils/searchBar.test.ts
@@ -3,17 +3,20 @@ import { searchTokenToTokenSearchResult } from 'lib/utils/searchBar'
import { getNativeAddress } from 'uniswap/src/constants/addresses'
import {
Chain,
+ ProtectionResult,
SafetyLevel,
TokenStandard,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { SearchResultType } from 'uniswap/src/features/search/SearchResult'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { TokenList } from 'uniswap/src/features/dataApi/types'
+import { getCurrencySafetyInfo } from 'uniswap/src/features/dataApi/utils'
+import { SearchResultType, TokenSearchResult } from 'uniswap/src/features/search/SearchResult'
describe('searchBar', () => {
describe('searchTokenToTokenSearchResult', () => {
describe(`${NATIVE_CHAIN_ID}`, () => {
it('accepts a searchToken and returns a TokenSearchResult', () => {
- const ethSearchResult = {
+ const ethSearchResult: TokenSearchResult = {
type: SearchResultType.Token,
chainId: UniverseChainId.Mainnet,
address: null,
@@ -21,6 +24,8 @@ describe('searchBar', () => {
symbol: 'ETH',
name: 'Ethereum',
safetyLevel: SafetyLevel.Verified,
+ safetyInfo: getCurrencySafetyInfo(SafetyLevel.Verified, { attackTypes: [], result: ProtectionResult.Benign }),
+ feeData: null,
}
expect(
@@ -39,24 +44,10 @@ describe('searchBar', () => {
logoUrl: 'eth-logo.png',
safetyLevel: SafetyLevel.Verified,
},
- }),
- ).toEqual(ethSearchResult)
-
- expect(
- searchTokenToTokenSearchResult({
- decimals: 18,
- name: 'Ethereum',
- chain: Chain.Ethereum,
- // This is not a mistake, sometimes the standard for ETH is ERC20
- // in search results.
- standard: TokenStandard.Erc20,
- address: NATIVE_CHAIN_ID,
- symbol: 'ETH',
- chainId: UniverseChainId.Mainnet,
- // @ts-ignore
- project: {
- logoUrl: 'eth-logo.png',
- safetyLevel: SafetyLevel.Verified,
+ feeData: undefined,
+ protectionInfo: {
+ attackTypes: [],
+ result: ProtectionResult.Benign,
},
}),
).toEqual(ethSearchResult)
@@ -75,6 +66,11 @@ describe('searchBar', () => {
logoUrl: 'matic-logo.png',
safetyLevel: SafetyLevel.Verified,
},
+ feeData: undefined,
+ protectionInfo: {
+ attackTypes: [],
+ result: ProtectionResult.Benign,
+ },
}),
).toEqual({
type: SearchResultType.Token,
@@ -84,12 +80,18 @@ describe('searchBar', () => {
symbol: 'MATIC',
name: 'Polygon',
safetyLevel: SafetyLevel.Verified,
- })
+ feeData: null,
+ safetyInfo: {
+ tokenList: TokenList.Default,
+ attackType: undefined,
+ protectionResult: ProtectionResult.Benign,
+ },
+ } as TokenSearchResult)
})
})
describe(`${TokenStandard.Erc20}`, () => {
it('accepts a searchToken and returns a TokenSearchResult', () => {
- const tokenSearchResult = {
+ const tokenSearchResult: TokenSearchResult = {
type: SearchResultType.Token,
chainId: 1,
address: '0x123',
@@ -97,6 +99,12 @@ describe('searchBar', () => {
symbol: 'ABC',
name: 'ABC Token',
safetyLevel: SafetyLevel.Verified,
+ feeData: null,
+ safetyInfo: {
+ tokenList: TokenList.Default,
+ attackType: undefined,
+ protectionResult: ProtectionResult.Benign,
+ },
}
expect(
@@ -113,6 +121,11 @@ describe('searchBar', () => {
logoUrl: 'token-logo.png',
safetyLevel: SafetyLevel.Verified,
},
+ feeData: undefined,
+ protectionInfo: {
+ attackTypes: [],
+ result: ProtectionResult.Benign,
+ },
}),
).toEqual(tokenSearchResult)
})
diff --git a/apps/web/src/lib/utils/searchBar.ts b/apps/web/src/lib/utils/searchBar.ts
index 16cc51a8bf7..f2a0a13888b 100644
--- a/apps/web/src/lib/utils/searchBar.ts
+++ b/apps/web/src/lib/utils/searchBar.ts
@@ -1,12 +1,13 @@
import { GqlSearchToken } from 'graphql/data/SearchTokens'
import { GenieCollection } from 'nft/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { getCurrencySafetyInfo } from 'uniswap/src/features/dataApi/utils'
import {
NFTCollectionSearchResult,
SearchResultType,
TokenSearchResult,
} from 'uniswap/src/features/search/SearchResult'
import { tokenAddressOrNativeAddress } from 'uniswap/src/features/search/utils'
-import { UniverseChainId } from 'uniswap/src/types/chains'
/**
* Organizes the number of Token and NFT results to be shown to a user depending on if they're in the NFT or Token experience
@@ -38,6 +39,8 @@ export const searchTokenToTokenSearchResult = (
name: searchToken.name ?? null,
logoUrl: searchToken.project?.logoUrl ?? null,
safetyLevel: searchToken.project?.safetyLevel ?? null,
+ safetyInfo: getCurrencySafetyInfo(searchToken.project?.safetyLevel, searchToken.protectionInfo),
+ feeData: searchToken.feeData ?? null,
}
}
diff --git a/apps/web/src/nft/components/bag/BagFooter.test.tsx b/apps/web/src/nft/components/bag/BagFooter.test.tsx
index cbcd22d0c67..d123f8e5ca5 100644
--- a/apps/web/src/nft/components/bag/BagFooter.test.tsx
+++ b/apps/web/src/nft/components/bag/BagFooter.test.tsx
@@ -20,7 +20,7 @@ import { TEST_TOKEN_1, TEST_TRADE_EXACT_INPUT, USE_CONNECTED_ACCOUNT, toCurrency
import { mocked } from 'test-utils/mocked'
import { render, screen } from 'test-utils/render'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('hooks/useAccount', () => ({
useAccount: jest.fn(),
diff --git a/apps/web/src/nft/components/bag/BagFooter.tsx b/apps/web/src/nft/components/bag/BagFooter.tsx
index b5c2d910c09..278d943522b 100644
--- a/apps/web/src/nft/components/bag/BagFooter.tsx
+++ b/apps/web/src/nft/components/bag/BagFooter.tsx
@@ -10,7 +10,6 @@ import { LoadingBubble } from 'components/Tokens/loading'
import { MouseoverTooltip } from 'components/Tooltip'
import Column from 'components/deprecated/Column'
import Row from 'components/deprecated/Row'
-import { useIsSupportedChainId } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { getURAddress, useNftUniversalRouterAddress } from 'graphql/data/nft/NftUniversalRouterAddress'
import { useCurrency } from 'hooks/Tokens'
@@ -36,10 +35,11 @@ import { PropsWithChildren, useEffect, useMemo, useState } from 'react'
import { AlertTriangle, ChevronDown } from 'react-feather'
import { InterfaceTrade, TradeFillType, TradeState } from 'state/routing/types'
import { ThemedText } from 'theme/components'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans, t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const FooterContainer = styled.div`
diff --git a/apps/web/src/nft/components/collection/ActivityCells.tsx b/apps/web/src/nft/components/collection/ActivityCells.tsx
index f397d185a5b..3d77db63ba7 100644
--- a/apps/web/src/nft/components/collection/ActivityCells.tsx
+++ b/apps/web/src/nft/components/collection/ActivityCells.tsx
@@ -32,9 +32,9 @@ import {
NftMarketplace,
OrderStatus,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { shortenAddress } from 'utilities/src/addresses'
import { useTrace } from 'utilities/src/telemetry/trace/TraceContext'
diff --git a/apps/web/src/nft/components/collection/Filters.tsx b/apps/web/src/nft/components/collection/Filters.tsx
index 22e5b9ea400..766dccae5f2 100644
--- a/apps/web/src/nft/components/collection/Filters.tsx
+++ b/apps/web/src/nft/components/collection/Filters.tsx
@@ -37,7 +37,12 @@ export const Filters = ({ traitsByGroup }: { traitsByGroup: Record
Buy now
-
+
{isMobileWeb && }
diff --git a/apps/web/src/nft/components/explore/TrendingCollections.tsx b/apps/web/src/nft/components/explore/TrendingCollections.tsx
index ac2165c8986..010d4e67ae6 100644
--- a/apps/web/src/nft/components/explore/TrendingCollections.tsx
+++ b/apps/web/src/nft/components/explore/TrendingCollections.tsx
@@ -7,7 +7,7 @@ import { CollectionTableColumn, Denomination, TimePeriod, VolumeType } from 'nft
import { useMemo, useState } from 'react'
import { ThemedText } from 'theme/components'
import { HistoryDuration } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { useFormatterLocales } from 'utils/formatNumbers'
+import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
const timeOptions: { label: string; value: TimePeriod }[] = [
{ label: '1D', value: TimePeriod.OneDay },
@@ -85,7 +85,7 @@ function convertTimePeriodToHistoryDuration(timePeriod: TimePeriod): HistoryDura
}
const TrendingCollections = () => {
- const { formatterLocalCurrency } = useFormatterLocales()
+ const currentCurrency = useAppFiatCurrency()
const [timePeriod, setTimePeriod] = useState(TimePeriod.OneDay)
const [isEthToggled, setEthToggled] = useState(true)
@@ -155,7 +155,7 @@ const TrendingCollections = () => {
- {formatterLocalCurrency}
+ {currentCurrency}
diff --git a/apps/web/src/nft/hooks/useUsdPrice.ts b/apps/web/src/nft/hooks/useUsdPrice.ts
index a1b30d11dc6..6606cb48fa9 100644
--- a/apps/web/src/nft/hooks/useUsdPrice.ts
+++ b/apps/web/src/nft/hooks/useUsdPrice.ts
@@ -3,7 +3,7 @@ import { useUSDPrice } from 'hooks/useUSDPrice'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { GenieAsset } from 'nft/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export const useNativeUsdPrice = (chainId: number = UniverseChainId.Mainnet): number => {
const nativeCurrency = useNativeCurrency(chainId)
diff --git a/apps/web/src/nft/utils/tokenRoutes.ts b/apps/web/src/nft/utils/tokenRoutes.ts
index e9a8b070575..e2a2c094e9b 100644
--- a/apps/web/src/nft/utils/tokenRoutes.ts
+++ b/apps/web/src/nft/utils/tokenRoutes.ts
@@ -4,12 +4,13 @@ import { Pair } from '@uniswap/v2-sdk'
import { Pool as V3Pool } from '@uniswap/v3-sdk'
import { Pool as V4Pool } from '@uniswap/v4-sdk'
import { ClassicTrade } from 'state/routing/types'
-import { DEFAULT_NATIVE_ADDRESS, UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import {
TokenAmountInput,
TokenTradeRouteInput,
TradePoolInput,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { DEFAULT_NATIVE_ADDRESS, getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { isUniverseChainId } from 'uniswap/src/features/chains/types'
interface SwapAmounts {
inputAmount: CurrencyAmount
@@ -56,9 +57,9 @@ function buildTradeRouteInputAmounts(swapAmounts: SwapAmounts): TradeTokenInputA
function buildPool(pool: Pair | V3Pool | V4Pool): TradePoolInput {
const isPool = 'fee' in pool
- const chainIdInUniverseChainInfo = pool.chainId in UNIVERSE_CHAIN_INFO
- const nativeCurrencyAddress = chainIdInUniverseChainInfo
- ? UNIVERSE_CHAIN_INFO[pool.chainId as keyof typeof UNIVERSE_CHAIN_INFO].nativeCurrency.address
+ const knownChainId = isUniverseChainId(pool.chainId)
+ const nativeCurrencyAddress = knownChainId
+ ? getChainInfo(pool.chainId).nativeCurrency.address
: DEFAULT_NATIVE_ADDRESS
return {
diff --git a/apps/web/src/pages/AddLiquidity/redirects.tsx b/apps/web/src/pages/AddLiquidity/redirects.tsx
deleted file mode 100644
index b4cca59eb0f..00000000000
--- a/apps/web/src/pages/AddLiquidity/redirects.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useAccount } from 'hooks/useAccount'
-import AddLiquidity from 'pages/AddLiquidity/index'
-import { Navigate, useParams } from 'react-router-dom'
-import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
-
-export default function AddLiquidityWithTokenRedirects() {
- const { currencyIdA, currencyIdB } = useParams<{ currencyIdA: string; currencyIdB: string; feeAmount?: string }>()
-
- const { chainId } = useAccount()
-
- // prevent weth + eth
- const isETHOrWETHA =
- currencyIdA === 'ETH' || (chainId !== undefined && currencyIdA === WRAPPED_NATIVE_CURRENCY[chainId]?.address)
- const isETHOrWETHB =
- currencyIdB === 'ETH' || (chainId !== undefined && currencyIdB === WRAPPED_NATIVE_CURRENCY[chainId]?.address)
-
- if (
- currencyIdA &&
- currencyIdB &&
- (currencyIdA.toLowerCase() === currencyIdB.toLowerCase() || (isETHOrWETHA && isETHOrWETHB))
- ) {
- return
- }
- return
-}
diff --git a/apps/web/src/pages/AddLiquidityV2/redirects.tsx b/apps/web/src/pages/AddLiquidityV2/redirects.tsx
index cc62e8e7758..cbd9bcd18e3 100644
--- a/apps/web/src/pages/AddLiquidityV2/redirects.tsx
+++ b/apps/web/src/pages/AddLiquidityV2/redirects.tsx
@@ -1,9 +1,15 @@
import AddLiquidityV2 from 'pages/AddLiquidityV2/index'
import { Navigate, useParams } from 'react-router-dom'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
export default function AddLiquidityV2WithTokenRedirects() {
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
const { currencyIdA, currencyIdB } = useParams<{ currencyIdA: string; currencyIdB: string }>()
-
+ if (isV4EverywhereEnabled) {
+ // TODO(WEB-5361): update this to enable prefilling form from URL currencyIdA and currencyIdB
+ return
+ }
if (currencyIdA && currencyIdB && currencyIdA.toLowerCase() === currencyIdB.toLowerCase()) {
return
}
diff --git a/apps/web/src/pages/AddLiquidity/Review.tsx b/apps/web/src/pages/AddLiquidityV3/Review.tsx
similarity index 100%
rename from apps/web/src/pages/AddLiquidity/Review.tsx
rename to apps/web/src/pages/AddLiquidityV3/Review.tsx
diff --git a/apps/web/src/pages/AddLiquidity/blastAlerts.tsx b/apps/web/src/pages/AddLiquidityV3/blastAlerts.tsx
similarity index 100%
rename from apps/web/src/pages/AddLiquidity/blastAlerts.tsx
rename to apps/web/src/pages/AddLiquidityV3/blastAlerts.tsx
diff --git a/apps/web/src/pages/AddLiquidity/index.tsx b/apps/web/src/pages/AddLiquidityV3/index.tsx
similarity index 98%
rename from apps/web/src/pages/AddLiquidity/index.tsx
rename to apps/web/src/pages/AddLiquidityV3/index.tsx
index 4d2e00c077c..3601f2c132f 100644
--- a/apps/web/src/pages/AddLiquidity/index.tsx
+++ b/apps/web/src/pages/AddLiquidityV3/index.tsx
@@ -35,7 +35,6 @@ import { TokenTaxV3Warning } from 'components/addLiquidity/TokenTaxV3Warning'
import { AutoColumn } from 'components/deprecated/Column'
import Row, { RowBetween, RowFixed } from 'components/deprecated/Row'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
-import { isSupportedChainId, useIsSupportedChainId } from 'constants/chains'
import { ZERO_PERCENT } from 'constants/misc'
import { useCurrency } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
@@ -54,8 +53,8 @@ import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { atomWithStorage, useAtomValue, useUpdateAtom } from 'jotai/utils'
import { useSingleCallResult } from 'lib/hooks/multicall'
import styled, { useTheme } from 'lib/styled-components'
-import { Review } from 'pages/AddLiquidity/Review'
-import { BlastRebasingAlert, BlastRebasingModal } from 'pages/AddLiquidity/blastAlerts'
+import { Review } from 'pages/AddLiquidityV3/Review'
+import { BlastRebasingAlert, BlastRebasingModal } from 'pages/AddLiquidityV3/blastAlerts'
import {
DynamicSection,
MediumOnly,
@@ -63,7 +62,7 @@ import {
ScrollablePage,
StyledInput,
Wrapper,
-} from 'pages/AddLiquidity/styled'
+} from 'pages/AddLiquidityV3/styled'
import { BodyWrapper } from 'pages/App/AppBody'
import { PositionPageUnsupportedContent } from 'pages/LegacyPool/PositionPage'
import { Dots } from 'pages/LegacyPool/styled'
@@ -83,12 +82,13 @@ import { TransactionInfo, TransactionType } from 'state/transactions/types'
import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
import { ThemedText } from 'theme/components'
import { Text } from 'ui/src'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId, isUniverseChainId } from 'uniswap/src/features/chains/types'
+import { getChainLabel } from 'uniswap/src/features/chains/utils'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans, t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { logger } from 'utilities/src/logger/logger'
import { useTrace } from 'utilities/src/telemetry/trace/TraceContext'
import { addressesAreEquivalent } from 'utils/addressesAreEquivalent'
@@ -674,9 +674,7 @@ function AddLiquidity() {
quoteCurrency?.symbol && baseCurrency?.symbol
? `${quoteCurrency.symbol}/${baseCurrency.symbol}`
: quoteCurrency?.symbol ?? baseCurrency?.symbol ?? 'pools',
- chain:
- UNIVERSE_CHAIN_INFO[isSupportedChainId(account.chainId) ? account.chainId : UniverseChainId.Mainnet]
- .label,
+ chain: getChainLabel(isUniverseChainId(account.chainId) ? account.chainId : UniverseChainId.Mainnet),
})}
diff --git a/apps/web/src/pages/AddLiquidityV3/redirects.tsx b/apps/web/src/pages/AddLiquidityV3/redirects.tsx
new file mode 100644
index 00000000000..3d6fa744754
--- /dev/null
+++ b/apps/web/src/pages/AddLiquidityV3/redirects.tsx
@@ -0,0 +1,34 @@
+import { checkIsNative } from 'hooks/Tokens'
+import { useAccount } from 'hooks/useAccount'
+import AddLiquidity from 'pages/AddLiquidityV3/index'
+import { Navigate, useParams } from 'react-router-dom'
+import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+
+export default function AddLiquidityV3WithTokenRedirects() {
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+ const { currencyIdA, currencyIdB } = useParams<{ currencyIdA: string; currencyIdB: string; feeAmount?: string }>()
+
+ const { chainId } = useAccount()
+
+ if (isV4EverywhereEnabled) {
+ // TODO(WEB-5361): update this to enable prefilling form from URL currencyIdA and currencyIdB
+ return
+ }
+
+ // prevent weth + eth
+ const isETHOrWETHA =
+ checkIsNative(currencyIdA) || (chainId !== undefined && currencyIdA === WRAPPED_NATIVE_CURRENCY[chainId]?.address)
+ const isETHOrWETHB =
+ checkIsNative(currencyIdB) || (chainId !== undefined && currencyIdB === WRAPPED_NATIVE_CURRENCY[chainId]?.address)
+
+ if (
+ currencyIdA &&
+ currencyIdB &&
+ (currencyIdA.toLowerCase() === currencyIdB.toLowerCase() || (isETHOrWETHA && isETHOrWETHB))
+ ) {
+ return
+ }
+ return
+}
diff --git a/apps/web/src/pages/AddLiquidity/styled.tsx b/apps/web/src/pages/AddLiquidityV3/styled.tsx
similarity index 100%
rename from apps/web/src/pages/AddLiquidity/styled.tsx
rename to apps/web/src/pages/AddLiquidityV3/styled.tsx
diff --git a/apps/web/src/pages/Explore/charts/ExploreChartsSection.tsx b/apps/web/src/pages/Explore/charts/ExploreChartsSection.tsx
index 0a4756e2a62..16d1db78414 100644
--- a/apps/web/src/pages/Explore/charts/ExploreChartsSection.tsx
+++ b/apps/web/src/pages/Explore/charts/ExploreChartsSection.tsx
@@ -9,9 +9,7 @@ import { getCumulativeSum, getCumulativeVolume, getVolumeProtocolInfo } from 'co
import { ChartType } from 'components/Charts/utils'
import { DataQuality } from 'components/Tokens/TokenDetails/ChartSection/util'
import { MAX_WIDTH_MEDIA_BREAKPOINT } from 'components/Tokens/constants'
-import { chainIdToBackendChain, useChainFromUrlParam } from 'constants/chains'
-import { useDailyProtocolTVL, useHistoricalProtocolVolume } from 'graphql/data/protocolStats'
-import { TimePeriod, getProtocolColor, getProtocolGradient, getSupportedGraphQlChain } from 'graphql/data/util'
+import { TimePeriod, getProtocolColor, getProtocolGradient } from 'graphql/data/util'
import { useScreenSize } from 'hooks/screenSize/useScreenSize'
import { useAtomValue } from 'jotai/utils'
import { useTheme } from 'lib/styled-components'
@@ -24,13 +22,13 @@ import { EllipsisTamaguiStyle } from 'theme/components'
import { Flex, SegmentedControl, Text, styled } from 'ui/src'
import { HistoryDuration, PriceSource } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag, useFeatureFlagWithLoading } from 'uniswap/src/features/gating/hooks'
+import { useFeatureFlagWithLoading } from 'uniswap/src/features/gating/hooks'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const EXPLORE_CHART_HEIGHT_PX = 368
-const EXPLORE_PRICE_SOURCES = [PriceSource.SubgraphV2, PriceSource.SubgraphV3]
+const EXPLORE_PRICE_SOURCES_V3 = [PriceSource.SubgraphV2, PriceSource.SubgraphV3]
+const EXPLORE_PRICE_SOURCES_V4 = [PriceSource.SubgraphV2, PriceSource.SubgraphV3, PriceSource.SubgraphV4]
const TIME_SELECTOR_OPTIONS = [{ value: TimePeriod.DAY }, { value: TimePeriod.WEEK }, { value: TimePeriod.MONTH }]
@@ -70,14 +68,15 @@ const SectionTitle = styled(Text, {
lineHeight: 24,
})
-function VolumeChartSection({ chainId }: { chainId: UniverseChainId }) {
+function VolumeChartSection() {
const [timePeriod, setTimePeriod] = useState(TimePeriod.DAY)
const theme = useTheme()
const isSmallScreen = !useScreenSize()['sm']
- const { value: isMultichainExploreEnabledLoaded, isLoading: isMultichainExploreLoading } = useFeatureFlagWithLoading(
- FeatureFlags.MultichainExplore,
+ const { value: isV4EverywhereEnabledLoaded, isLoading: isV4EverywhereLoading } = useFeatureFlagWithLoading(
+ FeatureFlags.V4Everywhere,
)
- const isMultichainExploreEnabled = isMultichainExploreEnabledLoaded || isMultichainExploreLoading
+ const isV4EverywhereEnabled = isV4EverywhereEnabledLoaded || isV4EverywhereLoading
+ const EXPLORE_PRICE_SOURCES = isV4EverywhereEnabled ? EXPLORE_PRICE_SOURCES_V4 : EXPLORE_PRICE_SOURCES_V3
const refitChartContent = useAtomValue(refitChartContentAtom)
function timeGranularityToHistoryDuration(timePeriod: TimePeriod): HistoryDuration {
@@ -94,43 +93,36 @@ function VolumeChartSection({ chainId }: { chainId: UniverseChainId }) {
}
}
- const {
- entries: gqlEntries,
- loading: gqlLoading,
- dataQuality: gqlDataQuality,
- } = useHistoricalProtocolVolume(
- chainIdToBackendChain({ chainId, withFallback: true }),
+ const { entries, loading, dataQuality } = useRestHistoricalProtocolVolume(
isSmallScreen ? HistoryDuration.Month : timeGranularityToHistoryDuration(timePeriod),
)
- const {
- entries: restEntries,
- loading: restLoading,
- dataQuality: restDataQuality,
- } = useRestHistoricalProtocolVolume(
- isSmallScreen ? HistoryDuration.Month : timeGranularityToHistoryDuration(timePeriod),
+ const protocolColors = useMemo(
+ () =>
+ isV4EverywhereEnabled
+ ? [
+ getProtocolColor(PriceSource.SubgraphV4, theme),
+ getProtocolColor(PriceSource.SubgraphV3, theme),
+ getProtocolColor(PriceSource.SubgraphV2, theme),
+ ]
+ : [getProtocolColor(PriceSource.SubgraphV3, theme), getProtocolColor(PriceSource.SubgraphV2, theme)],
+ [isV4EverywhereEnabled, theme],
)
- const isRestExploreEnabled = useFeatureFlag(FeatureFlags.RestExplore)
- const { entries, loading, dataQuality } = isRestExploreEnabled
- ? { entries: restEntries, loading: restLoading, dataQuality: restDataQuality }
- : { entries: gqlEntries, loading: gqlLoading, dataQuality: gqlDataQuality }
const params = useMemo<{
data: StackedHistogramData[]
- colors: [string, string]
+ colors: string[]
useThinCrosshair: boolean
headerHeight: number
- isMultichainExploreEnabled: boolean
background: string
}>(
() => ({
data: entries,
- colors: [theme.accent1, theme.accent3],
- headerHeight: isMultichainExploreEnabled ? 0 : 80,
+ colors: protocolColors,
+ headerHeight: 0,
stale: dataQuality === DataQuality.STALE,
- useThinCrosshair: isMultichainExploreEnabled,
- isMultichainExploreEnabled,
+ useThinCrosshair: true,
background: theme.background,
}),
- [entries, theme.accent1, theme.accent3, theme.background, isMultichainExploreEnabled, dataQuality],
+ [entries, protocolColors, dataQuality, theme.background],
)
const cumulativeVolume = useMemo(() => getCumulativeVolume(entries), [entries])
@@ -194,30 +186,23 @@ function VolumeChartSection({ chainId }: { chainId: UniverseChainId }) {
)
}
-function TVLChartSection({ chainId }: { chainId: UniverseChainId }) {
+function TVLChartSection() {
const theme = useTheme()
- const isMultichainExploreEnabled = useFeatureFlag(FeatureFlags.MultichainExplore)
- const {
- entries: gqlEntries,
- loading: gqlLoading,
- dataQuality: gqlDataQuality,
- } = useDailyProtocolTVL(chainIdToBackendChain({ chainId }))
- const { entries: restEntries, loading: restLoading, dataQuality: restDataQuality } = useRestDailyProtocolTVL()
- const isRestExploreEnabled = useFeatureFlag(FeatureFlags.RestExplore)
- const { entries, loading, dataQuality } = isRestExploreEnabled
- ? { entries: restEntries, loading: restLoading, dataQuality: restDataQuality }
- : { entries: gqlEntries, loading: gqlLoading, dataQuality: gqlDataQuality }
+ const { value: isV4EverywhereEnabledLoaded, isLoading: isV4EverywhereLoading } = useFeatureFlagWithLoading(
+ FeatureFlags.V4Everywhere,
+ )
+ const isV4EverywhereEnabled = isV4EverywhereEnabledLoaded || isV4EverywhereLoading
+ const EXPLORE_PRICE_SOURCES = isV4EverywhereEnabled ? EXPLORE_PRICE_SOURCES_V4 : EXPLORE_PRICE_SOURCES_V3
+ const { entries, loading, dataQuality } = useRestDailyProtocolTVL()
const lastEntry = entries[entries.length - 1]
const params = useMemo(
() => ({
data: entries,
colors: EXPLORE_PRICE_SOURCES?.map((source) => getProtocolColor(source, theme)) ?? [theme.accent1],
- gradients: isMultichainExploreEnabled
- ? EXPLORE_PRICE_SOURCES?.map((source) => getProtocolGradient(source))
- : undefined,
+ gradients: EXPLORE_PRICE_SOURCES?.map((source) => getProtocolGradient(source)),
}),
- [entries, isMultichainExploreEnabled, theme],
+ [EXPLORE_PRICE_SOURCES, entries, theme],
)
const isSmallScreen = !useScreenSize()['sm']
@@ -273,12 +258,10 @@ function MinimalStatDisplay({ title, value, time }: { title: ReactNode; value: n
}
export function ExploreChartsSection() {
- const chain = getSupportedGraphQlChain(useChainFromUrlParam(), { fallbackToEthereum: true })
-
return (
-
-
+
+
)
}
diff --git a/apps/web/src/pages/Explore/index.tsx b/apps/web/src/pages/Explore/index.tsx
index 918e5f69447..7aa1b82146d 100644
--- a/apps/web/src/pages/Explore/index.tsx
+++ b/apps/web/src/pages/Explore/index.tsx
@@ -6,9 +6,8 @@ import SearchBar from 'components/Tokens/TokenTable/SearchBar'
import VolumeTimeFrameSelector from 'components/Tokens/TokenTable/VolumeTimeFrameSelector'
import { MAX_WIDTH_MEDIA_BREAKPOINT } from 'components/Tokens/constants'
import { MouseoverTooltip, TooltipSize } from 'components/Tooltip'
-import { useChainFromUrlParam } from 'constants/chains'
import { manualChainOutageAtom } from 'featureFlags/flags/outageBanner'
-import { getTokenExploreURL, isBackendSupportedChain } from 'graphql/data/util'
+import { getTokenExploreURL } from 'graphql/data/util'
import { useOnGlobalChainSwitch } from 'hooks/useGlobalChainSwitch'
import { useResetAtom } from 'jotai/utils'
import { ExploreChartsSection } from 'pages/Explore/charts/ExploreChartsSection'
@@ -18,13 +17,15 @@ import { NamedExoticComponent, useCallback, useEffect, useMemo, useRef, useState
import { useNavigate } from 'react-router-dom'
import { ExploreContextProvider } from 'state/explore'
import { TamaguiClickableStyle } from 'theme/components'
-import { Flex, Text, styled as tamaguiStyled } from 'ui/src'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { Button, Flex, Text, styled as tamaguiStyled } from 'ui/src'
+import { Plus } from 'ui/src/components/icons/Plus'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { isBackendSupportedChain } from 'uniswap/src/features/chains/utils'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
-import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { Trans, t } from 'uniswap/src/i18n'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
export enum ExploreTab {
Tokens = 'tokens',
@@ -62,8 +63,7 @@ const Pages: Array = [
const HeaderTab = tamaguiStyled(Text, {
...TamaguiClickableStyle,
- fontSize: 28,
- fontWeight: '$book',
+ variant: 'heading3',
userSelect: 'none',
color: '$neutral2',
variants: {
@@ -93,7 +93,7 @@ const HeaderTab = tamaguiStyled(Text, {
const Explore = ({ initialTab }: { initialTab?: ExploreTab }) => {
const tabNavRef = useRef(null)
const resetManualOutage = useResetAtom(manualChainOutageAtom)
- const isMultichainExploreEnabled = useFeatureFlag(FeatureFlags.MultichainExplore)
+ const v4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
const initialKey: number = useMemo(() => {
const key = initialTab && Pages.findIndex((page) => page.key === initialTab)
@@ -109,9 +109,7 @@ const Explore = ({ initialTab }: { initialTab?: ExploreTab }) => {
const offsetTop = tabNavRef.current.getBoundingClientRect().top + window.scrollY
window.scrollTo({ top: offsetTop - 90, behavior: 'smooth' })
}
- // scroll to tab navbar on initial page mount only
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [])
+ }, [initialTab])
const [currentTab, setCurrentTab] = useState(initialKey)
@@ -119,12 +117,10 @@ const Explore = ({ initialTab }: { initialTab?: ExploreTab }) => {
const { tab: tabName } = useExploreParams()
const tab = tabName ?? ExploreTab.Tokens
- const chainWithoutFallback = useChainFromUrlParam()
- const chain = useMemo(() => {
- return isMultichainExploreEnabled
- ? chainWithoutFallback
- : chainWithoutFallback ?? UNIVERSE_CHAIN_INFO[UniverseChainId.Mainnet]
- }, [chainWithoutFallback, isMultichainExploreEnabled])
+ const urlChainId = useChainIdFromUrlParam()
+ const chainInfo = useMemo(() => {
+ return urlChainId ? getChainInfo(urlChainId) : undefined
+ }, [urlChainId])
useEffect(() => {
const tabIndex = Pages.findIndex((page) => page.key === tab)
if (tabIndex !== -1) {
@@ -149,8 +145,12 @@ const Explore = ({ initialTab }: { initialTab?: ExploreTab }) => {
)
return (
-
-
+
+
{
>
{Pages.map(({ title, loggingElementName, key }, index) => {
// disable Transactions tab if no chain is selected
- const disabled = isMultichainExploreEnabled && key === ExploreTab.Transactions && !chain
- const url = getTokenExploreURL({ tab: key, chain: chain?.backendChain.chain })
+ const disabled = key === ExploreTab.Transactions && !chainInfo
return (
{
disabled={!disabled}
>
!disabled && navigate(url)}
+ onPress={() => {
+ // Update tab and only replace url when navigating from the header nav
+ !disabled && setCurrentTab(index)
+ }}
active={currentTab === index}
disabled={disabled}
key={key}
@@ -211,6 +213,22 @@ const Explore = ({ initialTab }: { initialTab?: ExploreTab }) => {
})}
+ {currentKey === ExploreTab.Pools && v4EverywhereEnabled && (
+ navigate('/positions/create')}
+ >
+
+
+
+ {t('common.addLiquidity')}
+
+
+
+ )}
{currentKey === ExploreTab.Tokens && }
{currentKey !== ExploreTab.Transactions && }
diff --git a/apps/web/src/pages/Explore/tables/RecentTransactions.tsx b/apps/web/src/pages/Explore/tables/RecentTransactions.tsx
index 24bf84000ca..67536218825 100644
--- a/apps/web/src/pages/Explore/tables/RecentTransactions.tsx
+++ b/apps/web/src/pages/Explore/tables/RecentTransactions.tsx
@@ -11,20 +11,22 @@ import {
TimestampCell,
TokenLinkCell,
} from 'components/Table/styled'
-import { useChainFromUrlParam } from 'constants/chains'
import { useUpdateManualOutage } from 'featureFlags/flags/outageBanner'
import { BETypeToTransactionType, TransactionType, useAllTransactions } from 'graphql/data/useAllTransactions'
-import { OrderDirection, getSupportedGraphQlChain } from 'graphql/data/util'
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
+import { OrderDirection } from 'graphql/data/util'
import { memo, useMemo, useReducer, useRef, useState } from 'react'
import { Flex, Text, styled } from 'ui/src'
import {
PoolTransaction,
PoolTransactionType,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
import { Trans } from 'uniswap/src/i18n'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { shortenAddress } from 'utilities/src/addresses'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
import { useFormatter } from 'utils/formatNumbers'
const TableRow = styled(Flex, {
@@ -34,7 +36,7 @@ const TableRow = styled(Flex, {
})
const RecentTransactions = memo(function RecentTransactions() {
- const activeLocalCurrency = useActiveLocalCurrency()
+ const activeLocalCurrency = useAppFiatCurrency()
const { formatNumber, formatFiatPrice } = useFormatter()
const [filterModalIsOpen, toggleFilterModal] = useReducer((s) => !s, false)
const filterAnchorRef = useRef(null)
@@ -43,16 +45,16 @@ const RecentTransactions = memo(function RecentTransactions() {
TransactionType.REMOVE,
TransactionType.ADD,
])
- const chain = getSupportedGraphQlChain(useChainFromUrlParam(), { fallbackToEthereum: true })
+ const chainInfo = getChainInfo(useChainIdFromUrlParam() ?? UniverseChainId.Mainnet)
- const { transactions, loading, loadMore, errorV2, errorV3 } = useAllTransactions(chain.backendChain.chain, filter)
+ const { transactions, loading, loadMore, errorV2, errorV3 } = useAllTransactions(chainInfo.backendChain.chain, filter)
const combinedError =
errorV2 && errorV3
- ? new ApolloError({ errorMessage: `Could not retrieve V2 and V3 Transactions for chain: ${chain.id}` })
+ ? new ApolloError({ errorMessage: `Could not retrieve V2 and V3 Transactions for chain: ${chainInfo.id}` })
: undefined
const allDataStillLoading = loading && !transactions.length
const showLoadingSkeleton = allDataStillLoading || !!combinedError
- useUpdateManualOutage({ chainId: chain.id, errorV3, errorV2 })
+ useUpdateManualOutage({ chainId: chainInfo.id, errorV3, errorV2 })
// TODO(WEB-3236): once GQL BE Transaction query is supported add usd, token0 amount, and token1 amount sort support
const columns = useMemo(() => {
const columnHelper = createColumnHelper()
@@ -73,7 +75,7 @@ const RecentTransactions = memo(function RecentTransactions() {
|
),
@@ -205,14 +207,16 @@ const RecentTransactions = memo(function RecentTransactions() {
),
cell: (makerAddress) => (
-
+
{shortenAddress(makerAddress.getValue?.())}
|
),
}),
]
- }, [activeLocalCurrency, chain.id, filter, filterModalIsOpen, formatFiatPrice, formatNumber, showLoadingSkeleton])
+ }, [activeLocalCurrency, chainInfo.id, filter, filterModalIsOpen, formatFiatPrice, formatNumber, showLoadingSkeleton])
return (
{
- setAddLiquidityState((prev) => ({
+ setIncreaseLiquidityState((prev) => ({
...prev,
exactField: field,
exactAmount: newValue,
@@ -40,7 +44,7 @@ export function IncreaseLiquidityForm() {
}
const handleOnSetMax = (field: PositionField, amount: string) => {
- setAddLiquidityState((prev) => ({
+ setIncreaseLiquidityState((prev) => ({
...prev,
exactField: field,
exactAmount: amount,
@@ -48,13 +52,18 @@ export function IncreaseLiquidityForm() {
}
// TODO(WEB-4978): account for gas in this calculation once we have the gasfee
+ const insufficientToken0Balance =
+ currencyBalances?.TOKEN0 && currencyAmounts?.TOKEN0?.greaterThan(currencyBalances.TOKEN0)
+ const insufficientToken1Balance =
+ currencyBalances?.TOKEN1 && currencyAmounts?.TOKEN1?.greaterThan(currencyBalances.TOKEN1)
+
const disableContinue =
!currencyAmounts?.TOKEN0 ||
!currencyBalances?.TOKEN0 ||
- currencyAmounts.TOKEN0.greaterThan(currencyBalances.TOKEN0) ||
+ insufficientToken0Balance ||
!currencyAmounts?.TOKEN1 ||
!currencyBalances.TOKEN1 ||
- currencyAmounts?.TOKEN1?.greaterThan(currencyBalances.TOKEN1)
+ insufficientToken1Balance
const handleOnContinue = () => {
if (!disableContinue) {
@@ -62,6 +71,15 @@ export function IncreaseLiquidityForm() {
}
}
+ const errorText =
+ insufficientToken0Balance && insufficientToken1Balance
+ ? t('common.insufficientBalance.error')
+ : insufficientToken0Balance || insufficientToken1Balance
+ ? t('common.insufficientTokenBalance.error', {
+ tokenSymbol: insufficientToken0Balance ? token0.symbol : token1.symbol,
+ })
+ : undefined
+
return (
<>
@@ -75,6 +93,8 @@ export function IncreaseLiquidityForm() {
currencyBalances={currencyBalances}
onUserInput={handleUserInput}
onSetMax={handleOnSetMax}
+ deposit0Disabled={deposit0Disabled}
+ deposit1Disabled={deposit1Disabled}
/>
-
- {t('common.add.label')}
-
+
+ {errorText || t('common.add.label')}
+
>
)
}
diff --git a/apps/web/src/pages/Landing/assets/approvedTokens.ts b/apps/web/src/pages/Landing/assets/approvedTokens.ts
index cd9332b988b..305b6e182f5 100644
--- a/apps/web/src/pages/Landing/assets/approvedTokens.ts
+++ b/apps/web/src/pages/Landing/assets/approvedTokens.ts
@@ -88,13 +88,14 @@ export const approvedERC20: InteractiveToken[] = [
'https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0F5D2fB29fb7d3CFeE444a200298f468908cC942/logo.png',
},
{
- name: 'Matic',
- symbol: 'MATIC',
+ name: 'Polygon',
+ symbol: 'POL',
address: '0x0000000000000000000000000000000000001010',
chain: Chain.Polygon,
standard: TokenStandard.ERC20,
color: '#833ADD',
- logoUrl: 'https://app.uniswap.org/static/media/matic-token-icon.efed2ee4e843195b44bf68ffc7439403.svg',
+ logoUrl:
+ 'https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/polygon/assets/0x0000000000000000000000000000000000001010/logo.png',
},
{
name: 'Moss Carbon Credit',
diff --git a/apps/web/src/pages/Landing/components/cards/WebappCard.tsx b/apps/web/src/pages/Landing/components/cards/WebappCard.tsx
index 00e1e03dc41..c1ada6ae257 100644
--- a/apps/web/src/pages/Landing/components/cards/WebappCard.tsx
+++ b/apps/web/src/pages/Landing/components/cards/WebappCard.tsx
@@ -1,6 +1,5 @@
import { PortfolioLogo } from 'components/AccountDrawer/MiniPortfolio/PortfolioLogo'
import { DeltaArrow } from 'components/Tokens/TokenDetails/Delta'
-import { chainIdToBackendChain } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { getTokenDetailsURL } from 'graphql/data/util'
import { useCurrency } from 'hooks/Tokens'
@@ -12,8 +11,9 @@ import { useNavigate } from 'react-router-dom'
import { Flex, Text } from 'ui/src'
import { LDO, UNI, USDC_BASE } from 'uniswap/src/constants/tokens'
import { useTokenPromoQuery } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const primary = '#2ABDFF'
@@ -45,7 +45,7 @@ function Token({ chainId, address }: { chainId: UniverseChainId; address: string
const tokenPromoQuery = useTokenPromoQuery({
variables: {
address: currency?.wrapped.address,
- chain: chainIdToBackendChain({ chainId }),
+ chain: toGraphQLChain(chainId),
},
})
const price = tokenPromoQuery.data?.token?.market?.price?.value ?? 0
@@ -68,7 +68,7 @@ function Token({ chainId, address }: { chainId: UniverseChainId; address: string
navigate(
getTokenDetailsURL({
address: address === 'ETH' ? NATIVE_CHAIN_ID : address,
- chain: chainIdToBackendChain({ chainId }),
+ chain: toGraphQLChain(chainId),
}),
)
}}
diff --git a/apps/web/src/pages/Landing/index.tsx b/apps/web/src/pages/Landing/index.tsx
index e04641f1b50..2dd11f913e5 100644
--- a/apps/web/src/pages/Landing/index.tsx
+++ b/apps/web/src/pages/Landing/index.tsx
@@ -25,8 +25,20 @@ export default function Landing() {
const accountDrawer = useAccountDrawer()
const prevAccount = usePrevious(account.address)
const redirectOnConnect = useRef(false)
+
+ const isInitialRender = useRef(true)
+
// Smoothly redirect to swap page if user connects while on landing page
useEffect(() => {
+ // Skip logic on the first render because prevAccount will always be undefined on the first render
+ // and we don't want to redirect on the first render because that mean's we're possibly coming from
+ // another page in the app.
+ // We need to wait until future renders to check if the user connected while on the landing page.
+ if (isInitialRender.current) {
+ isInitialRender.current = false
+ return undefined
+ }
+
if (accountDrawer.isOpen && account.address && !prevAccount) {
redirectOnConnect.current = true
setTransition(true)
diff --git a/apps/web/src/pages/Landing/sections/Hero.tsx b/apps/web/src/pages/Landing/sections/Hero.tsx
index 5343500d8cf..6c6d85016fa 100644
--- a/apps/web/src/pages/Landing/sections/Hero.tsx
+++ b/apps/web/src/pages/Landing/sections/Hero.tsx
@@ -9,10 +9,10 @@ import { ChevronDown } from 'react-feather'
import { useNavigate } from 'react-router-dom'
import { serializeSwapStateToURLParameters } from 'state/swap/hooks'
import { Flex, Text } from 'ui/src'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { SwapRedirectFn } from 'uniswap/src/features/transactions/TransactionModal/TransactionModalContext'
import { Trans, useTranslation } from 'uniswap/src/i18n'
import { INTERFACE_NAV_HEIGHT } from 'uniswap/src/theme/heights'
-import { UniverseChainId } from 'uniswap/src/types/chains'
interface HeroProps {
scrollToRef: () => void
diff --git a/apps/web/src/pages/LegacyPool/CTACards.tsx b/apps/web/src/pages/LegacyPool/CTACards.tsx
index faf24bec1c5..d73bc91475b 100644
--- a/apps/web/src/pages/LegacyPool/CTACards.tsx
+++ b/apps/web/src/pages/LegacyPool/CTACards.tsx
@@ -1,11 +1,11 @@
import { AutoColumn } from 'components/deprecated/Column'
-import { useSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import styled, { css } from 'lib/styled-components'
import { ExternalLink, StyledInternalLink, ThemedText } from 'theme/components'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
const CTASection = styled.section`
display: grid;
@@ -71,7 +71,7 @@ const ResponsiveColumn = styled(AutoColumn)`
export default function CTACards() {
const { chainId } = useAccount()
- const chain = UNIVERSE_CHAIN_INFO[useSupportedChainId(chainId) ?? UniverseChainId.Mainnet]
+ const chain = getChainInfo(useSupportedChainId(chainId) ?? UniverseChainId.Mainnet)
return (
diff --git a/apps/web/src/pages/LegacyPool/PositionPage.tsx b/apps/web/src/pages/LegacyPool/PositionPage.tsx
index 4e8ef046bb3..50b90911bbf 100644
--- a/apps/web/src/pages/LegacyPool/PositionPage.tsx
+++ b/apps/web/src/pages/LegacyPool/PositionPage.tsx
@@ -18,7 +18,6 @@ import TransactionConfirmationModal, { ConfirmationModalContent } from 'componen
import { AutoColumn } from 'components/deprecated/Column'
import { RowBetween, RowFixed } from 'components/deprecated/Row'
import { Dots } from 'components/swap/styled'
-import { chainIdToBackendChain, useIsSupportedChainId, useSupportedChainId } from 'constants/chains'
import { getPoolDetailsURL, getTokenDetailsURL, isGqlSupportedChain } from 'graphql/data/util'
import { useToken } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
@@ -42,10 +41,12 @@ import { useIsTransactionPending, useTransactionAdder } from 'state/transactions
import { TransactionType } from 'state/transactions/types'
import { ClickableStyle, ExternalLink, HideExtraSmall, HideSmall, StyledRouterLink, ThemedText } from 'theme/components'
import { Switch, Text } from 'ui/src'
+import { useEnabledChains, useIsSupportedChainId, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans, t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { logger } from 'utilities/src/logger/logger'
import { calculateGasMargin } from 'utils/calculateGasMargin'
@@ -204,7 +205,7 @@ const TokenLink = ({
chainId,
address,
}: PropsWithChildren<{ chainId: UniverseChainId; address: string }>) => {
- const tokenLink = getTokenDetailsURL({ address, chain: chainIdToBackendChain({ chainId }) })
+ const tokenLink = getTokenDetailsURL({ address, chain: toGraphQLChain(chainId) })
return {children}
}
@@ -333,6 +334,8 @@ function PositionPageContent() {
const theme = useTheme()
const { formatCurrencyAmount, formatDelta, formatTickPrice } = useFormatter()
+ const { defaultChainId } = useEnabledChains()
+
const parsedTokenId = parseTokenId(tokenIdFromUrl)
const { loading, position: positionDetails } = useV3PositionFromTokenId(parsedTokenId)
@@ -653,10 +656,7 @@ function PositionPageContent() {
diff --git a/apps/web/src/pages/LegacyPool/index.test.tsx b/apps/web/src/pages/LegacyPool/index.test.tsx
index 0a385491591..9ee92ace678 100644
--- a/apps/web/src/pages/LegacyPool/index.test.tsx
+++ b/apps/web/src/pages/LegacyPool/index.test.tsx
@@ -1,15 +1,31 @@
-import { useIsSupportedChainId } from 'constants/chains'
import { useFilterPossiblyMaliciousPositions } from 'hooks/useFilterPossiblyMaliciousPositions'
import { useV3Positions } from 'hooks/useV3Positions'
import Pool from 'pages/LegacyPool'
import { mocked } from 'test-utils/mocked'
import { render, screen } from 'test-utils/render'
+import { useEnabledChains, useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
-jest.mock('constants/chains')
+jest.mock('uniswap/src/features/chains/hooks', () => ({
+ useEnabledChains: jest.fn(),
+ useSupportedChainId: jest.fn(),
+ useSupportedChainIdWithConnector: jest.fn(),
+ useIsSupportedChainId: jest.fn(),
+}))
jest.mock('hooks/useV3Positions')
jest.mock('hooks/useFilterPossiblyMaliciousPositions')
describe('networks', () => {
+ beforeEach(() => {
+ mocked(useEnabledChains).mockReturnValue({
+ isTestnetModeEnabled: false,
+ chains: [],
+ gqlChains: [],
+ defaultChainId: UniverseChainId.Mainnet,
+ })
+ mocked(useIsSupportedChainId).mockReturnValue(true)
+ })
+
it('renders error card when unsupported chain is selected', async () => {
mocked(useIsSupportedChainId).mockReturnValue(false)
mocked(useV3Positions).mockReturnValue({ loading: false, positions: undefined })
diff --git a/apps/web/src/pages/LegacyPool/index.tsx b/apps/web/src/pages/LegacyPool/index.tsx
index 83948e0edec..bc06c770b61 100644
--- a/apps/web/src/pages/LegacyPool/index.tsx
+++ b/apps/web/src/pages/LegacyPool/index.tsx
@@ -1,11 +1,10 @@
import { InterfaceElementName, InterfaceEventName, InterfacePageName } from '@uniswap/analytics-events'
import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks'
import { ButtonPrimary, ButtonText } from 'components/Button/buttons'
-import { AutoColumn } from 'components/deprecated/Column'
import { DropdownSelector } from 'components/DropdownSelector'
import PositionList from 'components/PositionList'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
-import { useIsSupportedChainId } from 'constants/chains'
+import { AutoColumn } from 'components/deprecated/Column'
import { useAccount } from 'hooks/useAccount'
import { useFilterPossiblyMaliciousPositions } from 'hooks/useFilterPossiblyMaliciousPositions'
import { useNetworkSupportsV2 } from 'hooks/useNetworkSupportsV2'
@@ -20,8 +19,9 @@ import { Link } from 'react-router-dom'
import { useUserHideClosedPositions } from 'state/user/hooks'
import { HideSmall, ThemedText } from 'theme/components'
import { PositionDetails } from 'types/position'
-import { Anchor, Flex, styled, Text } from 'ui/src'
+import { Anchor, Flex, Text, styled } from 'ui/src'
import { ProtocolVersion } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { t, useTranslation } from 'uniswap/src/i18n'
diff --git a/apps/web/src/pages/LegacyPool/redirects.tsx b/apps/web/src/pages/LegacyPool/redirects.tsx
new file mode 100644
index 00000000000..facfe3f1e87
--- /dev/null
+++ b/apps/web/src/pages/LegacyPool/redirects.tsx
@@ -0,0 +1,58 @@
+import LegacyPool from 'pages/LegacyPool'
+import LegacyPositionPage from 'pages/LegacyPool/PositionPage'
+import LegacyPoolV2 from 'pages/LegacyPool/v2'
+import PoolFinder from 'pages/PoolFinder'
+import { Navigate, useParams, useSearchParams } from 'react-router-dom'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+import { searchParamToBackendName } from 'utils/chainParams'
+import { useAccount } from 'wagmi'
+
+// /pool
+export function LegacyPoolRedirects() {
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+
+ if (isV4EverywhereEnabled) {
+ return
+ }
+ return
+}
+
+// /pool/v2
+export function LegacyPoolV2Redirects() {
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+
+ if (isV4EverywhereEnabled) {
+ return
+ }
+ return
+}
+
+// /pool/v2/find
+export function PoolFinderRedirects() {
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+
+ if (isV4EverywhereEnabled) {
+ return
+ }
+ return
+}
+
+// /pool/:tokenId?chain=...
+export function LegacyPositionPageRedirects() {
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+ const { tokenId } = useParams<{ tokenId: string }>()
+ const [searchParams] = useSearchParams()
+ const { chainId: connectedChainId } = useAccount()
+ const { defaultChainId } = useEnabledChains()
+
+ if (isV4EverywhereEnabled) {
+ const chainName =
+ searchParamToBackendName(searchParams.get('chain'))?.toLowerCase() ??
+ toGraphQLChain(connectedChainId ?? defaultChainId).toLowerCase()
+ return
+ }
+ return
+}
diff --git a/apps/web/src/pages/MigrateV2/MigrateV2Pair.tsx b/apps/web/src/pages/MigrateV2/MigrateV2Pair.tsx
index 1087d6d1045..2e264cbf7c4 100644
--- a/apps/web/src/pages/MigrateV2/MigrateV2Pair.tsx
+++ b/apps/web/src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -44,9 +44,9 @@ import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
import { BackArrowLink, ExternalLink, ThemedText } from 'theme/components'
import { Text } from 'ui/src'
import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans, t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
import { isAddress } from 'utilities/src/addresses'
import { logger } from 'utilities/src/logger/logger'
diff --git a/apps/web/src/pages/MigrateV3/index.tsx b/apps/web/src/pages/MigrateV3/index.tsx
index 5d459e15557..6659ce54a9f 100644
--- a/apps/web/src/pages/MigrateV3/index.tsx
+++ b/apps/web/src/pages/MigrateV3/index.tsx
@@ -8,7 +8,6 @@ import { PositionInfo } from 'components/Liquidity/types'
import { parseRestPosition } from 'components/Liquidity/utils'
import { LoadingRows } from 'components/Loader/styled'
import { PoolProgressIndicator } from 'components/PoolProgressIndicator/PoolProgressIndicator'
-import { useChainFromUrlParam } from 'constants/chains'
import useSelectChain from 'hooks/useSelectChain'
import { MigrateV3PositionTxContextProvider, useMigrateV3TxContext } from 'pages/MigrateV3/MigrateV3LiquidityTxContext'
import {
@@ -16,11 +15,17 @@ import {
DepositContextProvider,
PriceRangeContextProvider,
} from 'pages/Pool/Positions/create/ContextProviders'
-import { useCreatePositionContext } from 'pages/Pool/Positions/create/CreatePositionContext'
+import {
+ DEFAULT_DEPOSIT_STATE,
+ DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS,
+ useCreatePositionContext,
+ useDepositContext,
+ usePriceRangeContext,
+} from 'pages/Pool/Positions/create/CreatePositionContext'
import { EditSelectTokensStep } from 'pages/Pool/Positions/create/EditStep'
import { SelectPriceRangeStep } from 'pages/Pool/Positions/create/RangeSelectionStep'
import { SelectTokensStep } from 'pages/Pool/Positions/create/SelectTokenStep'
-import { PositionFlowStep } from 'pages/Pool/Positions/create/types'
+import { DEFAULT_POSITION_STATE, PositionFlowStep } from 'pages/Pool/Positions/create/types'
import { LoadingRow } from 'pages/Pool/Positions/shared'
import { useMemo, useState } from 'react'
import { ChevronRight } from 'react-feather'
@@ -29,7 +34,7 @@ import { Navigate, useParams } from 'react-router-dom'
import { liquiditySaga } from 'state/sagas/liquidity/liquiditySaga'
import { ClickableTamaguiStyle } from 'theme/components'
import { PositionField } from 'types/position'
-import { Flex, Main, Text, styled } from 'ui/src'
+import { Flex, Main, Text, styled, useMedia } from 'ui/src'
import { ArrowDown } from 'ui/src/components/icons/ArrowDown'
import { RotateLeft } from 'ui/src/components/icons/RotateLeft'
import { ProgressIndicator } from 'uniswap/src/components/ConfirmSwapModal/ProgressIndicator'
@@ -44,6 +49,7 @@ import { isValidLiquidityTxContext } from 'uniswap/src/features/transactions/liq
import { useUSDCValue } from 'uniswap/src/features/transactions/swap/hooks/useUSDCPrice'
import { TransactionStep } from 'uniswap/src/features/transactions/swap/types/steps'
import { Trans, useTranslation } from 'uniswap/src/i18n'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
import { useAccount } from 'wagmi'
const BodyWrapper = styled(Main, {
@@ -59,10 +65,14 @@ const BodyWrapper = styled(Main, {
})
function MigrateV3Inner({ positionInfo }: { positionInfo: PositionInfo }) {
- const { positionId } = useParams<{ positionId: string }>()
+ const { chainName, tokenId } = useParams<{ tokenId: string; chainName: string }>()
+
const { t } = useTranslation()
- const { step, setStep } = useCreatePositionContext()
+ const { positionState, setPositionState, setStep, step } = useCreatePositionContext()
+ const { protocolVersion } = positionState
+ const { setPriceRangeState } = usePriceRangeContext()
+ const { setDepositState } = useDepositContext()
const { value: v4Enabled, isLoading: isV4GateLoading } = useFeatureFlagWithLoading(FeatureFlags.V4Everywhere)
const [transactionSteps, setTransactionSteps] = useState([])
@@ -74,6 +84,7 @@ function MigrateV3Inner({ positionInfo }: { positionInfo: PositionInfo }) {
const account = useAccountMeta()
const dispatch = useDispatch()
const { txInfo } = useMigrateV3TxContext()
+ const media = useMedia()
const onClose = () => {
setCurrentTransactionStep(undefined)
@@ -92,33 +103,20 @@ function MigrateV3Inner({ positionInfo }: { positionInfo: PositionInfo }) {
}
return (
-
-
- {/* nav breadcrumbs */}
-
-
-
-
-
-
- {currency0Amount.currency.symbol} / {currency1Amount.currency.symbol}
-
-
-
-
-
-
-
-
-
-
- {/* TODO: replace with Spore button once available */}
+ <>
+
+
+
+
+
+
+ {currency0Amount.currency.symbol} / {currency1Amount.currency.symbol}
+
+
+
+
+
+
{
+ setPositionState({
+ ...DEFAULT_POSITION_STATE,
+ protocolVersion,
+ currencyInputs: {
+ [PositionField.TOKEN0]: currency0Amount.currency,
+ [PositionField.TOKEN1]: currency1Amount.currency,
+ },
+ })
+ setPriceRangeState(DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS)
+ setDepositState(DEFAULT_DEPOSIT_STATE)
setStep(PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER)
}}
>
@@ -139,50 +147,64 @@ function MigrateV3Inner({ positionInfo }: { positionInfo: PositionInfo }) {
-
-
-
-
+
+ {!media.xl && (
+
+
+
+ )}
+
+
+
+
+
+
+
+ {step === PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER ? (
+ {
+ setStep(PositionFlowStep.PRICE_RANGE)
+ }}
+ />
+ ) : (
+
+ )}
+ {step === PositionFlowStep.PRICE_RANGE && (
+ {
+ const isValidTx = isValidLiquidityTxContext(txInfo)
+ if (!account || account?.type !== AccountType.SignerMnemonic || !isValidTx) {
+ return
+ }
+ dispatch(
+ liquiditySaga.actions.trigger({
+ selectChain,
+ startChainId,
+ account,
+ liquidityTxContext: txInfo,
+ setCurrentStep: setCurrentTransactionStep,
+ setSteps: setTransactionSteps,
+ onSuccess: onClose,
+ onFailure: onClose,
+ }),
+ )
+ }}
+ />
+ )}
-
- {step === PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER ? (
- {
- setStep(PositionFlowStep.PRICE_RANGE)
- }}
- />
- ) : (
-
- )}
- {step === PositionFlowStep.PRICE_RANGE && (
- {
- const isValidTx = isValidLiquidityTxContext(txInfo)
- if (!account || account?.type !== AccountType.SignerMnemonic || !isValidTx) {
- return
- }
- dispatch(
- liquiditySaga.actions.trigger({
- selectChain,
- startChainId,
- account,
- liquidityTxContext: txInfo,
- setCurrentStep: setCurrentTransactionStep,
- setSteps: setTransactionSteps,
- onSuccess: onClose,
- onFailure: onClose,
- }),
- )
- }}
- />
- )}
+
-
+ >
)
}
@@ -208,7 +230,7 @@ function MigrateV3Inner({ positionInfo }: { positionInfo: PositionInfo }) {
*/
export default function MigrateV3() {
const { tokenId } = useParams<{ tokenId: string }>()
- const chainInfo = useChainFromUrlParam()
+ const chainId = useChainIdFromUrlParam()
const account = useAccount()
const { data, isLoading: positionLoading } = useGetPositionQuery(
account.address
@@ -216,7 +238,7 @@ export default function MigrateV3() {
owner: account.address,
protocolVersion: ProtocolVersion.V3,
tokenId,
- chainId: chainInfo?.id ?? account.chainId,
+ chainId: chainId ?? account.chainId,
}
: undefined,
)
diff --git a/apps/web/src/pages/NotFound/index.tsx b/apps/web/src/pages/NotFound/index.tsx
index 30f1e4109e4..036364107b3 100644
--- a/apps/web/src/pages/NotFound/index.tsx
+++ b/apps/web/src/pages/NotFound/index.tsx
@@ -4,6 +4,7 @@ import lightImage from 'assets/images/404-page-light.png'
import { SmallButtonPrimary } from 'components/Button/buttons'
import { useIsMobile } from 'hooks/screenSize/useIsMobile'
import styled from 'lib/styled-components'
+import { ReactNode } from 'react'
import { Link } from 'react-router-dom'
import { ThemedText } from 'theme/components'
import { useIsDarkMode } from 'theme/components/ThemeToggle'
@@ -37,7 +38,13 @@ const PageWrapper = styled(Container)`
}
`
-export default function NotFound() {
+interface NotFoundProps {
+ title?: ReactNode
+ subtitle?: ReactNode
+ actionButton?: ReactNode
+}
+
+export default function NotFound({ title, subtitle, actionButton }: NotFoundProps) {
const isDarkMode = useIsDarkMode()
const isMobile = useIsMobile()
@@ -49,16 +56,20 @@ export default function NotFound() {
- 404
-
-
-
+ {title ?? 404}
+ {subtitle ?? (
+
+
+
+ )}
-
-
-
+ {actionButton ?? (
+
+
+
+ )}
)
diff --git a/apps/web/src/pages/Pool/Positions/ClaimFeeModal.tsx b/apps/web/src/pages/Pool/Positions/ClaimFeeModal.tsx
index 1fa75cbf8c8..d2b51ff5da3 100644
--- a/apps/web/src/pages/Pool/Positions/ClaimFeeModal.tsx
+++ b/apps/web/src/pages/Pool/Positions/ClaimFeeModal.tsx
@@ -1,7 +1,7 @@
/* eslint-disable-next-line no-restricted-imports */
import { ProtocolVersion } from '@uniswap/client-pools/dist/pools/v1/types_pb'
-import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
-import { PositionInfo } from 'components/Liquidity/types'
+import { LoaderButton } from 'components/Button/LoaderButton'
+import { useModalLiquidityInitialState, useV3OrV4PositionDerivedInfo } from 'components/Liquidity/hooks'
import { getProtocolItems } from 'components/Liquidity/utils'
import { GetHelpHeader } from 'components/Modal/GetHelpHeader'
import { ZERO_ADDRESS } from 'constants/misc'
@@ -9,11 +9,12 @@ import { useCurrencyInfo } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
import { useEthersSigner } from 'hooks/useEthersSigner'
import { useMemo } from 'react'
+import { useCloseModal } from 'state/application/hooks'
import { PopupType, addPopup } from 'state/application/reducer'
import { useAppDispatch } from 'state/hooks'
import { useTransactionAdder } from 'state/transactions/hooks'
import { TransactionType } from 'state/transactions/types'
-import { Button, Flex, Text } from 'ui/src'
+import { Flex, Text } from 'ui/src'
import { iconSizes } from 'ui/src/theme'
import { CurrencyLogo } from 'uniswap/src/components/CurrencyLogo/CurrencyLogo'
import { Modal } from 'uniswap/src/components/modals/Modal'
@@ -26,36 +27,29 @@ import { useTranslation } from 'uniswap/src/i18n'
import { NumberType } from 'utilities/src/format/types'
import { currencyId } from 'utils/currencyId'
-type ClaimFeeModalProps = {
- positionInfo: PositionInfo
- isOpen: boolean
- onClose: () => void
- token0Fees?: CurrencyAmount
- token1Fees?: CurrencyAmount
- token0FeesUsd?: CurrencyAmount
- token1FeesUsd?: CurrencyAmount
- collectAsWETH: boolean
-}
-
-export function ClaimFeeModal({
- positionInfo,
- onClose,
- isOpen,
- token0Fees,
- token1Fees,
- token0FeesUsd,
- token1FeesUsd,
- collectAsWETH,
-}: ClaimFeeModalProps) {
+export function ClaimFeeModal() {
const { t } = useTranslation()
const { formatCurrencyAmount } = useLocalizationContext()
+ const positionInfo = useModalLiquidityInitialState()
+ const onClose = useCloseModal(ModalName.ClaimFee)
+ const {
+ feeValue0: token0Fees,
+ feeValue1: token1Fees,
+ fiatFeeValue0: token0FeesUsd,
+ fiatFeeValue1: token1FeesUsd,
+ } = useV3OrV4PositionDerivedInfo(positionInfo)
+
const currencyInfo0 = useCurrencyInfo(token0Fees?.currency)
const currencyInfo1 = useCurrencyInfo(token1Fees?.currency)
const account = useAccount()
const dispatch = useAppDispatch()
const addTransaction = useTransactionAdder()
- const claimLpFeesParams = useMemo((): ClaimLPFeesRequest => {
+ const claimLpFeesParams = useMemo(() => {
+ if (!positionInfo) {
+ return undefined
+ }
+
return {
protocol: getProtocolItems(positionInfo.version),
tokenId: positionInfo.tokenId ? Number(positionInfo.tokenId) : undefined,
@@ -80,16 +74,18 @@ export function ClaimFeeModal({
positionInfo.version !== ProtocolVersion.V4 ? token0Fees?.quotient.toString() : undefined,
expectedTokenOwed1RawAmount:
positionInfo.version !== ProtocolVersion.V4 ? token1Fees?.quotient.toString() : undefined,
- collectAsWETH: positionInfo.version !== ProtocolVersion.V4 ? collectAsWETH : undefined,
- }
- }, [account.address, positionInfo, token0Fees, token1Fees, collectAsWETH])
+ collectAsWETH: positionInfo.version !== ProtocolVersion.V4 ? positionInfo.collectAsWeth : undefined,
+ } satisfies ClaimLPFeesRequest
+ }, [account.address, positionInfo, token0Fees, token1Fees])
- const { data } = useClaimLpFeesCalldataQuery({ params: claimLpFeesParams, enabled: isOpen })
+ const { data, isLoading: calldataLoading } = useClaimLpFeesCalldataQuery({
+ params: claimLpFeesParams,
+ })
const signer = useEthersSigner()
return (
-
+
)}
- {
if (signer && data?.claim) {
const response = await signer.sendTransaction(data?.claim)
@@ -164,8 +162,10 @@ export function ClaimFeeModal({
}
}}
>
- {t('common.collect.button')}
-
+
+ {t('common.collect.button')}
+
+
)
diff --git a/apps/web/src/pages/Pool/Positions/PositionPage.tsx b/apps/web/src/pages/Pool/Positions/PositionPage.tsx
index d39f9ee1073..58fcd1ee256 100644
--- a/apps/web/src/pages/Pool/Positions/PositionPage.tsx
+++ b/apps/web/src/pages/Pool/Positions/PositionPage.tsx
@@ -9,22 +9,25 @@ import { PositionNFT } from 'components/Liquidity/PositionNFT'
import { useV3OrV4PositionDerivedInfo } from 'components/Liquidity/hooks'
import { parseRestPosition } from 'components/Liquidity/utils'
import { LoadingFullscreen, LoadingRows } from 'components/Loader/styled'
-import { useChainFromUrlParam } from 'constants/chains'
+import { ZERO_ADDRESS } from 'constants/misc'
import { usePositionTokenURI } from 'hooks/usePositionTokenURI'
-import { ClaimFeeModal } from 'pages/Pool/Positions/ClaimFeeModal'
-import { LoadingRow, useRefetchOnLpModalClose } from 'pages/Pool/Positions/shared'
+import NotFound from 'pages/NotFound'
+import { LoadingRow } from 'pages/Pool/Positions/shared'
import { useMemo, useState } from 'react'
import { ChevronRight } from 'react-feather'
import { Navigate, useLocation, useNavigate, useParams } from 'react-router-dom'
import { setOpenModal } from 'state/application/reducer'
import { useAppDispatch } from 'state/hooks'
+import { usePendingLPTransactionsChangeListener } from 'state/transactions/hooks'
import { ClickableTamaguiStyle } from 'theme/components'
-import { Flex, Main, Switch, Text, styled } from 'ui/src'
+import { Button, Flex, Main, Switch, Text, styled } from 'ui/src'
import { useGetPositionQuery } from 'uniswap/src/data/rest/getPosition'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlagWithLoading } from 'uniswap/src/features/gating/hooks'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
-import { Trans } from 'uniswap/src/i18n'
+import { Trans, useTranslation } from 'uniswap/src/i18n'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { useAccount } from 'wagmi'
@@ -35,6 +38,7 @@ const BodyWrapper = styled(Main, {
gap: '$spacing32',
mx: 'auto',
width: '100%',
+ maxWidth: 768,
zIndex: '$default',
p: '$spacing24',
})
@@ -62,42 +66,51 @@ export const HeaderButton = styled(Flex, {
} as const,
})
+function parseTokenId(tokenId: string | undefined): BigNumber | undefined {
+ if (!tokenId) {
+ return undefined
+ }
+ try {
+ return BigNumber.from(tokenId)
+ } catch (error) {
+ return undefined
+ }
+}
+
export default function PositionPage() {
- const { tokenId } = useParams<{ tokenId: string }>()
- const chainInfo = useChainFromUrlParam()
+ const { tokenId: tokenIdFromUrl } = useParams<{ tokenId: string }>()
+ const tokenId = parseTokenId(tokenIdFromUrl)
+ const chainId = useChainIdFromUrlParam()
+ const chainInfo = chainId ? getChainInfo(chainId) : undefined
const account = useAccount()
const { pathname } = useLocation()
const {
data,
isLoading: positionLoading,
refetch,
- } = useGetPositionQuery(
- account.address
- ? {
- owner: account.address,
- protocolVersion: pathname.includes('v3')
- ? ProtocolVersion.V3
- : pathname.includes('v4')
- ? ProtocolVersion.V4
- : ProtocolVersion.UNSPECIFIED,
- tokenId,
- chainId: chainInfo?.id ?? account.chainId,
- }
- : undefined,
- )
+ } = useGetPositionQuery({
+ owner: account?.address ?? ZERO_ADDRESS,
+ protocolVersion: pathname.includes('v3')
+ ? ProtocolVersion.V3
+ : pathname.includes('v4')
+ ? ProtocolVersion.V4
+ : ProtocolVersion.UNSPECIFIED,
+ tokenId: tokenIdFromUrl,
+ chainId: chainId ?? account.chainId,
+ })
const position = data?.position
const positionInfo = useMemo(() => parseRestPosition(position), [position])
- const metadata = usePositionTokenURI(tokenId ? BigNumber.from(tokenId) : undefined, chainInfo?.id)
+ const metadata = usePositionTokenURI(tokenId, chainInfo?.id, positionInfo?.version)
- useRefetchOnLpModalClose(refetch)
+ usePendingLPTransactionsChangeListener(refetch)
const dispatch = useAppDispatch()
const [collectAsWeth, setCollectAsWeth] = useState(false)
- const [claimFeeModalOpen, setClaimFeeModalOpen] = useState(false)
const { value: v4Enabled, isLoading } = useFeatureFlagWithLoading(FeatureFlags.V4Everywhere)
const { formatCurrencyAmount } = useFormatter()
const navigate = useNavigate()
+ const { t } = useTranslation()
const { currency0Amount, currency1Amount, status } = positionInfo ?? {}
const {
@@ -116,7 +129,7 @@ export default function PositionPage() {
return
}
- if (positionLoading || !position || !positionInfo || !currency0Amount || !currency1Amount) {
+ if (positionLoading) {
return (
@@ -136,6 +149,26 @@ export default function PositionPage() {
)
}
+ if (!position || !positionInfo || !currency0Amount || !currency1Amount) {
+ return (
+ {t('position.notFound')}}
+ subtitle={
+
+
+ {t('position.notFound.description')}
+
+
+ }
+ actionButton={ navigate('/positions')}>{t('common.backToPositions')}}
+ />
+ )
+ }
+
+ const hasFees = feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) || false
+
+ // TODO (WEB-4920): hide action buttons if position owner is not connected wallet.
+
return (
@@ -146,7 +179,12 @@ export default function PositionPage() {
-
+
{status !== PositionStatus.CLOSED && (
@@ -154,7 +192,7 @@ export default function PositionPage() {
{
- navigate(`/migrate/v3/${chainInfo?.urlParam}/${tokenId}`)
+ navigate(`/migrate/v3/${chainInfo?.urlParam}/${tokenIdFromUrl}`)
}}
>
@@ -186,7 +224,7 @@ export default function PositionPage() {
)}
-
+
{'result' in metadata ? (
@@ -221,18 +259,24 @@ export default function PositionPage() {
- {
- setClaimFeeModalOpen(true)
- }}
- >
-
-
-
-
+ {hasFees && (
+ {
+ if (hasFees) {
+ dispatch(
+ setOpenModal({ name: ModalName.ClaimFee, initialState: { ...positionInfo, collectAsWeth } }),
+ )
+ }
+ }}
+ >
+
+
+
+
+ )}
-
+
{fiatFeeValue0 && fiatFeeValue1
? formatCurrencyAmount({
amount: fiatFeeValue0.add(fiatFeeValue1),
@@ -249,7 +293,7 @@ export default function PositionPage() {
/>
)}
{positionInfo.version !== ProtocolVersion.V4 && (
-
+
@@ -267,7 +311,6 @@ export default function PositionPage() {
{priceOrdering && token0CurrentPrice && token1CurrentPrice && (
)}
- setClaimFeeModalOpen(false)}
- token0Fees={feeValue0}
- token1Fees={feeValue1}
- token0FeesUsd={fiatFeeValue0}
- token1FeesUsd={fiatFeeValue1}
- collectAsWETH={collectAsWeth}
- />
)
}
diff --git a/apps/web/src/pages/Pool/Positions/PositionsHeader.tsx b/apps/web/src/pages/Pool/Positions/PositionsHeader.tsx
index c2bec807410..9ebde53657d 100644
--- a/apps/web/src/pages/Pool/Positions/PositionsHeader.tsx
+++ b/apps/web/src/pages/Pool/Positions/PositionsHeader.tsx
@@ -1,22 +1,22 @@
// eslint-disable-next-line no-restricted-imports
import { PositionStatus, ProtocolVersion } from '@uniswap/client-pools/dist/pools/v1/types_pb'
+import { DropdownSelector } from 'components/DropdownSelector'
import { getProtocolStatusLabel, getProtocolVersionLabel } from 'components/Liquidity/utils'
import { useAccount } from 'hooks/useAccount'
-import { useMemo } from 'react'
+import { useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { ClickableTamaguiStyle } from 'theme/components'
import { Flex, LabeledCheckbox, Text } from 'ui/src'
import { Plus } from 'ui/src/components/icons/Plus'
import { RotatableChevron } from 'ui/src/components/icons/RotatableChevron'
import { SortHorizontalLines } from 'ui/src/components/icons/SortHorizontalLines'
-import { ActionSheetDropdown } from 'uniswap/src/components/dropdowns/ActionSheetDropdown'
import { NetworkFilter } from 'uniswap/src/components/network/NetworkFilter'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Trans, useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
type PositionsHeaderProps = {
- showFilters: boolean
+ showFilters?: boolean
selectedChain: UniverseChainId | null
selectedVersions?: ProtocolVersion[]
selectedStatus?: PositionStatus[]
@@ -26,7 +26,7 @@ type PositionsHeaderProps = {
}
export function PositionsHeader({
- showFilters,
+ showFilters = true,
selectedChain,
selectedVersions,
selectedStatus,
@@ -41,59 +41,41 @@ export function PositionsHeader({
const filterOptions = useMemo(() => {
const statusOptions = [PositionStatus.IN_RANGE, PositionStatus.OUT_OF_RANGE, PositionStatus.CLOSED].map(
- (status) => ({
- key: `PositionsHeader-status-${status}`,
- onPress: () => null,
- render: () => (
-
- {
- onStatusChange(status)
- }}
- />
-
- ),
- }),
- )
- const versionOptions = [ProtocolVersion.V2, ProtocolVersion.V3, ProtocolVersion.V4].map((version) => ({
- key: `PositionsHeader-version-${version}`,
- onPress: () => null,
- render: () => (
-
- {
- onVersionChange(version)
- }}
- />
-
+ (status) => (
+ {
+ onStatusChange(status)
+ }}
+ />
),
- }))
+ )
+ const versionOptions = [ProtocolVersion.V4, ProtocolVersion.V3, ProtocolVersion.V2].map((version) => (
+ {
+ onVersionChange(version)
+ }}
+ />
+ ))
return [
- {
- key: 'PositionsHeader-status-section-title',
- onPress: () => null,
- render: () => (
-
- {t('common.status')}
-
- ),
- },
+
+ {t('common.status')}
+ ,
...statusOptions,
- {
- key: 'PositionsHeader-version-section-title',
- onPress: () => null,
- render: () => (
-
- {t('common.version')}
-
- ),
- },
+
+ {t('common.version')}
+ ,
...versionOptions,
]
}, [onStatusChange, onVersionChange, selectedStatus, selectedVersions, t])
@@ -102,23 +84,27 @@ export function PositionsHeader({
() =>
[ProtocolVersion.V2, ProtocolVersion.V3, ProtocolVersion.V4].map((version) => {
const protocolVersionLabel = getProtocolVersionLabel(version)?.toLowerCase()
- return {
- key: `PositionsHeader-create-${protocolVersionLabel}`,
- onPress: () => {
- navigate(`/positions/create/${protocolVersionLabel}`)
- },
- render: () => (
-
-
-
-
-
- ),
- }
+ return (
+ {
+ navigate(`/positions/create/${protocolVersionLabel}`)
+ }}
+ >
+
+
+
+
+ )
}),
[navigate],
)
+ const [createDropdownOpen, setCreateDropdownOpen] = useState(false)
+ const [filterDropdownOpen, setFilterDropdownOpen] = useState(false)
+
return (
{t('pool.positions.title')}
@@ -142,42 +128,11 @@ export function PositionsHeader({
{t('common.new')}
-
-
-
-
-
-
- {showFilters && (
- <>
-
+
-
+
-
+ }
+ buttonStyle={{
+ borderWidth: 0,
+ p: 0,
+ }}
+ dropdownStyle={{
+ width: 160,
+ }}
+ internalMenuItems={<>{createOptions}>}
+ hideChevron={true}
+ isOpen={createDropdownOpen}
+ toggleOpen={() => {
+ setCreateDropdownOpen((prev) => !prev)
+ }}
+ />
+
+ {showFilters && (
+
+ {
+ setFilterDropdownOpen((prev) => !prev)
+ }}
+ menuLabel={
+
+
+
+ }
+ internalMenuItems={<>{filterOptions}>}
+ hideChevron={true}
+ dropdownStyle={{
+ width: 160,
+ }}
+ buttonStyle={{
+ borderWidth: 0,
+ p: 0,
+ }}
+ />
- >
+
)}
)}
diff --git a/apps/web/src/pages/Pool/Positions/V2PositionPage.tsx b/apps/web/src/pages/Pool/Positions/V2PositionPage.tsx
index 2a39d54289e..a2b6dc0c36f 100644
--- a/apps/web/src/pages/Pool/Positions/V2PositionPage.tsx
+++ b/apps/web/src/pages/Pool/Positions/V2PositionPage.tsx
@@ -4,25 +4,28 @@ import { BreadcrumbNavContainer, BreadcrumbNavLink } from 'components/Breadcrumb
import { LiquidityPositionInfo } from 'components/Liquidity/LiquidityPositionInfo'
import { useGetPoolTokenPercentage } from 'components/Liquidity/hooks'
import { parseRestPosition } from 'components/Liquidity/utils'
-import { LoadingRows } from 'components/Loader/styled'
import { DoubleCurrencyAndChainLogo } from 'components/Logo/DoubleLogo'
-import { useChainFromUrlParam } from 'constants/chains'
+import { ZERO_ADDRESS } from 'constants/misc'
+import { LoadingRows } from 'pages/LegacyPool/styled'
+import NotFound from 'pages/NotFound'
import { HeaderButton } from 'pages/Pool/Positions/PositionPage'
-import { LoadingRow, useRefetchOnLpModalClose } from 'pages/Pool/Positions/shared'
+import { LoadingRow } from 'pages/Pool/Positions/shared'
import { useMemo } from 'react'
import { ChevronRight } from 'react-feather'
import { Navigate, useNavigate, useParams } from 'react-router-dom'
import { setOpenModal } from 'state/application/reducer'
import { useAppDispatch } from 'state/hooks'
-import { Flex, Main, Text, styled } from 'ui/src'
+import { usePendingLPTransactionsChangeListener } from 'state/transactions/hooks'
+import { Button, Flex, Main, Text, styled } from 'ui/src'
import { useGetPositionQuery } from 'uniswap/src/data/rest/getPosition'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlagWithLoading } from 'uniswap/src/features/gating/hooks'
import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { useUSDCValue } from 'uniswap/src/features/transactions/swap/hooks/useUSDCPrice'
-import { Trans } from 'uniswap/src/i18n'
+import { Trans, useTranslation } from 'uniswap/src/i18n'
import { NumberType } from 'utilities/src/format/types'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
import { useAccount } from 'wagmi'
const BodyWrapper = styled(Main, {
@@ -38,30 +41,27 @@ const BodyWrapper = styled(Main, {
export default function V2PositionPage() {
const { pairAddress } = useParams<{ pairAddress: string }>()
- const chainInfo = useChainFromUrlParam()
+ const chainId = useChainIdFromUrlParam()
const account = useAccount()
const {
data,
isLoading: positionLoading,
refetch,
- } = useGetPositionQuery(
- account.address
- ? {
- owner: account.address,
- protocolVersion: ProtocolVersion.V2,
- pairAddress,
- chainId: chainInfo?.id ?? account.chainId,
- }
- : undefined,
- )
+ } = useGetPositionQuery({
+ owner: account?.address ?? ZERO_ADDRESS,
+ protocolVersion: ProtocolVersion.V2,
+ pairAddress,
+ chainId: chainId ?? account.chainId,
+ })
const position = data?.position
const positionInfo = useMemo(() => parseRestPosition(position), [position])
const dispatch = useAppDispatch()
const navigate = useNavigate()
const { formatCurrencyAmount, formatPercent } = useLocalizationContext()
+ const { t } = useTranslation()
- useRefetchOnLpModalClose(refetch)
+ usePendingLPTransactionsChangeListener(refetch)
const { value: v4Enabled, isLoading } = useFeatureFlagWithLoading(FeatureFlags.V4Everywhere)
@@ -75,7 +75,7 @@ export default function V2PositionPage() {
return
}
- if (positionLoading || !positionInfo || !liquidityAmount || !currency0Amount || !currency1Amount) {
+ if (positionLoading) {
return (
@@ -96,9 +96,25 @@ export default function V2PositionPage() {
)
}
+ if (!positionInfo || !liquidityAmount || !currency0Amount || !currency1Amount) {
+ return (
+ {t('position.notFound')}}
+ subtitle={
+
+
+ {t('position.notFound.description')}
+
+
+ }
+ actionButton={ navigate('/positions')}>{t('common.backToPositions')}}
+ />
+ )
+ }
+
return (
-
+
@@ -109,7 +125,7 @@ export default function V2PositionPage() {
{status === PositionStatus.IN_RANGE && (
-
+
{
diff --git a/apps/web/src/pages/Pool/Positions/create/AddHook.tsx b/apps/web/src/pages/Pool/Positions/create/AddHook.tsx
index 6119ca59ca9..b4644735b96 100644
--- a/apps/web/src/pages/Pool/Positions/create/AddHook.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/AddHook.tsx
@@ -1,58 +1,189 @@
+import { HookModal } from 'components/Liquidity/HookModal'
+import { isDynamicFeeTier } from 'components/Liquidity/utils'
+import { useCreatePositionContext } from 'pages/Pool/Positions/create/CreatePositionContext'
import { AdvancedButton } from 'pages/Pool/Positions/create/shared'
-import { useState } from 'react'
-import { Button } from 'ui/src'
+import { DEFAULT_POSITION_STATE } from 'pages/Pool/Positions/create/types'
+import { useCallback, useRef, useState } from 'react'
+import { Button, Text, TouchableArea, styled } from 'ui/src'
import { DocumentList } from 'ui/src/components/icons/DocumentList'
import { X } from 'ui/src/components/icons/X'
import { Flex } from 'ui/src/components/layout/Flex'
import { fonts } from 'ui/src/theme'
import { TextInput } from 'uniswap/src/components/input/TextInput'
import { useTranslation } from 'uniswap/src/i18n'
+import { getValidAddress, shortenAddress } from 'uniswap/src/utils/addresses'
+import { useOnClickOutside } from 'utilities/src/react/hooks'
+
+const MenuFlyout = styled(Flex, {
+ animation: 'fastHeavy',
+ enterStyle: { top: 30, opacity: 0 },
+ exitStyle: { top: 30, opacity: 0 },
+ width: 'calc(100% - 48px)',
+ backgroundColor: '$surface2',
+ borderColor: '$surface3',
+ borderWidth: 1,
+ borderRadius: '$rounded12',
+ position: 'absolute',
+ top: 40,
+ zIndex: 100,
+ p: '$padding16',
+ opacity: 1,
+ shadowColor: '$shadowColor',
+ shadowOffset: { width: 0, height: 25 },
+ shadowOpacity: 0.2,
+ shadowRadius: 50,
+})
+
+function AutocompleteFlyout({ address, handleSelectAddress }: { address: string; handleSelectAddress: () => void }) {
+ const { t } = useTranslation()
+ const validAddress = getValidAddress(address)
+
+ return (
+
+ {validAddress ? (
+
+ {address}
+
+ ) : (
+
+ {t('position.addingHook.invalidAddress')}
+
+ )}
+
+ )
+}
export function AddHook() {
const { t } = useTranslation()
+ const [isFocusing, setFocus] = useState(false)
+ const handleFocus = useCallback((focus: boolean) => setFocus(focus), [])
+
+ const inputWrapperNode = useRef(null)
+ useOnClickOutside(inputWrapperNode, isFocusing ? () => handleFocus(false) : undefined)
+
const [hookInputEnabled, setHookInputEnabled] = useState(false)
- const [hookAddress, setHookAddress] = useState('')
+ const [hookModalOpen, setHookModalOpen] = useState(false)
- const handleToggleHookInput = () => {
- setHookInputEnabled((prev) => !prev)
- setHookAddress('')
+ const [hookValue, setHookValue] = useState('')
+ const {
+ positionState: { hook, fee },
+ setPositionState,
+ } = useCreatePositionContext()
+
+ const onSelectHook = (value: string | undefined) => {
+ setPositionState((state) => ({
+ ...state,
+ hook: value,
+ }))
+ }
+
+ const onClearHook = () => {
+ if (isDynamicFeeTier(fee)) {
+ setPositionState((state) => ({
+ ...state,
+ fee: DEFAULT_POSITION_STATE.fee,
+ }))
+ }
+
+ setHookInputEnabled(false)
+ setHookValue('')
+ onSelectHook(undefined)
}
if (hookInputEnabled) {
+ const showFlyout = isFocusing && hookValue
+
return (
-
- setHookAddress(text)}
- />
-
-
-
-
+ <>
+ {hookModalOpen && (
+ // intentionally only render this when the value is true to ensure that the address is valid.
+ setHookModalOpen(false)}
+ onClearHook={() => {
+ setHookInputEnabled(false)
+ setHookValue('')
+ }}
+ onContinue={() => onSelectHook(hookValue)}
+ />
+ )}
+ {hook ? (
+
+ {
+ setHookInputEnabled(true)
+ onSelectHook(undefined)
+ }}
+ >
+
+
+ {shortenAddress(hook)}
+
+
+
+
+ {t('common.clear')}
+
+
+
+ ) : (
+
+ handleFocus(true)}
+ />
+ {
+ setHookInputEnabled(false)
+ setHookValue('')
+ }}
+ >
+
+
+ {showFlyout && (
+ setHookModalOpen(true)} />
+ )}
+
+ )}
+ >
)
}
@@ -60,7 +191,7 @@ export function AddHook() {
setHookInputEnabled(true)}
tooltipText={t('position.addHook.tooltip')}
/>
)
diff --git a/apps/web/src/pages/Pool/Positions/create/ContextProviders.tsx b/apps/web/src/pages/Pool/Positions/create/ContextProviders.tsx
index a1583f09293..168c8a2d0a8 100644
--- a/apps/web/src/pages/Pool/Positions/create/ContextProviders.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/ContextProviders.tsx
@@ -1,11 +1,12 @@
-// eslint-disable-next-line no-restricted-imports
import { FeeTierSearchModal } from 'components/Liquidity/FeeTierSearchModal'
import { DepositState } from 'components/Liquidity/types'
+import { useAccount } from 'hooks/useAccount'
import {
CreatePositionContext,
CreateTxContext,
DEFAULT_DEPOSIT_STATE,
- DEFAULT_PRICE_RANGE_STATE,
+ DEFAULT_PRICE_RANGE_STATE_CREATING_POOL,
+ DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS,
DepositContext,
PriceRangeContext,
useCreatePositionContext,
@@ -28,10 +29,14 @@ import {
generateCreateCalldataQueryParams,
generateCreatePositionTxRequest,
} from 'pages/Pool/Positions/create/utils'
-import { useMemo, useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
+import { PositionField } from 'types/position'
+import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { useAccountMeta } from 'uniswap/src/contexts/UniswapContext'
import { useCheckLpApprovalQuery } from 'uniswap/src/data/apiClients/tradingApi/useCheckLpApprovalQuery'
import { useCreateLpPositionCalldataQuery } from 'uniswap/src/data/apiClients/tradingApi/useCreateLpPositionCalldataQuery'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { usePrevious } from 'utilities/src/react/hooks'
import { ONE_SECOND_MS } from 'utilities/src/time/time'
export function CreatePositionContextProvider({
@@ -45,7 +50,20 @@ export function CreatePositionContextProvider({
const [step, setStep] = useState(PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER)
const derivedPositionInfo = useDerivedPositionInfo(positionState)
const [feeTierSearchModalOpen, setFeeTierSearchModalOpen] = useState(false)
- const [createPoolInfoDismissed, setCreatePoolInfoDismissed] = useState(false)
+
+ const account = useAccount()
+ const prevChainId = usePrevious(account.chainId)
+ useEffect(() => {
+ if (prevChainId && prevChainId !== account.chainId) {
+ setPositionState((prevState) => ({
+ ...prevState,
+ currencyInputs: {
+ [PositionField.TOKEN0]: nativeOnChain(account.chainId ?? UniverseChainId.Mainnet),
+ },
+ }))
+ setStep(PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER)
+ }
+ }, [account.chainId, prevChainId])
return (
{children}
@@ -68,7 +84,24 @@ export function CreatePositionContextProvider({
}
export function PriceRangeContextProvider({ children }: { children: React.ReactNode }) {
- const [priceRangeState, setPriceRangeState] = useState(DEFAULT_PRICE_RANGE_STATE)
+ const { derivedPositionInfo } = useCreatePositionContext()
+ const [priceRangeState, setPriceRangeState] = useState(DEFAULT_PRICE_RANGE_STATE_CREATING_POOL)
+
+ useEffect(() => {
+ // creatingPoolOrPair is calculated in the previous step of the create flow, so
+ // it's safe to reset PriceRangeState to defaults when it changes.
+ setPriceRangeState(
+ derivedPositionInfo.creatingPoolOrPair
+ ? DEFAULT_PRICE_RANGE_STATE_CREATING_POOL
+ : DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS,
+ )
+ }, [derivedPositionInfo.creatingPoolOrPair])
+
+ useEffect(() => {
+ // When the price is inverted, reset the state so that LiquidityChartRangeInput redraws the default range.
+ setPriceRangeState((prevState) => ({ ...prevState, fullRange: false, minPrice: undefined, maxPrice: undefined }))
+ }, [priceRangeState.priceInverted])
+
const derivedPriceRangeInfo = useDerivedPriceRangeInfo(priceRangeState)
return (
diff --git a/apps/web/src/pages/Pool/Positions/create/CreatePosition.tsx b/apps/web/src/pages/Pool/Positions/create/CreatePosition.tsx
index 51c39ad9fd9..78a532accf9 100644
--- a/apps/web/src/pages/Pool/Positions/create/CreatePosition.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/CreatePosition.tsx
@@ -12,7 +12,7 @@ import {
} from 'pages/Pool/Positions/create/ContextProviders'
import {
DEFAULT_DEPOSIT_STATE,
- DEFAULT_PRICE_RANGE_STATE,
+ DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS,
useCreatePositionContext,
useDepositContext,
usePriceRangeContext,
@@ -21,22 +21,51 @@ import { DepositStep } from 'pages/Pool/Positions/create/Deposit'
import { EditRangeSelectionStep, EditSelectTokensStep } from 'pages/Pool/Positions/create/EditStep'
import { SelectPriceRangeStep, SelectPriceRangeStepV2 } from 'pages/Pool/Positions/create/RangeSelectionStep'
import { SelectTokensStep } from 'pages/Pool/Positions/create/SelectTokenStep'
+import { Container } from 'pages/Pool/Positions/create/shared'
import { DEFAULT_POSITION_STATE, PositionFlowStep } from 'pages/Pool/Positions/create/types'
import { useCallback, useMemo } from 'react'
import { ChevronRight } from 'react-feather'
-import { Navigate, useParams } from 'react-router-dom'
+import { Navigate, useNavigate, useParams } from 'react-router-dom'
import { PositionField } from 'types/position'
-import { Button, Flex, Text } from 'ui/src'
+import { Button, Flex, Text, useMedia } from 'ui/src'
+import { InfoCircleFilled } from 'ui/src/components/icons/InfoCircleFilled'
import { RotatableChevron } from 'ui/src/components/icons/RotatableChevron'
import { RotateLeft } from 'ui/src/components/icons/RotateLeft'
import { Settings } from 'ui/src/components/icons/Settings'
import { iconSizes } from 'ui/src/theme/iconSizes'
import { ActionSheetDropdown } from 'uniswap/src/components/dropdowns/ActionSheetDropdown'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlagWithLoading } from 'uniswap/src/features/gating/hooks'
import { Trans, useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { usePrevious } from 'utilities/src/react/hooks'
+
+function CreatingPoolInfo() {
+ const { derivedPositionInfo } = useCreatePositionContext()
+
+ const previouslyCreatingPoolOrPair = usePrevious(derivedPositionInfo.creatingPoolOrPair)
+
+ const shouldShowDisabled = previouslyCreatingPoolOrPair && derivedPositionInfo.poolOrPairLoading
+
+ if (!shouldShowDisabled && !derivedPositionInfo.creatingPoolOrPair) {
+ return null
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
function CreatePositionInner() {
const {
@@ -59,27 +88,35 @@ function CreatePositionInner() {
}
}, [creatingPoolOrPair, setStep, step, v2Selected])
- return (
-
- {step === PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER ? (
+ if (step === PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER) {
+ return (
+ <>
- ) : step === PositionFlowStep.PRICE_RANGE ? (
- <>
-
- {v2Selected ? (
-
- ) : (
-
- )}
- >
- ) : (
- <>
-
- {!v2Selected && }
-
- >
- )}
-
+
+ >
+ )
+ }
+
+ if (step === PositionFlowStep.PRICE_RANGE) {
+ return (
+ <>
+
+ {v2Selected ? (
+
+ ) : (
+
+ )}
+
+ >
+ )
+ }
+
+ return (
+ <>
+
+ {!v2Selected && }
+
+ >
)
}
@@ -89,43 +126,40 @@ const Sidebar = () => {
positionState: { protocolVersion },
derivedPositionInfo: { creatingPoolOrPair },
step,
+ setStep,
} = useCreatePositionContext()
const PoolProgressSteps = useMemo(() => {
+ const createStep = (label: string, stepEnum: PositionFlowStep) => ({
+ label,
+ active: step === stepEnum,
+ // This relies on the ordering of PositionFlowStep enum values matching the actual order in the form.
+ onPress: stepEnum < step ? () => setStep(stepEnum) : undefined,
+ })
+
if (protocolVersion === ProtocolVersion.V2) {
if (creatingPoolOrPair) {
return [
- { label: t(`position.step.select`), active: step === PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER },
- { label: t(`position.step.price`), active: step === PositionFlowStep.PRICE_RANGE },
- { label: t(`position.step.deposit`), active: step == PositionFlowStep.DEPOSIT },
+ createStep(t(`position.step.select`), PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER),
+ createStep(t('position.step.price'), PositionFlowStep.PRICE_RANGE),
+ createStep(t('position.step.deposit'), PositionFlowStep.DEPOSIT),
]
}
-
return [
- { label: t(`position.step.select`), active: step === PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER },
- { label: t(`position.step.deposit`), active: step == PositionFlowStep.DEPOSIT },
+ createStep(t('position.step.select'), PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER),
+ createStep(t('position.step.deposit'), PositionFlowStep.DEPOSIT),
]
}
return [
- { label: t(`position.step.select`), active: step === PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER },
- { label: t(`position.step.range`), active: step === PositionFlowStep.PRICE_RANGE },
- { label: t(`position.step.deposit`), active: step == PositionFlowStep.DEPOSIT },
+ createStep(t('position.step.select'), PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER),
+ createStep(t('position.step.range'), PositionFlowStep.PRICE_RANGE),
+ createStep(t('position.step.deposit'), PositionFlowStep.DEPOSIT),
]
- }, [creatingPoolOrPair, protocolVersion, step, t])
+ }, [creatingPoolOrPair, protocolVersion, setStep, step, t])
return (
-
-
-
-
-
-
-
-
-
-
-
+
)
@@ -136,6 +170,7 @@ const Toolbar = () => {
const { protocolVersion } = positionState
const { priceRangeState, setPriceRangeState } = usePriceRangeContext()
const { depositState, setDepositState } = useDepositContext()
+ const navigate = useNavigate()
const isFormUnchanged = useMemo(() => {
// Check if all form fields (except protocol version) are set to their default values
@@ -143,34 +178,39 @@ const Toolbar = () => {
positionState.currencyInputs === DEFAULT_POSITION_STATE.currencyInputs &&
positionState.fee === DEFAULT_POSITION_STATE.fee &&
positionState.hook === DEFAULT_POSITION_STATE.hook &&
- priceRangeState === DEFAULT_PRICE_RANGE_STATE &&
+ priceRangeState.initialPrice === DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS.initialPrice &&
depositState === DEFAULT_DEPOSIT_STATE
)
}, [positionState.currencyInputs, positionState.fee, positionState.hook, priceRangeState, depositState])
const handleReset = useCallback(() => {
setPositionState({ ...DEFAULT_POSITION_STATE, protocolVersion })
- setPriceRangeState(DEFAULT_PRICE_RANGE_STATE)
+ setPriceRangeState(DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS)
setDepositState(DEFAULT_DEPOSIT_STATE)
setStep(PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER)
}, [protocolVersion, setDepositState, setPositionState, setPriceRangeState, setStep])
const handleVersionChange = useCallback(
(version: ProtocolVersion) => {
+ const versionUrl = getProtocolVersionLabel(version)?.toLowerCase()
+ if (versionUrl) {
+ navigate(`/positions/create/${versionUrl}`)
+ }
+
setPositionState((prevState) => ({
...DEFAULT_POSITION_STATE,
currencyInputs: prevState.currencyInputs,
protocolVersion: version,
}))
- setPriceRangeState(DEFAULT_PRICE_RANGE_STATE)
+ setPriceRangeState(DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS)
setStep(PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER)
},
- [setPositionState, setPriceRangeState, setStep],
+ [setPositionState, setPriceRangeState, setStep, navigate],
)
const versionOptions = useMemo(
() =>
- [ProtocolVersion.V2, ProtocolVersion.V3, ProtocolVersion.V4]
+ [ProtocolVersion.V4, ProtocolVersion.V3, ProtocolVersion.V2]
.filter((version) => version != protocolVersion)
.map((version) => ({
key: `version-${version}`,
@@ -190,7 +230,7 @@ const Toolbar = () => {
)
return (
-
+
{
>
{
borderRadius="$rounded12"
borderColor="$surface3"
borderWidth="$spacing1"
- gap={6}
+ gap="$gap4"
>
{
onPress={handleReset}
disabled={isFormUnchanged}
>
-
+
@@ -258,6 +298,7 @@ export function CreatePosition() {
const { value: v4Enabled, isLoading } = useFeatureFlagWithLoading(FeatureFlags.V4Everywhere)
const { protocolVersion } = useParams<{ protocolVersion: string }>()
const account = useAccount()
+ const media = useMedia()
if (!isLoading && !v4Enabled) {
return
@@ -278,11 +319,33 @@ export function CreatePosition() {
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+ {!media.xl && }
+
+
+
diff --git a/apps/web/src/pages/Pool/Positions/create/CreatePositionContext.tsx b/apps/web/src/pages/Pool/Positions/create/CreatePositionContext.tsx
index 11a83d97338..b9b22be49c0 100644
--- a/apps/web/src/pages/Pool/Positions/create/CreatePositionContext.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/CreatePositionContext.tsx
@@ -19,8 +19,6 @@ export const CreatePositionContext = React.createContext undefined,
feeTierSearchModalOpen: false,
setFeeTierSearchModalOpen: () => undefined,
- createPoolInfoDismissed: false,
- setCreatePoolInfoDismissed: () => undefined,
derivedPositionInfo: {
protocolVersion: ProtocolVersion.V4,
currencies: [undefined, undefined],
@@ -31,7 +29,16 @@ export const useCreatePositionContext = () => {
return useContext(CreatePositionContext)
}
-export const DEFAULT_PRICE_RANGE_STATE: PriceRangeState = {
+export const DEFAULT_PRICE_RANGE_STATE_CREATING_POOL: PriceRangeState = {
+ priceInverted: false,
+ fullRange: true,
+ minPrice: '',
+ maxPrice: '',
+ initialPrice: '',
+ initialPriceInverted: false,
+}
+
+export const DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS: PriceRangeState = {
priceInverted: false,
fullRange: false,
minPrice: undefined,
@@ -41,7 +48,7 @@ export const DEFAULT_PRICE_RANGE_STATE: PriceRangeState = {
}
export const PriceRangeContext = React.createContext({
- priceRangeState: DEFAULT_PRICE_RANGE_STATE,
+ priceRangeState: DEFAULT_PRICE_RANGE_STATE_CREATING_POOL,
setPriceRangeState: () => undefined,
derivedPriceRangeInfo: {
protocolVersion: ProtocolVersion.V4,
diff --git a/apps/web/src/pages/Pool/Positions/create/CreatePositionModal.tsx b/apps/web/src/pages/Pool/Positions/create/CreatePositionModal.tsx
index 395f550bf75..f81566d4644 100644
--- a/apps/web/src/pages/Pool/Positions/create/CreatePositionModal.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/CreatePositionModal.tsx
@@ -1,5 +1,7 @@
// eslint-disable-next-line no-restricted-imports
import { ProtocolVersion } from '@uniswap/client-pools/dist/pools/v1/types_pb'
+import { LiquidityPositionInfoBadges } from 'components/Liquidity/LiquidityPositionInfoBadges'
+import { getProtocolVersionLabel } from 'components/Liquidity/utils'
import { DoubleCurrencyLogo } from 'components/Logo/DoubleLogo'
import { GetHelpHeader } from 'components/Modal/GetHelpHeader'
import { useCurrencyInfo } from 'hooks/Tokens'
@@ -14,6 +16,7 @@ import { formatPrices } from 'pages/Pool/Positions/create/shared'
import { getInvertedTuple } from 'pages/Pool/Positions/create/utils'
import { useCallback, useMemo, useState } from 'react'
import { useDispatch } from 'react-redux'
+import { useNavigate } from 'react-router-dom'
import { liquiditySaga } from 'state/sagas/liquidity/liquiditySaga'
import { Button, Flex, Text } from 'ui/src'
import { iconSizes } from 'ui/src/theme'
@@ -32,8 +35,8 @@ import { useAccount } from 'wagmi'
export function CreatePositionModal({ isOpen, onClose }: { isOpen: boolean; onClose: () => void }) {
const {
- positionState: { protocolVersion },
- derivedPositionInfo,
+ positionState: { fee, hook },
+ derivedPositionInfo: { currencies, protocolVersion },
} = useCreatePositionContext()
const {
derivedPriceRangeInfo,
@@ -47,12 +50,14 @@ export function CreatePositionModal({ isOpen, onClose }: { isOpen: boolean; onCl
const token1CurrencyInfo = useCurrencyInfo(currencyAmounts?.TOKEN1?.currency)
const { formatNumberOrString, formatCurrencyAmount } = useLocalizationContext()
- const [baseCurrency, quoteCurrency] = getInvertedTuple(derivedPositionInfo.currencies, priceInverted)
+ const [baseCurrency, quoteCurrency] = getInvertedTuple(currencies, priceInverted)
const formattedPrices = useMemo(() => {
return formatPrices(derivedPriceRangeInfo, formatNumberOrString)
}, [formatNumberOrString, derivedPriceRangeInfo])
+ const versionLabel = getProtocolVersionLabel(protocolVersion)
+
const [steps, setSteps] = useState([])
const [currentStep, setCurrentStep] = useState<{ step: TransactionStep; accepted: boolean } | undefined>()
const dispatch = useDispatch()
@@ -60,6 +65,7 @@ export function CreatePositionModal({ isOpen, onClose }: { isOpen: boolean; onCl
const account = useAccountMeta()
const selectChain = useSelectChain()
const startChainId = useAccount().chainId
+ const navigate = useNavigate()
const onFailure = () => {
setCurrentStep(undefined)
@@ -69,7 +75,8 @@ export function CreatePositionModal({ isOpen, onClose }: { isOpen: boolean; onCl
setSteps([])
setCurrentStep(undefined)
onClose()
- }, [onClose])
+ navigate('/positions')
+ }, [onClose, navigate])
const handleCreate = useCallback(() => {
const isValidTx = isValidLiquidityTxContext(createTxContext)
@@ -104,11 +111,21 @@ export function CreatePositionModal({ isOpen, onClose }: { isOpen: boolean; onCl
closeModal={() => onClose()}
/>
-
-
- {currencyAmounts?.TOKEN0?.currency?.symbol}
- /
- {currencyAmounts?.TOKEN1?.currency?.symbol}
+
+
+
+ {currencyAmounts?.TOKEN0?.currency?.symbol}
+ /
+ {currencyAmounts?.TOKEN1?.currency?.symbol}
+
+
+
+
) : (
-
-
+
+
diff --git a/apps/web/src/pages/Pool/Positions/create/Deposit.tsx b/apps/web/src/pages/Pool/Positions/create/Deposit.tsx
index f70cc57a398..c9219d9faad 100644
--- a/apps/web/src/pages/Pool/Positions/create/Deposit.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/Deposit.tsx
@@ -1,6 +1,8 @@
+import { LoaderButton } from 'components/Button/LoaderButton'
import { DepositInputForm } from 'components/Liquidity/DepositInputForm'
import {
useCreatePositionContext,
+ useCreateTxContext,
useDepositContext,
usePriceRangeContext,
} from 'pages/Pool/Positions/create/CreatePositionContext'
@@ -8,7 +10,7 @@ import { CreatePositionModal } from 'pages/Pool/Positions/create/CreatePositionM
import { Container } from 'pages/Pool/Positions/create/shared'
import { useCallback, useState } from 'react'
import { PositionField } from 'types/position'
-import { Button, Flex, FlexProps, Text } from 'ui/src'
+import { Flex, FlexProps, Text } from 'ui/src'
import { Trans } from 'uniswap/src/i18n'
export const DepositStep = ({ ...rest }: FlexProps) => {
@@ -18,6 +20,7 @@ export const DepositStep = ({ ...rest }: FlexProps) => {
setDepositState,
derivedDepositInfo: { formattedAmounts, currencyAmounts, currencyAmountsUSDValue, currencyBalances, error },
} = useDepositContext()
+ const txContext = useCreateTxContext()
const [isReviewModalOpen, setIsReviewModalOpen] = useState(false)
const handleUserInput = (field: PositionField, newValue: string) => {
@@ -75,11 +78,19 @@ export const DepositStep = ({ ...rest }: FlexProps) => {
deposit0Disabled={deposit0Disabled}
deposit1Disabled={deposit1Disabled}
/>
-
+
{error ? error : }
-
+
setIsReviewModalOpen(false)} />
>
diff --git a/apps/web/src/pages/Pool/Positions/create/EditStep.tsx b/apps/web/src/pages/Pool/Positions/create/EditStep.tsx
index 1695ddb812f..a9971aa6e45 100644
--- a/apps/web/src/pages/Pool/Positions/create/EditStep.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/EditStep.tsx
@@ -1,6 +1,14 @@
// eslint-disable-next-line no-restricted-imports
+import { LiquidityPositionInfoBadges } from 'components/Liquidity/LiquidityPositionInfoBadges'
+import { getProtocolVersionLabel } from 'components/Liquidity/utils'
import { DoubleCurrencyLogo } from 'components/Logo/DoubleLogo'
-import { useCreatePositionContext, usePriceRangeContext } from 'pages/Pool/Positions/create/CreatePositionContext'
+import {
+ DEFAULT_DEPOSIT_STATE,
+ DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS,
+ useCreatePositionContext,
+ useDepositContext,
+ usePriceRangeContext,
+} from 'pages/Pool/Positions/create/CreatePositionContext'
import { Container, formatPrices } from 'pages/Pool/Positions/create/shared'
import { PositionFlowStep } from 'pages/Pool/Positions/create/types'
import { getInvertedTuple } from 'pages/Pool/Positions/create/utils'
@@ -26,15 +34,19 @@ const EditStep = ({ children, onClick, ...rest }: { children: JSX.Element; onCli
}
export const EditSelectTokensStep = (props?: FlexProps) => {
- const {
- setStep,
- derivedPositionInfo: { currencies },
- } = useCreatePositionContext()
+ const { setStep, derivedPositionInfo, positionState } = useCreatePositionContext()
+ const { setPriceRangeState } = usePriceRangeContext()
+ const { setDepositState } = useDepositContext()
+ const { currencies, protocolVersion } = derivedPositionInfo
+ const { fee, hook } = positionState
const [token0, token1] = currencies
+ const versionLabel = getProtocolVersionLabel(protocolVersion)
const handleEdit = useCallback(() => {
+ setPriceRangeState(DEFAULT_PRICE_RANGE_STATE_POOL_EXISTS)
+ setDepositState(DEFAULT_DEPOSIT_STATE)
setStep(PositionFlowStep.SELECT_TOKENS_AND_FEE_TIER)
- }, [setStep])
+ }, [setDepositState, setPriceRangeState, setStep])
return (
@@ -45,6 +57,9 @@ export const EditSelectTokensStep = (props?: FlexProps) => {
/
{token1?.symbol}
+
+
+
)
@@ -59,13 +74,15 @@ export const EditRangeSelectionStep = (props?: FlexProps) => {
priceRangeState: { priceInverted },
derivedPriceRangeInfo,
} = usePriceRangeContext()
+ const { setDepositState } = useDepositContext()
const { formatNumberOrString } = useLocalizationContext()
const [baseCurrency, quoteCurrency] = getInvertedTuple(currencies, priceInverted)
const handleEdit = useCallback(() => {
+ setDepositState(DEFAULT_DEPOSIT_STATE)
setStep(PositionFlowStep.PRICE_RANGE)
- }, [setStep])
+ }, [setDepositState, setStep])
const formattedPrices = useMemo(() => {
return formatPrices(derivedPriceRangeInfo, formatNumberOrString)
diff --git a/apps/web/src/pages/Pool/Positions/create/RangeSelectionStep.tsx b/apps/web/src/pages/Pool/Positions/create/RangeSelectionStep.tsx
index 026aa1c5bd6..32a72d01315 100644
--- a/apps/web/src/pages/Pool/Positions/create/RangeSelectionStep.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/RangeSelectionStep.tsx
@@ -4,7 +4,7 @@ import { Currency, Price } from '@uniswap/sdk-core'
import { calculateInvertedPrice } from 'components/Liquidity/utils'
import LiquidityChartRangeInput from 'components/LiquidityChartRangeInput'
import { useCreatePositionContext, usePriceRangeContext } from 'pages/Pool/Positions/create/CreatePositionContext'
-import { Container, CreatingPoolInfo } from 'pages/Pool/Positions/create/shared'
+import { Container } from 'pages/Pool/Positions/create/shared'
import { getInvertedTuple } from 'pages/Pool/Positions/create/utils'
import { useCallback, useMemo, useState } from 'react'
import { Minus, Plus } from 'react-feather'
@@ -169,11 +169,13 @@ function RangeInput({
input,
decrement,
increment,
+ showIncrementButtons = true,
}: {
value: string
input: RangeSelectionInput
decrement: () => string
increment: () => string
+ showIncrementButtons?: boolean
}) {
const colors = useSporeColors()
const { t } = useTranslation()
@@ -257,14 +259,22 @@ function RangeInput({
/>
-
-
-
-
-
-
-
-
+ {showIncrementButtons && (
+
+
+
+
+
+
+
+
+ )}
)
}
@@ -273,7 +283,6 @@ export const SelectPriceRangeStepV2 = ({ onContinue, ...rest }: { onContinue: ()
return (
-
-
-
}
{feeTier.title}
- {feeTier.selectionPercent && (
+ {feeTier.selectionPercent && feeTier.selectionPercent.greaterThan(0) && (
{formatPercent(feeTier.selectionPercent)} select
@@ -172,6 +174,8 @@ export function SelectTokensStep({
switch (currencySearchInputState) {
case PositionField.TOKEN0:
case PositionField.TOKEN1:
+ // If the tokens change, we want to reset the default fee tier in the useEffect below.
+ setDefaultFeeTierSelected(false)
setPositionState((prevState) => ({
...prevState,
currencyInputs: { ...prevState.currencyInputs, [currencySearchInputState]: currency },
@@ -191,34 +195,26 @@ export function SelectTokensStep({
[setPositionState],
)
- const feeTierData = useAllFeeTierPoolData({
+ const { feeTierData, hasExistingFeeTiers } = useAllFeeTierPoolData({
chainId: token0?.chainId,
protocolVersion,
currencies: derivedPositionInfo.currencies,
})
- const feeTiers: FeeTier[] = [
- {
- value: { feeAmount: FeeAmount.LOWEST, tickSpacing: TICK_SPACINGS[FeeAmount.LOWEST] },
- title: t(`fee.bestForVeryStable`),
- selectionPercent: feeTierData[FeeAmount.LOWEST]?.percentage,
- },
- {
- value: { feeAmount: FeeAmount.LOW, tickSpacing: TICK_SPACINGS[FeeAmount.LOW] },
- title: t(`fee.bestForStablePairs`),
- selectionPercent: feeTierData[FeeAmount.LOW]?.percentage,
- },
- {
- value: { feeAmount: FeeAmount.MEDIUM, tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM] },
- title: t(`fee.bestForMost`),
- selectionPercent: feeTierData[FeeAmount.MEDIUM]?.percentage,
- },
- {
- value: { feeAmount: FeeAmount.HIGH, tickSpacing: TICK_SPACINGS[FeeAmount.HIGH] },
- title: t(`fee.bestForExotic`),
- selectionPercent: feeTierData[FeeAmount.HIGH]?.percentage,
- },
- ]
+ const feeTiers = getDefaultFeeTiersWithData({ chainId: token0?.chainId, feeTierData, t })
+ const [defaultFeeTierSelected, setDefaultFeeTierSelected] = useState(false)
+ useEffect(() => {
+ if (hasExistingFeeTiers && feeTierData && Object.keys(feeTierData).length > 0 && !defaultFeeTierSelected) {
+ const mostUsedFeeTier = Object.values(feeTierData).reduce((highest, current) => {
+ return current.percentage.greaterThan(highest.percentage) ? current : highest
+ })
+ setDefaultFeeTierSelected(true)
+ setPositionState((prevState) => ({
+ ...prevState,
+ fee: mostUsedFeeTier.fee,
+ }))
+ }
+ }, [defaultFeeTierSelected, feeTierData, hasExistingFeeTiers, setPositionState])
return (
<>
@@ -274,10 +270,14 @@ export function SelectTokensStep({
-
+ {isDynamicFeeTier(fee) ? (
+
+ ) : (
+
+ )}
{fee.feeAmount === FeeAmount.MEDIUM ? (
@@ -294,6 +294,7 @@ export function SelectTokensStep({
- {isShowMoreFeeTiersEnabled && (
-
- {feeTiers.map((feeTier) => (
-
+
+
+ {feeTiers.map((feeTier) => (
+
+ ))}
+
+ {protocolVersion === ProtocolVersion.V4 && (
+ {
+ setFeeTierSearchModalOpen(true)
+ }}
/>
- ))}
+ )}
- )}
- {protocolVersion === ProtocolVersion.V4 && (
- {
- setFeeTierSearchModalOpen(true)
- }}
- />
- )}
+
)}
-
-
-
+
0 ? poolData.pools[0] : undefined
- const pairsQueryEnabled = pairEnabledProtocolVersion(protocolVersion) && validCurrencyInput
- const pairAddress = useMemo(() => {
- return pairsQueryEnabled && validCurrencyInput
- ? computePairAddress({
- factoryAddress: V2_FACTORY_ADDRESSES[sortedCurrencies[0].chainId],
- tokenA: getCurrencyWithWrap(sortedCurrencies[0], protocolVersion),
- tokenB: getCurrencyWithWrap(sortedCurrencies[1], protocolVersion),
- })
- : undefined
- }, [pairsQueryEnabled, protocolVersion, sortedCurrencies, validCurrencyInput])
-
- const { data: pairData, isFetched: pairIsFetched } = useGetPair(
+ const { pairsQueryEnabled, pairAddress, sortedTokens } = useMemo(() => {
+ if (!pairEnabledProtocolVersion(protocolVersion)) {
+ return {
+ pairsQueryEnabled: false,
+ } as const
+ }
+
+ const sortedTokens = getSortedCurrenciesTuple(
+ getCurrencyWithWrap(sortedCurrencies[0], protocolVersion),
+ getCurrencyWithWrap(sortedCurrencies[1], protocolVersion),
+ )
+
+ if (!validateCurrencyInput(sortedTokens)) {
+ return {
+ pairsQueryEnabled: false,
+ } as const
+ }
+
+ return {
+ pairsQueryEnabled: true,
+ pairAddress: computePairAddress({
+ factoryAddress: V2_FACTORY_ADDRESSES[sortedTokens[0].chainId],
+ tokenA: sortedTokens[0],
+ tokenB: sortedTokens[1],
+ }),
+ sortedTokens,
+ } as const
+ }, [protocolVersion, sortedCurrencies])
+
+ const {
+ data: pairData,
+ isFetched: pairIsFetched,
+ isLoading: pairIsLoading,
+ } = useGetPair(
{
chainId: chainId ?? (UniverseChainId.Mainnet as number),
pairAddress,
@@ -102,8 +124,8 @@ export function useDerivedPositionInfo(state: PositionState): CreatePositionInfo
const pair = pairsQueryEnabled
? getPairFromRest({
pair: pairData?.pair,
- token0: getCurrencyWithWrap(sortedCurrencies[0], protocolVersion),
- token1: getCurrencyWithWrap(sortedCurrencies[1], protocolVersion),
+ token0: sortedTokens[0],
+ token1: sortedTokens[1],
})
: undefined
@@ -138,6 +160,7 @@ export function useDerivedPositionInfo(state: PositionState): CreatePositionInfo
protocolVersion,
pair,
creatingPoolOrPair,
+ poolOrPairLoading: pairIsLoading,
} satisfies CreateV2PositionInfo
}
@@ -152,6 +175,7 @@ export function useDerivedPositionInfo(state: PositionState): CreatePositionInfo
protocolVersion,
}),
creatingPoolOrPair,
+ poolOrPairLoading: poolIsLoading,
} satisfies CreateV3PositionInfo
}
@@ -166,8 +190,20 @@ export function useDerivedPositionInfo(state: PositionState): CreatePositionInfo
hooks: pool?.hooks?.address || '',
}),
creatingPoolOrPair,
+ poolOrPairLoading: poolIsLoading,
} satisfies CreateV4PositionInfo
- }, [TOKEN0, TOKEN1, protocolVersion, pool, sortedCurrencies, creatingPoolOrPair, pair, poolData?.pools])
+ }, [
+ TOKEN0,
+ TOKEN1,
+ protocolVersion,
+ pool,
+ sortedCurrencies,
+ creatingPoolOrPair,
+ poolIsLoading,
+ pair,
+ pairIsLoading,
+ poolData?.pools,
+ ])
}
export function useDerivedPriceRangeInfo(state: PriceRangeState): PriceRangeInfo {
@@ -368,7 +404,14 @@ export function useDepositInfo(state: UseDepositInfoProps): DepositInfo {
return t('common.noAmount.error')
}
- if (currency0Amount && token0Balance?.lessThan(currency0Amount)) {
+ const insufficientToken0Balance = currency0Amount && token0Balance?.lessThan(currency0Amount)
+ const insufficientToken1Balance = currency1Amount && token1Balance?.lessThan(currency1Amount)
+
+ if (insufficientToken0Balance && insufficientToken1Balance) {
+ return
+ }
+
+ if (insufficientToken0Balance) {
return (
-
-
-
-
-
-
-
-
-
- setCreatePoolInfoDismissed(true)}>
-
-
-
- )
-}
-
export function formatPrices(
derivedPriceRangeInfo: PriceRangeInfo,
formatter: (input: FormatNumberOrStringInput) => string,
diff --git a/apps/web/src/pages/Pool/Positions/create/types.ts b/apps/web/src/pages/Pool/Positions/create/types.ts
index 643c08f1447..1653c707ab8 100644
--- a/apps/web/src/pages/Pool/Positions/create/types.ts
+++ b/apps/web/src/pages/Pool/Positions/create/types.ts
@@ -12,6 +12,17 @@ export type FeeData = {
tickSpacing: number
}
+const DYNAMIC_FEE_AMOUNT = 8388608
+
+export type DynamicFeeData = FeeData & {
+ feeAmount: typeof DYNAMIC_FEE_AMOUNT
+}
+
+export const DYNAMIC_FEE_DATA = {
+ feeAmount: DYNAMIC_FEE_AMOUNT,
+ tickSpacing: 60,
+} as const satisfies DynamicFeeData
+
export enum PositionFlowStep {
SELECT_TOKENS_AND_FEE_TIER,
PRICE_RANGE,
@@ -37,6 +48,7 @@ type BaseCreatePositionInfo = {
protocolVersion: ProtocolVersion
currencies: [OptionalCurrency, OptionalCurrency]
creatingPoolOrPair?: boolean
+ poolOrPairLoading?: boolean
}
export type CreateV4PositionInfo = BaseCreatePositionInfo & {
@@ -64,8 +76,6 @@ export type CreatePositionContextType = {
derivedPositionInfo: CreatePositionInfo
feeTierSearchModalOpen: boolean
setFeeTierSearchModalOpen: Dispatch>
- createPoolInfoDismissed: boolean
- setCreatePoolInfoDismissed: Dispatch>
}
export interface PriceRangeState {
diff --git a/apps/web/src/pages/Pool/Positions/create/utils.tsx b/apps/web/src/pages/Pool/Positions/create/utils.tsx
index 5f7ebe5a527..80121966096 100644
--- a/apps/web/src/pages/Pool/Positions/create/utils.tsx
+++ b/apps/web/src/pages/Pool/Positions/create/utils.tsx
@@ -48,6 +48,7 @@ import { areCurrenciesEqual } from 'uniswap/src/utils/currencyId'
import { getTickToPrice, getV4TickToPrice } from 'utils/getTickToPrice'
type OptionalToken = Token | undefined
+export function getSortedCurrenciesTuple(a: Token, b: Token): [Token, Token]
export function getSortedCurrenciesTuple(a: OptionalToken, b: OptionalToken): [OptionalToken, OptionalToken]
export function getSortedCurrenciesTuple(a: OptionalCurrency, b: OptionalCurrency): [OptionalCurrency, OptionalCurrency]
export function getSortedCurrenciesTuple(
@@ -65,6 +66,14 @@ export function getSortedCurrenciesTuple(
return a.sortsBefore(b) ? [a, b] : [b, a]
}
+export function getSortedCurrenciesTupleWithWrap(
+ a: OptionalCurrency,
+ b: OptionalCurrency,
+ protocolVersion: ProtocolVersion,
+): [OptionalCurrency, OptionalCurrency] {
+ return getSortedCurrenciesTuple(getCurrencyWithWrap(a, protocolVersion), getCurrencyWithWrap(b, protocolVersion))
+}
+
export function getCurrencyWithWrap(currency: Currency, protocolVersion: ProtocolVersion.V2 | ProtocolVersion.V3): Token
export function getCurrencyWithWrap(
currency: OptionalCurrency,
@@ -107,9 +116,9 @@ export function getCurrencyAddressWithWrap(
return currency?.wrapped.address
}
-function getCurrencyAddressForTradingApi(currency: Currency): string
-function getCurrencyAddressForTradingApi(currency: OptionalCurrency): string | undefined
-function getCurrencyAddressForTradingApi(currency: OptionalCurrency): string | undefined {
+export function getCurrencyAddressForTradingApi(currency: Currency): string
+export function getCurrencyAddressForTradingApi(currency: OptionalCurrency): string
+export function getCurrencyAddressForTradingApi(currency: OptionalCurrency): string {
return currency?.isToken ? currency.address : ZERO_ADDRESS
}
@@ -127,6 +136,10 @@ export function protocolShouldCalculateTaxes(protocolVersion: ProtocolVersion):
return protocolVersion === ProtocolVersion.V3
}
+export function validateCurrencyInput(currencies: [OptionalToken, OptionalToken]): currencies is [Token, Token]
+export function validateCurrencyInput(
+ currencies: [OptionalCurrency, OptionalCurrency],
+): currencies is [Currency, Currency]
export function validateCurrencyInput(
currencies: [OptionalCurrency, OptionalCurrency],
): currencies is [Currency, Currency] {
@@ -317,8 +330,8 @@ function createMockV3Pool({
const wrappedPrice = new Price(
price.baseCurrency.wrapped,
price.quoteCurrency.wrapped,
- price.numerator.toString(),
- price.denominator.toString(),
+ price.denominator,
+ price.numerator,
)
const invertedPrice = wrappedPrice.baseCurrency.sortsBefore(wrappedPrice.quoteCurrency)
@@ -335,12 +348,14 @@ function createMockV4Pool({
baseToken,
quoteToken,
fee,
+ hook,
price,
invalidPrice,
}: {
baseToken?: Currency
quoteToken?: Currency
fee: FeeData
+ hook?: string
price?: Price
invalidPrice?: boolean
}): V4Pool | undefined {
@@ -355,7 +370,7 @@ function createMockV4Pool({
quoteToken,
fee.feeAmount,
fee.tickSpacing,
- ZERO_ADDRESS,
+ hook ?? ZERO_ADDRESS,
currentSqrt,
JSBI.BigInt(0),
currentTick,
@@ -377,8 +392,8 @@ function createMockPair({
if (baseToken && quoteToken && price) {
return new Pair(
- CurrencyAmount.fromRawAmount(baseToken, price.denominator),
- CurrencyAmount.fromRawAmount(quoteToken, price.numerator),
+ CurrencyAmount.fromRawAmount(baseToken, price.numerator),
+ CurrencyAmount.fromRawAmount(quoteToken, price.denominator),
)
} else {
return undefined
@@ -533,13 +548,14 @@ export function getV3PriceRangeInfo({
getCurrencyWithWrap(baseCurrency, protocolVersion),
getCurrencyWithWrap(quoteCurrency, protocolVersion),
]
- const baseInitialPriceCurrency = state.initialPriceInverted
- ? getCurrencyWithWrap(currencies[0], protocolVersion)
- : getCurrencyWithWrap(currencies[1], protocolVersion)
+ const initialPriceTokens = getInvertedTuple(
+ [getCurrencyWithWrap(currencies[0], protocolVersion), getCurrencyWithWrap(currencies[1], protocolVersion)],
+ state.initialPriceInverted,
+ )
const price = derivedPositionInfo.creatingPoolOrPair
? getInitialPrice({
- baseCurrency: baseInitialPriceCurrency,
+ baseCurrency: initialPriceTokens[0],
sortedCurrencies: sortedTokens,
initialPrice: state.initialPrice,
})
@@ -690,7 +706,7 @@ export function getV4PriceRangeInfo({
positionState: PositionState
derivedPositionInfo: CreateV4PositionInfo
}): V4PriceRangeInfo {
- const { fee } = positionState
+ const { fee, hook } = positionState
const { protocolVersion, currencies, pool } = derivedPositionInfo
const sortedCurrencies = getSortedCurrenciesTuple(currencies[0], currencies[1])
@@ -714,6 +730,7 @@ export function getV4PriceRangeInfo({
baseToken: baseCurrency,
quoteToken: quoteCurrency,
fee,
+ hook,
price,
invalidPrice,
})
diff --git a/apps/web/src/pages/Pool/Positions/index.tsx b/apps/web/src/pages/Pool/Positions/index.tsx
index 286cb4a4d0f..be8947a11ec 100644
--- a/apps/web/src/pages/Pool/Positions/index.tsx
+++ b/apps/web/src/pages/Pool/Positions/index.tsx
@@ -1,11 +1,11 @@
/* eslint-disable-next-line no-restricted-imports */
import { PositionStatus, ProtocolVersion } from '@uniswap/client-pools/dist/pools/v1/types_pb'
+import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks'
import { Pool } from 'components/Icons/Pool'
import { LiquidityPositionCard } from 'components/Liquidity/LiquidityPositionCard'
import { PositionInfo } from 'components/Liquidity/types'
-import { parseRestPosition } from 'components/Liquidity/utils'
+import { getPositionUrl, parseRestPosition } from 'components/Liquidity/utils'
import { LoadingRows } from 'components/Loader/styled'
-import { getChain } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { useAtom } from 'jotai'
import { atomWithStorage } from 'jotai/utils'
@@ -14,13 +14,16 @@ import { LoadingRow } from 'pages/Pool/Positions/shared'
import { useCallback, useMemo, useState } from 'react'
import { ChevronLeft, ChevronRight } from 'react-feather'
import { useNavigate } from 'react-router-dom'
+import { usePendingLPTransactionsChangeListener } from 'state/transactions/hooks'
import { ClickableTamaguiStyle } from 'theme/components'
import { Button, Flex, Text, useSporeColors } from 'ui/src'
+import { InfoCircleFilled } from 'ui/src/components/icons/InfoCircleFilled'
+import { X } from 'ui/src/components/icons/X'
import { iconSizes } from 'ui/src/theme'
import { useGetPositionsQuery } from 'uniswap/src/data/rest/getPositions'
-import { useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
-import { logger } from 'utilities/src/logger/logger'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { Trans, useTranslation } from 'uniswap/src/i18n'
const PAGE_SIZE = 8
@@ -28,6 +31,7 @@ function EmptyPositionsView({ isConnected }: { isConnected: boolean }) {
const colors = useSporeColors()
const { t } = useTranslation()
const navigate = useNavigate()
+ const accountDrawer = useAccountDrawer()
return (
{
+ accountDrawer.toggle()
+ }
+ }
>
@@ -71,38 +83,31 @@ const statusFilterAtom = atomWithStorage('positions-status-fil
export default function Positions() {
const [chainFilter, setChainFilter] = useAtom(chainFilterAtom)
+ const { chains: currentModeChains } = useEnabledChains()
const [versionFilter, setVersionFilter] = useAtom(versionFilterAtom)
const [statusFilter, setStatusFilter] = useAtom(statusFilterAtom)
+ const [closedCTADismissed, setClosedCTADismissed] = useState(false)
const navigate = useNavigate()
const account = useAccount()
const { address, isConnected } = account
const [currentPage, setCurrentPage] = useState(0)
- const { data, isLoading: positionsLoading } = useGetPositionsQuery(
+ const { data, isPlaceholderData, refetch } = useGetPositionsQuery(
{
address,
- chainIds: chainFilter ? [chainFilter] : undefined,
+ chainIds: chainFilter ? [chainFilter] : currentModeChains,
positionStatuses: statusFilter,
protocolVersions: versionFilter,
},
!isConnected,
)
+ usePendingLPTransactionsChangeListener(refetch)
+
const onNavigateToPosition = useCallback(
(position: PositionInfo) => {
- const chainInfo = getChain({ chainId: position.currency0Amount.currency.chainId })
- if (position.version === ProtocolVersion.V2) {
- navigate(`/positions/v2/${chainInfo.urlParam}/${position.liquidityToken.address}`)
- } else if (position.version === ProtocolVersion.V3) {
- navigate(`/positions/v3/${chainInfo.urlParam}/${position.tokenId}`)
- } else if (position.version === ProtocolVersion.V4) {
- navigate(`/positions/v4/${chainInfo.urlParam}/${position.tokenId}`)
- } else {
- logger.error('Invalid position', {
- tags: { file: 'Positions/index.tsx', function: 'onPress' },
- })
- }
+ navigate(getPositionUrl(position))
},
[navigate],
)
@@ -116,7 +121,7 @@ export default function Positions() {
return (
0}
+ showFilters={account.isConnected}
selectedChain={chainFilter}
selectedVersions={versionFilter}
selectedStatus={statusFilter}
@@ -138,9 +143,9 @@ export default function Positions() {
}
}}
/>
- {!positionsLoading ? (
+ {data || !account.address ? (
currentPageItems.length > 0 ? (
-
+
{currentPageItems.map((position, index) => {
return (
position && (
@@ -157,8 +162,7 @@ export default function Positions() {
) : (
)
- ) : null}
- {!data && positionsLoading && (
+ ) : (
@@ -173,6 +177,33 @@ export default function Positions() {
)}
+ {!statusFilter.includes(PositionStatus.CLOSED) && !closedCTADismissed && account.address && (
+
+
+
+
+
+
+
+
+
+
+
+
+ setClosedCTADismissed(true)} cursor="pointer">
+
+
+
+ )}
{!!pageCount && pageCount > 1 && data?.positions && (
void) {
- const isAddLiquidityModalOpen = useModalIsOpen(ModalName.AddLiquidity)
- const isRemoveLiquidityModalOpen = useModalIsOpen(ModalName.RemoveLiquidity)
- const addLiquidityModalOpenPrev = usePrevious(isAddLiquidityModalOpen)
- const removeLiquidityModalOpenPrev = usePrevious(isRemoveLiquidityModalOpen)
-
- useEffect(() => {
- if (addLiquidityModalOpenPrev && !isAddLiquidityModalOpen) {
- refetch()
- }
- if (removeLiquidityModalOpenPrev && !isRemoveLiquidityModalOpen) {
- refetch()
- }
- }, [
- addLiquidityModalOpenPrev,
- removeLiquidityModalOpenPrev,
- isAddLiquidityModalOpen,
- isRemoveLiquidityModalOpen,
- refetch,
- ])
-}
diff --git a/apps/web/src/pages/Pool/index.tsx b/apps/web/src/pages/Pool/index.tsx
index 91c0511ae15..1ca54b1aa92 100644
--- a/apps/web/src/pages/Pool/index.tsx
+++ b/apps/web/src/pages/Pool/index.tsx
@@ -48,7 +48,7 @@ export default function Pool() {
-
+
{t('liquidity.learnMoreLabel')}
()
- const chainInfo = getSupportedGraphQlChain(useChainFromUrlParam())
+ const urlChain = useChainIdFromUrlParam()
+ const chainInfo = urlChain ? getChainInfo(urlChain) : undefined
const { data: poolData, loading } = usePoolData(poolAddress?.toLowerCase() ?? '', chainInfo?.id)
const [isReversed, toggleReversed] = useReducer((x) => !x, false)
const unwrappedTokens = getUnwrappedPoolToken(poolData, chainInfo?.id)
diff --git a/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityForm.tsx b/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityForm.tsx
index a2d1d27c124..d66a46985d7 100644
--- a/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityForm.tsx
+++ b/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityForm.tsx
@@ -1,11 +1,15 @@
+import { LoaderButton } from 'components/Button/LoaderButton'
import { LiquidityModalDetailRows } from 'components/Liquidity/LiquidityModalDetailRows'
import { LiquidityPositionInfo } from 'components/Liquidity/LiquidityPositionInfo'
import { StyledPercentInput } from 'components/PercentInput'
-import { DecreaseLiquidityStep, useLiquidityModalContext } from 'components/RemoveLiquidity/RemoveLiquidityModalContext'
+import {
+ DecreaseLiquidityStep,
+ useRemoveLiquidityModalContext,
+} from 'components/RemoveLiquidity/RemoveLiquidityModalContext'
import { useRemoveLiquidityTxContext } from 'components/RemoveLiquidity/RemoveLiquidityTxContext'
import { ClickablePill } from 'pages/Swap/Buy/PredefinedAmount'
import { NumericalInputMimic, NumericalInputSymbolContainer, NumericalInputWrapper } from 'pages/Swap/common/shared'
-import { Button, Flex, Text, useSporeColors } from 'ui/src'
+import { Flex, Text, useSporeColors } from 'ui/src'
import { Trans, useTranslation } from 'uniswap/src/i18n'
import useResizeObserver from 'use-resize-observer'
@@ -14,7 +18,7 @@ export function RemoveLiquidityForm() {
const { t } = useTranslation()
const colors = useSporeColors()
- const { percent, positionInfo, setPercent, setStep, percentInvalid } = useLiquidityModalContext()
+ const { percent, positionInfo, setPercent, setStep, percentInvalid } = useRemoveLiquidityModalContext()
const removeLiquidityTxContext = useRemoveLiquidityTxContext()
const { gasFeeEstimateUSD, txContext } = removeLiquidityTxContext
@@ -80,17 +84,18 @@ export function RemoveLiquidityForm() {
currency1Amount={currency1Amount}
networkCost={gasFeeEstimateUSD}
/>
- setStep(DecreaseLiquidityStep.Review)}
+ loading={!percentInvalid && !txContext?.txRequest}
+ buttonKey="RemoveLiquidity-continue"
>
{t('common.button.remove')}
-
+
>
)
}
diff --git a/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityModal.tsx b/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityModal.tsx
index d53098a2251..2fb964bc615 100644
--- a/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityModal.tsx
+++ b/apps/web/src/pages/RemoveLiquidity/RemoveLiquidityModal.tsx
@@ -3,7 +3,7 @@ import { LiquidityModalHeader } from 'components/Liquidity/LiquidityModalHeader'
import {
DecreaseLiquidityStep,
RemoveLiquidityModalContextProvider,
- useLiquidityModalContext,
+ useRemoveLiquidityModalContext,
} from 'components/RemoveLiquidity/RemoveLiquidityModalContext'
import { RemoveLiquidityReview } from 'components/RemoveLiquidity/RemoveLiquidityReview'
import { RemoveLiquidityTxContextProvider } from 'components/RemoveLiquidity/RemoveLiquidityTxContext'
@@ -17,7 +17,7 @@ import { useTranslation } from 'uniswap/src/i18n'
function RemoveLiquidityModalInner() {
const closeModal = useCloseModal(ModalName.RemoveLiquidity)
const { t } = useTranslation()
- const { step, setStep } = useLiquidityModalContext()
+ const { step, setStep } = useRemoveLiquidityModalContext()
let modalContent
switch (step) {
diff --git a/apps/web/src/pages/RemoveLiquidity/index.tsx b/apps/web/src/pages/RemoveLiquidity/V2.tsx
similarity index 97%
rename from apps/web/src/pages/RemoveLiquidity/index.tsx
rename to apps/web/src/pages/RemoveLiquidity/V2.tsx
index f1f91aeec0e..69a356bf2cd 100644
--- a/apps/web/src/pages/RemoveLiquidity/index.tsx
+++ b/apps/web/src/pages/RemoveLiquidity/V2.tsx
@@ -24,7 +24,6 @@ import { V2Unsupported } from 'components/V2Unsupported'
import { AutoColumn, ColumnCenter } from 'components/deprecated/Column'
import Row, { RowBetween, RowFixed } from 'components/deprecated/Row'
import { Dots } from 'components/swap/styled'
-import { useIsSupportedChainId } from 'constants/chains'
import { useCurrency } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
import { ApprovalState, useApproveCallback } from 'hooks/useApproveCallback'
@@ -40,7 +39,7 @@ import { PositionPageUnsupportedContent } from 'pages/LegacyPool/PositionPage'
import { ClickableText, MaxButton, Wrapper } from 'pages/LegacyPool/styled'
import { useCallback, useMemo, useState } from 'react'
import { ArrowDown, Plus } from 'react-feather'
-import { useNavigate, useParams } from 'react-router-dom'
+import { Navigate, useNavigate, useParams } from 'react-router-dom'
import { Field } from 'state/burn/actions'
import { useBurnActionHandlers, useBurnState, useDerivedBurnInfo } from 'state/burn/hooks'
import { useTransactionAdder } from 'state/transactions/hooks'
@@ -49,6 +48,10 @@ import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
import { StyledInternalLink, ThemedText } from 'theme/components'
import { Text } from 'ui/src'
import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
+import { useEnabledChains, useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans } from 'uniswap/src/i18n'
@@ -60,11 +63,20 @@ import { currencyId } from 'utils/currencyId'
const DEFAULT_REMOVE_LIQUIDITY_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
-export default function RemoveLiquidityWrapper() {
+export default function RemoveLiquidityV2() {
const { chainId } = useAccount()
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
const isSupportedChain = useIsSupportedChainId(chainId)
const { currencyIdA, currencyIdB } = useParams<{ currencyIdA: string; currencyIdB: string }>()
const [currencyA, currencyB] = [useCurrency(currencyIdA) ?? undefined, useCurrency(currencyIdB) ?? undefined]
+ const { defaultChainId } = useEnabledChains()
+
+ if (isV4EverywhereEnabled) {
+ // TODO(WEB-5361): prefill poolId from legacy URL /remove/ETH/0x123
+ const chainName = toGraphQLChain(chainId ?? defaultChainId).toLowerCase()
+ return
+ }
+
if (isSupportedChain && currencyA !== currencyB) {
return
} else {
diff --git a/apps/web/src/pages/RemoveLiquidity/V3.tsx b/apps/web/src/pages/RemoveLiquidity/V3.tsx
index ce89b465cef..8a03414f301 100644
--- a/apps/web/src/pages/RemoveLiquidity/V3.tsx
+++ b/apps/web/src/pages/RemoveLiquidity/V3.tsx
@@ -15,7 +15,6 @@ import TransactionConfirmationModal, { ConfirmationModalContent } from 'componen
import { AutoColumn } from 'components/deprecated/Column'
import { AutoRow, RowBetween, RowFixed } from 'components/deprecated/Row'
import { Break } from 'components/earn/styled'
-import { useIsSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import useDebouncedChangeHandler from 'hooks/useDebouncedChangeHandler'
@@ -36,6 +35,10 @@ import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
import { ThemedText } from 'theme/components'
import { Switch, Text } from 'ui/src'
import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
+import { useEnabledChains, useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { toGraphQLChain } from 'uniswap/src/features/chains/utils'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { Trans } from 'uniswap/src/i18n'
import { logger } from 'utilities/src/logger/logger'
@@ -50,6 +53,7 @@ const DEFAULT_REMOVE_V3_LIQUIDITY_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
// redirect invalid tokenIds
export default function RemoveLiquidityV3() {
const { chainId } = useAccount()
+ const { defaultChainId } = useEnabledChains()
const isSupportedChain = useIsSupportedChainId(chainId)
const { tokenId } = useParams<{ tokenId: string }>()
const location = useLocation()
@@ -62,6 +66,11 @@ export default function RemoveLiquidityV3() {
}, [tokenId])
const { position, loading } = useV3PositionFromTokenId(parsedTokenId ?? undefined)
+ const isV4EverywhereEnabled = useFeatureFlag(FeatureFlags.V4Everywhere)
+ if (isV4EverywhereEnabled) {
+ const chainName = toGraphQLChain(chainId ?? defaultChainId).toLowerCase()
+ return
+ }
if (parsedTokenId === null || parsedTokenId.eq(0)) {
return
}
diff --git a/apps/web/src/pages/RouteDefinitions.tsx b/apps/web/src/pages/RouteDefinitions.tsx
index a510c44b2f5..8e736d1278b 100644
--- a/apps/web/src/pages/RouteDefinitions.tsx
+++ b/apps/web/src/pages/RouteDefinitions.tsx
@@ -15,7 +15,7 @@ const NftExplore = lazy(() => import('nft/pages/explore'))
const Collection = lazy(() => import('nft/pages/collection'))
const Profile = lazy(() => import('nft/pages/profile'))
const Asset = lazy(() => import('nft/pages/asset/Asset'))
-const AddLiquidityWithTokenRedirects = lazy(() => import('pages/AddLiquidity/redirects'))
+const AddLiquidityV3WithTokenRedirects = lazy(() => import('pages/AddLiquidityV3/redirects'))
const AddLiquidityV2WithTokenRedirects = lazy(() => import('pages/AddLiquidityV2/redirects'))
const RedirectExplore = lazy(() => import('pages/Explore/redirects'))
const MigrateV2 = lazy(() => import('pages/MigrateV2'))
@@ -23,14 +23,22 @@ const MigrateV2Pair = lazy(() => import('pages/MigrateV2/MigrateV2Pair'))
const MigrateV3 = lazy(() => import('pages/MigrateV3'))
const NotFound = lazy(() => import('pages/NotFound'))
const Pool = lazy(() => import('pages/Pool'))
-const LegacyPool = lazy(() => import('pages/LegacyPool'))
-const LegacyPositionPage = lazy(() => import('pages/LegacyPool/PositionPage'))
+const LegacyPoolRedirects = lazy(() =>
+ import('pages/LegacyPool/redirects').then((module) => ({ default: module.LegacyPoolRedirects })),
+)
+const PoolFinderRedirects = lazy(() =>
+ import('pages/LegacyPool/redirects').then((module) => ({ default: module.PoolFinderRedirects })),
+)
+const LegacyPoolV2Redirects = lazy(() =>
+ import('pages/LegacyPool/redirects').then((module) => ({ default: module.LegacyPoolV2Redirects })),
+)
+const LegacyPositionPageRedirects = lazy(() =>
+ import('pages/LegacyPool/redirects').then((module) => ({ default: module.LegacyPositionPageRedirects })),
+)
const PositionPage = lazy(() => import('pages/Pool/Positions/PositionPage'))
const V2PositionPage = lazy(() => import('pages/Pool/Positions/V2PositionPage'))
-const LegacyPoolV2 = lazy(() => import('pages/LegacyPool/v2'))
const PoolDetails = lazy(() => import('pages/PoolDetails'))
-const PoolFinder = lazy(() => import('pages/PoolFinder'))
-const RemoveLiquidity = lazy(() => import('pages/RemoveLiquidity'))
+const RemoveLiquidityV2 = lazy(() => import('pages/RemoveLiquidity/V2'))
const RemoveLiquidityV3 = lazy(() => import('pages/RemoveLiquidity/V3'))
const TokenDetails = lazy(() => import('pages/TokenDetails'))
@@ -248,49 +256,49 @@ export const routes: RouteDefinition[] = [
// Legacy pool routes
createRouteDefinition({
path: '/pool',
- getElement: () => ,
+ getElement: () => ,
getTitle: getPositionPageTitle,
getDescription: getPositionPageDescription,
}),
createRouteDefinition({
path: '/pool/v2/find',
- getElement: () => ,
- getTitle: () => t('title.importLiquidityv2'),
- getDescription: () => t('title.useImportTool'),
+ getElement: () => ,
+ getTitle: getPositionPageDescription,
+ getDescription: getPositionPageDescription,
}),
createRouteDefinition({
path: '/pool/v2',
- getElement: () => ,
+ getElement: () => ,
getTitle: getPositionPageTitle,
getDescription: getPositionPageDescription,
}),
createRouteDefinition({
path: '/pool/:tokenId',
- getElement: () => ,
+ getElement: () => ,
getTitle: getPositionPageTitle,
getDescription: getPositionPageDescription,
}),
createRouteDefinition({
path: '/pools/v2/find',
- getElement: () => ,
- getTitle: () => t('title.importLiquidityv2'),
- getDescription: () => t('title.useImportTool'),
+ getElement: () => ,
+ getTitle: getPositionPageTitle,
+ getDescription: getPositionPageDescription,
}),
createRouteDefinition({
path: '/pools/v2',
- getElement: () => ,
+ getElement: () => ,
getTitle: getPositionPageTitle,
getDescription: getPositionPageDescription,
}),
createRouteDefinition({
path: '/pools',
- getElement: () => ,
+ getElement: () => ,
getTitle: getPositionPageTitle,
getDescription: getPositionPageDescription,
}),
createRouteDefinition({
path: '/pools/:tokenId',
- getElement: () => ,
+ getElement: () => ,
getTitle: getPositionPageTitle,
getDescription: getPositionPageDescription,
}),
@@ -309,13 +317,13 @@ export const routes: RouteDefinition[] = [
':currencyIdA/:currencyIdB/:feeAmount',
':currencyIdA/:currencyIdB/:feeAmount/:tokenId',
],
- getElement: () => ,
+ getElement: () => ,
getTitle: getAddLiquidityPageTitle,
getDescription: () => StaticTitlesAndDescriptions.AddLiquidityDescription,
}),
createRouteDefinition({
path: '/remove/v2/:currencyIdA/:currencyIdB',
- getElement: () => ,
+ getElement: () => ,
getTitle: () => t('title.removeLiquidityv2'),
getDescription: () => t('title.removeTokensv2'),
}),
diff --git a/apps/web/src/pages/Swap/Buy/BuyForm.tsx b/apps/web/src/pages/Swap/Buy/BuyForm.tsx
index 788f48a6c3f..f6ac17c821b 100644
--- a/apps/web/src/pages/Swap/Buy/BuyForm.tsx
+++ b/apps/web/src/pages/Swap/Buy/BuyForm.tsx
@@ -1,6 +1,4 @@
import { useAccount } from 'hooks/useAccount'
-import { useActiveLocalCurrencyComponents } from 'hooks/useActiveLocalCurrency'
-import useParsedQueryString from 'hooks/useParsedQueryString'
import { BuyFormButton } from 'pages/Swap/Buy/BuyFormButton'
import { BuyFormContextProvider, ethCurrencyInfo, useBuyFormContext } from 'pages/Swap/Buy/BuyFormContext'
import { ChooseProviderModal } from 'pages/Swap/Buy/ChooseProviderModal'
@@ -16,6 +14,9 @@ import {
} from 'pages/Swap/common/shared'
import { useEffect } from 'react'
import { Flex, Text, styled } from 'ui/src'
+import { useUrlContext } from 'uniswap/src/contexts/UrlContext'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { useAppFiatCurrency, useFiatCurrencyComponents } from 'uniswap/src/features/fiatCurrency/hooks'
import { FiatOnRampCountryPicker } from 'uniswap/src/features/fiatOnRamp/FiatOnRampCountryPicker'
import { SelectTokenButton } from 'uniswap/src/features/fiatOnRamp/SelectTokenButton'
import { useFiatOnRampAggregatorGetCountryQuery } from 'uniswap/src/features/fiatOnRamp/api'
@@ -23,7 +24,6 @@ import Trace from 'uniswap/src/features/telemetry/Trace'
import { FiatOnRampEventName, InterfacePageNameLocal } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import useResizeObserver from 'use-resize-observer'
import { useFormatter } from 'utils/formatNumbers'
@@ -56,7 +56,8 @@ function BuyFormInner({ disabled }: BuyFormProps) {
const account = useAccount()
const { t } = useTranslation()
const { convertToFiatAmount } = useFormatter()
- const { symbol: fiatSymbol } = useActiveLocalCurrencyComponents()
+ const fiatCurrency = useAppFiatCurrency()
+ const { symbol: fiatSymbol } = useFiatCurrencyComponents(fiatCurrency)
const { buyFormState, setBuyFormState, derivedBuyFormInfo } = useBuyFormContext()
const { inputAmount, selectedCountry, quoteCurrency, currencyModalOpen, countryModalOpen, providerModalOpen } =
@@ -82,6 +83,7 @@ function BuyFormInner({ disabled }: BuyFormProps) {
}
}, [buyFormState.selectedCountry, countryResult, selectedCountry, setBuyFormState])
+ const { useParsedQueryString } = useUrlContext()
const parsedQs = useParsedQueryString()
useEffect(() => {
const quoteCurrencyCode = parsedQs.quoteCurrencyCode
diff --git a/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx b/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx
index c12c63400fe..7f2c789e943 100644
--- a/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx
+++ b/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx
@@ -1,9 +1,9 @@
import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks'
+import { LoaderButton } from 'components/Button/LoaderButton'
import { ButtonLight } from 'components/Button/buttons'
import { ConnectWalletButtonText } from 'components/NavBar/accountCTAsExperimentUtils'
import { useBuyFormContext } from 'pages/Swap/Buy/BuyFormContext'
-import { Button, Flex, SpinningLoader, Text, WidthAnimator } from 'ui/src'
-import { iconSizes } from 'ui/src/theme'
+import { Button, Text } from 'ui/src'
import { useTranslation } from 'uniswap/src/i18n'
import { useAccount } from 'wagmi'
@@ -46,25 +46,17 @@ export function BuyFormButton({ forceDisabled }: BuyFormButtonProps) {
}
return (
- {
setBuyFormState((prev) => ({ ...prev, providerModalOpen: true }))
}}
+ loading={fetchingQuotes}
>
-
-
-
-
-
-
-
- {t('common.button.continue')}
-
-
-
+
+ {t('common.button.continue')}
+
+
)
}
diff --git a/apps/web/src/pages/Swap/Buy/BuyFormContext.tsx b/apps/web/src/pages/Swap/Buy/BuyFormContext.tsx
index 8f75a95209b..46bcf138686 100644
--- a/apps/web/src/pages/Swap/Buy/BuyFormContext.tsx
+++ b/apps/web/src/pages/Swap/Buy/BuyFormContext.tsx
@@ -5,6 +5,7 @@ import { formatFiatOnRampFiatAmount } from 'pages/Swap/Buy/shared'
import { Dispatch, PropsWithChildren, SetStateAction, createContext, useContext, useMemo, useState } from 'react'
import { buildPartialCurrencyInfo } from 'uniswap/src/constants/routing'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import {
useFiatOnRampAggregatorCountryListQuery,
useFiatOnRampAggregatorCryptoQuoteQuery,
@@ -15,6 +16,7 @@ import {
FORSupportedCountriesResponse,
FiatCurrencyInfo,
FiatOnRampCurrency,
+ RampDirection,
} from 'uniswap/src/features/fiatOnRamp/types'
import {
InvalidRequestAmountTooLow,
@@ -23,7 +25,6 @@ import {
isInvalidRequestAmountTooLow,
} from 'uniswap/src/features/fiatOnRamp/utils'
import { t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { useAccount } from 'wagmi'
class BuyFormError extends Error {
@@ -102,7 +103,9 @@ function useDerivedBuyFormInfo(state: BuyFormState): BuyInfo {
const { meldSupportedFiatCurrency, notAvailableInThisRegion } = useMeldFiatCurrencyInfo(state.selectedCountry)
- const { data: countryOptionsResult } = useFiatOnRampAggregatorCountryListQuery()
+ const { data: countryOptionsResult } = useFiatOnRampAggregatorCountryListQuery({
+ rampDirection: RampDirection.ONRAMP,
+ })
const supportedTokens = useFiatOnRampSupportedTokens(meldSupportedFiatCurrency, state.selectedCountry?.countryCode)
const {
diff --git a/apps/web/src/pages/Swap/Buy/hooks.ts b/apps/web/src/pages/Swap/Buy/hooks.ts
index ec8eba69460..ff1e9291d2e 100644
--- a/apps/web/src/pages/Swap/Buy/hooks.ts
+++ b/apps/web/src/pages/Swap/Buy/hooks.ts
@@ -1,8 +1,10 @@
import { meldSupportedCurrencyToCurrencyInfo } from 'graphql/data/types'
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
-import { useActiveLocale } from 'hooks/useActiveLocale'
import { useMemo } from 'react'
-import { getFiatCurrencyName } from 'uniswap/src/features/fiatCurrency/hooks'
+import {
+ getFiatCurrencyName,
+ useAppFiatCurrency,
+ useFiatCurrencyComponents,
+} from 'uniswap/src/features/fiatCurrency/hooks'
import {
useFiatOnRampAggregatorSupportedFiatCurrenciesQuery,
useFiatOnRampAggregatorSupportedTokensQuery,
@@ -34,8 +36,8 @@ export function useMeldFiatCurrencyInfo(selectedCountry?: FORCountry): FiatOnRam
countryCode: selectedCountry?.countryCode ?? 'US',
})
- const activeLocale = useActiveLocale()
- const activeLocalCurrency = useActiveLocalCurrency()
+ const activeLocalCurrency = useAppFiatCurrency()
+ const fiatCurrencyComponents = useFiatCurrencyComponents(activeLocalCurrency)
const { t } = useTranslation()
const appFiatCurrencySupported =
@@ -44,16 +46,15 @@ export function useMeldFiatCurrencyInfo(selectedCountry?: FORCountry): FiatOnRam
(currency): boolean => activeLocalCurrency.toLowerCase() === currency.fiatCurrencyCode.toLowerCase(),
)
const meldSupportedFiatCurrency: FiatCurrencyInfo = useMemo(() => {
- const activeLocalCurrencyComponents = getFiatCurrencyComponents(activeLocale, activeLocalCurrency)
const { name, shortName } = getFiatCurrencyName(t, activeLocalCurrency)
const activeLocalCurrencyFiatCurrencyInfo: FiatCurrencyInfo = {
- ...activeLocalCurrencyComponents,
+ ...fiatCurrencyComponents,
name,
shortName,
code: activeLocalCurrency,
}
return appFiatCurrencySupported ? activeLocalCurrencyFiatCurrencyInfo : fallbackCurrencyInfo
- }, [activeLocalCurrency, activeLocale, appFiatCurrencySupported, t])
+ }, [activeLocalCurrency, appFiatCurrencySupported, fiatCurrencyComponents, t])
return {
meldSupportedFiatCurrency,
diff --git a/apps/web/src/pages/Swap/Limit/LimitForm.tsx b/apps/web/src/pages/Swap/Limit/LimitForm.tsx
index fe90706ce94..a56ee65b735 100644
--- a/apps/web/src/pages/Swap/Limit/LimitForm.tsx
+++ b/apps/web/src/pages/Swap/Limit/LimitForm.tsx
@@ -16,9 +16,9 @@ import { ConnectWalletButtonText } from 'components/NavBar/accountCTAsExperiment
import Column from 'components/deprecated/Column'
import Row from 'components/deprecated/Row'
import { ArrowContainer, ArrowWrapper, SwapSection } from 'components/swap/styled'
-import { getChain, useIsSupportedChainId, useIsUniswapXSupportedChain } from 'constants/chains'
import { ZERO_PERCENT } from 'constants/misc'
import { useAccount } from 'hooks/useAccount'
+import { useIsUniswapXSupportedChain } from 'hooks/useIsUniswapXSupportedChain'
import usePermit2Allowance, { AllowanceState } from 'hooks/usePermit2Allowance'
import { SwapResult, useSwapCallback } from 'hooks/useSwapCallback'
import { useUSDPrice } from 'hooks/useUSDPrice'
@@ -39,6 +39,8 @@ import { Anchor, Text, styled as tamaguiStyled } from 'ui/src'
import { AlertTriangleFilled } from 'ui/src/components/icons/AlertTriangleFilled'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { uniswapUrls } from 'uniswap/src/constants/urls'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
import { Locale } from 'uniswap/src/features/language/constants'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { ElementName, InterfacePageNameLocal } from 'uniswap/src/features/telemetry/constants'
@@ -206,7 +208,7 @@ function LimitForm({ onCurrencyChange }: LimitFormProps) {
useEffect(() => {
if (!outputCurrency && isSupportedChain) {
- const stablecoinCurrency = getChain({ chainId }).spotPriceStablecoinAmount.currency
+ const stablecoinCurrency = getChainInfo(chainId).spotPriceStablecoinAmount.currency
onSelectCurrency(
'outputCurrency',
inputCurrency?.equals(stablecoinCurrency) ? nativeOnChain(chainId) : stablecoinCurrency,
@@ -220,7 +222,7 @@ function LimitForm({ onCurrencyChange }: LimitFormProps) {
? [inputCurrency, outputCurrency]
: [outputCurrency, inputCurrency]
if (nativeCurrency.wrapped.equals(nonNativeCurrency)) {
- onSelectCurrency('outputCurrency', getChain({ chainId }).spotPriceStablecoinAmount.currency)
+ onSelectCurrency('outputCurrency', getChainInfo(chainId).spotPriceStablecoinAmount.currency)
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
diff --git a/apps/web/src/pages/Swap/Send/SendCurrencyInputForm.tsx b/apps/web/src/pages/Swap/Send/SendCurrencyInputForm.tsx
index d3025def6d3..066445b5a62 100644
--- a/apps/web/src/pages/Swap/Send/SendCurrencyInputForm.tsx
+++ b/apps/web/src/pages/Swap/Send/SendCurrencyInputForm.tsx
@@ -8,9 +8,7 @@ import { isInputGreaterThanDecimals } from 'components/NumericalInput'
import CurrencySearchModal from 'components/SearchModal/CurrencySearchModal'
import Column from 'components/deprecated/Column'
import Row, { RowBetween } from 'components/deprecated/Row'
-import { getChain, useSupportedChainId } from 'constants/chains'
import { PrefetchBalancesWrapper } from 'graphql/data/apollo/AdaptiveTokenBalancesProvider'
-import { useActiveLocalCurrency, useActiveLocalCurrencyComponents } from 'hooks/useActiveLocalCurrency'
import { useUSDPrice } from 'hooks/useUSDPrice'
import styled, { css } from 'lib/styled-components'
import {
@@ -28,10 +26,12 @@ import { useSwapAndLimitContext } from 'state/swap/useSwapContext'
import { ClickableStyle, ThemedText } from 'theme/components'
import { Text } from 'ui/src'
import { ArrowUpDown } from 'ui/src/components/icons/ArrowUpDown'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useEnabledChains, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { useAppFiatCurrency, useFiatCurrencyComponents } from 'uniswap/src/features/fiatCurrency/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import useResizeObserver from 'use-resize-observer'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { maxAmountSpend } from 'utils/maxAmountSpend'
@@ -114,7 +114,7 @@ const AlternateCurrencyDisplayRow = styled(Row)<{ $disabled: boolean }>`
const AlternateCurrencyDisplay = ({ disabled, onToggle }: { disabled: boolean; onToggle: () => void }) => {
const { formatConvertedFiatNumberOrString, formatNumberOrString } = useFormatter()
- const activeCurrency = useActiveLocalCurrency()
+ const activeCurrency = useAppFiatCurrency()
const { sendState, derivedSendInfo } = useSendContext()
const { inputCurrency, inputInFiat } = sendState
@@ -188,10 +188,12 @@ export default function SendCurrencyInputForm({
onCurrencyChange?: (selected: CurrencyState) => void
}) {
const { chainId } = useSwapAndLimitContext()
- const supportedChain = useSupportedChainId(chainId)
+ const { defaultChainId } = useEnabledChains()
+ const supportedChainId = useSupportedChainId(chainId)
const { isTestnetModeEnabled } = useEnabledChains()
const { formatCurrencyAmount } = useFormatter()
- const { symbol: fiatSymbol } = useActiveLocalCurrencyComponents()
+ const appFiatCurrency = useAppFiatCurrency()
+ const { symbol: fiatSymbol } = useFiatCurrencyComponents(appFiatCurrency)
const { formatNumber } = useFormatter()
const { sendState, setSendState, derivedSendInfo } = useSendContext()
@@ -202,8 +204,8 @@ export default function SendCurrencyInputForm({
const [tokenSelectorOpen, setTokenSelectorOpen] = useState(false)
const fiatCurrency = useMemo(
- () => getChain({ chainId: supportedChain, withFallback: true }).spotPriceStablecoinAmount.currency,
- [supportedChain],
+ () => getChainInfo(supportedChainId ?? defaultChainId).spotPriceStablecoinAmount.currency,
+ [defaultChainId, supportedChainId],
)
const fiatCurrencyEqualsTransferCurrency = !!inputCurrency && fiatCurrency.equals(inputCurrency)
diff --git a/apps/web/src/pages/Swap/Send/SendForm.tsx b/apps/web/src/pages/Swap/Send/SendForm.tsx
index 17a3e7ec3f0..fea263ef01b 100644
--- a/apps/web/src/pages/Swap/Send/SendForm.tsx
+++ b/apps/web/src/pages/Swap/Send/SendForm.tsx
@@ -3,7 +3,6 @@ import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks'
import { ButtonLight, ButtonPrimary } from 'components/Button/buttons'
import { ConnectWalletButtonText } from 'components/NavBar/accountCTAsExperimentUtils'
import Column from 'components/deprecated/Column'
-import { useIsSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import { useGroupedRecentTransfers } from 'hooks/useGroupedRecentTransfers'
import useSelectChain from 'hooks/useSelectChain'
@@ -17,7 +16,8 @@ import { useCallback, useEffect, useMemo, useState } from 'react'
import { SendContextProvider, useSendContext } from 'state/send/SendContext'
import { CurrencyState } from 'state/swap/types'
import { useSwapAndLimitContext } from 'state/swap/useSwapContext'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { useIsSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { getChainLabel } from 'uniswap/src/features/chains/utils'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { InterfacePageNameLocal } from 'uniswap/src/features/telemetry/constants'
import { Trans } from 'uniswap/src/i18n'
@@ -205,7 +205,7 @@ function SendFormInner({ disableTokenInputs = false, onCurrencyChange }: SendFor
await selectChain(initialChainId)}>
) : (
diff --git a/apps/web/src/pages/Swap/Send/SendReviewModal.tsx b/apps/web/src/pages/Swap/Send/SendReviewModal.tsx
index 028298625fa..ba40223f522 100644
--- a/apps/web/src/pages/Swap/Send/SendReviewModal.tsx
+++ b/apps/web/src/pages/Swap/Send/SendReviewModal.tsx
@@ -15,9 +15,9 @@ import { useSwapAndLimitContext } from 'state/swap/useSwapContext'
import { Separator, ThemedText } from 'theme/components'
import { capitalize } from 'tsafe'
import { Unitag } from 'ui/src/components/icons/Unitag'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { Trans, useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { shortenAddress } from 'utilities/src/addresses'
import { NumberType, useFormatter } from 'utils/formatNumbers'
diff --git a/apps/web/src/pages/Swap/SwapForm.tsx b/apps/web/src/pages/Swap/SwapForm.tsx
index ed575db0efa..23135029a71 100644
--- a/apps/web/src/pages/Swap/SwapForm.tsx
+++ b/apps/web/src/pages/Swap/SwapForm.tsx
@@ -21,7 +21,6 @@ import PriceImpactModal from 'components/swap/PriceImpactModal'
import SwapDetailsDropdown from 'components/swap/SwapDetailsDropdown'
import confirmPriceImpactWithoutFee from 'components/swap/confirmPriceImpactWithoutFee'
import { ArrowContainer, ArrowWrapper, OutputSwapSection, SwapSection } from 'components/swap/styled'
-import { useIsSupportedChainId, useSupportedChainId } from 'constants/chains'
import { useCurrencyInfo } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
import { useIsLandingPage } from 'hooks/useIsLandingPage'
@@ -49,15 +48,16 @@ import { CurrencyState } from 'state/swap/types'
import { useSwapAndLimitContext, useSwapContext } from 'state/swap/useSwapContext'
import { ExternalLink, ThemedText } from 'theme/components'
import { Text } from 'ui/src'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useIsSupportedChainId, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { getChainLabel } from 'uniswap/src/features/chains/utils'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { maybeLogFirstSwapAction } from 'uniswap/src/features/transactions/swap/utils/maybeLogFirstSwapAction'
import { WrapType } from 'uniswap/src/features/transactions/types/wrap'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { CurrencyField } from 'uniswap/src/types/currency'
import { logger } from 'utilities/src/logger/logger'
import { useTrace } from 'utilities/src/telemetry/trace/TraceContext'
@@ -98,15 +98,22 @@ export function SwapForm({
setDismissTokenWarning(true)
}, [])
- // dismiss warning if all imported tokens are in active lists
- const urlTokensNotInDefault = useMemo(() => {
- return prefilledInputCurrencyInfo || prefilledOutputCurrencyInfo
- ? [prefilledInputCurrencyInfo, prefilledOutputCurrencyInfo]
- .filter((token): token is CurrencyInfo => {
- return (token?.currency.isToken && token.safetyLevel !== SafetyLevel.Verified) ?? false
- })
- .map((token: CurrencyInfo) => token.currency as Token)
- : []
+ // dismiss warning if prefilled tokens don't have warnings
+ const prefilledTokensWithWarnings: { field: CurrencyField; token: Token }[] = useMemo(() => {
+ const tokens = []
+ if (
+ prefilledInputCurrencyInfo?.currency.isToken &&
+ prefilledInputCurrencyInfo.safetyLevel !== SafetyLevel.Verified
+ ) {
+ tokens.push({ field: CurrencyField.INPUT, token: prefilledInputCurrencyInfo.currency as Token })
+ }
+ if (
+ prefilledOutputCurrencyInfo?.currency.isToken &&
+ prefilledOutputCurrencyInfo.safetyLevel !== SafetyLevel.Verified
+ ) {
+ tokens.push({ field: CurrencyField.OUTPUT, token: prefilledOutputCurrencyInfo.currency as Token })
+ }
+ return tokens
}, [prefilledInputCurrencyInfo, prefilledOutputCurrencyInfo])
const theme = useTheme()
@@ -505,23 +512,25 @@ export function SwapForm({
return (
<>
- 0 && !dismissTokenWarning}
- token0={urlTokensNotInDefault[0]}
- token1={urlTokensNotInDefault[1]}
- onAcknowledge={handleConfirmTokenWarning}
- onReject={() => {
- setDismissTokenWarning(true)
- onCurrencySelection(CurrencyField.INPUT, undefined)
- onCurrencySelection(CurrencyField.OUTPUT, undefined)
- }}
- closeModalOnly={() => {
- setDismissTokenWarning(true)
- }}
- onToken0BlockAcknowledged={() => onCurrencySelection(CurrencyField.INPUT, undefined)}
- onToken1BlockAcknowledged={() => onCurrencySelection(CurrencyField.OUTPUT, undefined)}
- showCancel={true}
- />
+ {prefilledTokensWithWarnings.length >= 1 && (
+ = 1 && !dismissTokenWarning}
+ token0={prefilledTokensWithWarnings[0].token}
+ token1={prefilledTokensWithWarnings[1]?.token}
+ onAcknowledge={handleConfirmTokenWarning}
+ onReject={() => {
+ setDismissTokenWarning(true)
+ onCurrencySelection(CurrencyField.INPUT, undefined)
+ onCurrencySelection(CurrencyField.OUTPUT, undefined)
+ }}
+ closeModalOnly={() => {
+ setDismissTokenWarning(true)
+ }}
+ onToken0BlockAcknowledged={() => onCurrencySelection(prefilledTokensWithWarnings[0].field, undefined)}
+ onToken1BlockAcknowledged={() => onCurrencySelection(prefilledTokensWithWarnings[1].field, undefined)}
+ showCancel={true}
+ />
+ )}
{trade && showConfirm && (
@@ -691,7 +700,7 @@ export function SwapForm({
await selectChain(initialChainId)}>
) : showWrap ? (
diff --git a/apps/web/src/pages/Swap/index.tsx b/apps/web/src/pages/Swap/index.tsx
index 79ddfb5460c..b7afc883c0f 100644
--- a/apps/web/src/pages/Swap/index.tsx
+++ b/apps/web/src/pages/Swap/index.tsx
@@ -27,10 +27,10 @@ import { AppTFunction } from 'ui/src/i18n/types'
import { zIndices } from 'ui/src/theme'
import { useUniswapContext } from 'uniswap/src/contexts/UniswapContext'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { InterfaceEventNameLocal } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
@@ -46,7 +46,6 @@ import { useSwapPrefilledState } from 'uniswap/src/features/transactions/swap/ho
import { Deadline } from 'uniswap/src/features/transactions/swap/settings/configs/Deadline'
import { currencyToAsset } from 'uniswap/src/features/transactions/swap/utils/asset'
import { useTranslation } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { CurrencyField } from 'uniswap/src/types/currency'
import { SwapTab } from 'uniswap/src/types/screens/interface'
import { currencyId } from 'uniswap/src/utils/currencyId'
@@ -184,7 +183,6 @@ export function Swap({
swapRedirectCallback={swapRedirectCallback}
prefilledState={prefilledState}
/>
-
@@ -309,58 +307,61 @@ function UniversalSwapFlow({
const prefilledOutputCurrencyInfo = useCurrencyInfo(initialOutputCurrency ? currencyId(initialOutputCurrency) : '')
const [dismissTokenWarning, setDismissTokenWarning] = useState(false)
const closeTokenWarning = useCallback(() => setDismissTokenWarning(true), [setDismissTokenWarning])
- const urlTokensNotInDefault = useMemo(
- () =>
- prefilledInputCurrencyInfo || prefilledOutputCurrencyInfo
- ? // dismiss warning if all imported tokens are in active lists
- [prefilledInputCurrencyInfo, prefilledOutputCurrencyInfo]
- .filter(
- (token): token is CurrencyInfo =>
- (token?.currency.isToken && token.safetyLevel !== SafetyLevel.Verified) ?? false,
- )
- .map((token: CurrencyInfo) => token.currency as Token)
- : [],
- [prefilledInputCurrencyInfo, prefilledOutputCurrencyInfo],
- )
-
+ const prefilledTokensWithWarnings: { field: CurrencyField; token: Token }[] = useMemo(() => {
+ const tokens = []
+ if (
+ prefilledInputCurrencyInfo?.currency.isToken &&
+ prefilledInputCurrencyInfo.safetyLevel !== SafetyLevel.Verified
+ ) {
+ tokens.push({ field: CurrencyField.INPUT, token: prefilledInputCurrencyInfo.currency as Token })
+ }
+ if (
+ prefilledOutputCurrencyInfo?.currency.isToken &&
+ prefilledOutputCurrencyInfo.safetyLevel !== SafetyLevel.Verified
+ ) {
+ tokens.push({ field: CurrencyField.OUTPUT, token: prefilledOutputCurrencyInfo.currency as Token })
+ }
+ return tokens
+ }, [prefilledInputCurrencyInfo, prefilledOutputCurrencyInfo])
const { updateSwapForm } = useSwapFormContext()
+ const onTokenBlockAcknowledged = useCallback(
+ (field: CurrencyField) => {
+ updateSwapForm({ [field]: undefined, selectingCurrencyField: undefined })
+ onCurrencyChange?.({ [field === CurrencyField.INPUT ? 'inputCurrency' : 'outputCurrency']: undefined })
+ },
+ [updateSwapForm, onCurrencyChange],
+ )
return (
<>
- 0 && !dismissTokenWarning}
- token0={urlTokensNotInDefault[0]}
- token1={urlTokensNotInDefault[1]}
- onAcknowledge={closeTokenWarning}
- onReject={() => {
- closeTokenWarning()
- updateSwapForm({
- [CurrencyField.INPUT]: undefined,
- [CurrencyField.OUTPUT]: undefined,
- selectingCurrencyField: undefined,
- })
- onCurrencyChange?.({
- inputCurrency: undefined,
- outputCurrency: undefined,
- })
- }}
- closeModalOnly={closeTokenWarning}
- onToken0BlockAcknowledged={() => {
- updateSwapForm({
- [CurrencyField.INPUT]: undefined,
- selectingCurrencyField: undefined,
- })
- onCurrencyChange?.({ inputCurrency: undefined })
- }}
- onToken1BlockAcknowledged={() => {
- updateSwapForm({
- [CurrencyField.OUTPUT]: undefined,
- selectingCurrencyField: undefined,
- })
- onCurrencyChange?.({ outputCurrency: undefined })
- }}
- showCancel={true}
- />
+ {prefilledTokensWithWarnings.length >= 1 && (
+ = 1 && !dismissTokenWarning}
+ token0={prefilledTokensWithWarnings[0].token}
+ token1={prefilledTokensWithWarnings[1]?.token}
+ onAcknowledge={closeTokenWarning}
+ onReject={() => {
+ closeTokenWarning()
+ updateSwapForm({
+ [CurrencyField.INPUT]: undefined,
+ [CurrencyField.OUTPUT]: undefined,
+ selectingCurrencyField: undefined,
+ })
+ onCurrencyChange?.({
+ inputCurrency: undefined,
+ outputCurrency: undefined,
+ })
+ }}
+ closeModalOnly={closeTokenWarning}
+ onToken0BlockAcknowledged={() =>
+ prefilledTokensWithWarnings.length >= 1 && onTokenBlockAcknowledged(prefilledTokensWithWarnings[0].field)
+ }
+ onToken1BlockAcknowledged={() =>
+ prefilledTokensWithWarnings.length == 2 && onTokenBlockAcknowledged(prefilledTokensWithWarnings[1].field)
+ }
+ showCancel={true}
+ />
+ )}
{!hideHeader && (
@@ -374,16 +375,19 @@ function UniversalSwapFlow({
)}
{currentTab === SwapTab.Swap && (
-
+
+
+
+
)}
{currentTab === SwapTab.Limit && }
{currentTab === SwapTab.Send && (
diff --git a/apps/web/src/pages/TokenDetails/TDPContext.tsx b/apps/web/src/pages/TokenDetails/TDPContext.tsx
index 1ecdad7a8fd..35270288107 100644
--- a/apps/web/src/pages/TokenDetails/TDPContext.tsx
+++ b/apps/web/src/pages/TokenDetails/TDPContext.tsx
@@ -1,19 +1,18 @@
import { QueryResult } from '@apollo/client'
import { Currency } from '@uniswap/sdk-core'
import { TDPChartState } from 'components/Tokens/TokenDetails/ChartSection'
-import { InterfaceGqlChain } from 'constants/chains'
import { Warning } from 'constants/deprecatedTokenSafety'
import { PortfolioBalance } from 'graphql/data/portfolios'
import { PropsWithChildren, createContext, useContext } from 'react'
import { Chain, Exact, TokenWebQuery } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { GqlChainId, UniverseChainId } from 'uniswap/src/features/chains/types'
export type MultiChainMap = {
[chain in Chain]?: { address?: string; balance?: PortfolioBalance } | undefined
}
type BaseTDPContext = {
- currencyChain: InterfaceGqlChain
+ currencyChain: GqlChainId
/** Equivalent to `currency.chainId`, typed as `ChainId` instead of `number` */
currencyChainId: UniverseChainId
diff --git a/apps/web/src/pages/TokenDetails/index.tsx b/apps/web/src/pages/TokenDetails/index.tsx
index b7d2b20b366..26c1ace8a17 100644
--- a/apps/web/src/pages/TokenDetails/index.tsx
+++ b/apps/web/src/pages/TokenDetails/index.tsx
@@ -2,11 +2,10 @@ import TokenDetails from 'components/Tokens/TokenDetails'
import { useCreateTDPChartState } from 'components/Tokens/TokenDetails/ChartSection'
import InvalidTokenDetails from 'components/Tokens/TokenDetails/InvalidTokenDetails'
import { TokenDetailsPageSkeleton } from 'components/Tokens/TokenDetails/Skeleton'
-import { useChainFromUrlParam } from 'constants/chains'
import { useTokenWarning } from 'constants/deprecatedTokenSafety'
import { NATIVE_CHAIN_ID, UNKNOWN_TOKEN_SYMBOL } from 'constants/tokens'
import { useTokenBalancesQuery } from 'graphql/data/apollo/AdaptiveTokenBalancesProvider'
-import { getSupportedGraphQlChain, gqlToCurrency } from 'graphql/data/util'
+import { gqlToCurrency } from 'graphql/data/util'
import { useCurrency } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
import { useSrcColor } from 'hooks/useColor'
@@ -21,8 +20,10 @@ import { formatTokenMetatagTitleName } from 'shared-cloud/metatags'
import { ThemeProvider } from 'theme'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
import { useTokenWebQuery } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { isAddress } from 'utilities/src/addresses'
+import { useChainIdFromUrlParam } from 'utils/chainParams'
import { getNativeTokenDBAddress } from 'utils/nativeTokens'
function useOnChainToken(address: string | undefined, chainId: UniverseChainId, skip: boolean) {
@@ -93,7 +94,8 @@ function useCreateTDPContext(): PendingTDPContext | LoadedTDPContext {
if (!tokenAddress) {
throw new Error('Invalid token details route: token address URL param is undefined')
}
- const currencyChainInfo = getSupportedGraphQlChain(useChainFromUrlParam(), { fallbackToEthereum: true })
+
+ const currencyChainInfo = getChainInfo(useChainIdFromUrlParam() ?? UniverseChainId.Mainnet)
const isNative = tokenAddress === NATIVE_CHAIN_ID
diff --git a/apps/web/src/pages/TokenDetails/utils.ts b/apps/web/src/pages/TokenDetails/utils.ts
index bb49ccf0ef7..b4c39513710 100644
--- a/apps/web/src/pages/TokenDetails/utils.ts
+++ b/apps/web/src/pages/TokenDetails/utils.ts
@@ -1,7 +1,7 @@
import { Currency } from '@uniswap/sdk-core'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { getChainLabel } from 'uniswap/src/features/chains/utils'
import { t } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
export const getTokenPageTitle = (currency?: Currency, chainId?: UniverseChainId) => {
const tokenName = currency?.name
@@ -11,7 +11,7 @@ export const getTokenPageTitle = (currency?: Currency, chainId?: UniverseChainId
return baseTitle
}
- const chainSuffix = chainId && chainId !== UniverseChainId.Mainnet ? ` on ${UNIVERSE_CHAIN_INFO[chainId].label}` : ''
+ const chainSuffix = chainId && chainId !== UniverseChainId.Mainnet ? ` on ${getChainLabel(chainId)}` : ''
if (!tokenName && tokenSymbol) {
return `${tokenSymbol}${chainSuffix}: ${baseTitle}`
}
@@ -26,7 +26,7 @@ export const getTokenPageDescription = (currency?: Currency, chainId?: UniverseC
currency?.name && currency?.symbol
? `${currency?.name} (${currency?.symbol})`
: currency?.name ?? currency?.symbol ?? 'tokens'
- const chainSuffix = chainId && chainId !== UniverseChainId.Mainnet ? ` on ${UNIVERSE_CHAIN_INFO[chainId].label}` : ''
+ const chainSuffix = chainId && chainId !== UniverseChainId.Mainnet ? ` on ${getChainLabel(chainId)}` : ''
return `Buy, sell, and swap ${tokenPageName}${chainSuffix}. Real-time prices, charts, transaction data, and more.`
}
diff --git a/apps/web/src/pages/getExploreTitle.ts b/apps/web/src/pages/getExploreTitle.ts
index 10546cf3d45..a5dc9a35896 100644
--- a/apps/web/src/pages/getExploreTitle.ts
+++ b/apps/web/src/pages/getExploreTitle.ts
@@ -1,15 +1,15 @@
-import { ChainSlug, isChainUrlParam } from 'constants/chains'
import { ExploreTab } from 'pages/Explore'
import { capitalize } from 'tsafe/capitalize'
import { t } from 'uniswap/src/i18n'
import { logger } from 'utilities/src/logger/logger'
+import { isChainUrlParam } from 'utils/chainParams'
export const getExploreTitle = (path?: string) => {
const parts = path?.split('/').filter((part) => part !== '')
const tabsToFind: string[] = [ExploreTab.Pools, ExploreTab.Tokens, ExploreTab.Transactions]
const tab = parts?.find((part) => tabsToFind.includes(part)) ?? ExploreTab.Tokens
- const networkPart: ChainSlug = parts?.find(isChainUrlParam) ?? 'ethereum'
+ const networkPart: string = parts?.find(isChainUrlParam) ?? 'ethereum'
const network = capitalize(networkPart)
switch (tab) {
@@ -38,7 +38,7 @@ export const getExploreTitle = (path?: string) => {
export const getExploreDescription = (path?: string) => {
const parts = path?.split('/').filter((part) => part !== '')
- const network: ChainSlug = parts?.find(isChainUrlParam) ?? 'ethereum'
+ const network: string = parts?.find(isChainUrlParam) ?? 'ethereum'
return t(`web.explore.description`, {
network: capitalize(network),
diff --git a/apps/web/src/pages/getPositionPageTitle.ts b/apps/web/src/pages/getPositionPageTitle.ts
index b0621d47c1c..e3e7fc7dc35 100644
--- a/apps/web/src/pages/getPositionPageTitle.ts
+++ b/apps/web/src/pages/getPositionPageTitle.ts
@@ -3,26 +3,29 @@ import { t } from 'uniswap/src/i18n'
export const getPositionPageTitle = (path?: string) => {
const parts = path?.split('/').filter((part) => part !== '')
const isV2 = parts?.find((part) => part === 'v2')
+ const isV3 = parts?.find((part) => part === 'v3')
return t(`liquidityPool.positions.page.version.title`, {
- version: isV2 ? ' (v2)' : '',
+ version: isV2 ? ' (v2)' : isV3 ? ' (v3)' : '',
})
}
export const getPositionPageDescription = (path?: string) => {
const parts = path?.split('/').filter((part) => part !== '')
const isV2 = parts?.find((part) => part === 'v2')
+ const isV3 = parts?.find((part) => part === 'v3')
return t(`liquidityPool.positions.page.version.description`, {
- version: isV2 ? 'v2' : 'v3',
+ version: isV2 ? 'v2' : isV3 ? 'v3' : 'v4',
})
}
export const getAddLiquidityPageTitle = (path?: string) => {
const parts = path?.split('/').filter((part) => part !== '')
const isV2 = parts?.find((part) => part === 'v2')
+ const isV3 = parts?.find((part) => part === 'v3')
return t('liquidityPool.page.title', {
- version: isV2 ? ' (v2)' : '',
+ version: isV2 ? ' (v2)' : isV3 ? ' (v3)' : '',
})
}
diff --git a/apps/web/src/pages/paths.test.ts b/apps/web/src/pages/paths.test.ts
index 4fd81072cb3..ba131cd538d 100644
--- a/apps/web/src/pages/paths.test.ts
+++ b/apps/web/src/pages/paths.test.ts
@@ -67,22 +67,28 @@ describe('getExploreTitle', () => {
})
describe('positionPage static titles and descriptions', () => {
- it('should return the correct title for v3 pools', () => {
- expect(getPositionPageTitle('/pools')).toBe('Manage pool liquidity on Uniswap')
- })
-
- it('should return the correct title for v2 pools', () => {
- expect(getPositionPageTitle('/pools/v2')).toBe('Manage pool liquidity (v2) on Uniswap')
+ it('should return the correct title & description for v4 positions page', () => {
+ const v4PositionsPageUrl = '/positions/v4/optimism/512372'
+ expect(getPositionPageTitle(v4PositionsPageUrl)).toBe('Manage pool liquidity on Uniswap')
+ expect(getPositionPageDescription(v4PositionsPageUrl)).toBe(
+ 'View your active v4 liquidity positions. Add new positions.',
+ )
})
- it('should return the correct description for v3 pools', () => {
- expect(getPositionPageDescription('/pool/512372?chain=optimism')).toBe(
+ it('should return the correct title & description for v3 positions page', () => {
+ const v3PositionsPageUrl = '/positions/v3/optimism/512372'
+ expect(getPositionPageTitle(v3PositionsPageUrl)).toBe('Manage pool liquidity (v3) on Uniswap')
+ expect(getPositionPageDescription(v3PositionsPageUrl)).toBe(
'View your active v3 liquidity positions. Add new positions.',
)
})
- it('should return the correct description for v2 pools', () => {
- expect(getPositionPageDescription('/pool/v2')).toBe('View your active v2 liquidity positions. Add new positions.')
+ it('should return the correct title & description for v2 positions page', () => {
+ const v2PositionsPageUrl = '/positions/v2/ethereum/0x004375Dff511095CC5A197A54140a24eFEF3A416'
+ expect(getPositionPageTitle(v2PositionsPageUrl)).toBe('Manage pool liquidity (v2) on Uniswap')
+ expect(getPositionPageDescription(v2PositionsPageUrl)).toBe(
+ 'View your active v2 liquidity positions. Add new positions.',
+ )
})
it('should return the correct title for Add Liquidity pages', () => {
diff --git a/apps/web/src/rpc/AppJsonRpcProvider.ts b/apps/web/src/rpc/AppJsonRpcProvider.ts
index f62d8094920..f62d5f657cc 100644
--- a/apps/web/src/rpc/AppJsonRpcProvider.ts
+++ b/apps/web/src/rpc/AppJsonRpcProvider.ts
@@ -1,6 +1,6 @@
import { JsonRpcProvider } from '@ethersproject/providers'
-import { AVERAGE_L1_BLOCK_TIME } from 'constants/chains'
import ConfiguredJsonRpcProvider from 'rpc/ConfiguredJsonRpcProvider'
+import { AVERAGE_L1_BLOCK_TIME_MS } from 'uniswap/src/features/transactions/swap/hooks/usePollingIntervalByChain'
import { logger } from 'utilities/src/logger/logger'
/**
@@ -66,7 +66,7 @@ export default class AppJsonRpcProvider extends ConfiguredJsonRpcProvider {
constructor(
providers: JsonRpcProvider[],
- { minimumBackoffTime = AVERAGE_L1_BLOCK_TIME }: AppJsonRpcProviderOptions = {},
+ { minimumBackoffTime = AVERAGE_L1_BLOCK_TIME_MS }: AppJsonRpcProviderOptions = {},
) {
if (providers.length === 0) {
throw new Error('Missing providers for AppJsonRpcProvider')
diff --git a/apps/web/src/rpc/ConfiguredJsonRpcProvider.ts b/apps/web/src/rpc/ConfiguredJsonRpcProvider.ts
index e521dc84d6c..53b0f664e8b 100644
--- a/apps/web/src/rpc/ConfiguredJsonRpcProvider.ts
+++ b/apps/web/src/rpc/ConfiguredJsonRpcProvider.ts
@@ -1,14 +1,14 @@
import { Networkish } from '@ethersproject/networks'
import { StaticJsonRpcProvider } from '@ethersproject/providers'
-import { AVERAGE_L1_BLOCK_TIME } from 'constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { AVERAGE_L1_BLOCK_TIME_MS } from 'uniswap/src/features/transactions/swap/hooks/usePollingIntervalByChain'
export default class ConfiguredJsonRpcProvider extends StaticJsonRpcProvider {
constructor(
url: string | undefined,
// Including networkish allows ethers to skip the initial detectNetwork call.
networkish: Networkish & { chainId: UniverseChainId },
- pollingInterval = AVERAGE_L1_BLOCK_TIME,
+ pollingInterval = AVERAGE_L1_BLOCK_TIME_MS,
) {
super(url, networkish)
diff --git a/apps/web/src/state/activity/polling/bridge.ts b/apps/web/src/state/activity/polling/bridge.ts
index cd376abdeed..898ac9143ae 100644
--- a/apps/web/src/state/activity/polling/bridge.ts
+++ b/apps/web/src/state/activity/polling/bridge.ts
@@ -12,8 +12,8 @@ import { isPendingTx } from 'state/transactions/utils'
import { fetchSwaps } from 'uniswap/src/data/apiClients/tradingApi/TradingApiClient'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
import { SwapStatus } from 'uniswap/src/data/tradingApi/__generated__'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { toTradingApiSupportedChainId } from 'uniswap/src/features/transactions/swap/utils/tradingApi'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { logger } from 'utilities/src/logger/logger'
const MIN_BRIDGE_WAIT_TIME = ms('2s')
diff --git a/apps/web/src/state/activity/polling/retry.ts b/apps/web/src/state/activity/polling/retry.ts
index 9b3b5fefedb..5172ca8e934 100644
--- a/apps/web/src/state/activity/polling/retry.ts
+++ b/apps/web/src/state/activity/polling/retry.ts
@@ -1,4 +1,4 @@
-import { RetryOptions } from 'uniswap/src/types/chains'
+import { RetryOptions } from 'uniswap/src/features/chains/types'
function wait(ms: number): Promise {
return new Promise((resolve) => setTimeout(resolve, ms))
diff --git a/apps/web/src/state/activity/polling/transactions.ts b/apps/web/src/state/activity/polling/transactions.ts
index 3157eeef353..7a2f61db235 100644
--- a/apps/web/src/state/activity/polling/transactions.ts
+++ b/apps/web/src/state/activity/polling/transactions.ts
@@ -1,6 +1,5 @@
import { NEVER_RELOAD } from '@uniswap/redux-multicall'
import { useWeb3React } from '@web3-react/core'
-import { getChain } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import useBlockNumber from 'lib/hooks/useBlockNumber'
@@ -14,9 +13,10 @@ import { checkedTransaction } from 'state/transactions/reducer'
import { PendingTransactionDetails } from 'state/transactions/types'
import { isPendingTx } from 'state/transactions/utils'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { RetryOptions, UniverseChainId } from 'uniswap/src/features/chains/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { RetryOptions, UniverseChainId } from 'uniswap/src/types/chains'
import { SUBSCRIPTION_CHAINIDS } from 'utilities/src/apollo/constants'
interface Transaction {
@@ -93,8 +93,7 @@ export function usePollPendingTransactions(onActivityUpdate: OnActivityUpdate) {
if (!provider || !account.chainId) {
throw new Error('No provider or chainId')
}
- const retryOptions =
- getChain({ chainId: account.chainId })?.pendingTransactionsRetryOptions ?? DEFAULT_RETRY_OPTIONS
+ const retryOptions = getChainInfo(account.chainId)?.pendingTransactionsRetryOptions ?? DEFAULT_RETRY_OPTIONS
return retry(
() =>
provider.getTransactionReceipt(tx.hash).then(async (receipt) => {
diff --git a/apps/web/src/state/activity/subscription.ts b/apps/web/src/state/activity/subscription.ts
index 5a5f4a9242b..69260e43d5a 100644
--- a/apps/web/src/state/activity/subscription.ts
+++ b/apps/web/src/state/activity/subscription.ts
@@ -14,7 +14,7 @@ import {
TransactionDirection,
TransactionStatus,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export function useOnAssetActivity(onActivityUpdate: OnActivityUpdate) {
const onOrderActivity = useOnOrderActivity(onActivityUpdate)
diff --git a/apps/web/src/state/activity/types.ts b/apps/web/src/state/activity/types.ts
index 08028f85fe4..24034dc5baf 100644
--- a/apps/web/src/state/activity/types.ts
+++ b/apps/web/src/state/activity/types.ts
@@ -1,6 +1,6 @@
import { FilledUniswapXOrderDetails, SignatureDetails, UnfilledUniswapXOrderDetails } from 'state/signatures/types'
import { ConfirmedTransactionDetails, TransactionDetails } from 'state/transactions/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
interface BaseUpdate {
type: string
diff --git a/apps/web/src/state/application/reducer.ts b/apps/web/src/state/application/reducer.ts
index ca4e255621c..58c55c31b1b 100644
--- a/apps/web/src/state/application/reducer.ts
+++ b/apps/web/src/state/application/reducer.ts
@@ -1,8 +1,8 @@
import { createSlice, nanoid, PayloadAction } from '@reduxjs/toolkit'
import { PositionInfo } from 'components/Liquidity/types'
import { DEFAULT_TXN_DISMISS_MS } from 'constants/misc'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { ModalName, ModalNameType } from 'uniswap/src/features/telemetry/constants'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { SwapTab } from 'uniswap/src/types/screens/interface'
export enum PopupType {
@@ -58,20 +58,28 @@ export enum ApplicationModal {
GET_THE_APP,
}
+export type LiquidityModalInitialState = PositionInfo & { collectAsWeth?: boolean }
+
type AddLiquidityModalParams = {
name: typeof ModalName.AddLiquidity
- initialState: PositionInfo
+ initialState: LiquidityModalInitialState
}
type RemoveLiquidityModalParams = {
name: typeof ModalName.RemoveLiquidity
- initialState: PositionInfo
+ initialState: LiquidityModalInitialState
+}
+
+type ClaimFeeModalParams = {
+ name: typeof ModalName.ClaimFee
+ initialState: LiquidityModalInitialState
}
export type OpenModalParams =
| { name: ModalNameType | ApplicationModal; initialState?: undefined }
| AddLiquidityModalParams
| RemoveLiquidityModalParams
+ | ClaimFeeModalParams
export type CloseModalParams = ModalNameType | ApplicationModal
diff --git a/apps/web/src/state/application/updater.ts b/apps/web/src/state/application/updater.ts
index 6131e3098dc..e0e260c01c7 100644
--- a/apps/web/src/state/application/updater.ts
+++ b/apps/web/src/state/application/updater.ts
@@ -1,11 +1,11 @@
import { useWeb3React } from '@web3-react/core'
-import { useSupportedChainId } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import useDebounce from 'hooks/useDebounce'
import useIsWindowVisible from 'hooks/useIsWindowVisible'
import { useEffect, useState } from 'react'
import { updateChainId } from 'state/application/reducer'
import { useAppDispatch } from 'state/hooks'
+import { useSupportedChainId } from 'uniswap/src/features/chains/hooks'
export default function Updater(): null {
const account = useAccount()
diff --git a/apps/web/src/state/explore/index.tsx b/apps/web/src/state/explore/index.tsx
index 584ca3f8ad0..b3679efa901 100644
--- a/apps/web/src/state/explore/index.tsx
+++ b/apps/web/src/state/explore/index.tsx
@@ -4,7 +4,7 @@ import { createContext, useMemo } from 'react'
import { ALL_NETWORKS_ARG } from 'uniswap/src/data/rest/base'
import { useExploreStatsQuery } from 'uniswap/src/data/rest/exploreStats'
import { useProtocolStatsQuery } from 'uniswap/src/data/rest/protocolStats'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
interface QueryResult {
data?: T
diff --git a/apps/web/src/state/explore/protocolStats.ts b/apps/web/src/state/explore/protocolStats.ts
index 1885a947ff9..4080cda7188 100644
--- a/apps/web/src/state/explore/protocolStats.ts
+++ b/apps/web/src/state/explore/protocolStats.ts
@@ -8,24 +8,35 @@ import { UTCTimestamp } from 'lightweight-charts'
import { useContext, useMemo } from 'react'
import { ExploreContext } from 'state/explore'
import { HistoryDuration } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { FeatureFlags } from 'uniswap/src/features/gating/flags'
+import { useFeatureFlagWithLoading } from 'uniswap/src/features/gating/hooks'
function mapDataByTimestamp(
v2Data?: TimestampedAmount[],
v3Data?: TimestampedAmount[],
+ v4Data?: TimestampedAmount[],
): Record> {
const dataByTime: Record> = {}
v2Data?.forEach((v2Point) => {
const timestamp = Number(v2Point.timestamp)
- dataByTime[timestamp] = { ['v2']: Number(v2Point.value), ['v3']: 0 }
+ dataByTime[timestamp] = { ['v2']: Number(v2Point.value), ['v3']: 0, ['v4']: 0 }
})
v3Data?.forEach((v3Point) => {
const timestamp = Number(v3Point.timestamp)
if (!dataByTime[timestamp]) {
- dataByTime[timestamp] = { ['v2']: 0, ['v3']: Number(v3Point.value) }
+ dataByTime[timestamp] = { ['v2']: 0, ['v3']: Number(v3Point.value), ['v4']: 0 }
} else {
dataByTime[timestamp]['v3'] = Number(v3Point.value)
}
})
+ v4Data?.forEach((v4Point) => {
+ const timestamp = Number(v4Point.timestamp)
+ if (!dataByTime[timestamp]) {
+ dataByTime[timestamp] = { ['v2']: 0, ['v3']: 0, ['v4']: Number(v4Point.value) }
+ } else {
+ dataByTime[timestamp]['v4'] = Number(v4Point.value)
+ }
+ })
return dataByTime
}
@@ -33,25 +44,34 @@ export function useHistoricalProtocolVolume(duration: HistoryDuration) {
const {
protocolStats: { data, isLoading },
} = useContext(ExploreContext)
+
+ const { value: isV4EverywhereEnabledLoaded, isLoading: isV4EverywhereLoading } = useFeatureFlagWithLoading(
+ FeatureFlags.V4Everywhere,
+ )
+ const isV4EverywhereEnabled = isV4EverywhereEnabledLoaded || isV4EverywhereLoading
+ let v4Data: TimestampedAmount[] | undefined
let v3Data: TimestampedAmount[] | undefined
let v2Data: TimestampedAmount[] | undefined
switch (duration) {
case HistoryDuration.Max:
v2Data = data?.historicalProtocolVolume?.Max?.v2
v3Data = data?.historicalProtocolVolume?.Max?.v3
+ v4Data = data?.historicalProtocolVolume?.Max?.v4
break
case HistoryDuration.Year:
v2Data = data?.historicalProtocolVolume?.Year?.v2
v3Data = data?.historicalProtocolVolume?.Year?.v3
+ v4Data = data?.historicalProtocolVolume?.Year?.v4
break
default:
v2Data = data?.historicalProtocolVolume?.Month?.v2
v3Data = data?.historicalProtocolVolume?.Month?.v3
+ v4Data = data?.historicalProtocolVolume?.Month?.v4
break
}
return useMemo(() => {
- const dataByTime = mapDataByTimestamp(v2Data, v3Data)
+ const dataByTime = mapDataByTimestamp(v2Data, v3Data, isV4EverywhereEnabled ? v4Data : undefined)
const entries = Object.entries(dataByTime).reduce((acc, [timestamp, values]) => {
acc.push({
@@ -59,7 +79,7 @@ export function useHistoricalProtocolVolume(duration: HistoryDuration) {
values: {
['SUBGRAPH_V2']: values['v2'],
['SUBGRAPH_V3']: values['v3'],
- ['SUBGRAPH_V4']: values['v4'],
+ ['SUBGRAPH_V4']: isV4EverywhereEnabled ? values['v4'] : undefined,
},
})
return acc
@@ -67,24 +87,30 @@ export function useHistoricalProtocolVolume(duration: HistoryDuration) {
const dataQuality = checkDataQuality(entries, ChartType.VOLUME, duration)
return { chartType: ChartType.VOLUME, entries, loading: isLoading, dataQuality }
- }, [duration, isLoading, v2Data, v3Data])
+ }, [duration, isLoading, isV4EverywhereEnabled, v2Data, v3Data, v4Data])
}
export function useDailyProtocolTVL() {
const {
protocolStats: { data, isLoading },
} = useContext(ExploreContext)
+
+ const { value: isV4EverywhereEnabledLoaded, isLoading: isV4EverywhereLoading } = useFeatureFlagWithLoading(
+ FeatureFlags.V4Everywhere,
+ )
+ const isV4EverywhereEnabled = isV4EverywhereEnabledLoaded || isV4EverywhereLoading
+ const v4Data = data?.dailyProtocolTvl?.v4
const v3Data = data?.dailyProtocolTvl?.v3
const v2Data = data?.dailyProtocolTvl?.v2
return useMemo(() => {
- const dataByTime = mapDataByTimestamp(v2Data, v3Data)
+ const dataByTime = mapDataByTimestamp(v2Data, v3Data, isV4EverywhereEnabled ? v4Data : undefined)
const entries = Object.entries(dataByTime).map(([timestamp, values]) => ({
time: Number(timestamp),
- values: [values['v2'], values['v3']],
+ values: isV4EverywhereEnabled ? [values['v2'], values['v3'], values['v4']] : [values['v2'], values['v3']],
})) as StackedLineData[]
const dataQuality = checkDataQuality(entries, ChartType.TVL, HistoryDuration.Year)
return { chartType: ChartType.TVL, entries, loading: isLoading, dataQuality }
- }, [isLoading, v2Data, v3Data])
+ }, [isLoading, isV4EverywhereEnabled, v2Data, v3Data, v4Data])
}
diff --git a/apps/web/src/state/explore/topTokens.ts b/apps/web/src/state/explore/topTokens.ts
index 3e09a0d4ee5..b5b029fdf6b 100644
--- a/apps/web/src/state/explore/topTokens.ts
+++ b/apps/web/src/state/explore/topTokens.ts
@@ -7,14 +7,14 @@ import {
sortAscendingAtom,
sortMethodAtom,
} from 'components/Tokens/state'
-import { getChainFromChainUrlParam } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
-import { SparklineMap } from 'graphql/data/TopTokens'
+import { SparklineMap } from 'graphql/data/types'
import { PricePoint, TimePeriod, unwrapToken } from 'graphql/data/util'
import { useAtomValue } from 'jotai/utils'
import { useContext, useMemo } from 'react'
import { ExploreContext, giveExploreStatDefaultValue } from 'state/explore'
import { TokenStat } from 'state/explore/types'
+import { getChainIdFromChainUrlParam } from 'utils/chainParams'
const TokenSortMethods = {
[TokenSortMethod.PRICE]: (a: TokenStat, b: TokenStat) =>
@@ -145,7 +145,7 @@ export function useTopTokens() {
const filteredTokens = useFilteredTokens(sortedTokenStats)?.slice(0, MAX_TOP_TOKENS)
const sparklines = useMemo(() => {
const unwrappedTokens = filteredTokens?.map((tokenStat) => {
- const chainId = getChainFromChainUrlParam(tokenStat?.chain.toLowerCase())?.id
+ const chainId = getChainIdFromChainUrlParam(tokenStat?.chain.toLowerCase())
return chainId ? unwrapToken(chainId, tokenStat) : undefined
})
const map: SparklineMap = {}
diff --git a/apps/web/src/state/explore/types.ts b/apps/web/src/state/explore/types.ts
index 42166933e31..65effb5e3ec 100644
--- a/apps/web/src/state/explore/types.ts
+++ b/apps/web/src/state/explore/types.ts
@@ -1,6 +1,7 @@
// eslint-disable-next-line no-restricted-imports
import { Amount, PoolStats, TokenStats } from '@uniswap/client-explore/dist/uniswap/explore/v1/service_pb'
import { Percent } from '@uniswap/sdk-core'
+import { FeeData } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
type PricePoint = { timestamp: number; value: number }
@@ -8,6 +9,7 @@ export interface TokenStat
extends Omit {
volume?: Amount
priceHistory?: PricePoint[]
+ feeData?: FeeData
}
type PoolStatWithoutMethods = Omit<
diff --git a/apps/web/src/state/index.ts b/apps/web/src/state/index.ts
index 4dfd196a592..a0e1c63352c 100644
--- a/apps/web/src/state/index.ts
+++ b/apps/web/src/state/index.ts
@@ -10,7 +10,7 @@ import { quickRouteApi } from 'state/routing/quickRouteSlice'
import { routingApi } from 'state/routing/slice'
import { rootWebSaga } from 'state/sagas/root'
import { InterfaceState, interfacePersistedStateList, interfaceReducer } from 'state/webReducer'
-import { fiatOnRampAggregatorApi } from 'uniswap/src/features/fiatOnRamp/api'
+import { getFiatOnRampAggregatorApi } from 'uniswap/src/features/fiatOnRamp/api'
import { isDevEnv, isTestEnv } from 'utilities/src/environment/env'
const persistConfig: PersistConfig = {
@@ -66,7 +66,7 @@ export function createDefaultStore() {
})
.concat(routingApi.middleware)
.concat(quickRouteApi.middleware)
- .concat(fiatOnRampAggregatorApi.middleware)
+ .concat(getFiatOnRampAggregatorApi().middleware)
.concat(sagaMiddleware),
})
sagaMiddleware.run(rootWebSaga)
diff --git a/apps/web/src/state/limit/hooks.ts b/apps/web/src/state/limit/hooks.ts
index 492f31d31d3..84cd1b5c65e 100644
--- a/apps/web/src/state/limit/hooks.ts
+++ b/apps/web/src/state/limit/hooks.ts
@@ -1,5 +1,4 @@
import { Currency, CurrencyAmount, Price, TradeType } from '@uniswap/sdk-core'
-import { isStablecoin } from 'constants/chains'
import { useAccount } from 'hooks/useAccount'
import JSBI from 'jsbi'
import { useCurrencyBalances } from 'lib/hooks/useCurrencyBalance'
@@ -13,6 +12,8 @@ import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
import { getUSDCostPerGas, isClassicTrade } from 'state/routing/utils'
import { useSwapAndLimitContext } from 'state/swap/useSwapContext'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { isUniverseChainId } from 'uniswap/src/features/chains/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import { CurrencyField } from 'uniswap/src/types/currency'
@@ -26,6 +27,14 @@ export type LimitInfo = {
fee?: SwapFeeInfo
}
+function isStablecoin(currency?: Currency): boolean {
+ return (
+ currency !== undefined &&
+ isUniverseChainId(currency.chainId) &&
+ getChainInfo(currency.chainId).stablecoins.some((stablecoin) => stablecoin.equals(currency))
+ )
+}
+
// By default, inputCurrency is base currency and outputCurrency is quote currency
// If only one of these tokens is a stablecoin, prefer the denomination (quote currency) to be the stablecoin
// TODO(limits): Also add preference for ETH, BTC to be default
diff --git a/apps/web/src/state/migrations/16.test.ts b/apps/web/src/state/migrations/16.test.ts
index ac243ef79cb..b1dc32da78e 100644
--- a/apps/web/src/state/migrations/16.test.ts
+++ b/apps/web/src/state/migrations/16.test.ts
@@ -16,7 +16,7 @@ import { migration7 } from 'state/migrations/7'
import { migration8 } from 'state/migrations/8'
import { migration9 } from 'state/migrations/9'
import { DAI_ARBITRUM_ONE, USDC } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { serializeToken } from 'uniswap/src/utils/currency'
const tokenMap = {
diff --git a/apps/web/src/state/migrations/3.test.ts b/apps/web/src/state/migrations/3.test.ts
index 8558181b10e..9e63931c491 100644
--- a/apps/web/src/state/migrations/3.test.ts
+++ b/apps/web/src/state/migrations/3.test.ts
@@ -5,7 +5,7 @@ import { migration2 } from 'state/migrations/2'
import { PersistAppStateV3, migration3 } from 'state/migrations/3'
import { RouterPreference } from 'state/routing/types'
import { SlippageTolerance } from 'state/user/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const previousState: PersistAppStateV3 = {
user: {
diff --git a/apps/web/src/state/migrations/3.ts b/apps/web/src/state/migrations/3.ts
index 7d5b422981a..7908fa6d74d 100644
--- a/apps/web/src/state/migrations/3.ts
+++ b/apps/web/src/state/migrations/3.ts
@@ -1,7 +1,7 @@
import { Token } from '@uniswap/sdk-core'
import { PersistState } from 'redux-persist'
import { PreV16UserState } from 'state/migrations/oldTypes'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { serializeToken } from 'uniswap/src/utils/currency'
export type PersistAppStateV3 = {
diff --git a/apps/web/src/state/reducerTypeTest.ts b/apps/web/src/state/reducerTypeTest.ts
index 53629adfcff..761d0692239 100644
--- a/apps/web/src/state/reducerTypeTest.ts
+++ b/apps/web/src/state/reducerTypeTest.ts
@@ -26,15 +26,17 @@ import { Wallet } from 'state/wallets/types'
import { InterfaceState } from 'state/webReducer'
import { Equals, assert } from 'tsafe'
import { UniswapBehaviorHistoryState } from 'uniswap/src/features/behaviorHistory/slice'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { FavoritesState } from 'uniswap/src/features/favorites/slice'
-import { fiatOnRampAggregatorApi } from 'uniswap/src/features/fiatOnRamp/api'
+import { getFiatOnRampAggregatorApi } from 'uniswap/src/features/fiatOnRamp/api'
import { NotificationState } from 'uniswap/src/features/notifications/slice'
import { SearchHistoryState } from 'uniswap/src/features/search/searchHistorySlice'
import { UserSettingsState } from 'uniswap/src/features/settings/slice'
import { TimingState } from 'uniswap/src/features/timing/slice'
import { TokensState } from 'uniswap/src/features/tokens/slice/slice'
import { TransactionsState } from 'uniswap/src/features/transactions/slice'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+
+const forAggregatorApi = getFiatOnRampAggregatorApi()
/**
* WARNING:
@@ -74,7 +76,7 @@ type ExpectedAppState = CombinedState<{
readonly [quickRouteApi.reducerPath]: ReturnType
// Uniswap State
- readonly [fiatOnRampAggregatorApi.reducerPath]: ReturnType
+ readonly [forAggregatorApi.reducerPath]: ReturnType
readonly uniswapBehaviorHistory: UniswapBehaviorHistoryState
readonly favorites: FavoritesState
readonly notifications: NotificationState
diff --git a/apps/web/src/state/routing/gas.ts b/apps/web/src/state/routing/gas.ts
index 40bd57f7bd7..4f7e9299bbf 100644
--- a/apps/web/src/state/routing/gas.ts
+++ b/apps/web/src/state/routing/gas.ts
@@ -6,8 +6,8 @@ import ERC20_ABI from 'uniswap/src/abis/erc20.json'
import { Erc20, Weth } from 'uniswap/src/abis/types'
import WETH_ABI from 'uniswap/src/abis/weth.json'
import { WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { WRAP_FALLBACK_GAS_LIMIT_IN_GWEI } from 'uniswap/src/features/transactions/swap/hooks/useTransactionRequestInfo'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { getContract } from 'utilities/src/contracts/getContract'
// TODO(UniswapX): add fallback gas limits per chain? l2s have higher costs
diff --git a/apps/web/src/state/routing/types.ts b/apps/web/src/state/routing/types.ts
index 26dce1726ae..98c7e1e9350 100644
--- a/apps/web/src/state/routing/types.ts
+++ b/apps/web/src/state/routing/types.ts
@@ -17,7 +17,7 @@ import { Route as V2Route } from '@uniswap/v2-sdk'
import { Route as V3Route } from '@uniswap/v3-sdk'
import { ZERO_PERCENT } from 'constants/misc'
import { BigNumber } from 'ethers/lib/ethers'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export enum TradeState {
LOADING = 'loading',
diff --git a/apps/web/src/state/routing/usePreviewTrade.ts b/apps/web/src/state/routing/usePreviewTrade.ts
index 34fb0d1bf9d..1afdfb0b9ab 100644
--- a/apps/web/src/state/routing/usePreviewTrade.ts
+++ b/apps/web/src/state/routing/usePreviewTrade.ts
@@ -8,9 +8,9 @@ import { useMemo } from 'react'
import { useGetQuickRouteQuery, useGetQuickRouteQueryState } from 'state/routing/quickRouteSlice'
import { GetQuickQuoteArgs, PreviewTrade, QuoteState, TradeState } from 'state/routing/types'
import { currencyAddressForSwapQuote } from 'state/routing/utils'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
const TRADE_NOT_FOUND = { state: TradeState.NO_ROUTE_FOUND, trade: undefined } as const
const TRADE_LOADING = { state: TradeState.LOADING, trade: undefined } as const
diff --git a/apps/web/src/state/routing/useRoutingAPITrade.test.ts b/apps/web/src/state/routing/useRoutingAPITrade.test.ts
index 9bdd8566c05..2d5e22a328a 100644
--- a/apps/web/src/state/routing/useRoutingAPITrade.test.ts
+++ b/apps/web/src/state/routing/useRoutingAPITrade.test.ts
@@ -1,7 +1,6 @@
import { skipToken } from '@reduxjs/toolkit/query/react'
import { renderHook } from '@testing-library/react'
import { CurrencyAmount, TradeType } from '@uniswap/sdk-core'
-import { AVERAGE_L1_BLOCK_TIME } from 'constants/chains'
import useIsWindowVisible from 'hooks/useIsWindowVisible'
import ms from 'ms'
import { useGetQuoteQuery, useGetQuoteQueryState } from 'state/routing/slice'
@@ -13,6 +12,7 @@ import { ETH_MAINNET } from 'test-utils/constants'
import { mocked } from 'test-utils/mocked'
import { USDC_MAINNET } from 'uniswap/src/constants/tokens'
import { useExperimentValue } from 'uniswap/src/features/gating/hooks'
+import { AVERAGE_L1_BLOCK_TIME_MS } from 'uniswap/src/features/transactions/swap/hooks/usePollingIntervalByChain'
const USDCAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '10000')
@@ -94,7 +94,7 @@ describe('#useRoutingAPITrade ExactIn', () => {
)
expect(useGetQuoteQuery).toHaveBeenCalledWith(skipToken, {
- pollingInterval: AVERAGE_L1_BLOCK_TIME,
+ pollingInterval: AVERAGE_L1_BLOCK_TIME_MS,
refetchOnMountOrArgChange: 2 * 60,
})
expect(result.current?.trade).toEqual(undefined)
@@ -106,7 +106,7 @@ describe('#useRoutingAPITrade ExactIn', () => {
renderHook(() => useRoutingAPITrade(false, TradeType.EXACT_INPUT, USDCAmount, ETH_MAINNET, RouterPreference.API))
expect(useGetQuoteQuery).toHaveBeenCalledWith(MOCK_ARGS, {
- pollingInterval: AVERAGE_L1_BLOCK_TIME,
+ pollingInterval: AVERAGE_L1_BLOCK_TIME_MS,
refetchOnMountOrArgChange: 2 * 60,
})
})
diff --git a/apps/web/src/state/routing/useRoutingAPITrade.ts b/apps/web/src/state/routing/useRoutingAPITrade.ts
index 5839f5ef9aa..e7ac0d45076 100644
--- a/apps/web/src/state/routing/useRoutingAPITrade.ts
+++ b/apps/web/src/state/routing/useRoutingAPITrade.ts
@@ -1,7 +1,6 @@
import { skipToken } from '@reduxjs/toolkit/query/react'
import { Protocol } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
-import { AVERAGE_L1_BLOCK_TIME } from 'constants/chains'
import useIsWindowVisible from 'hooks/useIsWindowVisible'
import { useRoutingAPIArguments } from 'lib/hooks/routing/useRoutingAPIArguments'
import ms from 'ms'
@@ -16,6 +15,7 @@ import {
SubmittableTrade,
TradeState,
} from 'state/routing/types'
+import { AVERAGE_L1_BLOCK_TIME_MS } from 'uniswap/src/features/transactions/swap/hooks/usePollingIntervalByChain'
const TRADE_NOT_FOUND = { state: TradeState.NO_ROUTE_FOUND, trade: undefined, currentData: undefined } as const
const TRADE_LOADING = { state: TradeState.LOADING, trade: undefined, currentData: undefined } as const
@@ -98,7 +98,7 @@ export function useRoutingAPITrade(
const { isError, data: tradeResult, error, currentData } = useGetQuoteQueryState(queryArgs)
useGetQuoteQuery(skipFetch || !isWindowVisible ? skipToken : queryArgs, {
// Price-fetching is informational and costly, so it's done less frequently.
- pollingInterval: routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE ? ms(`1m`) : AVERAGE_L1_BLOCK_TIME,
+ pollingInterval: routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE ? ms(`1m`) : AVERAGE_L1_BLOCK_TIME_MS,
// If latest quote from cache was fetched > 2m ago, instantly repoll for another instead of waiting for next poll period
refetchOnMountOrArgChange: 2 * 60,
})
diff --git a/apps/web/src/state/routing/utils.test.ts b/apps/web/src/state/routing/utils.test.ts
index 0c299c074f7..25845f3d0dd 100644
--- a/apps/web/src/state/routing/utils.test.ts
+++ b/apps/web/src/state/routing/utils.test.ts
@@ -2,7 +2,7 @@ import { Currency, Token, TradeType } from '@uniswap/sdk-core'
import { GetQuoteArgs, PoolType, RouterPreference, TokenInRoute } from 'state/routing/types'
import { computeRoutes } from 'state/routing/utils'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', undefined, false)
const USDC_IN_ROUTE = toTokenInRoute(USDC)
diff --git a/apps/web/src/state/sagas/transactions/uniswapx.ts b/apps/web/src/state/sagas/transactions/uniswapx.ts
index 2dec0dd1cc6..86dcf3ea3b7 100644
--- a/apps/web/src/state/sagas/transactions/uniswapx.ts
+++ b/apps/web/src/state/sagas/transactions/uniswapx.ts
@@ -13,13 +13,13 @@ import { call, put } from 'typed-redux-saga'
import { UniswapXOrderStatus } from 'types/uniswapx'
import { submitOrder } from 'uniswap/src/data/apiClients/tradingApi/TradingApiClient'
import { Routing } from 'uniswap/src/data/tradingApi/__generated__'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { InterfaceEventNameLocal } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { HandledTransactionInterrupt } from 'uniswap/src/features/transactions/errors'
import { getBaseTradeAnalyticsProperties } from 'uniswap/src/features/transactions/swap/analytics'
import { UniswapXSignatureStep } from 'uniswap/src/features/transactions/swap/types/steps'
import { UniswapXTrade } from 'uniswap/src/features/transactions/swap/types/trade'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { percentFromFloat } from 'utilities/src/format/percent'
interface HandleUniswapXSignatureStepParams extends HandleSignatureStepParams {
diff --git a/apps/web/src/state/send/SendContext.tsx b/apps/web/src/state/send/SendContext.tsx
index 153ae2c40a6..e6cc1e24d4c 100644
--- a/apps/web/src/state/send/SendContext.tsx
+++ b/apps/web/src/state/send/SendContext.tsx
@@ -11,7 +11,7 @@ import {
} from 'react'
import { RecipientData, SendInfo, useDerivedSendInfo } from 'state/send/hooks'
import { useSwapAndLimitContext } from 'state/swap/useSwapContext'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
export type SendState = {
readonly exactAmountToken?: string
diff --git a/apps/web/src/state/signatures/hooks.ts b/apps/web/src/state/signatures/hooks.ts
index be2b78c1e63..7f311e4e287 100644
--- a/apps/web/src/state/signatures/hooks.ts
+++ b/apps/web/src/state/signatures/hooks.ts
@@ -11,7 +11,7 @@ import {
UniswapXOrderDetails,
} from 'state/signatures/types'
import { UniswapXOrderStatus } from 'types/uniswapx'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export function useAllSignatures(): { [id: string]: SignatureDetails } {
const account = useAccount()
diff --git a/apps/web/src/state/signatures/types.ts b/apps/web/src/state/signatures/types.ts
index 0464566922b..9e068ec6677 100644
--- a/apps/web/src/state/signatures/types.ts
+++ b/apps/web/src/state/signatures/types.ts
@@ -5,7 +5,7 @@ import {
AssetActivityPartsFragment,
SwapOrderDetailsPartsFragment,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { Prettify } from 'viem/chains'
export type OrderActivity = AssetActivityPartsFragment & { details: SwapOrderDetailsPartsFragment }
diff --git a/apps/web/src/state/stake/hooks.tsx b/apps/web/src/state/stake/hooks.tsx
index d74f51620c9..332ecd6a77a 100644
--- a/apps/web/src/state/stake/hooks.tsx
+++ b/apps/web/src/state/stake/hooks.tsx
@@ -8,7 +8,7 @@ import JSBI from 'jsbi'
import { NEVER_RELOAD, useMultipleContractSingleData } from 'lib/hooks/multicall'
import { useMemo } from 'react'
import { DAI, UNI, USDC_MAINNET, USDT, WBTC, WRAPPED_NATIVE_CURRENCY } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { logger } from 'utilities/src/logger/logger'
const STAKING_REWARDS_INTERFACE = new Interface(StakingRewardsJSON.abi)
diff --git a/apps/web/src/state/swap/SwapContext.test.tsx b/apps/web/src/state/swap/SwapContext.test.tsx
index 130350be02b..95fb381932e 100644
--- a/apps/web/src/state/swap/SwapContext.test.tsx
+++ b/apps/web/src/state/swap/SwapContext.test.tsx
@@ -5,7 +5,7 @@ import { SwapAndLimitContext, SwapInfo } from 'state/swap/types'
import { useSwapAndLimitContext, useSwapContext } from 'state/swap/useSwapContext'
import { render, screen } from 'test-utils/render'
import { nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyField } from 'uniswap/src/types/currency'
import { SwapTab } from 'uniswap/src/types/screens/interface'
diff --git a/apps/web/src/state/swap/SwapContext.tsx b/apps/web/src/state/swap/SwapContext.tsx
index 5b1be57efd9..0931f9cb0ec 100644
--- a/apps/web/src/state/swap/SwapContext.tsx
+++ b/apps/web/src/state/swap/SwapContext.tsx
@@ -8,8 +8,8 @@ import { PropsWithChildren, useEffect, useMemo, useState } from 'react'
import { useDerivedSwapInfo } from 'state/swap/hooks'
import { CurrencyState, SwapAndLimitContext, SwapContext, SwapState, initialSwapState } from 'state/swap/types'
import { useSwapAndLimitContext } from 'state/swap/useSwapContext'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyField } from 'uniswap/src/types/currency'
import { SwapTab } from 'uniswap/src/types/screens/interface'
import { areCurrenciesEqual } from 'uniswap/src/utils/currencyId'
diff --git a/apps/web/src/state/swap/hooks.test.ts b/apps/web/src/state/swap/hooks.test.tsx
similarity index 84%
rename from apps/web/src/state/swap/hooks.test.ts
rename to apps/web/src/state/swap/hooks.test.tsx
index 0c34748fb36..8154c7eb9a2 100644
--- a/apps/web/src/state/swap/hooks.test.ts
+++ b/apps/web/src/state/swap/hooks.test.tsx
@@ -1,10 +1,12 @@
import { UNI_ADDRESSES } from '@uniswap/sdk-core'
import { parse } from 'qs'
+import { ReactNode } from 'react'
import { queryParametersToCurrencyState, useInitialCurrencyState } from 'state/swap/hooks'
import { ETH_MAINNET } from 'test-utils/constants'
import { renderHook, waitFor } from 'test-utils/render'
import { UNI, nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UrlContext } from 'uniswap/src/contexts/UrlContext'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
jest.mock('uniswap/src/features/gating/hooks', () => {
return {
@@ -12,6 +14,15 @@ jest.mock('uniswap/src/features/gating/hooks', () => {
}
})
+function mockQueryStringInUrlProvider(
+ qs: Record,
+): ({ children }: { children?: ReactNode }) => JSX.Element {
+ function MockedProvider({ children }: { children?: ReactNode }): JSX.Element {
+ return qs }}>{children}
+ }
+ return MockedProvider
+}
+
describe('hooks', () => {
describe('#queryParametersToCurrencyState', () => {
test('ETH to DAI on mainnet', () => {
@@ -86,8 +97,8 @@ describe('hooks', () => {
describe('#useInitialCurrencyState', () => {
describe('Disconnected wallet', () => {
test('optimism output UNI', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
inputCurrency: undefined,
outputCurrency: UNI_ADDRESSES[UniverseChainId.Optimism],
chainId: 10,
@@ -108,9 +119,9 @@ describe('hooks', () => {
})
test('optimism input ETH, output UNI', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
- inputCurrency: 'ETH',
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
+ inputCurrency: undefined,
outputCurrency: UNI_ADDRESSES[UniverseChainId.Optimism],
chainId: 10,
}),
@@ -130,8 +141,8 @@ describe('hooks', () => {
})
test('optimism input ETH, output UNI, input value, field output', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
inputCurrency: 'ETH',
outputCurrency: UNI_ADDRESSES[UniverseChainId.Optimism],
chainId: 10,
@@ -156,8 +167,8 @@ describe('hooks', () => {
})
test('empty query should default to ETH mainnet', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
inputCurrency: undefined,
outputCurrency: undefined,
chainId: undefined,
@@ -211,8 +222,8 @@ describe('hooks', () => {
}))
test('optimism output UNI', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
inputCurrency: undefined,
outputCurrency: UNI_ADDRESSES[UniverseChainId.Optimism],
chainId: 10,
@@ -233,8 +244,8 @@ describe('hooks', () => {
})
test('mainnet', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
inputCurrency: undefined,
outputCurrency: undefined,
chainId: 1,
@@ -255,8 +266,8 @@ describe('hooks', () => {
})
test('optimism input ETH, output UNI', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
inputCurrency: 'ETH',
outputCurrency: UNI_ADDRESSES[UniverseChainId.Optimism],
chainId: 10,
@@ -277,8 +288,8 @@ describe('hooks', () => {
})
test('empty query should show highest balance native token', () => {
- jest.mock('hooks/useParsedQueryString', () => ({
- useParsedQueryString: () => ({
+ jest.mock('uniswap/src/contexts/UrlContext', () => ({
+ ReactRouterUrlProvider: mockQueryStringInUrlProvider({
inputCurrency: undefined,
outputCurrency: undefined,
chainId: undefined,
diff --git a/apps/web/src/state/swap/hooks.tsx b/apps/web/src/state/swap/hooks.tsx
index 2659797deaa..0bb36c931bf 100644
--- a/apps/web/src/state/swap/hooks.tsx
+++ b/apps/web/src/state/swap/hooks.tsx
@@ -1,12 +1,10 @@
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { ConnectWalletButtonText } from 'components/NavBar/accountCTAsExperimentUtils'
-import { CHAIN_IDS_TO_NAMES, useSupportedChainId } from 'constants/chains'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { useCurrency, useCurrencyInfo } from 'hooks/Tokens'
import { useAccount } from 'hooks/useAccount'
import useAutoSlippageTolerance from 'hooks/useAutoSlippageTolerance'
import { useDebouncedTrade } from 'hooks/useDebouncedTrade'
-import useParsedQueryString from 'hooks/useParsedQueryString'
import { useSwapTaxes } from 'hooks/useSwapTaxes'
import { useUSDPrice } from 'hooks/useUSDPrice'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
@@ -19,14 +17,16 @@ import { isClassicTrade, isSubmittableTrade, isUniswapXTrade } from 'state/routi
import { CurrencyState, SerializedCurrencyState, SwapInfo, SwapState } from 'state/swap/types'
import { useSwapAndLimitContext, useSwapContext } from 'state/swap/useSwapContext'
import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
+import { useUrlContext } from 'uniswap/src/contexts/UrlContext'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useEnabledChains, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId, isUniverseChainId } from 'uniswap/src/features/chains/types'
import { useTokenProjects } from 'uniswap/src/features/dataApi/tokenProjects'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
import { Trans } from 'uniswap/src/i18n'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { CurrencyField } from 'uniswap/src/types/currency'
import { areCurrencyIdsEqual, currencyId } from 'uniswap/src/utils/currencyId'
import { isAddress } from 'utilities/src/addresses'
-import { ParsedChainIdKey, getParsedChainId } from 'utils/chains'
+import { getParsedChainId } from 'utils/chainParams'
export function useSwapActionHandlers(): {
onCurrencySelection: (field: CurrencyField, currency?: Currency) => void
@@ -337,10 +337,15 @@ export function serializeSwapStateToURLParameters(
const { inputCurrency, outputCurrency, typedValue, independentField, chainId } = state
const params = new URLSearchParams()
- params.set('chain', CHAIN_IDS_TO_NAMES[chainId])
+ params.set('chain', getChainInfo(chainId).interfaceName)
- if (outputCurrency && inputCurrency && outputCurrency.chainId !== inputCurrency.chainId) {
- params.set('outputChain', CHAIN_IDS_TO_NAMES[outputCurrency.chainId as UniverseChainId])
+ if (
+ outputCurrency &&
+ inputCurrency &&
+ outputCurrency.chainId !== inputCurrency.chainId &&
+ isUniverseChainId(outputCurrency.chainId)
+ ) {
+ params.set('outputChain', getChainInfo(outputCurrency.chainId).interfaceName)
}
if (inputCurrency) {
@@ -365,7 +370,7 @@ export function serializeSwapStateToURLParameters(
export function queryParametersToCurrencyState(parsedQs: ParsedQs): SerializedCurrencyState {
const chainId = getParsedChainId(parsedQs)
- const outputChainId = getParsedChainId(parsedQs, ParsedChainIdKey.OUTPUT)
+ const outputChainId = getParsedChainId(parsedQs, CurrencyField.OUTPUT)
const inputCurrencyId = parseCurrencyFromURLParameter(parsedQs.inputCurrency ?? parsedQs.inputcurrency)
const parsedOutputCurrencyId = parseCurrencyFromURLParameter(parsedQs.outputCurrency ?? parsedQs.outputcurrency)
const outputCurrencyId =
@@ -401,6 +406,7 @@ export function useInitialCurrencyState(): {
const { chainId, setIsUserSelectedToken } = useSwapAndLimitContext()
const { defaultChainId } = useEnabledChains()
+ const { useParsedQueryString } = useUrlContext()
const parsedQs = useParsedQueryString()
const parsedCurrencyState = useMemo(() => {
return queryParametersToCurrencyState(parsedQs)
diff --git a/apps/web/src/state/swap/types.ts b/apps/web/src/state/swap/types.ts
index 76721e52194..98aee5aec5f 100644
--- a/apps/web/src/state/swap/types.ts
+++ b/apps/web/src/state/swap/types.ts
@@ -1,7 +1,7 @@
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import { Dispatch, ReactNode, SetStateAction, createContext } from 'react'
import { InterfaceTrade, RouterPreference, TradeState } from 'state/routing/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyField } from 'uniswap/src/types/currency'
import { SwapTab } from 'uniswap/src/types/screens/interface'
diff --git a/apps/web/src/state/transactions/hooks.test.tsx b/apps/web/src/state/transactions/hooks.test.tsx
index 985f2e402c7..4abe8e6a8e3 100644
--- a/apps/web/src/state/transactions/hooks.test.tsx
+++ b/apps/web/src/state/transactions/hooks.test.tsx
@@ -15,7 +15,7 @@ import { mocked } from 'test-utils/mocked'
import { act, renderHook } from 'test-utils/render'
import { USDC_MAINNET } from 'uniswap/src/constants/tokens'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const PERMIT2_ADDRESS_MAINNET = permit2Address(UniverseChainId.Mainnet)
diff --git a/apps/web/src/state/transactions/hooks.tsx b/apps/web/src/state/transactions/hooks.tsx
index 779a6f9bf5b..b58708cdc9d 100644
--- a/apps/web/src/state/transactions/hooks.tsx
+++ b/apps/web/src/state/transactions/hooks.tsx
@@ -3,7 +3,7 @@ import type { TransactionResponse } from '@ethersproject/providers'
import { Token } from '@uniswap/sdk-core'
import { useAccount } from 'hooks/useAccount'
import { SwapResult } from 'hooks/useSwapCallback'
-import { useCallback, useMemo } from 'react'
+import { useCallback, useEffect, useMemo } from 'react'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { TradeFillType } from 'state/routing/types'
import { addTransaction, cancelTransaction, removeTransaction } from 'state/transactions/reducer'
@@ -15,7 +15,7 @@ import {
} from 'state/transactions/types'
import { isConfirmedTx, isPendingTx } from 'state/transactions/utils'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { COMBINED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/types/chains'
+import { ALL_CHAIN_IDS, UniverseChainId } from 'uniswap/src/features/chains/types'
// helper that can take a ethers library transaction response and add it to the list of transactions
export function useTransactionAdder(): (
@@ -75,7 +75,7 @@ export function useMultichainTransactions(): [TransactionDetails, UniverseChainI
return useMemo(
() =>
- COMBINED_CHAIN_IDS.flatMap((chainId) =>
+ ALL_CHAIN_IDS.flatMap((chainId) =>
state[chainId]
? Object.values(state[chainId]).map((tx): [TransactionDetails, UniverseChainId] => [tx, chainId])
: [],
@@ -179,3 +179,30 @@ export function usePendingTransactions(): PendingTransactionDetails[] {
[account.address, allTransactions],
)
}
+
+function usePendingLPTransactions(): PendingTransactionDetails[] {
+ const allTransactions = useAllTransactions()
+ const account = useAccount()
+
+ return useMemo(
+ () =>
+ Object.values(allTransactions).filter(
+ (tx): tx is PendingTransactionDetails =>
+ tx.from === account.address &&
+ isPendingTx(tx) &&
+ [
+ TransactionType.INCREASE_LIQUIDITY,
+ TransactionType.DECREASE_LIQUIDITY,
+ TransactionType.COLLECT_FEES,
+ ].includes(tx.info.type),
+ ),
+ [account.address, allTransactions],
+ )
+}
+
+export function usePendingLPTransactionsChangeListener(callback: () => void) {
+ const pendingLPTransactions = usePendingLPTransactions()
+ useEffect(() => {
+ callback()
+ }, [pendingLPTransactions, callback])
+}
diff --git a/apps/web/src/state/transactions/reducer.test.ts b/apps/web/src/state/transactions/reducer.test.ts
index 5333023473e..180277e52ee 100644
--- a/apps/web/src/state/transactions/reducer.test.ts
+++ b/apps/web/src/state/transactions/reducer.test.ts
@@ -10,7 +10,7 @@ import reducer, {
} from 'state/transactions/reducer'
import { ConfirmedTransactionDetails, PendingTransactionDetails, TransactionType } from 'state/transactions/types'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
describe('transaction reducer', () => {
let store: Store
diff --git a/apps/web/src/state/transactions/reducer.ts b/apps/web/src/state/transactions/reducer.ts
index c94dc3adbd3..4988c9355fb 100644
--- a/apps/web/src/state/transactions/reducer.ts
+++ b/apps/web/src/state/transactions/reducer.ts
@@ -6,7 +6,7 @@ import {
TransactionType,
} from 'state/transactions/types'
import { TransactionStatus } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
// TODO(WEB-2053): update this to be a map of account -> chainId -> txHash -> TransactionDetails
// to simplify usage, once we're able to invalidate localstorage
diff --git a/apps/web/src/state/transactions/types.ts b/apps/web/src/state/transactions/types.ts
index e205b383799..fd4db944f25 100644
--- a/apps/web/src/state/transactions/types.ts
+++ b/apps/web/src/state/transactions/types.ts
@@ -5,7 +5,7 @@ import {
TransactionDetailsPartsFragment,
TransactionStatus,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export type TransactionActivity = AssetActivityPartsFragment & { details: TransactionDetailsPartsFragment }
diff --git a/apps/web/src/state/user/hooks.tsx b/apps/web/src/state/user/hooks.tsx
index c1eb36228da..e349d1dc242 100644
--- a/apps/web/src/state/user/hooks.tsx
+++ b/apps/web/src/state/user/hooks.tsx
@@ -1,6 +1,5 @@
import { Percent, Token, V2_FACTORY_ADDRESSES } from '@uniswap/sdk-core'
import { Pair, computePairAddress } from '@uniswap/v2-sdk'
-import { chainIdToBackendChain, useSupportedChainId } from 'constants/chains'
import { L2_DEADLINE_FROM_NOW } from 'constants/misc'
import { BASES_TO_TRACK_LIQUIDITY_FOR, PINNED_PAIRS } from 'constants/routing'
import { gqlToCurrency } from 'graphql/data/util'
@@ -18,11 +17,11 @@ import {
} from 'state/user/reducer'
import { SerializedPair, SlippageTolerance } from 'state/user/types'
import {
- Chain,
TokenSortableField,
useTopTokensQuery,
} from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { isL2ChainId } from 'uniswap/src/features/chains/utils'
+import { useEnabledChains, useSupportedChainId } from 'uniswap/src/features/chains/hooks'
+import { isL2ChainId, toGraphQLChain } from 'uniswap/src/features/chains/utils'
import { deserializeToken, serializeToken } from 'uniswap/src/utils/currency'
export function useRouterPreference(): [RouterPreference, (routerPreference: RouterPreference) => void] {
@@ -173,12 +172,13 @@ export function toV2LiquidityToken([tokenA, tokenB]: [Token, Token]): Token {
*/
export function useTrackedTokenPairs(): [Token, Token][] {
const { chainId } = useAccount()
+ const { defaultChainId } = useEnabledChains()
const supportedChainId = useSupportedChainId(chainId)
// TODO(WEB-4001): use an "all tokens" query for better LP detection
const { data: popularTokens } = useTopTokensQuery({
variables: {
- chain: supportedChainId ? chainIdToBackendChain({ chainId: supportedChainId }) : Chain.Ethereum,
+ chain: toGraphQLChain(supportedChainId ?? defaultChainId),
orderBy: TokenSortableField.Popularity,
page: 1,
pageSize: 100,
diff --git a/apps/web/src/state/wallets/reducer.ts b/apps/web/src/state/wallets/reducer.ts
index 00de61abdc3..a0ca57ec5c3 100644
--- a/apps/web/src/state/wallets/reducer.ts
+++ b/apps/web/src/state/wallets/reducer.ts
@@ -1,7 +1,7 @@
import { createSlice } from '@reduxjs/toolkit'
import { shallowEqual } from 'react-redux'
import { Wallet } from 'state/wallets/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export interface ConnectedWalletsState {
// Used to track wallets that have been connected by the user in current session, and remove them when deliberately disconnected.
diff --git a/apps/web/src/test-utils/bundle-size-test.ts b/apps/web/src/test-utils/bundle-size-test.ts
index c1d3f7b18f4..dd407e5a58f 100644
--- a/apps/web/src/test-utils/bundle-size-test.ts
+++ b/apps/web/src/test-utils/bundle-size-test.ts
@@ -32,8 +32,8 @@ const entryGzipSize = report.reduce(
0,
)
-// somewhat arbitrary, based on current size (10/18/2024)
-const limit = 2_327_000
+// somewhat arbitrary, based on current size (10/30/2024)
+const limit = 2_350_000
if (entryGzipSize > limit) {
console.error(`Bundle size has grown too big! Entry JS size is ${entryGzipSize}, over the limit of ${limit}.`)
diff --git a/apps/web/src/test-utils/constants.ts b/apps/web/src/test-utils/constants.ts
index af733ab278b..8ee14dade17 100644
--- a/apps/web/src/test-utils/constants.ts
+++ b/apps/web/src/test-utils/constants.ts
@@ -21,10 +21,10 @@ import {
nativeOnChain,
} from 'uniswap/src/constants/tokens'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
import { FORCountry } from 'uniswap/src/features/fiatOnRamp/types'
import { benignSafetyInfo } from 'uniswap/src/test/fixtures'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { LimitsExpiry } from 'uniswap/src/types/limits'
import { UseAccountReturnType } from 'wagmi'
diff --git a/apps/web/src/test-utils/pools/fixtures.ts b/apps/web/src/test-utils/pools/fixtures.ts
index 2eeee1a0a5d..be43f6c8721 100644
--- a/apps/web/src/test-utils/pools/fixtures.ts
+++ b/apps/web/src/test-utils/pools/fixtures.ts
@@ -2,13 +2,14 @@ import { BigNumber } from '@ethersproject/bignumber'
import { Currency, WETH9 } from '@uniswap/sdk-core'
import { FeeAmount, Pool, Position } from '@uniswap/v3-sdk'
import { PoolData } from 'graphql/data/pools/usePoolData'
+import { PoolStat } from 'state/explore/types'
import { USDC_MAINNET } from 'uniswap/src/constants/tokens'
import { Token } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export const validParams = { poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640', chainName: 'ethereum' }
-export const validBEPoolToken0 = {
+const validPoolToken0 = {
id: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
symbol: 'USDC',
@@ -25,7 +26,10 @@ export const validBEPoolToken0 = {
url: 'https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png',
},
},
-} as Token
+}
+
+export const validBEPoolToken0 = validPoolToken0 as Token
+export const validRestPoolToken0 = validPoolToken0 as unknown as PoolStat['token0']
export const validUSDCCurrency = {
isNative: false,
@@ -42,7 +46,7 @@ export const validUSDCCurrency = {
wrapped: validBEPoolToken0,
} as unknown as Currency
-export const validBEPoolToken1 = {
+const validPoolToken1 = {
symbol: 'WETH',
name: 'Wrapped Ether',
derivedETH: '1',
@@ -59,7 +63,10 @@ export const validBEPoolToken1 = {
url: 'https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png',
},
},
-} as Token
+}
+
+export const validBEPoolToken1 = validPoolToken1 as Token
+export const validRestPoolToken1 = validPoolToken1 as unknown as PoolStat['token0']
export const owner = '0xf5b6bb25f5beaea03dd014c6ef9fa9f3926bf36c'
diff --git a/apps/web/src/test-utils/render.tsx b/apps/web/src/test-utils/render.tsx
index 36572a97e06..40c6ca31b60 100644
--- a/apps/web/src/test-utils/render.tsx
+++ b/apps/web/src/test-utils/render.tsx
@@ -3,7 +3,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { queries } from '@testing-library/dom'
import { RenderOptions, render } from '@testing-library/react'
import { RenderHookOptions, WrapperComponent, renderHook } from '@testing-library/react-hooks'
-import Web3Provider from 'components/Web3Provider'
+import Web3Provider, { Web3ProviderUpdater } from 'components/Web3Provider'
import { AssetActivityProvider } from 'graphql/data/apollo/AssetActivityProvider'
import { TokenBalancesProvider } from 'graphql/data/apollo/TokenBalancesProvider'
import { BlockNumberContext } from 'lib/hooks/useBlockNumber'
@@ -14,6 +14,7 @@ import { BrowserRouter } from 'react-router-dom'
import store from 'state'
import { ThemeProvider } from 'theme'
import { TamaguiProvider } from 'theme/tamaguiProvider'
+import { ReactRouterUrlProvider } from 'uniswap/src/contexts/UrlContext'
import { UnitagUpdaterContextProvider } from 'uniswap/src/features/unitags/context'
const queryClient = new QueryClient()
@@ -33,13 +34,18 @@ const WithProviders = ({ children }: { children?: ReactNode }) => {
-
-
-
- {children}
-
-
-
+
+
+
+
+
+
+ {children}
+
+
+
+
+
diff --git a/apps/web/src/test-utils/tokens/mocks.ts b/apps/web/src/test-utils/tokens/mocks.ts
index f3498e8f7c2..88d986fd3e2 100644
--- a/apps/web/src/test-utils/tokens/mocks.ts
+++ b/apps/web/src/test-utils/tokens/mocks.ts
@@ -26,7 +26,7 @@ import {
import { mocked } from 'test-utils/mocked'
import { COMMON_BASES } from 'uniswap/src/constants/routing'
import { DAI, DAI_ARBITRUM_ONE, USDC_ARBITRUM, USDC_MAINNET, USDT, WBTC } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { isSameAddress } from 'utilities/src/addresses'
beforeEach(() => {
diff --git a/apps/web/src/theme/components/RadialGradientByChainUpdater.ts b/apps/web/src/theme/components/RadialGradientByChainUpdater.ts
index 2926c649883..6fd4d369bab 100644
--- a/apps/web/src/theme/components/RadialGradientByChainUpdater.ts
+++ b/apps/web/src/theme/components/RadialGradientByChainUpdater.ts
@@ -3,7 +3,7 @@ import { useIsNftPage } from 'hooks/useIsNftPage'
import { useEffect } from 'react'
import { darkTheme, lightTheme } from 'theme/colors'
import { useDarkModeManager } from 'theme/components/ThemeToggle'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const initialStyles = {
width: '200vw',
diff --git a/apps/web/src/tracing/request.ts b/apps/web/src/tracing/request.ts
index 8aec6f9d900..c08a75b4067 100644
--- a/apps/web/src/tracing/request.ts
+++ b/apps/web/src/tracing/request.ts
@@ -1,7 +1,7 @@
-import { INFURA_PREFIX_TO_CHAIN_ID, chainIdToBackendChain } from 'constants/chains'
import { isTracing, trace } from 'tracing/trace'
import { TraceContext } from 'tracing/types'
import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { getChainIdByInfuraPrefix, toGraphQLChain } from 'uniswap/src/features/chains/utils'
export function patchFetch(api: Pick) {
const apiFetch = api.fetch
@@ -95,8 +95,11 @@ export function getTraceContext(url: URL, init?: RequestInit, force = false): Tr
try {
const body = JSON.parse(Buffer.from(init?.body as Uint8Array).toString())
method = body.method
- const chainId = INFURA_PREFIX_TO_CHAIN_ID[url.host.split('.')[0]]
- chain = chainId && chainIdToBackendChain({ chainId })
+
+ const chainId = getChainIdByInfuraPrefix(url.host.split('.')[0])
+ if (chainId) {
+ chain = toGraphQLChain(chainId)
+ }
} catch {
// ignore the error
}
diff --git a/apps/web/src/utils/chainParams.ts b/apps/web/src/utils/chainParams.ts
new file mode 100644
index 00000000000..713278fd499
--- /dev/null
+++ b/apps/web/src/utils/chainParams.ts
@@ -0,0 +1,46 @@
+import { ParsedQs } from 'qs'
+import { useParams } from 'react-router-dom'
+// eslint-disable-next-line no-restricted-imports
+import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { CurrencyField } from 'uniswap/src/types/currency'
+
+// i.e. ?chain=mainnet -> ethereum
+export function searchParamToBackendName(interfaceName: string | null): string | undefined {
+ if (interfaceName === null) {
+ return undefined
+ }
+
+ const chain = Object.values(UNIVERSE_CHAIN_INFO).find((item) => item.interfaceName === interfaceName)
+ return chain ? chain.urlParam : undefined
+}
+
+export function isChainUrlParam(str: string): boolean {
+ return !!str && Object.values(UNIVERSE_CHAIN_INFO).some((chain) => chain.urlParam === str)
+}
+
+export function getChainIdFromChainUrlParam(chainUrlParam?: string): UniverseChainId | undefined {
+ return chainUrlParam !== undefined
+ ? Object.values(UNIVERSE_CHAIN_INFO).find((chain) => chainUrlParam === chain.urlParam)?.id
+ : undefined
+}
+
+export function useChainIdFromUrlParam(): UniverseChainId | undefined {
+ const chainName = useParams<{ chainName?: string }>().chainName
+ // In the case where /explore/:chainName is used, the chainName is passed as a tab param
+ const tab = useParams<{ tab?: string }>().tab
+ return getChainIdFromChainUrlParam(chainName ?? tab)
+}
+
+export function getParsedChainId(
+ parsedQs?: ParsedQs,
+ key: CurrencyField = CurrencyField.INPUT,
+): UniverseChainId | undefined {
+ const chain = key === CurrencyField.INPUT ? parsedQs?.chain : parsedQs?.outputChain
+ if (!chain || typeof chain !== 'string') {
+ return undefined
+ }
+
+ const chainInfo = Object.values(UNIVERSE_CHAIN_INFO).find((i) => i.interfaceName === chain)
+ return chainInfo?.id
+}
diff --git a/apps/web/src/utils/chains.tsx b/apps/web/src/utils/chains.tsx
deleted file mode 100644
index a6db9e43d37..00000000000
--- a/apps/web/src/utils/chains.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { CHAIN_IDS_TO_NAMES } from 'constants/chains'
-import { ParsedQs } from 'qs'
-
-function getChainIdFromName(name: string) {
- const entry = Object.entries(CHAIN_IDS_TO_NAMES).find(([, n]) => n === name)
- const chainId = entry?.[0]
- return chainId ? parseInt(chainId) : undefined
-}
-
-export enum ParsedChainIdKey {
- INPUT = 'input',
- OUTPUT = 'output',
-}
-
-export function getParsedChainId(parsedQs?: ParsedQs, key: ParsedChainIdKey = ParsedChainIdKey.INPUT) {
- const chain = key === ParsedChainIdKey.INPUT ? parsedQs?.chain : parsedQs?.outputChain
- if (!chain || typeof chain !== 'string') {
- return undefined
- }
-
- return getChainIdFromName(chain)
-}
diff --git a/apps/web/src/utils/currencyId.ts b/apps/web/src/utils/currencyId.ts
index 34ac1386b03..1088c452466 100644
--- a/apps/web/src/utils/currencyId.ts
+++ b/apps/web/src/utils/currencyId.ts
@@ -1,5 +1,6 @@
import { Currency } from '@uniswap/sdk-core'
+/** @deprecated confusing since currencyId from packages/uniswap is formatted as `chainId-address` */
export function currencyId(currency?: Currency): string {
if (currency?.isNative) {
return 'ETH'
diff --git a/apps/web/src/utils/currencyKey.ts b/apps/web/src/utils/currencyKey.ts
index 1caeb79f474..03a86913b6f 100644
--- a/apps/web/src/utils/currencyKey.ts
+++ b/apps/web/src/utils/currencyKey.ts
@@ -1,8 +1,8 @@
import { Currency } from '@uniswap/sdk-core'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
-import { supportedChainIdFromGQLChain } from 'graphql/data/util'
import { Chain, TokenStandard } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { fromGraphQLChain } from 'uniswap/src/features/chains/utils'
export type CurrencyKey = string
@@ -20,7 +20,7 @@ export function currencyKeyFromGraphQL(contract: {
chain: Chain
standard?: TokenStandard
}): CurrencyKey {
- const chainId = supportedChainIdFromGQLChain(contract.chain)
+ const chainId = fromGraphQLChain(contract.chain)
const address = contract.standard === TokenStandard.Native ? NATIVE_CHAIN_ID : contract.address
if (!address) {
throw new Error('Non-native token missing address')
diff --git a/apps/web/src/utils/formatNumbers.test.ts b/apps/web/src/utils/formatNumbers.test.ts
index a0061539023..1243ed4d5da 100644
--- a/apps/web/src/utils/formatNumbers.test.ts
+++ b/apps/web/src/utils/formatNumbers.test.ts
@@ -1,17 +1,15 @@
import { renderHook } from '@testing-library/react'
import { CurrencyAmount, Percent } from '@uniswap/sdk-core'
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
-import { useActiveLocale } from 'hooks/useActiveLocale'
import { mocked } from 'test-utils/mocked'
import { USDC_MAINNET } from 'uniswap/src/constants/tokens'
import { Currency } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
import { DEFAULT_LOCAL_CURRENCY, FiatCurrency } from 'uniswap/src/features/fiatCurrency/constants'
import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
import { Locale } from 'uniswap/src/features/language/constants'
+import { useCurrentLocale } from 'uniswap/src/features/language/hooks'
import { NumberType, useFormatter } from 'utils/formatNumbers'
-jest.mock('hooks/useActiveLocale')
-jest.mock('hooks/useActiveLocalCurrency')
+jest.mock('uniswap/src/features/language/hooks')
jest.mock('uniswap/src/features/fiatCurrency/hooks')
describe('formatNumber', () => {
@@ -28,7 +26,7 @@ describe('formatNumber', () => {
})
it('formats token reference numbers correctly with Dutch locale', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.DutchNetherlands)
+ mocked(useCurrentLocale).mockReturnValue(Locale.DutchNetherlands)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567000000000, type: NumberType.TokenNonTx })).toBe('>999\xa0bln.')
@@ -62,7 +60,7 @@ describe('formatNumber', () => {
})
it('formats token transaction numbers correctly with russian locale', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.RussianRussia)
+ mocked(useCurrentLocale).mockReturnValue(Locale.RussianRussia)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567.8901, type: NumberType.TokenTx })).toBe('1\xa0234\xa0567,89')
@@ -98,8 +96,8 @@ describe('formatNumber', () => {
})
it('formats fiat estimates on token details pages correctly with french locale and euro currency', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.FrenchFrance)
- mocked(useActiveLocalCurrency).mockReturnValue(FiatCurrency.Euro)
+ mocked(useCurrentLocale).mockReturnValue(Locale.FrenchFrance)
+ mocked(useAppFiatCurrency).mockReturnValue(FiatCurrency.Euro)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenDetails })).toBe('1,23\xa0M\xa0€')
@@ -131,8 +129,8 @@ describe('formatNumber', () => {
})
it('formats fiat estimates for tokens correctly with spanish locale and yen currency', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.SpanishSpain)
- mocked(useActiveLocalCurrency).mockReturnValue(FiatCurrency.JapaneseYen)
+ mocked(useCurrentLocale).mockReturnValue(Locale.SpanishSpain)
+ mocked(useAppFiatCurrency).mockReturnValue(FiatCurrency.JapaneseYen)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenPrice })).toBe('1,23\xa0M¥')
@@ -163,8 +161,8 @@ describe('formatNumber', () => {
})
it('formats fiat estimates for token stats correctly with japenese locale and cad currency', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.JapaneseJapan)
- mocked(useActiveLocalCurrency).mockReturnValue(FiatCurrency.CanadianDollar)
+ mocked(useCurrentLocale).mockReturnValue(Locale.JapaneseJapan)
+ mocked(useAppFiatCurrency).mockReturnValue(FiatCurrency.CanadianDollar)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234576, type: NumberType.FiatTokenStats })).toBe('CA$123.5万')
@@ -186,8 +184,8 @@ describe('formatNumber', () => {
})
it('formats gas prices correctly with portugese locale and thai baht currency', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.PortugueseBrazil)
- mocked(useActiveLocalCurrency).mockReturnValue(FiatCurrency.ThaiBaht)
+ mocked(useCurrentLocale).mockReturnValue(Locale.PortugueseBrazil)
+ mocked(useAppFiatCurrency).mockReturnValue(FiatCurrency.ThaiBaht)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatGasPrice })).toBe('฿\xa01,23\xa0mi')
@@ -206,7 +204,7 @@ describe('formatNumber', () => {
})
it('formats token quantities prices correctly with nigerian naira currency', () => {
- mocked(useActiveLocalCurrency).mockReturnValue(FiatCurrency.NigerianNaira)
+ mocked(useAppFiatCurrency).mockReturnValue(FiatCurrency.NigerianNaira)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenQuantity })).toBe('₦1.23M')
@@ -237,7 +235,7 @@ describe('formatNumber', () => {
})
it('formats Swap text input/output numbers correctly with Korean locale', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.KoreanKorea)
+ mocked(useCurrentLocale).mockReturnValue(Locale.KoreanKorea)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567.8901, type: NumberType.SwapTradeAmount })).toBe('1234570')
@@ -283,8 +281,8 @@ describe('formatNumber', () => {
})
it('formats NFT numbers correctly with brazilian portuguese locale and brazilian real currency', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.PortugueseBrazil)
- mocked(useActiveLocalCurrency).mockReturnValue(FiatCurrency.BrazilianReal)
+ mocked(useCurrentLocale).mockReturnValue(Locale.PortugueseBrazil)
+ mocked(useAppFiatCurrency).mockReturnValue(FiatCurrency.BrazilianReal)
const { formatNumber } = renderHook(() => useFormatter()).result.current
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTTokenFloorPrice })).toBe('>999\xa0tri')
@@ -327,8 +325,8 @@ describe('formatUSDPrice', () => {
})
it('format fiat price correctly in euros with french locale', () => {
- mocked(useActiveLocalCurrency).mockReturnValue(FiatCurrency.Euro)
- mocked(useActiveLocale).mockReturnValue(Locale.FrenchFrance)
+ mocked(useAppFiatCurrency).mockReturnValue(FiatCurrency.Euro)
+ mocked(useCurrentLocale).mockReturnValue(Locale.FrenchFrance)
const { formatFiatPrice } = renderHook(() => useFormatter()).result.current
expect(formatFiatPrice({ price: 0.000000009876 })).toBe('<0,00000001\xa0€')
@@ -363,7 +361,7 @@ describe('formatPercent', () => {
})
it('correctly formats a percent with french locale', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.FrenchFrance)
+ mocked(useCurrentLocale).mockReturnValue(Locale.FrenchFrance)
const { formatPercent } = renderHook(() => useFormatter()).result.current
expect(formatPercent(new Percent(1, 100000))).toBe('0,001%')
@@ -383,7 +381,7 @@ describe('formatReviewSwapCurrencyAmount', () => {
})
it('should use TokenTx formatting under a default length with french locales', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.FrenchFrance)
+ mocked(useCurrentLocale).mockReturnValue(Locale.FrenchFrance)
const { formatReviewSwapCurrencyAmount } = renderHook(() => useFormatter()).result.current
const currencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '2000000000') // 2,000 USDC
@@ -398,7 +396,7 @@ describe('formatReviewSwapCurrencyAmount', () => {
})
it('should use SwapTradeAmount formatting over the default length with french locales', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.FrenchFrance)
+ mocked(useCurrentLocale).mockReturnValue(Locale.FrenchFrance)
const { formatReviewSwapCurrencyAmount } = renderHook(() => useFormatter()).result.current
const currencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '2000000000000') // 2,000,000 USDC
@@ -424,7 +422,7 @@ describe('formatDelta', () => {
})
it('correctly formats a percent with 2 decimal places in french locale', () => {
- mocked(useActiveLocale).mockReturnValue(Locale.FrenchFrance)
+ mocked(useCurrentLocale).mockReturnValue(Locale.FrenchFrance)
const { formatDelta } = renderHook(() => useFormatter()).result.current
expect(formatDelta(0)).toBe('0,00%')
diff --git a/apps/web/src/utils/formatNumbers.ts b/apps/web/src/utils/formatNumbers.ts
index c781b96e537..dc0101c5cc9 100644
--- a/apps/web/src/utils/formatNumbers.ts
+++ b/apps/web/src/utils/formatNumbers.ts
@@ -1,16 +1,15 @@
import { formatEther as ethersFormatEther } from '@ethersproject/units'
import { Currency, CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'
import { getCurrencySymbolDisplayType } from 'constants/localCurrencies'
-import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
-import { useActiveLocale } from 'hooks/useActiveLocale'
import usePrevious from 'hooks/usePrevious'
import { useCallback, useMemo } from 'react'
import { Bound } from 'state/mint/v3/actions'
import { DEFAULT_LOCAL_CURRENCY, FiatCurrency } from 'uniswap/src/features/fiatCurrency/constants'
+import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks'
import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext'
import { DEFAULT_LOCALE, Locale } from 'uniswap/src/features/language/constants'
+import { useCurrentLocale } from 'uniswap/src/features/language/hooks'
-type Nullish = T | null | undefined
type NumberFormatOptions = Intl.NumberFormatOptions
// Number formatting follows the standards laid out in this spec:
@@ -507,7 +506,7 @@ function getFormatterRule(input: number, type: FormatterType, conversionRate?: n
}
interface FormatNumberOptions {
- input: Nullish
+ input: Maybe
type?: FormatterType
placeholder?: string
locale?: Locale
@@ -561,7 +560,7 @@ function formatNumber({
}
interface FormatCurrencyAmountOptions {
- amount: Nullish>
+ amount: Maybe>
type?: FormatterType
placeholder?: string
locale?: Locale
@@ -599,7 +598,7 @@ function formatPercent(percent: Percent | undefined, locale: Locale = DEFAULT_LO
}
// Used to format floats representing percent change with fixed decimal places
-function formatDelta(delta: Nullish, locale: Locale = DEFAULT_LOCALE) {
+function formatDelta(delta: Maybe, locale: Locale = DEFAULT_LOCALE) {
if (delta === null || delta === undefined || delta === Infinity || isNaN(delta)) {
return '-'
}
@@ -612,7 +611,7 @@ function formatDelta(delta: Nullish, locale: Locale = DEFAULT_LOCALE) {
}
interface FormatPriceOptions {
- price: Nullish>
+ price: Maybe>
type?: FormatterType
locale?: Locale
localCurrency?: FiatCurrency
@@ -672,7 +671,7 @@ function formatTickPrice({
}
interface FormatNumberOrStringOptions {
- input: Nullish
+ input: Maybe
type: FormatterType
locale?: Locale
localCurrency?: FiatCurrency
@@ -696,7 +695,7 @@ function formatNumberOrString({
}
interface FormatEtherOptions {
- input: Nullish
+ input: Maybe
type: FormatterType
locale?: Locale
localCurrency?: FiatCurrency
@@ -710,7 +709,7 @@ function formatEther({ input, type, locale, localCurrency }: FormatEtherOptions)
}
interface FormatFiatPriceOptions {
- price: Nullish
+ price: Maybe
type?: FormatterType
locale?: Locale
localCurrency?: FiatCurrency
@@ -737,78 +736,6 @@ function formatReviewSwapCurrencyAmount(amount: CurrencyAmount, locale
return formattedAmount
}
-// TODO: https://linear.app/uniswap/issue/WEB-3495/import-useasyncdata-from-mobile
-type FiatCurrencyComponents = {
- groupingSeparator: string
- decimalSeparator: string
- symbol: string
- fullSymbol: string // Some currencies have whitespace in between number and currency
- symbolAtFront: boolean // All currencies are at front or back except CVE, which we won't ever support
-}
-
-/**
- * Helper function to return components of a currency value for a specific locale
- * E.g. comma, period, or space for separating thousands
- */
-export function getFiatCurrencyComponents(
- locale = DEFAULT_LOCALE,
- localCurrency = DEFAULT_LOCAL_CURRENCY,
-): FiatCurrencyComponents {
- const format = new Intl.NumberFormat(locale, {
- ...TWO_DECIMALS_CURRENCY,
- currency: localCurrency,
- currencyDisplay: getCurrencySymbolDisplayType(localCurrency),
- })
-
- // See MDN for official docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/formatToParts
- // Returns something like [{"type":"currency","value":"$"},{"type":"integer","value":"1"}]
- const parts = format.formatToParts(1000000.0) // This number should provide both types of separators
- let groupingSeparator = ','
- let decimalSeparator = '.'
- let symbol = ''
- let fullSymbol = ''
- let symbolAtFront = true
-
- parts.forEach((part, index) => {
- if (part.type === 'group') {
- groupingSeparator = part.value
- } else if (part.type === 'decimal') {
- decimalSeparator = part.value
- } else if (part.type === 'currency') {
- symbol = part.value
- fullSymbol = symbol
-
- symbolAtFront = index === 0
- const nextPart = symbolAtFront ? parts[index + 1] : parts[index - 1]
- // Check for additional characters between symbol and number, like whitespace
- if (nextPart?.type === 'literal') {
- fullSymbol = symbolAtFront ? symbol + nextPart.value : nextPart.value + symbol
- }
- }
- })
-
- return {
- groupingSeparator,
- decimalSeparator,
- symbol,
- fullSymbol,
- symbolAtFront,
- }
-}
-
-export function useFormatterLocales(): {
- formatterLocale: Locale
- formatterLocalCurrency: FiatCurrency
-} {
- const activeLocale = useActiveLocale()
- const activeLocalCurrency = useActiveLocalCurrency()
-
- return {
- formatterLocale: activeLocale,
- formatterLocalCurrency: activeLocalCurrency,
- }
-}
-
function handleFallbackCurrency(
selectedCurrency: FiatCurrency,
previousSelectedCurrency: FiatCurrency | undefined,
@@ -827,16 +754,17 @@ function handleFallbackCurrency(
// Constructs an object that injects the correct locale and local currency into each of the above formatter functions.
export function useFormatter() {
- const { formatterLocale, formatterLocalCurrency } = useFormatterLocales()
+ const activeLocale = useCurrentLocale()
+ const activeLocalCurrency = useAppFiatCurrency()
const { convertFiatAmount, conversionRate: localCurrencyConversionRate } = useLocalizationContext()
- const previousSelectedCurrency = usePrevious(formatterLocalCurrency)
+ const previousSelectedCurrency = usePrevious(activeLocalCurrency)
const previousConversionRate = usePrevious(localCurrencyConversionRate)
const shouldFallbackToPrevious = !localCurrencyConversionRate
const shouldFallbackToUSD = !localCurrencyConversionRate
const currencyToFormatWith = handleFallbackCurrency(
- formatterLocalCurrency,
+ activeLocalCurrency,
previousSelectedCurrency,
previousConversionRate,
shouldFallbackToUSD,
@@ -851,102 +779,102 @@ export function useFormatter() {
(options: Omit) =>
formatNumber({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
conversionRate: localCurrencyConversionRateToFormatWith,
}),
- [currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith],
+ [currencyToFormatWith, activeLocale, localCurrencyConversionRateToFormatWith],
)
const formatCurrencyAmountWithLocales = useCallback(
(options: Omit) =>
formatCurrencyAmount({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
conversionRate: localCurrencyConversionRateToFormatWith,
}),
- [currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith],
+ [currencyToFormatWith, activeLocale, localCurrencyConversionRateToFormatWith],
)
const formatPriceWithLocales = useCallback(
(options: Omit) =>
formatPrice({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
conversionRate: localCurrencyConversionRateToFormatWith,
}),
- [currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith],
+ [currencyToFormatWith, activeLocale, localCurrencyConversionRateToFormatWith],
)
const formatReviewSwapCurrencyAmountWithLocales = useCallback(
- (amount: CurrencyAmount) => formatReviewSwapCurrencyAmount(amount, formatterLocale),
- [formatterLocale],
+ (amount: CurrencyAmount) => formatReviewSwapCurrencyAmount(amount, activeLocale),
+ [activeLocale],
)
const formatTickPriceWithLocales = useCallback(
(options: Omit) =>
formatTickPrice({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
conversionRate: localCurrencyConversionRateToFormatWith,
}),
- [currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith],
+ [currencyToFormatWith, activeLocale, localCurrencyConversionRateToFormatWith],
)
const formatNumberOrStringWithLocales = useCallback(
(options: Omit) =>
formatNumberOrString({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
conversionRate: localCurrencyConversionRateToFormatWith,
}),
- [currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith],
+ [currencyToFormatWith, activeLocale, localCurrencyConversionRateToFormatWith],
)
const formatFiatPriceWithLocales = useCallback(
(options: Omit) =>
formatFiatPrice({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
conversionRate: localCurrencyConversionRateToFormatWith,
}),
- [currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith],
+ [currencyToFormatWith, activeLocale, localCurrencyConversionRateToFormatWith],
)
const formatDeltaWithLocales = useCallback(
- (percent: Nullish) => formatDelta(percent, formatterLocale),
- [formatterLocale],
+ (percent: Maybe) => formatDelta(percent, activeLocale),
+ [activeLocale],
)
const formatPercentWithLocales = useCallback(
- (percent: Percent | undefined) => formatPercent(percent, formatterLocale),
- [formatterLocale],
+ (percent: Percent | undefined) => formatPercent(percent, activeLocale),
+ [activeLocale],
)
const formatEtherwithLocales = useCallback(
(options: Omit) =>
formatEther({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
}),
- [currencyToFormatWith, formatterLocale],
+ [currencyToFormatWith, activeLocale],
)
const formatConvertedFiatNumberOrString = useCallback(
(options: Omit) =>
formatNumberOrString({
...options,
- locale: formatterLocale,
+ locale: activeLocale,
localCurrency: currencyToFormatWith,
conversionRate: undefined,
}),
- [currencyToFormatWith, formatterLocale],
+ [currencyToFormatWith, activeLocale],
)
return useMemo(
diff --git a/apps/web/src/utils/getInitialLogoURL.ts b/apps/web/src/utils/getInitialLogoURL.ts
index 5178ab95085..544e65e05d9 100644
--- a/apps/web/src/utils/getInitialLogoURL.ts
+++ b/apps/web/src/utils/getInitialLogoURL.ts
@@ -1,6 +1,7 @@
-import { getChain, isSupportedChainId } from 'constants/chains'
import { CELO_LOGO } from 'ui/src/assets'
import { isCelo, nativeOnChain } from 'uniswap/src/constants/tokens'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { isUniverseChainId } from 'uniswap/src/features/chains/types'
import { isAddress } from 'utilities/src/addresses'
export function getInitialLogoUrl(
@@ -9,9 +10,7 @@ export function getInitialLogoUrl(
isNative?: boolean,
backupImg?: string | null,
) {
- const networkName = isSupportedChainId(chainId)
- ? getChain({ chainId }).assetRepoNetworkName ?? 'ethereum'
- : 'ethereum'
+ const networkName = isUniverseChainId(chainId) ? getChainInfo(chainId).assetRepoNetworkName ?? 'ethereum' : 'ethereum'
const checksummedAddress = isAddress(address)
if (chainId && isCelo(chainId) && address === nativeOnChain(chainId).wrapped.address) {
diff --git a/apps/web/src/utils/getSupportedChainIdsFromWalletConnectSession.ts b/apps/web/src/utils/getSupportedChainIdsFromWalletConnectSession.ts
index 62e85f67502..bdf026145da 100644
--- a/apps/web/src/utils/getSupportedChainIdsFromWalletConnectSession.ts
+++ b/apps/web/src/utils/getSupportedChainIdsFromWalletConnectSession.ts
@@ -1,5 +1,5 @@
import type { SessionTypes } from '@walletconnect/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
// Helper function to extract chainId from string in format 'eip155:{chainId}'
function getChainIdFromFormattedString(item: string): number | null {
diff --git a/apps/web/src/utils/nativeTokens.ts b/apps/web/src/utils/nativeTokens.ts
index a9e69861e6a..aed156c492e 100644
--- a/apps/web/src/utils/nativeTokens.ts
+++ b/apps/web/src/utils/nativeTokens.ts
@@ -1,6 +1,6 @@
-import { getChain } from 'constants/chains'
import { supportedChainIdFromGQLChain } from 'graphql/data/util'
import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
export function getNativeTokenDBAddress(chain: Chain): string | undefined {
const pageChainId = supportedChainIdFromGQLChain(chain)
@@ -8,5 +8,5 @@ export function getNativeTokenDBAddress(chain: Chain): string | undefined {
return undefined
}
- return getChain({ chainId: pageChainId }).backendChain.nativeTokenBackendAddress
+ return getChainInfo(pageChainId).backendChain.nativeTokenBackendAddress
}
diff --git a/apps/web/src/utils/transfer.test.ts b/apps/web/src/utils/transfer.test.ts
index b6f9e52e97f..d35024aefca 100644
--- a/apps/web/src/utils/transfer.test.ts
+++ b/apps/web/src/utils/transfer.test.ts
@@ -2,7 +2,7 @@ import { ExternalProvider, JsonRpcProvider, JsonRpcSigner, Web3Provider } from '
import { CurrencyAmount } from '@uniswap/sdk-core'
import { act, renderHook } from 'test-utils/render'
import { DAI, nativeOnChain } from 'uniswap/src/constants/tokens'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { useCreateTransferTransaction } from 'utils/transfer'
type Mutable = { -readonly [P in keyof T]: T[P] }
diff --git a/apps/web/src/utils/transfer.ts b/apps/web/src/utils/transfer.ts
index 620e950fc5c..c72f2d1bfaa 100644
--- a/apps/web/src/utils/transfer.ts
+++ b/apps/web/src/utils/transfer.ts
@@ -5,7 +5,7 @@ import { useWeb3React } from '@web3-react/core'
import { useCallback } from 'react'
import ERC20_ABI from 'uniswap/src/abis/erc20.json'
import { Erc20 } from 'uniswap/src/abis/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { getContract } from 'utilities/src/contracts/getContract'
import { logger } from 'utilities/src/logger/logger'
import { useAsyncData } from 'utilities/src/react/hooks'
diff --git a/config/jest-presets/jest/setup.js b/config/jest-presets/jest/setup.js
index 8ebf9d11221..166379a9f5c 100644
--- a/config/jest-presets/jest/setup.js
+++ b/config/jest-presets/jest/setup.js
@@ -89,14 +89,6 @@ jest.mock('@walletconnect/utils', () => ({
buildApprovedNamespaces: jest.fn(),
}))
-// Mock Sentry crash reporting
-jest.mock('@sentry/react-native', () => ({
- init: () => jest.fn(),
- wrap: (val) => val,
- ReactNavigationInstrumentation: jest.fn(),
- ReactNativeTracing: jest.fn(),
-}))
-
jest.mock('react-native-appsflyer', () => {
return {
initSdk: jest.fn(),
diff --git a/dangerfile.ts b/dangerfile.ts
index 306feaa902b..456c8234998 100644
--- a/dangerfile.ts
+++ b/dangerfile.ts
@@ -33,6 +33,29 @@ async function getLinesAddedByFile(files: string[], { exclude = [] }: { exclude?
)
}
+function checkGeneralizedHookFiles() {
+ const touchedFiles = danger.git.modified_files.concat(danger.git.created_files)
+
+ touchedFiles.forEach((file) => {
+ const isGeneralHookFile = file.endsWith('hooks.ts') || file.endsWith('hooks.tsx')
+ const isNonSpecificHookFile = file.includes('/hooks/') && !file.includes('/use')
+
+ const sharedWarningExampleExplanation = `e.g. \`hooks/useXXX.ts{x}\`. This helps in development for discovery and navigation purposes.`
+
+ if (isGeneralHookFile) {
+ warn(
+ `\`${file}\` should be split out into a \`hooks/*\` folder with a hook per file, ${sharedWarningExampleExplanation}`,
+ )
+ }
+
+ if (isNonSpecificHookFile) {
+ warn(
+ `\`${file}\` should only have one exported hook per file and be named accordingly, ${sharedWarningExampleExplanation}`,
+ )
+ }
+ })
+}
+
// Put any files here that we explicitly want to ignore!
const IGNORED_SPLIT_RULE_FILES: string[] = []
@@ -240,6 +263,9 @@ if (envChanged) {
// Check native and web file splits
checkSplitFiles()
+// Check hook file pattern
+checkGeneralizedHookFiles()
+
// Run checks on added changes
processAddChanges()
diff --git a/package.json b/package.json
index c1a3ff439f9..962e1ddb2f3 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"@uniswap/v2-sdk": "4.6.1",
"@uniswap/router-sdk": "1.14.3",
"@apollo/client": "3.10.4",
- "@uniswap/sdk-core": "5.8.4",
+ "@uniswap/sdk-core": "5.9.0",
"@react-navigation/routers": "6.1.9",
"@react-navigation/core": "6.2.2",
"@sideway/formula": "3.0.1",
@@ -61,7 +61,6 @@
"json5": "2.2.2",
"expo/uuid": "3.4.0",
"is-core-module": "2.13.0",
- "qs": "6.11.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native-fast-image@8.6.3": "patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch",
diff --git a/packages/eslint-config/__snapshots__/preset.test.ts.snap b/packages/eslint-config/__snapshots__/preset.test.ts.snap
index 3002605fd37..6b830d8e97b 100644
--- a/packages/eslint-config/__snapshots__/preset.test.ts.snap
+++ b/packages/eslint-config/__snapshots__/preset.test.ts.snap
@@ -902,6 +902,13 @@ exports[`should have a correct configuration for a React file 1`] = `
"message": "Use specific imports (e.g. \`import isEqual from 'lodash/isEqual'\`) to avoid pulling in all of lodash to web to keep bundle size down!",
"name": "lodash",
},
+ {
+ "importNames": [
+ "UNIVERSE_CHAIN_INFO",
+ ],
+ "message": "Use useChainInfo or helpers in packages/uniswap/src/features/chains/utils.ts when possible!",
+ "name": "uniswap/src/features/chains/chainInfo",
+ },
{
"message": "Please import from '@ethersproject/module' directly to support tree-shaking.",
"name": "ethers",
diff --git a/packages/eslint-config/native.js b/packages/eslint-config/native.js
index 9fa81917c5c..1ede3402523 100644
--- a/packages/eslint-config/native.js
+++ b/packages/eslint-config/native.js
@@ -312,7 +312,7 @@ module.exports = {
},
// enforce saga imports from typed-redux-saga
{
- files: ['./**/*.ts'],
+ files: ['./**/*.ts', './**/*.tsx'],
excludedFiles: ['./**/*.test.ts', './**/*.test.tsx'],
rules: {
'@jambit/typed-redux-saga/use-typed-effects': 'error',
diff --git a/packages/eslint-config/restrictedImports.js b/packages/eslint-config/restrictedImports.js
index f20e410a43b..0cf57336582 100644
--- a/packages/eslint-config/restrictedImports.js
+++ b/packages/eslint-config/restrictedImports.js
@@ -51,7 +51,12 @@ exports.shared = {
{
name: 'lodash',
message: 'Use specific imports (e.g. `import isEqual from \'lodash/isEqual\'`) to avoid pulling in all of lodash to web to keep bundle size down!',
- }
+ },
+ {
+ name: 'uniswap/src/features/chains/chainInfo',
+ importNames: ['UNIVERSE_CHAIN_INFO'],
+ message: 'Use useChainInfo or helpers in packages/uniswap/src/features/chains/utils.ts when possible!',
+ },
],
patterns: [
{
diff --git a/packages/ui/README.md b/packages/ui/README.md
index fcb905b9438..0ef0b56aee9 100644
--- a/packages/ui/README.md
+++ b/packages/ui/README.md
@@ -1,30 +1,21 @@
-# Uniswap UI
+# `ui` Package
-This package holds a component library and themes that can be used across both mobile and web contexts. Below is instructions for both use and development of this package.
+This package holds a component library and themes that can be used across all apps.
-## Library Usage
+## UI Package Philosophy
-### Core components
+The `ui` package contains all low level components that are shared between apps. It should *not* contain components that are specific to any one app or Uniswap business logic. Each component should be guided by the following principles:
-Many base components are available in the UI library. Below key use cases are detailed, but many more are available.
+- All components should be compatible with all platforms.
+- Wrap as many implementation details as possible, including any direct exports from Tamagui.
+- Export only what’s needed from `ui/src` or another allowlisted path.
+- Only include components that will be used beyond a single feature.
-While some are customized `tamagui` elements or even fully custom elements, many are simple or direct exposure of `tamagui` elements. If you would like to use any `tamagui` elements, please add them through this library to ensure a layer of abstraction between tamagui and our usage when possible.
+Components that are shared between all applications but encode Uniswap business logic should most likely be placed in the `uniswap` package!
-#### Flex
+## Icons and Logos
-The `Flex` component is the core organizational element of the UI library, acting as a base of a flexbox styling approach. Shortcuts are available for `row`, `grow`, `shrink`, `fill`, and `centered`. All other styling props can be added directly as needed.
-
-#### Text
-
-The `Text` element is the core element for displaying text through the app. The `variant` prop takes in the text variant from our design system (e.g `heading1`, `body2`, etc.) that is desired. All other text styling props can be added directly as needed.
-
-#### Button
-
-The `Button` element is used consistently to ensure action buttons maintain similar action and style, utilizing `size` and `theme` properties to enforce consistent usage. Even when not using either, this component ensures consistent haptics and other implementation details.
-
-#### Icons and Logos
-
-Icons and Logos are made available off `ui/src/components/icons` and `ui/src/components/logos`. These files are generated from placing the file in `packages/ui/src/assets/icons` or `packages/ui/src/assets/logos/svg` and running the generate command(s):
+Icons and logos are placed in `ui/src/components/{icons|logos}`. These files are generated from placing the file in `packages/ui/src/assets/icons` or `packages/ui/src/assets/logos/svg` and running the generate command(s):
```bash
# Generate all icons
@@ -37,6 +28,22 @@ When adding an SVG, please ensure you replace color references as needed with `c
Custom icons that take props can be added to the same icons import by adding the file in `packages/ui/src/components/icons/index.ts`.
+## Core Components
+
+Many base components are available in the UI library. While some are customized `tamagui` elements or even fully custom elements, many are simple or direct exposure of `tamagui` elements. If you would like to use any `tamagui` elements, please add them through this library to ensure a layer of abstraction between tamagui and our usage when possible.
+
+Below are summaries of the most commonly used elements.
+
+### Flex
+
+The `Flex` component is the core organizational element of the UI library, acting as a base of a flexbox styling approach. Shortcuts are available for `row`, `grow`, `shrink`, `fill`, and `centered`. All other styling props can be added directly as needed.
+
+### Text
+
+The `Text` element is the core element for displaying text through the app. The `variant` prop takes in the text variant from our design system (e.g `heading1`, `body2`, etc.) that is desired. All other text styling props can be added directly as needed.
+
+## Theme and Platform
+
### Theming
Theming is applied through two primary methods:
@@ -69,9 +76,7 @@ To account for screen size references, components take in props to adapt custom
When components cannot take in these props or a value needs to be resued multiple times, the `useMedia` hook allows these same breakpoint values to be defined programmatically.
-### Other notable usage
-
-#### Accessing colors
+### Colors
We've made a hook `useSporeColors()` which gives you access to the current theme, and you can access the values off it as follows:
@@ -86,7 +91,7 @@ function MyComponent() {
}
```
-##### When to use `.get()` vs `.val`
+#### When to use `.get()` vs `.val`
After some discussion we've come to prefer `.val` by default. This will always return the raw string color (in our case hex color) on all platforms, whereas `.get()` returns either an Object (iOS) or a string, which can cause issues when used with things like animations, or external components.
@@ -102,65 +107,3 @@ In summary:
- On iOS, it returns an object like `{ dynamic: { light: '#fff', dark: '#000' } }`
- On the web, it returns a CSS variable string, `var(--colorName)`
- You can call `.get('web')` to only optimize for web, or `.get('ios')` to only optimize for ios.
-
-#### When should you use `styled()` vs inline props
-
-When possible, usage of `styled` should be limited to use within the `ui` package or direct styling only repetition of . In general try to use the following rules:
-
-1. If it's used only once, always prefer inline for simplicity's sake. It avoids having to name things and avoids having to jump between files or places in code to understand styling.
-
-2. If it's used more than once, try to create a component that abstracts properties to the minimum needed. This new component should live as close to the usage as possible, so if used only within a single file, keep it within that file. You should only use `styled` when said component is being used more than once, otherwise defer to inline styles.
-
-3. If it's used across multiple apps or has a strong potential to be, consider extracting it into a shared package. To decide where to place it, see "What code should be placed in the package?"
-
-## Library Design
-
-### What code should be placed in the package?
-
-The `ui` package should be where we put all low level interface components that are shared between apps (or will likely be shared). It should *not* contain components that are specific to any one app, or which touch app-level data in any way.
-
-A good rule of thumb is: if it deals with app-specific state (eg anything thats stored in redux) or has a very complex interface, then:
-
-- If it's specific to just one app, put it in that app.
-- Else if it's shared between multiple apps, put it in a shared package above the UI package, e.g `packages/{package}`.
-
-Otherwise, if it's simpler, put it in `packages/ui`.
-
-Think of `packages/ui` as our low level and more pure building blocks for interface, and `packages/{package}` as our higher level shared components that deal with complex dependencies or app-specific state.
-
-### Optimization
-
-The Tamagui optimizing compiler will extract CSS and do tree-flattening optimizations for all of `ui`, and for all usages of components from `ui` in the apps.
-
-Where it will bail out of optimization is if you define a new `styled()` component outside of `ui` and then use that component.
-
-But this is fine! It will still be pretty fast.
-
-Also, in the future we can turn `enableDynamicEvaluation` which enables the compiler to optimize those one-off `styled()` definitions within apps to also extract CSS and flatten. Its still a bit of a beta feature so no rush to turn it on, and likely it's fast enough that we don't need to worry about it.
-
-### useStyle, useProps, and usePropsAndStyle
-
-These three are useful more advanced patterns to get styles or props from Tamagui form into plain objects and [are documented on the Tamagui site](https://tamagui.dev/docs/core/exports#useprops).
-
-In short:
-
-- `useProps`: takes in props returns props as-is just with media queries resolved and shorthands expanded (not transformed so tokens like $color stay as $color)
-- `useStyle`: takes in props returns only styles (media queries, shorthands, tokens, etc resolved)
-- `usePropsAndStyle`: splits the props and styles apart for you, fully resolves everything
-
-Also the `forComponent` pattern is useful and works with all of them:
-
-```tsx
-const CustomText = styled(Text, {
- variants: {
- large: {
- true: {
- fontSize: 100
- }
- }
- }
-})
-
-useStyle({ large: true }, { forComponent: CustomText } })
-// returns { fontSize: 100 }
-```
diff --git a/packages/ui/src/animations/components/HeightAnimator.tsx b/packages/ui/src/animations/components/HeightAnimator.tsx
index 23d9455dba9..28d8eb288d1 100644
--- a/packages/ui/src/animations/components/HeightAnimator.tsx
+++ b/packages/ui/src/animations/components/HeightAnimator.tsx
@@ -1,36 +1,29 @@
-import { useCallback, useEffect, useState } from 'react'
+import { useState } from 'react'
import { View, useEvent } from 'tamagui'
export const HeightAnimator = View.styleable<{ open?: boolean }>((props, ref) => {
const { open = true, children, ...rest } = props
- const [height, setHeight] = useState(0)
- const [hide, setHide] = useState(false)
-
- const close = useCallback(() => {
- setHeight(0)
- setTimeout(() => {
- setHide(true)
- }, 300)
- }, [setHeight, setHide])
-
- useEffect(() => {
- if (open) {
- setHide(false)
- } else {
- close()
- }
- }, [open, setHide, close])
+ const [visibleHeight, setVisibleHeight] = useState(0)
const onLayout = useEvent(({ nativeEvent }) => {
if (nativeEvent.layout.height) {
- setHeight(nativeEvent.layout.height)
+ setVisibleHeight(nativeEvent.layout.height)
}
})
return (
-
+
- {!hide && children}
+ {children}
)
diff --git a/packages/ui/src/animations/components/WidthAnimator.tsx b/packages/ui/src/animations/components/WidthAnimator.tsx
index c5676d223b0..21ffb340130 100644
--- a/packages/ui/src/animations/components/WidthAnimator.tsx
+++ b/packages/ui/src/animations/components/WidthAnimator.tsx
@@ -1,29 +1,13 @@
-import { useCallback, useEffect, useState } from 'react'
+import { useState } from 'react'
import { View, useEvent } from 'tamagui'
export const WidthAnimator = View.styleable<{ open?: boolean; height: number }>((props, ref) => {
const { open = true, height, children, ...rest } = props
- const [width, setWidth] = useState(0)
- const [hide, setHide] = useState(false)
-
- const close = useCallback(() => {
- setWidth(0)
- setTimeout(() => {
- setHide(true)
- }, 300)
- }, [setWidth, setHide])
-
- useEffect(() => {
- if (open) {
- setHide(false)
- } else {
- close()
- }
- }, [open, setHide, close])
+ const [visibleWidth, setVisibleWidth] = useState(0)
const onLayout = useEvent(({ nativeEvent }) => {
if (nativeEvent.layout.width) {
- setWidth(nativeEvent.layout.width)
+ setVisibleWidth(nativeEvent.layout.width)
}
})
@@ -36,11 +20,11 @@ export const WidthAnimator = View.styleable<{ open?: boolean; height: number }>(
exitStyle={{ opacity: 0 }}
height={height}
overflow="hidden"
- width={width}
+ width={open ? visibleWidth : 0}
{...rest}
>
- {!hide && children}
+ {children}
)
diff --git a/packages/ui/src/assets/backgrounds/android/notifications-dark.png b/packages/ui/src/assets/backgrounds/android/notifications-dark.png
index ade6e0f3d92..5ce57622275 100644
Binary files a/packages/ui/src/assets/backgrounds/android/notifications-dark.png and b/packages/ui/src/assets/backgrounds/android/notifications-dark.png differ
diff --git a/packages/ui/src/assets/backgrounds/android/notifications-light.png b/packages/ui/src/assets/backgrounds/android/notifications-light.png
index 5768534ab4a..19b4c1c1553 100644
Binary files a/packages/ui/src/assets/backgrounds/android/notifications-light.png and b/packages/ui/src/assets/backgrounds/android/notifications-light.png differ
diff --git a/packages/ui/src/assets/backgrounds/android/security-background-dark.png b/packages/ui/src/assets/backgrounds/android/security-background-dark.png
index 6f97db70dc4..54938d6df4d 100644
Binary files a/packages/ui/src/assets/backgrounds/android/security-background-dark.png and b/packages/ui/src/assets/backgrounds/android/security-background-dark.png differ
diff --git a/packages/ui/src/assets/backgrounds/android/security-background-light.png b/packages/ui/src/assets/backgrounds/android/security-background-light.png
index 9b224e7607c..0479fcef6f1 100644
Binary files a/packages/ui/src/assets/backgrounds/android/security-background-light.png and b/packages/ui/src/assets/backgrounds/android/security-background-light.png differ
diff --git a/packages/ui/src/assets/backgrounds/ios/notifications-dark.png b/packages/ui/src/assets/backgrounds/ios/notifications-dark.png
index c1b0f40ff91..3aa12b550a2 100644
Binary files a/packages/ui/src/assets/backgrounds/ios/notifications-dark.png and b/packages/ui/src/assets/backgrounds/ios/notifications-dark.png differ
diff --git a/packages/ui/src/assets/backgrounds/ios/notifications-light.png b/packages/ui/src/assets/backgrounds/ios/notifications-light.png
index d4b5b7ec347..bc751e18d02 100644
Binary files a/packages/ui/src/assets/backgrounds/ios/notifications-light.png and b/packages/ui/src/assets/backgrounds/ios/notifications-light.png differ
diff --git a/packages/ui/src/assets/backgrounds/ios/security-background-dark.png b/packages/ui/src/assets/backgrounds/ios/security-background-dark.png
index b297a2c9e57..f384c519588 100644
Binary files a/packages/ui/src/assets/backgrounds/ios/security-background-dark.png and b/packages/ui/src/assets/backgrounds/ios/security-background-dark.png differ
diff --git a/packages/ui/src/assets/backgrounds/ios/security-background-light.png b/packages/ui/src/assets/backgrounds/ios/security-background-light.png
index c1bf7e5f760..ebc72439f59 100644
Binary files a/packages/ui/src/assets/backgrounds/ios/security-background-light.png and b/packages/ui/src/assets/backgrounds/ios/security-background-light.png differ
diff --git a/packages/ui/src/assets/icons/flag.svg b/packages/ui/src/assets/icons/flag.svg
new file mode 100644
index 00000000000..54d68c5b83c
--- /dev/null
+++ b/packages/ui/src/assets/icons/flag.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/ui/src/assets/icons/page.svg b/packages/ui/src/assets/icons/page.svg
new file mode 100644
index 00000000000..75e607f01e5
--- /dev/null
+++ b/packages/ui/src/assets/icons/page.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/ui/src/assets/icons/pools.svg b/packages/ui/src/assets/icons/pools.svg
new file mode 100644
index 00000000000..4e25e8860c5
--- /dev/null
+++ b/packages/ui/src/assets/icons/pools.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/ui/src/assets/icons/swap-coin.svg b/packages/ui/src/assets/icons/swap-coin.svg
new file mode 100644
index 00000000000..a6fabfdbe69
--- /dev/null
+++ b/packages/ui/src/assets/icons/swap-coin.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/ui/src/components/InlineCard/InlineCard.tsx b/packages/ui/src/components/InlineCard/InlineCard.tsx
index 50975471ce5..78994bbc2e1 100644
--- a/packages/ui/src/components/InlineCard/InlineCard.tsx
+++ b/packages/ui/src/components/InlineCard/InlineCard.tsx
@@ -10,7 +10,7 @@ type InlineCardProps = {
color: ColorTokens
description: string | JSX.Element
iconBackgroundColor?: ColorTokens
- heading?: string
+ heading?: string | JSX.Element
CtaButtonIcon?: GeneratedIcon | ((props: IconProps) => JSX.Element)
onPressCtaButton?: () => void
}
@@ -43,11 +43,14 @@ export function InlineCard({
description
)
- const headingElement = heading ? (
-
- {heading}
-
- ) : null
+ const headingElement =
+ typeof heading === 'string' ? (
+
+ {heading}
+
+ ) : (
+ heading
+ )
return (
diff --git a/packages/ui/src/components/button/Button.tsx b/packages/ui/src/components/button/Button.tsx
index 8a9c0f1af33..a0bcb76748b 100644
--- a/packages/ui/src/components/button/Button.tsx
+++ b/packages/ui/src/components/button/Button.tsx
@@ -18,7 +18,7 @@ import type { IconProps } from 'ui/src/components/factories/createIcon'
import { HapticFeedbackStyle } from 'ui/src/utils/haptics/helpers'
import { useHapticFeedback } from 'ui/src/utils/haptics/useHapticFeedback'
-type ButtonSize = 'small' | 'medium' | 'large'
+export type ButtonSize = 'small' | 'medium' | 'large'
const ButtonNestingContext = createContext(false)
diff --git a/packages/ui/src/components/checkbox/Checkbox.tsx b/packages/ui/src/components/checkbox/Checkbox.tsx
index a857e1f93b4..8bf50814fac 100644
--- a/packages/ui/src/components/checkbox/Checkbox.tsx
+++ b/packages/ui/src/components/checkbox/Checkbox.tsx
@@ -7,9 +7,10 @@ import {
getTokenValue,
} from 'tamagui'
import { Check } from 'ui/src/components/icons'
-import { Flex } from 'ui/src/components/layout'
+import { Flex, FlexProps } from 'ui/src/components/layout'
import { SporeComponentVariant } from 'ui/src/components/types'
import { IconSizeTokens } from 'ui/src/theme'
+import { isTestEnv } from 'utilities/src/environment/env'
import { v4 as uuid } from 'uuid'
type CheckboxSizes = {
@@ -41,6 +42,8 @@ type CheckboxProps = {
size?: CheckboxSizeTokens
} & Omit
+const animationProp = isTestEnv() ? undefined : ({ animation: 'simple' } satisfies FlexProps['animation'])
+
/**
* Spore Checkbox
*
@@ -61,13 +64,14 @@ export function Checkbox({ checked, variant = 'default', size = '$icon.20', ...r
// This outer ring is only shown when the button is focused.
{
@@ -41,8 +45,8 @@ export function LabeledCheckbox({
)
return (
-
-
+
+
{checkboxPosition === 'start' && }
{text && (
diff --git a/packages/ui/src/components/icons/Flag.tsx b/packages/ui/src/components/icons/Flag.tsx
new file mode 100644
index 00000000000..b7f2fc1e634
--- /dev/null
+++ b/packages/ui/src/components/icons/Flag.tsx
@@ -0,0 +1,20 @@
+import { G, Path, Svg } from 'react-native-svg'
+
+// eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
+import { createIcon } from '../factories/createIcon'
+
+export const [Flag, AnimatedFlag] = createIcon({
+ name: 'Flag',
+ getIcon: (props) => (
+
+ ),
+ defaultFill: '#FF5F52',
+})
diff --git a/packages/ui/src/components/icons/Page.tsx b/packages/ui/src/components/icons/Page.tsx
new file mode 100644
index 00000000000..8e0259189b4
--- /dev/null
+++ b/packages/ui/src/components/icons/Page.tsx
@@ -0,0 +1,20 @@
+import { G, Path, Svg } from 'react-native-svg'
+
+// eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
+import { createIcon } from '../factories/createIcon'
+
+export const [Page, AnimatedPage] = createIcon({
+ name: 'Page',
+ getIcon: (props) => (
+
+ ),
+ defaultFill: '#9B9B9B',
+})
diff --git a/packages/ui/src/components/icons/Pools.tsx b/packages/ui/src/components/icons/Pools.tsx
new file mode 100644
index 00000000000..e946c414873
--- /dev/null
+++ b/packages/ui/src/components/icons/Pools.tsx
@@ -0,0 +1,20 @@
+import { G, Path, Svg } from 'react-native-svg'
+
+// eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
+import { createIcon } from '../factories/createIcon'
+
+export const [Pools, AnimatedPools] = createIcon({
+ name: 'Pools',
+ getIcon: (props) => (
+
+ ),
+ defaultFill: '#9B9B9B',
+})
diff --git a/packages/ui/src/components/icons/SwapCoin.tsx b/packages/ui/src/components/icons/SwapCoin.tsx
new file mode 100644
index 00000000000..bbe98655ac7
--- /dev/null
+++ b/packages/ui/src/components/icons/SwapCoin.tsx
@@ -0,0 +1,20 @@
+import { G, Path, Svg } from 'react-native-svg'
+
+// eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
+import { createIcon } from '../factories/createIcon'
+
+export const [SwapCoin, AnimatedSwapCoin] = createIcon({
+ name: 'SwapCoin',
+ getIcon: (props) => (
+
+ ),
+ defaultFill: '#9B9B9B',
+})
diff --git a/packages/ui/src/components/icons/exported.ts b/packages/ui/src/components/icons/exported.ts
index c5bd1c54434..37b1ffe219c 100644
--- a/packages/ui/src/components/icons/exported.ts
+++ b/packages/ui/src/components/icons/exported.ts
@@ -86,6 +86,7 @@ export * from './Feedback'
export * from './FileListCheck'
export * from './FileListLock'
export * from './Fingerprint'
+export * from './Flag'
export * from './Flashbots'
export * from './Gallery'
export * from './Gas'
@@ -132,6 +133,7 @@ export * from './NoTokens'
export * from './NoTransactions'
export * from './OctagonExclamation'
export * from './OrderRouting'
+export * from './Page'
export * from './PaperStack'
export * from './PapersText'
export * from './Paste'
@@ -148,6 +150,7 @@ export * from './Pin'
export * from './Plus'
export * from './PlusCircle'
export * from './PlusSquare'
+export * from './Pools'
export * from './Power'
export * from './Profile'
export * from './ProfileFilled'
@@ -194,6 +197,7 @@ export * from './StickyNoteTextSquare'
export * from './Sun'
export * from './Swap'
export * from './SwapArrow'
+export * from './SwapCoin'
export * from './SwirlyArrowDown'
export * from './Testnets'
export * from './TextEdit'
diff --git a/packages/ui/src/components/menu/MenuContent.tsx b/packages/ui/src/components/menu/MenuContent.tsx
deleted file mode 100644
index 768629915c2..00000000000
--- a/packages/ui/src/components/menu/MenuContent.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { BaseSyntheticEvent, useCallback } from 'react'
-import { Flex, FlexProps } from 'ui/src/components/layout'
-import { MenuContentItem } from 'ui/src/components/menu/types'
-import { Text } from 'ui/src/components/text'
-import { TouchableArea } from 'ui/src/components/touchable'
-import { useIsDarkMode } from 'ui/src/hooks/useIsDarkMode'
-
-type MenuContentProps = {
- onClose?: () => void
- items: MenuContentItem[]
-}
-
-export function MenuContent({ items, onClose, ...rest }: MenuContentProps & FlexProps): JSX.Element {
- const isDarkMode = useIsDarkMode()
-
- const handleOnPress = useCallback(
- (e: BaseSyntheticEvent, onPress: (e: BaseSyntheticEvent) => void): void => {
- onPress(e)
- onClose?.()
- },
- [onClose],
- )
-
- return (
-
- {items.map(({ label, onPress, Icon, textProps, iconProps, destructive, ...touchableProps }, index) => (
- handleOnPress(e, onPress)}
- {...touchableProps}
- >
-
-
- {label}
-
- {Icon && }
-
-
- ))}
-
- )
-}
diff --git a/packages/ui/src/components/swipeablecards/ClickableWithinGesture.web.tsx b/packages/ui/src/components/swipeablecards/ClickableWithinGesture.web.tsx
index 55cc6fefbe9..d0f0fb0eff7 100644
--- a/packages/ui/src/components/swipeablecards/ClickableWithinGesture.web.tsx
+++ b/packages/ui/src/components/swipeablecards/ClickableWithinGesture.web.tsx
@@ -8,5 +8,9 @@ export function ClickableWithinGesture({ onPress, children }: ClickableWithinGes
onPress?.()
}
- return {children}
+ return (
+
+ {children}
+
+ )
}
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index 117a07076b0..fa39fd1cbaf 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -64,9 +64,6 @@ export * from './components/checkbox'
export type { GeneratedIcon, IconProps } from './components/factories/createIcon'
export * from './components/input/utils'
export { Flex, Inset, Separator, flexStyles, type FlexProps } from './components/layout'
-export { ContextMenu } from './components/menu/ContextMenu'
-export { MenuContent } from './components/menu/MenuContent'
-export type { MenuContentItem } from './components/menu/types'
export { AdaptiveWebModal, WebBottomSheet } from './components/modal/AdaptiveWebModal'
export * from './components/radio/Radio'
export { ClickableWithinGesture } from './components/swipeablecards/ClickableWithinGesture'
diff --git a/packages/ui/src/loading/Loader.tsx b/packages/ui/src/loading/Loader.tsx
index a2df5b30274..49b423380fe 100644
--- a/packages/ui/src/loading/Loader.tsx
+++ b/packages/ui/src/loading/Loader.tsx
@@ -24,6 +24,13 @@ const Transaction = memo(function _Transaction({ repeat = 1 }: { repeat?: number
)
})
+/**
+ * Loader used for search results e.g. search, recipient etc...
+ */
+const SearchResult = memo(function _SearchResult({ repeat = 1 }: { repeat?: number }): JSX.Element {
+ return
+})
+
const TransferInstitution = memo(function _TransferInstitution({
itemsCount,
iconSize,
@@ -130,6 +137,7 @@ export const Loader = {
Box,
NFT,
Image,
+ SearchResult,
Token,
TransferInstitution,
Transaction,
diff --git a/packages/uniswap/package.json b/packages/uniswap/package.json
index 9a4e3d3c69e..871eb62f59b 100644
--- a/packages/uniswap/package.json
+++ b/packages/uniswap/package.json
@@ -45,8 +45,8 @@
"@uniswap/client-pools": "0.0.8",
"@uniswap/permit2-sdk": "1.3.0",
"@uniswap/router-sdk": "1.14.3",
- "@uniswap/sdk-core": "5.8.4",
- "@uniswap/uniswapx-sdk": "^2.1.0-beta.14",
+ "@uniswap/sdk-core": "5.9.0",
+ "@uniswap/uniswapx-sdk": "2.1.0-beta.18",
"@uniswap/v2-sdk": "4.6.1",
"@uniswap/v3-sdk": "3.18.1",
"@uniswap/v4-sdk": "1.10.3",
@@ -66,6 +66,7 @@
"jsbi": "3.2.5",
"lodash": "4.17.21",
"openapi-typescript-codegen": "0.27.0",
+ "qs": "6.11.0",
"react": "18.2.0",
"react-i18next": "14.1.0",
"react-native": "0.73.6",
@@ -78,6 +79,7 @@
"react-native-restart": "0.0.27",
"react-native-svg": "15.1.0",
"react-redux": "8.0.5",
+ "react-router-dom": "6.10.0",
"react-test-renderer": "18.2.0",
"react-virtualized-auto-sizer": "1.0.20",
"react-window": "1.8.9",
diff --git a/packages/uniswap/src/assets/chainLogos.tsx b/packages/uniswap/src/assets/chainLogos.tsx
index b0db87dbc90..0e4a2c84464 100644
--- a/packages/uniswap/src/assets/chainLogos.tsx
+++ b/packages/uniswap/src/assets/chainLogos.tsx
@@ -7,7 +7,7 @@ import { OpEtherscanLogoDark } from 'ui/src/components/logos/OpEtherscanLogoDark
import { OpEtherscanLogoLight } from 'ui/src/components/logos/OpEtherscanLogoLight'
import { PolygonscanLogoDark } from 'ui/src/components/logos/PolygonscanLogoDark'
import { PolygonscanLogoLight } from 'ui/src/components/logos/PolygonscanLogoLight'
-import { UniverseChainId, UniverseChainLogoInfo } from 'uniswap/src/types/chains'
+import { UniverseChainId, UniverseChainLogoInfo } from 'uniswap/src/features/chains/types'
// Keeping this separate from UNIVERSE_CHAIN_INFO to avoid import issues on extension content script
export const UNIVERSE_CHAIN_LOGO = {
diff --git a/packages/uniswap/src/components/ConfirmSwapModal/steps/Approve.tsx b/packages/uniswap/src/components/ConfirmSwapModal/steps/Approve.tsx
index 9b0d12a1d91..0ebf7ed6ce0 100644
--- a/packages/uniswap/src/components/ConfirmSwapModal/steps/Approve.tsx
+++ b/packages/uniswap/src/components/ConfirmSwapModal/steps/Approve.tsx
@@ -12,7 +12,7 @@ export function TokenApprovalTransactionStepRow({
status,
}: StepRowProps): JSX.Element {
const { t } = useTranslation()
- const { token } = step
+ const { token, pair } = step
const symbol = token.symbol
const title = {
@@ -26,6 +26,7 @@ export function TokenApprovalTransactionStepRow({
{
interface StepRowSkeletonProps {
/** If passed, the step row icon will be the currency logo. */
currency?: Currency
+ /** If passed, the step row icon will be the split currency logo. */
+ pair?: [Currency, Currency]
/** Icon to display if there is no currency to be displayed for this step. */
icon?: JSX.Element
/** Color to display for the ripple effect around the icon or currency logo. This will default to a currency logo extracted color, if currency is defined. */
@@ -29,13 +32,22 @@ interface StepRowSkeletonProps {
}
export function StepRowSkeleton(props: StepRowSkeletonProps): JSX.Element {
- const { currency, icon, secondsRemaining, title, learnMore, status, rippleColor } = props
+ const { currency, icon, secondsRemaining, title, learnMore, status, rippleColor, pair } = props
const colors = useSporeColors()
const currencyInfo = useCurrencyInfo(currency ? currencyId(currency) : undefined)
+
+ // For V2 liquidity positions the user is generated a unique token which is
+ // the actual token they are approving, but since this token doesn't have
+ // a logo we use the SplitLogo component to display the pair logos instead.
+ const currency0Id = pair?.[0] ? currencyId(pair[0]) : undefined
+ const currency1Id = pair?.[1] ? currencyId(pair[1]) : undefined
+ const currency0Info = useCurrencyInfo(currency0Id)
+ const currency1Info = useCurrencyInfo(currency1Id)
+
const { tokenColor } = useExtractedTokenColor(
- currencyInfo?.logoUrl,
- currency?.symbol,
+ currency0Info ? currency0Info.logoUrl : currencyInfo?.logoUrl,
+ currency0Info ? currency0Info.currency.symbol : currency?.symbol,
/*background=*/ colors.surface1.val,
/*default=*/ colors.neutral3.val,
)
@@ -46,7 +58,16 @@ export function StepRowSkeleton(props: StepRowSkeletonProps): JSX.Element {
- {icon ?? }
+ {currency0Info && currency1Info ? (
+
+ ) : (
+ icon ??
+ )}
diff --git a/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanel.tsx b/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanel.tsx
index 797f899953b..11437ec3a3e 100644
--- a/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanel.tsx
+++ b/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanel.tsx
@@ -26,12 +26,12 @@ import { MaxAmountButton } from 'uniswap/src/components/CurrencyInputPanel/MaxAm
import { SelectTokenButton } from 'uniswap/src/components/CurrencyInputPanel/SelectTokenButton'
import { MAX_FIAT_INPUT_DECIMALS } from 'uniswap/src/constants/transactions'
import { useAccountMeta } from 'uniswap/src/contexts/UniswapContext'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
import { useAppFiatCurrencyInfo } from 'uniswap/src/features/fiatCurrency/hooks'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
import { useTokenAndFiatDisplayAmounts } from 'uniswap/src/features/transactions/hooks/useTokenAndFiatDisplayAmounts'
import { TestID } from 'uniswap/src/test/fixtures/testIDs'
import { CurrencyField } from 'uniswap/src/types/currency'
@@ -296,7 +296,7 @@ export const CurrencyInputPanel = memo(
autoFocus={autoFocus ?? focus}
backgroundColor="$transparent"
borderWidth={0}
- color={color}
+ color={showInsufficientBalanceWarning ? '$statusCritical' : color}
disabled={disabled || !currencyInfo}
flex={1}
focusable={!disabled && Boolean(currencyInfo)}
@@ -313,6 +313,7 @@ export const CurrencyInputPanel = memo(
overflow="visible"
placeholder="0"
placeholderTextColor={colors.neutral3.val}
+ borderRadius={0}
px="$none"
py="$none"
returnKeyType={showSoftInputOnFocus ? 'done' : undefined}
@@ -326,7 +327,7 @@ export const CurrencyInputPanel = memo(
) : (
-
+
0
diff --git a/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.test.tsx b/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.test.tsx
index 335b5d30faf..694876d6de3 100644
--- a/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.test.tsx
+++ b/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.test.tsx
@@ -1,25 +1,26 @@
import { NetworkLogo, TransactionSummaryNetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { render } from 'uniswap/src/test/test-utils'
-import { UniverseChainId } from 'uniswap/src/types/chains'
-jest.mock('uniswap/src/constants/chains', () => {
- const actualChains = jest.requireActual('uniswap/src/constants/chains')
-
- const mockedChainInfo = {
- ...actualChains.UNIVERSE_CHAIN_INFO,
- ['chainWithoutLogo']: {
- logo: undefined, // no logo - for testing
- },
- }
+jest.mock('uniswap/src/features/chains/chainInfo', () => {
+ const actualChains = jest.requireActual('uniswap/src/features/chains/chainInfo')
return {
...actualChains,
- UNIVERSE_CHAIN_INFO: mockedChainInfo,
+ getChainInfo: (chainId: unknown): unknown => {
+ if (chainId === 'chainWithoutLogo') {
+ return {
+ logo: undefined, // no logo - for testing
+ }
+ } else {
+ return actualChains.UNIVERSE_CHAIN_INFO[chainId as UniverseChainId]
+ }
+ },
}
})
describe('NetworkLogo', () => {
- const ACTUAL_CHAIN_INFO = jest.requireActual('uniswap/src/constants/chains').UNIVERSE_CHAIN_INFO
+ const ACTUAL_CHAIN_INFO = jest.requireActual('uniswap/src/features/chains/chainInfo').UNIVERSE_CHAIN_INFO
it('renders without error', () => {
const tree = render()
diff --git a/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.tsx b/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.tsx
index d93f0aada55..1d66d6e2703 100644
--- a/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.tsx
+++ b/packages/uniswap/src/components/CurrencyLogo/NetworkLogo.tsx
@@ -2,8 +2,8 @@ import React from 'react'
import { Flex, FlexProps, Image, useSporeColors } from 'ui/src'
import { ALL_NETWORKS_LOGO } from 'ui/src/assets'
import { iconSizes } from 'ui/src/theme'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export const SQUIRCLE_BORDER_RADIUS_RATIO = 0.3
@@ -49,7 +49,7 @@ function _NetworkLogo({
)
}
- const logo = UNIVERSE_CHAIN_INFO[chainId].logo
+ const logo = getChainInfo(chainId).logo
const imageSize = size - borderWidth * 2 // this prevents the border from cutting off the logo
return logo ? (
diff --git a/packages/uniswap/src/components/CurrencyLogo/SplitLogo.test.tsx b/packages/uniswap/src/components/CurrencyLogo/SplitLogo.test.tsx
index d47fdb43d2b..10327d18d80 100644
--- a/packages/uniswap/src/components/CurrencyLogo/SplitLogo.test.tsx
+++ b/packages/uniswap/src/components/CurrencyLogo/SplitLogo.test.tsx
@@ -1,7 +1,7 @@
import { SplitLogo } from 'uniswap/src/components/CurrencyLogo/SplitLogo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { DAI_CURRENCY_INFO, ETH_CURRENCY_INFO, daiCurrencyInfo, ethCurrencyInfo } from 'uniswap/src/test/fixtures'
import { render, within } from 'uniswap/src/test/test-utils'
-import { UniverseChainId } from 'uniswap/src/types/chains'
jest.mock('ui/src/components/UniversalImage/internal/PlainImage', () => ({
...jest.requireActual('ui/src/components/UniversalImage/internal/PlainImage.web'),
diff --git a/packages/uniswap/src/components/CurrencyLogo/SplitLogo.tsx b/packages/uniswap/src/components/CurrencyLogo/SplitLogo.tsx
index 9f64ce009e4..d51a9982184 100644
--- a/packages/uniswap/src/components/CurrencyLogo/SplitLogo.tsx
+++ b/packages/uniswap/src/components/CurrencyLogo/SplitLogo.tsx
@@ -4,8 +4,8 @@ import { Shuffle } from 'ui/src/components/icons/Shuffle'
import { iconSizes } from 'ui/src/theme'
import { CurrencyLogo, STATUS_RATIO } from 'uniswap/src/components/CurrencyLogo/CurrencyLogo'
import { TransactionSummaryNetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
interface Props {
inputCurrencyInfo: Maybe
diff --git a/packages/uniswap/src/components/CurrencyLogo/TokenLogo.test.tsx b/packages/uniswap/src/components/CurrencyLogo/TokenLogo.test.tsx
index 11071e9b847..0c96504fab3 100644
--- a/packages/uniswap/src/components/CurrencyLogo/TokenLogo.test.tsx
+++ b/packages/uniswap/src/components/CurrencyLogo/TokenLogo.test.tsx
@@ -1,6 +1,6 @@
import { TokenLogo } from 'uniswap/src/components/CurrencyLogo/TokenLogo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { render } from 'uniswap/src/test/test-utils'
-import { UniverseChainId } from 'uniswap/src/types/chains'
// This test expects the invalid image URLs to fail to load, so
// we silence the error logs to keep the test output clean.
diff --git a/packages/uniswap/src/components/CurrencyLogo/TokenLogo.tsx b/packages/uniswap/src/components/CurrencyLogo/TokenLogo.tsx
index a87ce585430..84554330652 100644
--- a/packages/uniswap/src/components/CurrencyLogo/TokenLogo.tsx
+++ b/packages/uniswap/src/components/CurrencyLogo/TokenLogo.tsx
@@ -3,8 +3,8 @@ import { Flex, Text, UniversalImage, useColorSchemeFromSeed, useSporeColors } fr
import { iconSizes, validColor } from 'ui/src/theme'
import { STATUS_RATIO } from 'uniswap/src/components/CurrencyLogo/CurrencyLogo'
import { NetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { isTestnetChain } from 'uniswap/src/features/chains/utils'
import { isMobileApp } from 'utilities/src/platform'
interface TokenLogoProps {
@@ -34,7 +34,7 @@ export const TokenLogo = memo(function _TokenLogo({
const colors = useSporeColors()
const { foreground, background } = useColorSchemeFromSeed(name ?? symbol ?? '')
- const isTestnetToken = UNIVERSE_CHAIN_INFO[chainId as UniverseChainId]?.testnet
+ const isTestnetToken = chainId && isTestnetChain(chainId)
const borderWidth = isTestnetToken ? size / TESTNET_BORDER_DIVISOR : 0
const showNetworkLogo = !hideNetworkLogo && chainId && chainId !== UniverseChainId.Mainnet
diff --git a/packages/uniswap/src/components/InlineWarningCard/InlineWarningCard.tsx b/packages/uniswap/src/components/InlineWarningCard/InlineWarningCard.tsx
index 83db0f8244d..3574764863a 100644
--- a/packages/uniswap/src/components/InlineWarningCard/InlineWarningCard.tsx
+++ b/packages/uniswap/src/components/InlineWarningCard/InlineWarningCard.tsx
@@ -16,6 +16,8 @@ type InlineWarningCardProps = {
checked?: boolean
setChecked?: (checked: boolean) => void
hideCtaIcon?: boolean
+ headingTestId?: string
+ descriptionTestId?: string
}
export function InlineWarningCard({
@@ -28,7 +30,9 @@ export function InlineWarningCard({
checked,
setChecked,
hideCtaIcon,
-}: InlineWarningCardProps): JSX.Element {
+ headingTestId,
+ descriptionTestId,
+}: InlineWarningCardProps): JSX.Element | null {
const tokenProtectionEnabled = useFeatureFlag(FeatureFlags.TokenProtection)
const [checkedFallback, setCheckedFallback] = useState(false)
const { color, textColor, backgroundColor } = getWarningIconColors(severity)
@@ -43,6 +47,11 @@ export function InlineWarningCard({
}
}
+ if (severity === WarningSeverity.None || !WarningIcon) {
+ // !WarningIcon for typecheck; should only be null if WarningSeverity == None
+ return null
+ }
+
const checkboxElement = checkboxLabel ? (
-
+
{description}
{checkboxElement}
}
- heading={heading}
+ heading={
+ heading && (
+
+ {heading}
+
+ )
+ }
iconBackgroundColor={heroIcon ? backgroundColor : undefined}
iconColor={color}
onPressCtaButton={onPressCtaButton}
diff --git a/packages/uniswap/src/components/TokenSelector/TokenSelector.tsx b/packages/uniswap/src/components/TokenSelector/TokenSelector.tsx
index d12d884b38a..8e5459d435d 100644
--- a/packages/uniswap/src/components/TokenSelector/TokenSelector.tsx
+++ b/packages/uniswap/src/components/TokenSelector/TokenSelector.tsx
@@ -7,29 +7,29 @@ import { Flex, Text, TouchableArea, isWeb, useMedia, useScrollbarStyles, useSpor
import { InfoCircleFilled } from 'ui/src/components/icons/InfoCircleFilled'
import { X } from 'ui/src/components/icons/X'
import { zIndices } from 'ui/src/theme'
-import { TokenSelectorEmptySearchList } from 'uniswap/src/components/TokenSelector/TokenSelectorEmptySearchList'
-import { TokenSelectorSearchResultsList } from 'uniswap/src/components/TokenSelector/TokenSelectorSearchResultsList'
-import { TokenSelectorSendList } from 'uniswap/src/components/TokenSelector/TokenSelectorSendList'
-import { TokenSelectorSwapInputList } from 'uniswap/src/components/TokenSelector/TokenSelectorSwapInputList'
-import { TokenSelectorSwapOutputList } from 'uniswap/src/components/TokenSelector/TokenSelectorSwapOutputList'
-import { flowToModalName } from 'uniswap/src/components/TokenSelector/flowToModalName'
-import { useFilterCallbacks } from 'uniswap/src/components/TokenSelector/hooks'
+import { useFilterCallbacks } from 'uniswap/src/components/TokenSelector/hooks/useFilterCallbacks'
+import { TokenSelectorEmptySearchList } from 'uniswap/src/components/TokenSelector/lists/TokenSelectorEmptySearchList'
+import { TokenSelectorSearchResultsList } from 'uniswap/src/components/TokenSelector/lists/TokenSelectorSearchResultsList'
+import { TokenSelectorSendList } from 'uniswap/src/components/TokenSelector/lists/TokenSelectorSendList'
+import { TokenSelectorSwapInputList } from 'uniswap/src/components/TokenSelector/lists/TokenSelectorSwapInputList'
+import { TokenSelectorSwapOutputList } from 'uniswap/src/components/TokenSelector/lists/TokenSelectorSwapOutputList'
import { TokenOptionSection, TokenSection, TokenSelectorFlow } from 'uniswap/src/components/TokenSelector/types'
+import { flowToModalName } from 'uniswap/src/components/TokenSelector/utils'
import PasteButton from 'uniswap/src/components/buttons/PasteButton'
import { useBottomSheetContext } from 'uniswap/src/components/modals/BottomSheetContext'
import { Modal } from 'uniswap/src/components/modals/Modal'
import { NetworkFilter } from 'uniswap/src/components/network/NetworkFilter'
import { useUniswapContext } from 'uniswap/src/contexts/UniswapContext'
import { TradeableAsset } from 'uniswap/src/entities/assets'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
import { SearchContext } from 'uniswap/src/features/search/SearchContext'
import { SearchTextInput } from 'uniswap/src/features/search/SearchTextInput'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
import Trace from 'uniswap/src/features/telemetry/Trace'
import { ElementName, ModalName, SectionName, UniswapEventName } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import useIsKeyboardOpen from 'uniswap/src/hooks/useIsKeyboardOpen'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { CurrencyField } from 'uniswap/src/types/currency'
import { getClipboard } from 'uniswap/src/utils/clipboard'
import { currencyAddress } from 'uniswap/src/utils/currencyId'
@@ -146,6 +146,7 @@ export function TokenSelectorContent({
position: searchContext.position,
suggestion_count: searchContext.suggestionCount,
query: searchContext.query,
+ tokenSection: section.sectionKey,
})
const isBridgePair = section.sectionKey === TokenOptionSection.BridgingTokens
diff --git a/packages/uniswap/src/components/TokenSelector/TokenSelectorList.tsx b/packages/uniswap/src/components/TokenSelector/TokenSelectorList.tsx
index f2cc7b9a43b..a2868925ed5 100644
--- a/packages/uniswap/src/components/TokenSelector/TokenSelectorList.tsx
+++ b/packages/uniswap/src/components/TokenSelector/TokenSelectorList.tsx
@@ -3,20 +3,20 @@ import { useTranslation } from 'react-i18next'
import { AnimateTransition, Flex, Loader, Skeleton, Text } from 'ui/src'
import { fonts } from 'ui/src/theme'
import { BaseCard } from 'uniswap/src/components/BaseCard/BaseCard'
-import { HorizontalTokenList } from 'uniswap/src/components/TokenSelector/HorizontalTokenList/HorizontalTokenList'
-import { TokenOptionItem } from 'uniswap/src/components/TokenSelector/TokenOptionItem'
+import { ITEM_SECTION_HEADER_ROW_HEIGHT } from 'uniswap/src/components/TokenSelector/constants'
+import { TokenOptionItem } from 'uniswap/src/components/TokenSelector/items/TokenOptionItem'
+import { SectionHeader, TokenSectionHeaderProps } from 'uniswap/src/components/TokenSelector/items/TokenSectionHeader'
+import { HorizontalTokenList } from 'uniswap/src/components/TokenSelector/lists/HorizontalTokenList/HorizontalTokenList'
import {
TokenSectionBaseList,
TokenSectionBaseListRef,
-} from 'uniswap/src/components/TokenSelector/TokenSectionBaseList'
-import { ITEM_SECTION_HEADER_ROW_HEIGHT } from 'uniswap/src/components/TokenSelector/TokenSectionBaseList.web'
-import { SectionHeader, TokenSectionHeaderProps } from 'uniswap/src/components/TokenSelector/TokenSectionHeader'
+} from 'uniswap/src/components/TokenSelector/lists/TokenSectionBaseList/TokenSectionBaseList'
import { OnSelectCurrency, TokenOption, TokenSection } from 'uniswap/src/components/TokenSelector/types'
import { useBottomSheetFocusHook } from 'uniswap/src/components/modals/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
import { useDismissedTokenWarnings } from 'uniswap/src/features/tokens/slice/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { CurrencyId } from 'uniswap/src/types/currency'
import { NumberType } from 'utilities/src/format/types'
@@ -49,9 +49,7 @@ const TokenOptionItemWrapper = memo(function _TokenOptionItemWrapper({
const { isTestnetModeEnabled } = useEnabledChains()
- const { tokenWarningDismissed, onDismissTokenWarning: dismissWarningCallback } = useDismissedTokenWarnings(
- tokenOption.currencyInfo.currency,
- )
+ const { tokenWarningDismissed } = useDismissedTokenWarnings(tokenOption.currencyInfo.currency)
const tokenBalance = formatNumberOrString({
value: tokenOption.quantity,
@@ -66,7 +64,6 @@ const TokenOptionItemWrapper = memo(function _TokenOptionItemWrapper({
return (
= {
includeMatches: true,
diff --git a/packages/uniswap/src/components/TokenSelector/flowToModalName.tsx b/packages/uniswap/src/components/TokenSelector/flowToModalName.tsx
deleted file mode 100644
index 97f795aa74e..00000000000
--- a/packages/uniswap/src/components/TokenSelector/flowToModalName.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { TokenSelectorFlow } from 'uniswap/src/components/TokenSelector/types'
-import { ModalName, ModalNameType } from 'uniswap/src/features/telemetry/constants'
-
-export function flowToModalName(flow: TokenSelectorFlow): ModalNameType | undefined {
- switch (flow) {
- case TokenSelectorFlow.Swap:
- return ModalName.Swap
- case TokenSelectorFlow.Send:
- return ModalName.Send
- default:
- return undefined
- }
-}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks.test.ts b/packages/uniswap/src/components/TokenSelector/hooks.test.ts
index 779e1935677..9c0fea2916b 100644
--- a/packages/uniswap/src/components/TokenSelector/hooks.test.ts
+++ b/packages/uniswap/src/components/TokenSelector/hooks.test.ts
@@ -2,21 +2,20 @@
import { ApolloError } from '@apollo/client'
import { toIncludeSameMembers } from 'jest-extended'
import { PreloadedState } from 'redux'
-import {
- useAllCommonBaseCurrencies,
- useCommonTokensOptionsWithFallback,
- useCurrencyInfosToTokenOptions,
- useFavoriteCurrencies,
- useFavoriteTokensOptions,
- useFilterCallbacks,
- usePopularTokensOptions,
- usePortfolioBalancesForAddressById,
- usePortfolioTokenOptions,
-} from 'uniswap/src/components/TokenSelector/hooks'
+import { useAllCommonBaseCurrencies } from 'uniswap/src/components/TokenSelector/hooks/useAllCommonBaseCurrencies'
+import { useCommonTokensOptionsWithFallback } from 'uniswap/src/components/TokenSelector/hooks/useCommonTokensOptionsWithFallback'
+import { useCurrencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions'
+import { useFavoriteCurrencies } from 'uniswap/src/components/TokenSelector/hooks/useFavoriteCurrencies'
+import { useFavoriteTokensOptions } from 'uniswap/src/components/TokenSelector/hooks/useFavoriteTokensOptions'
+import { useFilterCallbacks } from 'uniswap/src/components/TokenSelector/hooks/useFilterCallbacks'
+import { usePopularTokensOptions } from 'uniswap/src/components/TokenSelector/hooks/usePopularTokensOptions'
+import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById'
+import { usePortfolioTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioTokenOptions'
import { TokenSelectorFlow } from 'uniswap/src/components/TokenSelector/types'
import { createEmptyBalanceOption } from 'uniswap/src/components/TokenSelector/utils'
import { BRIDGED_BASE_ADDRESSES } from 'uniswap/src/constants/addresses'
-import { Chain } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { Chain, SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { fromGraphQLChain } from 'uniswap/src/features/chains/utils'
import { tokenProjectToCurrencyInfos } from 'uniswap/src/features/dataApi/utils'
import { UniswapState } from 'uniswap/src/state/uniswapReducer'
@@ -39,7 +38,6 @@ import {
} from 'uniswap/src/test/fixtures'
import { act, renderHook, waitFor } from 'uniswap/src/test/test-utils'
import { createArray, queryResolvers } from 'uniswap/src/test/utils'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { portfolioBalancesById } from 'uniswap/src/utils/balances'
import { buildCurrencyId } from 'uniswap/src/utils/currencyId'
@@ -49,12 +47,12 @@ jest.mock('uniswap/src/features/telemetry/send')
const eth = ethToken()
const dai = daiToken()
-const usdc = usdcBaseToken()
+const usdc_base = usdcBaseToken()
const ethBalance = tokenBalance({ token: eth })
const daiBalance = tokenBalance({ token: dai })
-const usdcBalance = tokenBalance({ token: usdc })
-const favoriteTokens = [eth, dai, usdc]
-const favoriteTokenBalances = [ethBalance, daiBalance, usdcBalance]
+const usdcBaseBalance = tokenBalance({ token: usdc_base })
+const favoriteTokens = [eth, dai, usdc_base]
+const favoriteTokenBalances = [ethBalance, daiBalance, usdcBaseBalance]
const favoriteCurrencyIds = favoriteTokens.map((t) =>
buildCurrencyId(fromGraphQLChain(t.chain) ?? UniverseChainId.Mainnet, t.address),
@@ -139,11 +137,12 @@ describe(useAllCommonBaseCurrencies, () => {
describe(useFavoriteCurrencies, () => {
const project = tokenProject({
// Add some more tokens to check if favorite tokens are filtered properly
- tokens: [usdcArbitrumToken(), usdcBaseToken(), ...favoriteTokens, usdcToken()],
+ tokens: [usdcArbitrumToken(), usdcToken(), ...favoriteTokens],
+ safetyLevel: SafetyLevel.Verified,
})
const projectWithFavoritesOnly = tokenProject({
- ...project,
tokens: favoriteTokens,
+ safetyLevel: SafetyLevel.Verified,
})
const cases = [
@@ -616,8 +615,8 @@ describe(usePopularTokensOptions, () => {
})
describe(useCommonTokensOptionsWithFallback, () => {
- const tokens = [eth, dai, usdc]
- const tokenBalances = [ethBalance, daiBalance, usdcBalance]
+ const tokens = [eth, dai, usdc_base]
+ const tokenBalances = [ethBalance, daiBalance, usdcBaseBalance]
const cases = [
{
diff --git a/packages/uniswap/src/components/TokenSelector/hooks.tsx b/packages/uniswap/src/components/TokenSelector/hooks.tsx
deleted file mode 100644
index 51c135c1544..00000000000
--- a/packages/uniswap/src/components/TokenSelector/hooks.tsx
+++ /dev/null
@@ -1,672 +0,0 @@
-/* eslint-disable max-lines */
-import { ApolloError } from '@apollo/client/errors'
-import { useCallback, useEffect, useMemo, useState } from 'react'
-import { useTranslation } from 'react-i18next'
-import { useDispatch, useSelector } from 'react-redux'
-import { Text, TouchableArea } from 'ui/src'
-import { filter } from 'uniswap/src/components/TokenSelector/filter'
-import { flowToModalName } from 'uniswap/src/components/TokenSelector/flowToModalName'
-import {
- TokenOption,
- TokenOptionSection,
- TokenSection,
- TokenSelectorFlow,
-} from 'uniswap/src/components/TokenSelector/types'
-import {
- createEmptyBalanceOption,
- formatSearchResults,
- mergeSearchResultsWithBridgingTokens,
- useTokenOptionsSection,
-} from 'uniswap/src/components/TokenSelector/utils'
-import { BRIDGED_BASE_ADDRESSES, getNativeAddress } from 'uniswap/src/constants/addresses'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { COMMON_BASES } from 'uniswap/src/constants/routing'
-import { USDC, USDT, WBTC } from 'uniswap/src/constants/tokens'
-import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { GqlResult } from 'uniswap/src/data/types'
-import { TradeableAsset } from 'uniswap/src/entities/assets'
-import { useBridgingTokensOptions } from 'uniswap/src/features/bridging/hooks/tokens'
-import {
- sortPortfolioBalances,
- usePortfolioBalances,
- useTokenBalancesGroupedByVisibility,
-} from 'uniswap/src/features/dataApi/balances'
-import { useSearchTokens } from 'uniswap/src/features/dataApi/searchTokens'
-import { useTokenProjects } from 'uniswap/src/features/dataApi/tokenProjects'
-import { usePopularTokens as usePopularTokensGql } from 'uniswap/src/features/dataApi/topTokens'
-import { CurrencyInfo, PortfolioBalance } from 'uniswap/src/features/dataApi/types'
-import {
- buildCurrency,
- buildCurrencyInfo,
- gqlTokenToCurrencyInfo,
- usePersistedError,
-} from 'uniswap/src/features/dataApi/utils'
-import { selectFavoriteTokens } from 'uniswap/src/features/favorites/selectors'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
-import { SearchResultType, TokenSearchResult } from 'uniswap/src/features/search/SearchResult'
-import { addToSearchHistory, clearSearchHistory } from 'uniswap/src/features/search/searchHistorySlice'
-import { selectSearchHistory } from 'uniswap/src/features/search/selectSearchHistory'
-import { tokenAddressOrNativeAddress } from 'uniswap/src/features/search/utils'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
-import { WalletEventName } from 'uniswap/src/features/telemetry/constants'
-import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
-import { usePopularTokens } from 'uniswap/src/features/tokens/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
-import { areAddressesEqual } from 'uniswap/src/utils/addresses'
-import { buildNativeCurrencyId, buildWrappedNativeCurrencyId, currencyId } from 'uniswap/src/utils/currencyId'
-
-const getNativeCurrencyNames = (chains: UniverseChainId[]): { chainId: UniverseChainId; name: string }[] =>
- chains
- .map((chainId) => {
- return UNIVERSE_CHAIN_INFO[chainId].testnet
- ? false
- : {
- chainId,
- name: UNIVERSE_CHAIN_INFO[chainId].nativeCurrency.name.toLowerCase(),
- }
- })
- .filter(Boolean) as { chainId: UniverseChainId; name: string }[]
-
-// Use Mainnet base token addresses since TokenProjects query returns each token
-// on each network
-const baseCurrencyIds = [
- buildNativeCurrencyId(UniverseChainId.Mainnet),
- buildNativeCurrencyId(UniverseChainId.Polygon),
- buildNativeCurrencyId(UniverseChainId.Bnb),
- buildNativeCurrencyId(UniverseChainId.Celo),
- buildNativeCurrencyId(UniverseChainId.Avalanche),
- currencyId(USDC),
- currencyId(USDT),
- currencyId(WBTC),
- buildWrappedNativeCurrencyId(UniverseChainId.Mainnet),
-]
-
-export function currencyInfosToTokenOptions(
- currencyInfos: Array | undefined,
-): TokenOption[] | undefined {
- return currencyInfos
- ?.filter((cI): cI is CurrencyInfo => Boolean(cI))
- .map((currencyInfo) => ({
- currencyInfo,
- quantity: null,
- balanceUSD: undefined,
- }))
-}
-
-export function searchResultToCurrencyInfo({
- chainId,
- address,
- symbol,
- name,
- logoUrl,
- safetyLevel,
- safetyInfo,
-}: TokenSearchResult): CurrencyInfo | null {
- const currency = buildCurrency({
- chainId: chainId as UniverseChainId,
- address,
- decimals: 0, // this does not matter in a context of CurrencyInfo here, as we do not provide any balance
- symbol,
- name,
- })
-
- if (!currency) {
- return null
- }
-
- return buildCurrencyInfo({
- currency,
- currencyId: currencyId(currency),
- logoUrl,
- safetyLevel: safetyLevel ?? SafetyLevel.StrongWarning,
- // defaulting to not spam, as user has searched and chosen this token before
- isSpam: false,
- safetyInfo,
- })
-}
-
-export function useAllCommonBaseCurrencies(): GqlResult {
- const { isTestnetModeEnabled } = useEnabledChains()
- return useCurrencies(isTestnetModeEnabled ? [] : baseCurrencyIds)
-}
-
-export function useCurrencies(currencyIds: string[]): GqlResult {
- const { data: baseCurrencyInfos, loading, error, refetch } = useTokenProjects(currencyIds)
- const persistedError = usePersistedError(loading, error instanceof ApolloError ? error : undefined)
-
- // TokenProjects returns tokens on every network, so filter out native assets that have a
- // bridged version on other networks
- const filteredBaseCurrencyInfos = useMemo(() => {
- return baseCurrencyInfos?.filter((currencyInfo) => {
- if (currencyInfo.currency.isNative) {
- return true
- }
-
- const { address } = currencyInfo.currency
- const bridgedAsset = BRIDGED_BASE_ADDRESSES.find((bridgedAddress) => areAddressesEqual(bridgedAddress, address))
-
- if (!bridgedAsset) {
- return true
- }
-
- return false
- })
- }, [baseCurrencyInfos])
-
- return { data: filteredBaseCurrencyInfos, loading, error: persistedError, refetch }
-}
-
-export function usePortfolioBalancesForAddressById(
- address: Address | undefined,
-): GqlResult | undefined> {
- const {
- data: portfolioBalancesById,
- error,
- refetch,
- loading,
- } = usePortfolioBalances({
- address,
- fetchPolicy: 'cache-first', // we want to avoid re-renders when token selector is opening
- })
-
- return {
- data: portfolioBalancesById,
- error,
- refetch,
- loading,
- }
-}
-
-export function useFavoriteCurrencies(): GqlResult {
- const favoriteCurrencyIds = useSelector(selectFavoriteTokens)
- const { data: favoriteTokensOnAllChains, loading, error, refetch } = useTokenProjects(favoriteCurrencyIds)
-
- const persistedError = usePersistedError(loading, error instanceof ApolloError ? error : undefined)
-
- // useTokenProjects returns each token on Arbitrum, Optimism, Polygon,
- // so we need to filter out the tokens which user has actually favorited
- const favoriteTokens = useMemo(
- () =>
- favoriteTokensOnAllChains &&
- favoriteCurrencyIds
- .map((_currencyId) => {
- return favoriteTokensOnAllChains.find((token) => token.currencyId === _currencyId)
- })
- .filter((token: CurrencyInfo | undefined): token is CurrencyInfo => {
- return !!token
- }),
- [favoriteCurrencyIds, favoriteTokensOnAllChains],
- )
-
- return { data: favoriteTokens, loading, error: persistedError, refetch }
-}
-
-export function useAddToSearchHistory(): { registerSearch: (currencyInfo: CurrencyInfo) => void } {
- const dispatch = useDispatch()
-
- const registerSearch = (currencyInfo: CurrencyInfo): void => {
- dispatch(
- addToSearchHistory({
- searchResult: currencyInfoToTokenSearchResult(currencyInfo),
- }),
- )
- }
-
- return { registerSearch }
-}
-
-function currencyInfoToTokenSearchResult(currencyInfo: CurrencyInfo): TokenSearchResult {
- const address = currencyInfo.currency.isToken
- ? currencyInfo.currency.address
- : getNativeAddress(currencyInfo.currency.chainId)
-
- return {
- type: SearchResultType.Token,
- chainId: currencyInfo.currency.chainId,
- address: tokenAddressOrNativeAddress(address, currencyInfo.currency.chainId),
- name: currencyInfo.currency.name ?? null,
- symbol: currencyInfo.currency.symbol ?? '',
- logoUrl: currencyInfo.logoUrl ?? null,
- safetyLevel: currencyInfo.safetyLevel ?? null,
- safetyInfo: currencyInfo.safetyInfo,
- }
-}
-
-export function useFavoriteTokensOptions(
- address: Address | undefined,
- chainFilter: UniverseChainId | null,
-): GqlResult {
- const {
- data: portfolioBalancesById,
- error: portfolioBalancesByIdError,
- refetch: portfolioBalancesByIdRefetch,
- loading: loadingPorfolioBalancesById,
- } = usePortfolioBalancesForAddressById(address)
-
- const {
- data: favoriteCurrencies,
- error: favoriteCurrenciesError,
- refetch: refetchFavoriteCurrencies,
- loading: loadingFavoriteCurrencies,
- } = useFavoriteCurrencies()
-
- const favoriteTokenOptions = useCurrencyInfosToTokenOptions({
- currencyInfos: favoriteCurrencies,
- portfolioBalancesById,
- sortAlphabetically: true,
- })
-
- const refetch = useCallback(() => {
- portfolioBalancesByIdRefetch?.()
- refetchFavoriteCurrencies?.()
- }, [portfolioBalancesByIdRefetch, refetchFavoriteCurrencies])
-
- const error =
- (!portfolioBalancesById && portfolioBalancesByIdError) || (!favoriteCurrencies && favoriteCurrenciesError)
-
- const filteredFavoriteTokenOptions = useMemo(
- () => favoriteTokenOptions && filter(favoriteTokenOptions, chainFilter),
- [chainFilter, favoriteTokenOptions],
- )
-
- return {
- data: filteredFavoriteTokenOptions,
- refetch,
- error: error || undefined,
- loading: loadingPorfolioBalancesById || loadingFavoriteCurrencies,
- }
-}
-
-function ClearAll({ onPress }: { onPress: () => void }): JSX.Element {
- const { t } = useTranslation()
- return (
-
-
- {t('tokens.selector.button.clear')}
-
-
- )
-}
-
-export function useTokenSectionsForEmptySearch(chainFilter: UniverseChainId | null): GqlResult {
- const dispatch = useDispatch()
-
- const { popularTokens, loading } = usePopularTokens()
-
- const recentlySearchedTokenOptions = useRecentlySearchedTokens(chainFilter)
-
- // it's a dependency of useMemo => useCallback
- const onPressClearSearchHistory = useCallback((): void => {
- dispatch(clearSearchHistory())
- }, [dispatch])
-
- const recentSection = useTokenOptionsSection({
- sectionKey: TokenOptionSection.RecentTokens,
- tokenOptions: recentlySearchedTokenOptions,
- endElement: ,
- })
-
- const popularSection = useTokenOptionsSection({
- sectionKey: TokenOptionSection.PopularTokens,
- tokenOptions: currencyInfosToTokenOptions(popularTokens?.map(gqlTokenToCurrencyInfo)),
- })
- const sections = useMemo(() => [...(recentSection ?? []), ...(popularSection ?? [])], [popularSection, recentSection])
-
- return useMemo(
- () => ({
- data: sections,
- loading,
- }),
- [loading, sections],
- )
-}
-
-export function useCurrencyInfosToTokenOptions({
- currencyInfos,
- portfolioBalancesById,
- sortAlphabetically,
-}: {
- currencyInfos?: CurrencyInfo[]
- sortAlphabetically?: boolean
- portfolioBalancesById?: Record
-}): TokenOption[] | undefined {
- // we use useMemo here to avoid recalculation of internals when function params are the same,
- // but the component, where this hook is used is re-rendered
- return useMemo(() => {
- if (!currencyInfos) {
- return undefined
- }
- const sortedCurrencyInfos = sortAlphabetically
- ? [...currencyInfos].sort((a, b) => {
- if (a.currency.name && b.currency.name) {
- return a.currency.name.localeCompare(b.currency.name)
- }
- return 0
- })
- : currencyInfos
-
- return sortedCurrencyInfos.map(
- (currencyInfo) => portfolioBalancesById?.[currencyInfo.currencyId] ?? createEmptyBalanceOption(currencyInfo),
- )
- }, [currencyInfos, portfolioBalancesById, sortAlphabetically])
-}
-
-export function useCommonTokensOptions(
- address: Address | undefined,
- chainFilter: UniverseChainId | null,
-): GqlResult {
- const {
- data: portfolioBalancesById,
- error: portfolioBalancesByIdError,
- refetch: portfolioBalancesByIdRefetch,
- loading: loadingPorfolioBalancesById,
- } = usePortfolioBalancesForAddressById(address)
-
- const {
- data: commonBaseCurrencies,
- error: commonBaseCurrenciesError,
- refetch: refetchCommonBaseCurrencies,
- loading: loadingCommonBaseCurrencies,
- } = useAllCommonBaseCurrencies()
-
- const commonBaseTokenOptions = useCurrencyInfosToTokenOptions({
- currencyInfos: commonBaseCurrencies,
- portfolioBalancesById,
- })
-
- const refetch = useCallback(() => {
- portfolioBalancesByIdRefetch?.()
- refetchCommonBaseCurrencies?.()
- }, [portfolioBalancesByIdRefetch, refetchCommonBaseCurrencies])
-
- const error =
- (!portfolioBalancesById && portfolioBalancesByIdError) || (!commonBaseCurrencies && commonBaseCurrenciesError)
-
- const filteredCommonBaseTokenOptions = useMemo(
- () => commonBaseTokenOptions && filter(commonBaseTokenOptions, chainFilter),
- [chainFilter, commonBaseTokenOptions],
- )
-
- return {
- data: filteredCommonBaseTokenOptions,
- refetch,
- error: error || undefined,
- loading: loadingPorfolioBalancesById || loadingCommonBaseCurrencies,
- }
-}
-
-export function useCommonTokensOptionsWithFallback(
- address: Address | undefined,
- chainFilter: UniverseChainId | null,
-): GqlResult {
- const { data, error, refetch, loading } = useCommonTokensOptions(address, chainFilter)
- const commonBases = chainFilter ? currencyInfosToTokenOptions(COMMON_BASES[chainFilter]) : undefined
-
- const shouldFallback = !loading && data?.length === 0 && commonBases?.length
-
- return {
- data: shouldFallback ? commonBases : data,
- error: shouldFallback ? undefined : error,
- refetch,
- loading,
- }
-}
-
-export function usePopularTokensOptions(
- address: Address | undefined,
- chainFilter: UniverseChainId,
-): GqlResult {
- const {
- data: portfolioBalancesById,
- error: portfolioBalancesByIdError,
- refetch: portfolioBalancesByIdRefetch,
- loading: loadingPorfolioBalancesById,
- } = usePortfolioBalancesForAddressById(address)
-
- const {
- data: popularTokens,
- error: popularTokensError,
- refetch: refetchPopularTokens,
- loading: loadingPopularTokens,
- } = usePopularTokensGql(chainFilter)
-
- const popularTokenOptions = useCurrencyInfosToTokenOptions({
- currencyInfos: popularTokens,
- portfolioBalancesById,
- sortAlphabetically: true,
- })
-
- const refetch = useCallback(() => {
- portfolioBalancesByIdRefetch?.()
- refetchPopularTokens?.()
- }, [portfolioBalancesByIdRefetch, refetchPopularTokens])
-
- const error = (!portfolioBalancesById && portfolioBalancesByIdError) || (!popularTokenOptions && popularTokensError)
-
- return {
- data: popularTokenOptions,
- refetch,
- error: error || undefined,
- loading: loadingPorfolioBalancesById || loadingPopularTokens,
- }
-}
-
-export function usePortfolioTokenOptions(
- address: Address | undefined,
- chainFilter: UniverseChainId | null,
- searchFilter?: string,
-): GqlResult {
- const { data: portfolioBalancesById, error, refetch, loading } = usePortfolioBalancesForAddressById(address)
- const { isTestnetModeEnabled } = useEnabledChains()
-
- const { shownTokens } = useTokenBalancesGroupedByVisibility({
- balancesById: portfolioBalancesById,
- })
-
- const portfolioBalances = useMemo(
- () => (shownTokens ? sortPortfolioBalances({ balances: shownTokens, isTestnetModeEnabled }) : undefined),
- [shownTokens, isTestnetModeEnabled],
- )
-
- const filteredPortfolioBalances = useMemo(
- () => portfolioBalances && filter(portfolioBalances, chainFilter, searchFilter),
- [chainFilter, portfolioBalances, searchFilter],
- )
-
- return {
- data: filteredPortfolioBalances,
- error,
- refetch,
- loading,
- }
-}
-
-export function useFilterCallbacks(
- chainId: UniverseChainId | null,
- flow: TokenSelectorFlow,
-): {
- chainFilter: UniverseChainId | null
- parsedChainFilter: UniverseChainId | null
- searchFilter: string | null
- parsedSearchFilter: string | null
- onChangeChainFilter: (newChainFilter: UniverseChainId | null) => void
- onClearSearchFilter: () => void
- onChangeText: (newSearchFilter: string) => void
-} {
- const [chainFilter, setChainFilter] = useState(chainId)
- const [parsedChainFilter, setParsedChainFilter] = useState(null)
- const [searchFilter, setSearchFilter] = useState(null)
- const [parsedSearchFilter, setParsedSearchFilter] = useState(null)
-
- const { chains: enabledChains } = useEnabledChains()
-
- // Parses the user input to determine if the user is searching for a chain + token
- // i.e "eth dai"
- // parsedChainFilter: 1
- // parsedSearchFilter: "dai"
- useEffect(() => {
- const splitSearch = searchFilter?.split(' ')
- const maybeChainName = splitSearch?.[0]?.toLowerCase()
-
- const chainMatch = getNativeCurrencyNames(enabledChains).find((currency) =>
- currency.name.startsWith(maybeChainName ?? ''),
- )
- const search = splitSearch?.slice(1).join(' ')
-
- if (!chainFilter && chainMatch && search) {
- setParsedChainFilter(chainMatch.chainId)
- setParsedSearchFilter(search)
- } else {
- setParsedChainFilter(null)
- setParsedSearchFilter(null)
- }
- }, [searchFilter, chainFilter, enabledChains])
-
- useEffect(() => {
- setChainFilter(chainId)
- }, [chainId])
-
- const onChangeChainFilter = useCallback(
- (newChainFilter: typeof chainFilter) => {
- setChainFilter(newChainFilter)
- sendAnalyticsEvent(WalletEventName.NetworkFilterSelected, {
- chain: newChainFilter ?? 'All',
- modal: flowToModalName(flow),
- })
- },
- [flow],
- )
-
- const onClearSearchFilter = useCallback(() => {
- setSearchFilter(null)
- }, [])
-
- const onChangeText = useCallback((newSearchFilter: string) => setSearchFilter(newSearchFilter), [setSearchFilter])
-
- return {
- chainFilter,
- parsedChainFilter,
- searchFilter,
- parsedSearchFilter,
- onChangeChainFilter,
- onClearSearchFilter,
- onChangeText,
- }
-}
-
-export const MAX_RECENT_SEARCH_RESULTS = 4
-
-export function useRecentlySearchedTokens(chainFilter: UniverseChainId | null): TokenOption[] | undefined {
- const searchHistory = useSelector(selectSearchHistory)
-
- return useMemo(
- () =>
- currencyInfosToTokenOptions(
- searchHistory
- .filter((searchResult): searchResult is TokenSearchResult => searchResult.type === SearchResultType.Token)
- .filter((searchResult) => (chainFilter ? searchResult.chainId === chainFilter : true))
- .slice(0, MAX_RECENT_SEARCH_RESULTS)
- .map(searchResultToCurrencyInfo),
- ),
- [chainFilter, searchHistory],
- )
-}
-
-export function useTokenSectionsForSearchResults(
- address: string | undefined,
- chainFilter: UniverseChainId | null,
- searchFilter: string | null,
- isBalancesOnlySearch: boolean,
- input: TradeableAsset | undefined,
-): GqlResult {
- const { t } = useTranslation()
- const isBridgingEnabled = useFeatureFlag(FeatureFlags.Bridging)
-
- const {
- data: portfolioBalancesById,
- error: portfolioBalancesByIdError,
- refetch: refetchPortfolioBalances,
- loading: portfolioBalancesByIdLoading,
- } = usePortfolioBalancesForAddressById(address)
-
- const {
- data: portfolioTokenOptions,
- error: portfolioTokenOptionsError,
- refetch: refetchPortfolioTokenOptions,
- loading: portfolioTokenOptionsLoading,
- } = usePortfolioTokenOptions(address, chainFilter, searchFilter ?? undefined)
-
- // Bridging tokens are only shown if input is provided
- const {
- data: bridgingTokenOptions,
- error: bridgingTokenOptionsError,
- refetch: refetchBridgingTokenOptions,
- loading: bridgingTokenOptionsLoading,
- } = useBridgingTokensOptions({ input, walletAddress: address, chainFilter })
-
- // Only call search endpoint if isBalancesOnlySearch is false
- const {
- data: searchResultCurrencies,
- error: searchTokensError,
- refetch: refetchSearchTokens,
- loading: searchTokensLoading,
- } = useSearchTokens(searchFilter, chainFilter, /*skip*/ isBalancesOnlySearch)
-
- const searchResults = useMemo(() => {
- return formatSearchResults(searchResultCurrencies, portfolioBalancesById, searchFilter)
- }, [searchResultCurrencies, portfolioBalancesById, searchFilter])
-
- const loading =
- portfolioTokenOptionsLoading ||
- portfolioBalancesByIdLoading ||
- (!isBalancesOnlySearch && searchTokensLoading) ||
- bridgingTokenOptionsLoading
-
- const searchResultsSections = useTokenOptionsSection({
- sectionKey: TokenOptionSection.SearchResults,
- // Use local search when only searching balances
- tokenOptions: isBalancesOnlySearch ? portfolioTokenOptions : searchResults,
- })
-
- // If there are bridging options, we need to extract them from the search results and then prepend them as a new section above.
- // The remaining non-bridging search results will be shown in a section with a different name
- const networkName = chainFilter ? UNIVERSE_CHAIN_INFO[chainFilter].label : undefined
- const searchResultsSectionHeader = networkName
- ? t('tokens.selector.section.otherSearchResults', { network: networkName })
- : undefined
- const sections = isBridgingEnabled
- ? mergeSearchResultsWithBridgingTokens(searchResultsSections, bridgingTokenOptions, searchResultsSectionHeader)
- : searchResultsSections
-
- const error =
- (!bridgingTokenOptions && bridgingTokenOptionsError) ||
- (!portfolioBalancesById && portfolioBalancesByIdError) ||
- (!portfolioTokenOptions && portfolioTokenOptionsError) ||
- (!isBalancesOnlySearch && !searchResults && searchTokensError)
-
- const refetchAll = useCallback(() => {
- refetchPortfolioBalances?.()
- refetchSearchTokens?.()
- refetchPortfolioTokenOptions?.()
- if (isBridgingEnabled) {
- refetchBridgingTokenOptions?.()
- }
- }, [
- isBridgingEnabled,
- refetchBridgingTokenOptions,
- refetchPortfolioBalances,
- refetchPortfolioTokenOptions,
- refetchSearchTokens,
- ])
-
- return useMemo(
- () => ({
- data: sections,
- loading,
- error: error || undefined,
- refetch: refetchAll,
- }),
- [error, loading, refetchAll, sections],
- )
-}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useAddToSearchHistory.ts b/packages/uniswap/src/components/TokenSelector/hooks/useAddToSearchHistory.ts
new file mode 100644
index 00000000000..784a2c27af1
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useAddToSearchHistory.ts
@@ -0,0 +1,43 @@
+import { useDispatch } from 'react-redux'
+import { getNativeAddress } from 'uniswap/src/constants/addresses'
+import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { SearchResultType, TokenSearchResult } from 'uniswap/src/features/search/SearchResult'
+import { addToSearchHistory } from 'uniswap/src/features/search/searchHistorySlice'
+import { tokenAddressOrNativeAddress } from 'uniswap/src/features/search/utils'
+
+export function useAddToSearchHistory(): { registerSearch: (currencyInfo: CurrencyInfo) => void } {
+ const dispatch = useDispatch()
+
+ const registerSearch = (currencyInfo: CurrencyInfo): void => {
+ dispatch(
+ addToSearchHistory({
+ searchResult: currencyInfoToTokenSearchResult(currencyInfo),
+ }),
+ )
+ }
+
+ return { registerSearch }
+}
+
+function currencyInfoToTokenSearchResult(currencyInfo: CurrencyInfo): TokenSearchResult {
+ const address = currencyInfo.currency.isToken
+ ? currencyInfo.currency.address
+ : getNativeAddress(currencyInfo.currency.chainId)
+
+ return {
+ type: SearchResultType.Token,
+ chainId: currencyInfo.currency.chainId,
+ address: tokenAddressOrNativeAddress(address, currencyInfo.currency.chainId),
+ name: currencyInfo.currency.name ?? null,
+ symbol: currencyInfo.currency.symbol ?? '',
+ logoUrl: currencyInfo.logoUrl ?? null,
+ safetyLevel: currencyInfo.safetyLevel ?? null,
+ safetyInfo: currencyInfo.safetyInfo,
+ feeData: currencyInfo.currency.isToken
+ ? {
+ buyFeeBps: currencyInfo.currency.buyFeeBps?.gt(0) ? currencyInfo.currency.buyFeeBps.toString() : undefined,
+ sellFeeBps: currencyInfo.currency.sellFeeBps?.gt(0) ? currencyInfo.currency.sellFeeBps.toString() : undefined,
+ }
+ : null,
+ }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useAllCommonBaseCurrencies.ts b/packages/uniswap/src/components/TokenSelector/hooks/useAllCommonBaseCurrencies.ts
new file mode 100644
index 00000000000..60b1595d286
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useAllCommonBaseCurrencies.ts
@@ -0,0 +1,26 @@
+import { useCurrencies } from 'uniswap/src/components/TokenSelector/hooks/useCurrencies'
+import { USDC, USDT, WBTC } from 'uniswap/src/constants/tokens'
+import { GqlResult } from 'uniswap/src/data/types'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { buildNativeCurrencyId, buildWrappedNativeCurrencyId, currencyId } from 'uniswap/src/utils/currencyId'
+
+// Use Mainnet base token addresses since TokenProjects query returns each token
+// on each network
+const baseCurrencyIds = [
+ buildNativeCurrencyId(UniverseChainId.Mainnet),
+ buildNativeCurrencyId(UniverseChainId.Polygon),
+ buildNativeCurrencyId(UniverseChainId.Bnb),
+ buildNativeCurrencyId(UniverseChainId.Celo),
+ buildNativeCurrencyId(UniverseChainId.Avalanche),
+ currencyId(USDC),
+ currencyId(USDT),
+ currencyId(WBTC),
+ buildWrappedNativeCurrencyId(UniverseChainId.Mainnet),
+]
+
+export function useAllCommonBaseCurrencies(): GqlResult {
+ const { isTestnetModeEnabled } = useEnabledChains()
+ return useCurrencies(isTestnetModeEnabled ? [] : baseCurrencyIds)
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useCommonTokensOptions.ts b/packages/uniswap/src/components/TokenSelector/hooks/useCommonTokensOptions.ts
new file mode 100644
index 00000000000..8e9a71b6e1d
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useCommonTokensOptions.ts
@@ -0,0 +1,52 @@
+import { useCallback, useMemo } from 'react'
+import { filter } from 'uniswap/src/components/TokenSelector/filter'
+import { useAllCommonBaseCurrencies } from 'uniswap/src/components/TokenSelector/hooks/useAllCommonBaseCurrencies'
+import { useCurrencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions'
+import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById'
+import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
+import { GqlResult } from 'uniswap/src/data/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+
+export function useCommonTokensOptions(
+ address: Address | undefined,
+ chainFilter: UniverseChainId | null,
+): GqlResult {
+ const {
+ data: portfolioBalancesById,
+ error: portfolioBalancesByIdError,
+ refetch: portfolioBalancesByIdRefetch,
+ loading: loadingPorfolioBalancesById,
+ } = usePortfolioBalancesForAddressById(address)
+
+ const {
+ data: commonBaseCurrencies,
+ error: commonBaseCurrenciesError,
+ refetch: refetchCommonBaseCurrencies,
+ loading: loadingCommonBaseCurrencies,
+ } = useAllCommonBaseCurrencies()
+
+ const commonBaseTokenOptions = useCurrencyInfosToTokenOptions({
+ currencyInfos: commonBaseCurrencies,
+ portfolioBalancesById,
+ })
+
+ const refetch = useCallback(() => {
+ portfolioBalancesByIdRefetch?.()
+ refetchCommonBaseCurrencies?.()
+ }, [portfolioBalancesByIdRefetch, refetchCommonBaseCurrencies])
+
+ const error =
+ (!portfolioBalancesById && portfolioBalancesByIdError) || (!commonBaseCurrencies && commonBaseCurrenciesError)
+
+ const filteredCommonBaseTokenOptions = useMemo(
+ () => commonBaseTokenOptions && filter(commonBaseTokenOptions, chainFilter),
+ [chainFilter, commonBaseTokenOptions],
+ )
+
+ return {
+ data: filteredCommonBaseTokenOptions,
+ refetch,
+ error: error || undefined,
+ loading: loadingPorfolioBalancesById || loadingCommonBaseCurrencies,
+ }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useCommonTokensOptionsWithFallback.ts b/packages/uniswap/src/components/TokenSelector/hooks/useCommonTokensOptionsWithFallback.ts
new file mode 100644
index 00000000000..6a717f60012
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useCommonTokensOptionsWithFallback.ts
@@ -0,0 +1,23 @@
+import { useCommonTokensOptions } from 'uniswap/src/components/TokenSelector/hooks/useCommonTokensOptions'
+import { currencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions'
+import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
+import { COMMON_BASES } from 'uniswap/src/constants/routing'
+import { GqlResult } from 'uniswap/src/data/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+
+export function useCommonTokensOptionsWithFallback(
+ address: Address | undefined,
+ chainFilter: UniverseChainId | null,
+): GqlResult {
+ const { data, error, refetch, loading } = useCommonTokensOptions(address, chainFilter)
+ const commonBases = chainFilter ? currencyInfosToTokenOptions(COMMON_BASES[chainFilter]) : undefined
+
+ const shouldFallback = !loading && data?.length === 0 && commonBases?.length
+
+ return {
+ data: shouldFallback ? commonBases : data,
+ error: shouldFallback ? undefined : error,
+ refetch,
+ loading,
+ }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useCurrencies.ts b/packages/uniswap/src/components/TokenSelector/hooks/useCurrencies.ts
new file mode 100644
index 00000000000..9291f3545d0
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useCurrencies.ts
@@ -0,0 +1,34 @@
+import { ApolloError } from '@apollo/client'
+import { useMemo } from 'react'
+import { BRIDGED_BASE_ADDRESSES } from 'uniswap/src/constants/addresses'
+import { GqlResult } from 'uniswap/src/data/types'
+import { useTokenProjects } from 'uniswap/src/features/dataApi/tokenProjects'
+import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { usePersistedError } from 'uniswap/src/features/dataApi/utils'
+import { areAddressesEqual } from 'uniswap/src/utils/addresses'
+
+export function useCurrencies(currencyIds: string[]): GqlResult {
+ const { data: baseCurrencyInfos, loading, error, refetch } = useTokenProjects(currencyIds)
+ const persistedError = usePersistedError(loading, error instanceof ApolloError ? error : undefined)
+
+ // TokenProjects returns tokens on every network, so filter out native assets that have a
+ // bridged version on other networks
+ const filteredBaseCurrencyInfos = useMemo(() => {
+ return baseCurrencyInfos?.filter((currencyInfo) => {
+ if (currencyInfo.currency.isNative) {
+ return true
+ }
+
+ const { address } = currencyInfo.currency
+ const bridgedAsset = BRIDGED_BASE_ADDRESSES.find((bridgedAddress) => areAddressesEqual(bridgedAddress, address))
+
+ if (!bridgedAsset) {
+ return true
+ }
+
+ return false
+ })
+ }, [baseCurrencyInfos])
+
+ return { data: filteredBaseCurrencyInfos, loading, error: persistedError, refetch }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions.ts b/packages/uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions.ts
new file mode 100644
index 00000000000..56ae6e1fb5a
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions.ts
@@ -0,0 +1,78 @@
+import { ApolloError } from '@apollo/client'
+import { useMemo } from 'react'
+import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
+import { createEmptyBalanceOption } from 'uniswap/src/components/TokenSelector/utils'
+import { BRIDGED_BASE_ADDRESSES } from 'uniswap/src/constants/addresses'
+import { GqlResult } from 'uniswap/src/data/types'
+import { useTokenProjects } from 'uniswap/src/features/dataApi/tokenProjects'
+import { CurrencyInfo, PortfolioBalance } from 'uniswap/src/features/dataApi/types'
+import { usePersistedError } from 'uniswap/src/features/dataApi/utils'
+import { areAddressesEqual } from 'uniswap/src/utils/addresses'
+
+export function useCurrencies(currencyIds: string[]): GqlResult {
+ const { data: baseCurrencyInfos, loading, error, refetch } = useTokenProjects(currencyIds)
+ const persistedError = usePersistedError(loading, error instanceof ApolloError ? error : undefined)
+
+ // TokenProjects returns tokens on every network, so filter out native assets that have a
+ // bridged version on other networks
+ const filteredBaseCurrencyInfos = useMemo(() => {
+ return baseCurrencyInfos?.filter((currencyInfo) => {
+ if (currencyInfo.currency.isNative) {
+ return true
+ }
+
+ const { address } = currencyInfo.currency
+ const bridgedAsset = BRIDGED_BASE_ADDRESSES.find((bridgedAddress) => areAddressesEqual(bridgedAddress, address))
+
+ if (!bridgedAsset) {
+ return true
+ }
+
+ return false
+ })
+ }, [baseCurrencyInfos])
+
+ return { data: filteredBaseCurrencyInfos, loading, error: persistedError, refetch }
+}
+
+export function currencyInfosToTokenOptions(
+ currencyInfos: Array | undefined,
+): TokenOption[] | undefined {
+ return currencyInfos
+ ?.filter((cI): cI is CurrencyInfo => Boolean(cI))
+ .map((currencyInfo) => ({
+ currencyInfo,
+ quantity: null,
+ balanceUSD: undefined,
+ }))
+}
+
+export function useCurrencyInfosToTokenOptions({
+ currencyInfos,
+ portfolioBalancesById,
+ sortAlphabetically,
+}: {
+ currencyInfos?: CurrencyInfo[]
+ sortAlphabetically?: boolean
+ portfolioBalancesById?: Record
+}): TokenOption[] | undefined {
+ // we use useMemo here to avoid recalculation of internals when function params are the same,
+ // but the component, where this hook is used is re-rendered
+ return useMemo(() => {
+ if (!currencyInfos) {
+ return undefined
+ }
+ const sortedCurrencyInfos = sortAlphabetically
+ ? [...currencyInfos].sort((a, b) => {
+ if (a.currency.name && b.currency.name) {
+ return a.currency.name.localeCompare(b.currency.name)
+ }
+ return 0
+ })
+ : currencyInfos
+
+ return sortedCurrencyInfos.map(
+ (currencyInfo) => portfolioBalancesById?.[currencyInfo.currencyId] ?? createEmptyBalanceOption(currencyInfo),
+ )
+ }, [currencyInfos, portfolioBalancesById, sortAlphabetically])
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useFavoriteCurrencies.ts b/packages/uniswap/src/components/TokenSelector/hooks/useFavoriteCurrencies.ts
new file mode 100644
index 00000000000..f0536614a87
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useFavoriteCurrencies.ts
@@ -0,0 +1,32 @@
+import { ApolloError } from '@apollo/client'
+import { useMemo } from 'react'
+import { useSelector } from 'react-redux'
+import { GqlResult } from 'uniswap/src/data/types'
+import { useTokenProjects } from 'uniswap/src/features/dataApi/tokenProjects'
+import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { usePersistedError } from 'uniswap/src/features/dataApi/utils'
+import { selectFavoriteTokens } from 'uniswap/src/features/favorites/selectors'
+
+export function useFavoriteCurrencies(): GqlResult {
+ const favoriteCurrencyIds = useSelector(selectFavoriteTokens)
+ const { data: favoriteTokensOnAllChains, loading, error, refetch } = useTokenProjects(favoriteCurrencyIds)
+
+ const persistedError = usePersistedError(loading, error instanceof ApolloError ? error : undefined)
+
+ // useTokenProjects returns each token on Arbitrum, Optimism, Polygon,
+ // so we need to filter out the tokens which user has actually favorited
+ const favoriteTokens = useMemo(
+ () =>
+ favoriteTokensOnAllChains &&
+ favoriteCurrencyIds
+ .map((_currencyId) => {
+ return favoriteTokensOnAllChains.find((token) => token.currencyId === _currencyId)
+ })
+ .filter((token: CurrencyInfo | undefined): token is CurrencyInfo => {
+ return !!token
+ }),
+ [favoriteCurrencyIds, favoriteTokensOnAllChains],
+ )
+
+ return { data: favoriteTokens, loading, error: persistedError, refetch }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useFavoriteTokensOptions.ts b/packages/uniswap/src/components/TokenSelector/hooks/useFavoriteTokensOptions.ts
new file mode 100644
index 00000000000..57bfa55f451
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useFavoriteTokensOptions.ts
@@ -0,0 +1,53 @@
+import { useCallback, useMemo } from 'react'
+import { filter } from 'uniswap/src/components/TokenSelector/filter'
+import { useCurrencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions'
+import { useFavoriteCurrencies } from 'uniswap/src/components/TokenSelector/hooks/useFavoriteCurrencies'
+import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById'
+import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
+import { GqlResult } from 'uniswap/src/data/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+
+export function useFavoriteTokensOptions(
+ address: Address | undefined,
+ chainFilter: UniverseChainId | null,
+): GqlResult {
+ const {
+ data: portfolioBalancesById,
+ error: portfolioBalancesByIdError,
+ refetch: portfolioBalancesByIdRefetch,
+ loading: loadingPorfolioBalancesById,
+ } = usePortfolioBalancesForAddressById(address)
+
+ const {
+ data: favoriteCurrencies,
+ error: favoriteCurrenciesError,
+ refetch: refetchFavoriteCurrencies,
+ loading: loadingFavoriteCurrencies,
+ } = useFavoriteCurrencies()
+
+ const favoriteTokenOptions = useCurrencyInfosToTokenOptions({
+ currencyInfos: favoriteCurrencies,
+ portfolioBalancesById,
+ sortAlphabetically: true,
+ })
+
+ const refetch = useCallback(() => {
+ portfolioBalancesByIdRefetch?.()
+ refetchFavoriteCurrencies?.()
+ }, [portfolioBalancesByIdRefetch, refetchFavoriteCurrencies])
+
+ const error =
+ (!portfolioBalancesById && portfolioBalancesByIdError) || (!favoriteCurrencies && favoriteCurrenciesError)
+
+ const filteredFavoriteTokenOptions = useMemo(
+ () => favoriteTokenOptions && filter(favoriteTokenOptions, chainFilter),
+ [chainFilter, favoriteTokenOptions],
+ )
+
+ return {
+ data: filteredFavoriteTokenOptions,
+ refetch,
+ error: error || undefined,
+ loading: loadingPorfolioBalancesById || loadingFavoriteCurrencies,
+ }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useFilterCallbacks.ts b/packages/uniswap/src/components/TokenSelector/hooks/useFilterCallbacks.ts
new file mode 100644
index 00000000000..0b4f4729200
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useFilterCallbacks.ts
@@ -0,0 +1,94 @@
+import { useCallback, useEffect, useState } from 'react'
+import { TokenSelectorFlow } from 'uniswap/src/components/TokenSelector/types'
+import { flowToModalName } from 'uniswap/src/components/TokenSelector/utils'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { isTestnetChain } from 'uniswap/src/features/chains/utils'
+import { WalletEventName } from 'uniswap/src/features/telemetry/constants'
+import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
+
+export function useFilterCallbacks(
+ chainId: UniverseChainId | null,
+ flow: TokenSelectorFlow,
+): {
+ chainFilter: UniverseChainId | null
+ parsedChainFilter: UniverseChainId | null
+ searchFilter: string | null
+ parsedSearchFilter: string | null
+ onChangeChainFilter: (newChainFilter: UniverseChainId | null) => void
+ onClearSearchFilter: () => void
+ onChangeText: (newSearchFilter: string) => void
+} {
+ const [chainFilter, setChainFilter] = useState(chainId)
+ const [parsedChainFilter, setParsedChainFilter] = useState(null)
+ const [searchFilter, setSearchFilter] = useState(null)
+ const [parsedSearchFilter, setParsedSearchFilter] = useState(null)
+
+ const { chains: enabledChains } = useEnabledChains()
+
+ // Parses the user input to determine if the user is searching for a chain + token
+ // i.e "eth dai"
+ // parsedChainFilter: 1
+ // parsedSearchFilter: "dai"
+ useEffect(() => {
+ const splitSearch = searchFilter?.split(' ')
+ const maybeChainName = splitSearch?.[0]?.toLowerCase()
+
+ const chainMatch = getNativeCurrencyNames(enabledChains).find((currency) =>
+ currency.name.startsWith(maybeChainName ?? ''),
+ )
+ const search = splitSearch?.slice(1).join(' ')
+
+ if (!chainFilter && chainMatch && search) {
+ setParsedChainFilter(chainMatch.chainId)
+ setParsedSearchFilter(search)
+ } else {
+ setParsedChainFilter(null)
+ setParsedSearchFilter(null)
+ }
+ }, [searchFilter, chainFilter, enabledChains])
+
+ useEffect(() => {
+ setChainFilter(chainId)
+ }, [chainId])
+
+ const onChangeChainFilter = useCallback(
+ (newChainFilter: typeof chainFilter) => {
+ setChainFilter(newChainFilter)
+ sendAnalyticsEvent(WalletEventName.NetworkFilterSelected, {
+ chain: newChainFilter ?? 'All',
+ modal: flowToModalName(flow),
+ })
+ },
+ [flow],
+ )
+
+ const onClearSearchFilter = useCallback(() => {
+ setSearchFilter(null)
+ }, [])
+
+ const onChangeText = useCallback((newSearchFilter: string) => setSearchFilter(newSearchFilter), [setSearchFilter])
+
+ return {
+ chainFilter,
+ parsedChainFilter,
+ searchFilter,
+ parsedSearchFilter,
+ onChangeChainFilter,
+ onClearSearchFilter,
+ onChangeText,
+ }
+}
+
+const getNativeCurrencyNames = (chains: UniverseChainId[]): { chainId: UniverseChainId; name: string }[] =>
+ chains
+ .map((chainId) => {
+ return isTestnetChain(chainId)
+ ? false
+ : {
+ chainId,
+ name: getChainInfo(chainId).nativeCurrency.name.toLowerCase(),
+ }
+ })
+ .filter(Boolean) as { chainId: UniverseChainId; name: string }[]
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/usePopularTokensOptions.ts b/packages/uniswap/src/components/TokenSelector/hooks/usePopularTokensOptions.ts
new file mode 100644
index 00000000000..7833ef9f724
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/usePopularTokensOptions.ts
@@ -0,0 +1,46 @@
+import { useCallback } from 'react'
+import { useCurrencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions'
+import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById'
+import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
+import { GqlResult } from 'uniswap/src/data/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { usePopularTokens as usePopularTokensGql } from 'uniswap/src/features/dataApi/topTokens'
+
+export function usePopularTokensOptions(
+ address: Address | undefined,
+ chainFilter: UniverseChainId,
+): GqlResult {
+ const {
+ data: portfolioBalancesById,
+ error: portfolioBalancesByIdError,
+ refetch: portfolioBalancesByIdRefetch,
+ loading: loadingPorfolioBalancesById,
+ } = usePortfolioBalancesForAddressById(address)
+
+ const {
+ data: popularTokens,
+ error: popularTokensError,
+ refetch: refetchPopularTokens,
+ loading: loadingPopularTokens,
+ } = usePopularTokensGql(chainFilter)
+
+ const popularTokenOptions = useCurrencyInfosToTokenOptions({
+ currencyInfos: popularTokens,
+ portfolioBalancesById,
+ sortAlphabetically: true,
+ })
+
+ const refetch = useCallback(() => {
+ portfolioBalancesByIdRefetch?.()
+ refetchPopularTokens?.()
+ }, [portfolioBalancesByIdRefetch, refetchPopularTokens])
+
+ const error = (!portfolioBalancesById && portfolioBalancesByIdError) || (!popularTokenOptions && popularTokensError)
+
+ return {
+ data: popularTokenOptions,
+ refetch,
+ error: error || undefined,
+ loading: loadingPorfolioBalancesById || loadingPopularTokens,
+ }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById.ts b/packages/uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById.ts
new file mode 100644
index 00000000000..3376de3b2d8
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById.ts
@@ -0,0 +1,24 @@
+import { GqlResult } from 'uniswap/src/data/types'
+import { usePortfolioBalances } from 'uniswap/src/features/dataApi/balances'
+import { PortfolioBalance } from 'uniswap/src/features/dataApi/types'
+
+export function usePortfolioBalancesForAddressById(
+ address: Address | undefined,
+): GqlResult | undefined> {
+ const {
+ data: portfolioBalancesById,
+ error,
+ refetch,
+ loading,
+ } = usePortfolioBalances({
+ address,
+ fetchPolicy: 'cache-first', // we want to avoid re-renders when token selector is opening
+ })
+
+ return {
+ data: portfolioBalancesById,
+ error,
+ refetch,
+ loading,
+ }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/usePortfolioTokenOptions.ts b/packages/uniswap/src/components/TokenSelector/hooks/usePortfolioTokenOptions.ts
new file mode 100644
index 00000000000..2b8b2c110f4
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/usePortfolioTokenOptions.ts
@@ -0,0 +1,38 @@
+import { useMemo } from 'react'
+import { filter } from 'uniswap/src/components/TokenSelector/filter'
+import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById'
+import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
+import { GqlResult } from 'uniswap/src/data/types'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { sortPortfolioBalances, useTokenBalancesGroupedByVisibility } from 'uniswap/src/features/dataApi/balances'
+
+export function usePortfolioTokenOptions(
+ address: Address | undefined,
+ chainFilter: UniverseChainId | null,
+ searchFilter?: string,
+): GqlResult {
+ const { data: portfolioBalancesById, error, refetch, loading } = usePortfolioBalancesForAddressById(address)
+ const { isTestnetModeEnabled } = useEnabledChains()
+
+ const { shownTokens } = useTokenBalancesGroupedByVisibility({
+ balancesById: portfolioBalancesById,
+ })
+
+ const portfolioBalances = useMemo(
+ () => (shownTokens ? sortPortfolioBalances({ balances: shownTokens, isTestnetModeEnabled }) : undefined),
+ [shownTokens, isTestnetModeEnabled],
+ )
+
+ const filteredPortfolioBalances = useMemo(
+ () => portfolioBalances && filter(portfolioBalances, chainFilter, searchFilter),
+ [chainFilter, portfolioBalances, searchFilter],
+ )
+
+ return {
+ data: filteredPortfolioBalances,
+ error,
+ refetch,
+ loading,
+ }
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useRecentlySearchedTokens.ts b/packages/uniswap/src/components/TokenSelector/hooks/useRecentlySearchedTokens.ts
new file mode 100644
index 00000000000..1f2f05dae13
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useRecentlySearchedTokens.ts
@@ -0,0 +1,63 @@
+import { useMemo } from 'react'
+import { useSelector } from 'react-redux'
+import { MAX_RECENT_SEARCH_RESULTS } from 'uniswap/src/components/TokenSelector/constants'
+import { currencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions'
+import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
+import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
+import { buildCurrency, buildCurrencyInfo } from 'uniswap/src/features/dataApi/utils'
+import { SearchResultType, TokenSearchResult } from 'uniswap/src/features/search/SearchResult'
+import { selectSearchHistory } from 'uniswap/src/features/search/selectSearchHistory'
+import { currencyId } from 'uniswap/src/utils/currencyId'
+
+export function useRecentlySearchedTokens(chainFilter: UniverseChainId | null): TokenOption[] | undefined {
+ const searchHistory = useSelector(selectSearchHistory)
+
+ return useMemo(
+ () =>
+ currencyInfosToTokenOptions(
+ searchHistory
+ .filter((searchResult): searchResult is TokenSearchResult => searchResult.type === SearchResultType.Token)
+ .filter((searchResult) => (chainFilter ? searchResult.chainId === chainFilter : true))
+ .slice(0, MAX_RECENT_SEARCH_RESULTS)
+ .map(searchResultToCurrencyInfo),
+ ),
+ [chainFilter, searchHistory],
+ )
+}
+
+function searchResultToCurrencyInfo({
+ chainId,
+ address,
+ symbol,
+ name,
+ logoUrl,
+ safetyLevel,
+ safetyInfo,
+ feeData,
+}: TokenSearchResult): CurrencyInfo | null {
+ const currency = buildCurrency({
+ chainId: chainId as UniverseChainId,
+ address,
+ decimals: 0, // this does not matter in a context of CurrencyInfo here, as we do not provide any balance
+ symbol,
+ name,
+ buyFeeBps: feeData?.buyFeeBps,
+ sellFeeBps: feeData?.sellFeeBps,
+ })
+
+ if (!currency) {
+ return null
+ }
+
+ return buildCurrencyInfo({
+ currency,
+ currencyId: currencyId(currency),
+ logoUrl,
+ safetyLevel: safetyLevel ?? SafetyLevel.StrongWarning,
+ // defaulting to not spam, as user has searched and chosen this token before
+ isSpam: false,
+ safetyInfo,
+ })
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useTokenSectionsForEmptySearch.tsx b/packages/uniswap/src/components/TokenSelector/hooks/useTokenSectionsForEmptySearch.tsx
new file mode 100644
index 00000000000..925e5486a71
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useTokenSectionsForEmptySearch.tsx
@@ -0,0 +1,57 @@
+import { useCallback, useMemo } from 'react'
+import { useTranslation } from 'react-i18next'
+import { useDispatch } from 'react-redux'
+import { Text, TouchableArea } from 'ui/src'
+import { currencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions'
+import { useRecentlySearchedTokens } from 'uniswap/src/components/TokenSelector/hooks/useRecentlySearchedTokens'
+import { TokenOptionSection, TokenSection } from 'uniswap/src/components/TokenSelector/types'
+import { useTokenOptionsSection } from 'uniswap/src/components/TokenSelector/utils'
+import { GqlResult } from 'uniswap/src/data/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { gqlTokenToCurrencyInfo } from 'uniswap/src/features/dataApi/utils'
+import { clearSearchHistory } from 'uniswap/src/features/search/searchHistorySlice'
+import { usePopularTokens } from 'uniswap/src/features/tokens/hooks'
+
+function ClearAll({ onPress }: { onPress: () => void }): JSX.Element {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('tokens.selector.button.clear')}
+
+
+ )
+}
+
+export function useTokenSectionsForEmptySearch(chainFilter: UniverseChainId | null): GqlResult {
+ const dispatch = useDispatch()
+
+ const { popularTokens, loading } = usePopularTokens()
+
+ const recentlySearchedTokenOptions = useRecentlySearchedTokens(chainFilter)
+
+ // it's a dependency of useMemo => useCallback
+ const onPressClearSearchHistory = useCallback((): void => {
+ dispatch(clearSearchHistory())
+ }, [dispatch])
+
+ const recentSection = useTokenOptionsSection({
+ sectionKey: TokenOptionSection.RecentTokens,
+ tokenOptions: recentlySearchedTokenOptions,
+ endElement: ,
+ })
+
+ const popularSection = useTokenOptionsSection({
+ sectionKey: TokenOptionSection.PopularTokens,
+ tokenOptions: currencyInfosToTokenOptions(popularTokens?.map(gqlTokenToCurrencyInfo)),
+ })
+ const sections = useMemo(() => [...(recentSection ?? []), ...(popularSection ?? [])], [popularSection, recentSection])
+
+ return useMemo(
+ () => ({
+ data: sections,
+ loading,
+ }),
+ [loading, sections],
+ )
+}
diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useTokenSectionsForSearchResults.ts b/packages/uniswap/src/components/TokenSelector/hooks/useTokenSectionsForSearchResults.ts
new file mode 100644
index 00000000000..fa92072f5a9
--- /dev/null
+++ b/packages/uniswap/src/components/TokenSelector/hooks/useTokenSectionsForSearchResults.ts
@@ -0,0 +1,107 @@
+import { useCallback, useMemo } from 'react'
+import { useTranslation } from 'react-i18next'
+import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById'
+import { usePortfolioTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioTokenOptions'
+import { TokenOptionSection, TokenSection } from 'uniswap/src/components/TokenSelector/types'
+import {
+ formatSearchResults,
+ mergeSearchResultsWithBridgingTokens,
+ useTokenOptionsSection,
+} from 'uniswap/src/components/TokenSelector/utils'
+import { GqlResult } from 'uniswap/src/data/types'
+import { TradeableAsset } from 'uniswap/src/entities/assets'
+import { useBridgingTokensOptions } from 'uniswap/src/features/bridging/hooks/tokens'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { getChainLabel } from 'uniswap/src/features/chains/utils'
+import { useSearchTokens } from 'uniswap/src/features/dataApi/searchTokens'
+
+export function useTokenSectionsForSearchResults(
+ address: string | undefined,
+ chainFilter: UniverseChainId | null,
+ searchFilter: string | null,
+ isBalancesOnlySearch: boolean,
+ input: TradeableAsset | undefined,
+): GqlResult {
+ const { t } = useTranslation()
+
+ const {
+ data: portfolioBalancesById,
+ error: portfolioBalancesByIdError,
+ refetch: refetchPortfolioBalances,
+ loading: portfolioBalancesByIdLoading,
+ } = usePortfolioBalancesForAddressById(address)
+
+ const {
+ data: portfolioTokenOptions,
+ error: portfolioTokenOptionsError,
+ refetch: refetchPortfolioTokenOptions,
+ loading: portfolioTokenOptionsLoading,
+ } = usePortfolioTokenOptions(address, chainFilter, searchFilter ?? undefined)
+
+ // Bridging tokens are only shown if input is provided
+ const {
+ data: bridgingTokenOptions,
+ error: bridgingTokenOptionsError,
+ refetch: refetchBridgingTokenOptions,
+ loading: bridgingTokenOptionsLoading,
+ } = useBridgingTokensOptions({ input, walletAddress: address, chainFilter })
+
+ // Only call search endpoint if isBalancesOnlySearch is false
+ const {
+ data: searchResultCurrencies,
+ error: searchTokensError,
+ refetch: refetchSearchTokens,
+ loading: searchTokensLoading,
+ } = useSearchTokens(searchFilter, chainFilter, /*skip*/ isBalancesOnlySearch)
+
+ const searchResults = useMemo(() => {
+ return formatSearchResults(searchResultCurrencies, portfolioBalancesById, searchFilter)
+ }, [searchResultCurrencies, portfolioBalancesById, searchFilter])
+
+ const loading =
+ portfolioTokenOptionsLoading ||
+ portfolioBalancesByIdLoading ||
+ (!isBalancesOnlySearch && searchTokensLoading) ||
+ bridgingTokenOptionsLoading
+
+ const searchResultsSections = useTokenOptionsSection({
+ sectionKey: TokenOptionSection.SearchResults,
+ // Use local search when only searching balances
+ tokenOptions: isBalancesOnlySearch ? portfolioTokenOptions : searchResults,
+ })
+
+ // If there are bridging options, we need to extract them from the search results and then prepend them as a new section above.
+ // The remaining non-bridging search results will be shown in a section with a different name
+ const networkName = chainFilter ? getChainLabel(chainFilter) : undefined
+ const searchResultsSectionHeader = networkName
+ ? t('tokens.selector.section.otherSearchResults', { network: networkName })
+ : undefined
+ const sections = mergeSearchResultsWithBridgingTokens(
+ searchResultsSections,
+ bridgingTokenOptions,
+ searchResultsSectionHeader,
+ )
+
+ const error =
+ (!bridgingTokenOptions && bridgingTokenOptionsError) ||
+ (!portfolioBalancesById && portfolioBalancesByIdError) ||
+ (!portfolioTokenOptions && portfolioTokenOptionsError) ||
+ (!isBalancesOnlySearch && !searchResults && searchTokensError)
+
+ const refetchAll = useCallback(() => {
+ refetchPortfolioBalances?.()
+ refetchSearchTokens?.()
+ refetchPortfolioTokenOptions?.()
+ refetchBridgingTokenOptions?.()
+ }, [refetchBridgingTokenOptions, refetchPortfolioBalances, refetchPortfolioTokenOptions, refetchSearchTokens])
+
+ return useMemo(
+ () => ({
+ data: sections,
+ loading,
+ error: error || undefined,
+ refetch: refetchAll,
+ }),
+ [error, loading, refetchAll, sections],
+ )
+}
diff --git a/packages/uniswap/src/components/TokenSelector/SuggestedToken.tsx b/packages/uniswap/src/components/TokenSelector/items/SuggestedToken.tsx
similarity index 95%
rename from packages/uniswap/src/components/TokenSelector/SuggestedToken.tsx
rename to packages/uniswap/src/components/TokenSelector/items/SuggestedToken.tsx
index b4b8204c149..0e1165e88cf 100644
--- a/packages/uniswap/src/components/TokenSelector/SuggestedToken.tsx
+++ b/packages/uniswap/src/components/TokenSelector/items/SuggestedToken.tsx
@@ -6,7 +6,7 @@ import { Pill } from 'uniswap/src/components/pill/Pill'
import { OnSelectCurrency, TokenOption, TokenSection } from 'uniswap/src/components/TokenSelector/types'
import { getSymbolDisplayText } from 'uniswap/src/utils/currency'
-function _SuggestedToken({
+function _TokenPill({
onSelectCurrency,
token,
index,
@@ -58,4 +58,4 @@ function _SuggestedToken({
)
}
-export const SuggestedToken = memo(_SuggestedToken)
+export const TokenPill = memo(_TokenPill)
diff --git a/packages/uniswap/src/components/TokenSelector/TokenCard.tsx b/packages/uniswap/src/components/TokenSelector/items/TokenCard.tsx
similarity index 100%
rename from packages/uniswap/src/components/TokenSelector/TokenCard.tsx
rename to packages/uniswap/src/components/TokenSelector/items/TokenCard.tsx
diff --git a/packages/uniswap/src/components/TokenSelector/TokenOptionItem.tsx b/packages/uniswap/src/components/TokenSelector/items/TokenOptionItem.tsx
similarity index 90%
rename from packages/uniswap/src/components/TokenSelector/TokenOptionItem.tsx
rename to packages/uniswap/src/components/TokenSelector/items/TokenOptionItem.tsx
index e3f04ba356a..8859e377616 100644
--- a/packages/uniswap/src/components/TokenSelector/TokenOptionItem.tsx
+++ b/packages/uniswap/src/components/TokenSelector/items/TokenOptionItem.tsx
@@ -6,7 +6,7 @@ import { TokenLogo } from 'uniswap/src/components/CurrencyLogo/TokenLogo'
import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
import { WarningSeverity } from 'uniswap/src/components/modals/WarningModal/types'
import WarningIcon from 'uniswap/src/components/warnings/WarningIcon'
-import { getWarningIconColorOverride } from 'uniswap/src/components/warnings/utils'
+import { getWarningIconColors } from 'uniswap/src/components/warnings/utils'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
import { CurrencyInfo, TokenList } from 'uniswap/src/features/dataApi/types'
import { FeatureFlags } from 'uniswap/src/features/gating/flags'
@@ -24,7 +24,6 @@ interface OptionProps {
onPress: () => void
showTokenAddress?: boolean
tokenWarningDismissed: boolean
- dismissWarningCallback: () => void
quantity: number | null
// TODO(WEB-4731): Remove isKeyboardOpen dependency
isKeyboardOpen?: boolean
@@ -36,15 +35,12 @@ interface OptionProps {
}
function getTokenWarningDetails(currencyInfo: CurrencyInfo): {
- severity: WarningSeverity | undefined
- isWarningSevere: boolean
+ severity: WarningSeverity
isNonDefaultList: boolean
isBlocked: boolean
} {
const { safetyLevel, safetyInfo } = currencyInfo
const severity = getTokenWarningSeverity(currencyInfo)
- const isWarningSevere =
- severity === WarningSeverity.Blocked || severity === WarningSeverity.High || severity === WarningSeverity.Medium
const isNonDefaultList =
safetyLevel === SafetyLevel.MediumWarning ||
safetyLevel === SafetyLevel.StrongWarning ||
@@ -52,7 +48,6 @@ function getTokenWarningDetails(currencyInfo: CurrencyInfo): {
const isBlocked = severity === WarningSeverity.Blocked || safetyLevel === SafetyLevel.Blocked
return {
severity,
- isWarningSevere,
isNonDefaultList,
isBlocked,
}
@@ -64,7 +59,6 @@ function _TokenOptionItem({
onPress,
showTokenAddress,
tokenWarningDismissed,
- dismissWarningCallback,
balance,
quantity,
quantityFormatted,
@@ -76,11 +70,12 @@ function _TokenOptionItem({
const [showWarningModal, setShowWarningModal] = useState(false)
const tokenProtectionEnabled = useFeatureFlag(FeatureFlags.TokenProtection)
- const { severity, isBlocked, isNonDefaultList, isWarningSevere } = getTokenWarningDetails(currencyInfo)
- const warningIconColor = getWarningIconColorOverride(severity)
+ const { severity, isBlocked, isNonDefaultList } = getTokenWarningDetails(currencyInfo)
+ // in token selector, we only show the warning icon if token is >=Medium severity
+ const { colorSecondary: warningIconColor } = getWarningIconColors(severity)
const shouldShowWarningModalOnPress = !tokenProtectionEnabled
? isBlocked || (isNonDefaultList && !tokenWarningDismissed)
- : isWarningSevere && !tokenWarningDismissed
+ : isBlocked || (severity !== WarningSeverity.None && !tokenWarningDismissed)
const handleShowWarningModal = useCallback((): void => {
dismissNativeKeyboard()
@@ -105,10 +100,9 @@ function _TokenOptionItem({
}, [showWarnings, shouldShowWarningModalOnPress, onPress, isKeyboardOpen, handleShowWarningModal])
const onAcceptTokenWarning = useCallback(() => {
- dismissWarningCallback()
setShowWarningModal(false)
onPress()
- }, [dismissWarningCallback, onPress])
+ }, [onPress])
return (
<>
diff --git a/packages/uniswap/src/components/TokenSelector/TokenSectionHeader.tsx b/packages/uniswap/src/components/TokenSelector/items/TokenSectionHeader.tsx
similarity index 100%
rename from packages/uniswap/src/components/TokenSelector/TokenSectionHeader.tsx
rename to packages/uniswap/src/components/TokenSelector/items/TokenSectionHeader.tsx
diff --git a/packages/uniswap/src/components/TokenSelector/HorizontalTokenList/HorizontalTokenList.native.tsx b/packages/uniswap/src/components/TokenSelector/lists/HorizontalTokenList/HorizontalTokenList.native.tsx
similarity index 59%
rename from packages/uniswap/src/components/TokenSelector/HorizontalTokenList/HorizontalTokenList.native.tsx
rename to packages/uniswap/src/components/TokenSelector/lists/HorizontalTokenList/HorizontalTokenList.native.tsx
index 3d7a6d3b357..e8fbea14027 100644
--- a/packages/uniswap/src/components/TokenSelector/HorizontalTokenList/HorizontalTokenList.native.tsx
+++ b/packages/uniswap/src/components/TokenSelector/lists/HorizontalTokenList/HorizontalTokenList.native.tsx
@@ -2,10 +2,8 @@ import { memo, useCallback } from 'react'
import { FlatList } from 'react-native-gesture-handler'
import { Flex } from 'ui/src'
import { spacing } from 'ui/src/theme'
-import { HorizontalTokenListProps } from 'uniswap/src/components/TokenSelector/HorizontalTokenList/HorizontalTokenList'
-import { SuggestedToken } from 'uniswap/src/components/TokenSelector/SuggestedToken'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
+import { TokenPill } from 'uniswap/src/components/TokenSelector/items/SuggestedToken'
+import { HorizontalTokenListProps } from 'uniswap/src/components/TokenSelector/lists/HorizontalTokenList/HorizontalTokenList'
export const HorizontalTokenList = memo(function _HorizontalTokenList({
tokens: suggestedTokens,
@@ -13,26 +11,8 @@ export const HorizontalTokenList = memo(function _HorizontalTokenList({
index,
section,
}: HorizontalTokenListProps): JSX.Element {
- const isBridgingEnabled = useFeatureFlag(FeatureFlags.Bridging)
-
const itemSeparatorComponent = useCallback(() => , [])
- if (!isBridgingEnabled) {
- return (
-
- {suggestedTokens.map((token) => (
-
- ))}
-
- )
- }
-
return (
token.currencyInfo.currencyId}
ItemSeparatorComponent={itemSeparatorComponent}
renderItem={({ item: token }) => (
- {
- const isBridgingEnabled = useFeatureFlag(FeatureFlags.Bridging)
const { defaultChainId, isTestnetModeEnabled } = useEnabledChains()
const {
@@ -169,7 +164,7 @@ function useTokenSectionsForSwapOutput({
return [
...(suggestedSection ?? []),
- ...(isBridgingEnabled ? bridgingSection ?? [] : []),
+ ...(bridgingSection ?? []),
...(portfolioSection ?? []),
...(recentSection ?? []),
// TODO(WEB-3061): Favorited wallets/tokens
@@ -182,7 +177,6 @@ function useTokenSectionsForSwapOutput({
portfolioSection,
popularSection,
suggestedSection,
- isBridgingEnabled,
bridgingSection,
recentSection,
favoriteSection,
diff --git a/packages/uniswap/src/components/TokenSelector/types.ts b/packages/uniswap/src/components/TokenSelector/types.ts
index 7c5e4860b7e..2adcc416b6a 100644
--- a/packages/uniswap/src/components/TokenSelector/types.ts
+++ b/packages/uniswap/src/components/TokenSelector/types.ts
@@ -1,6 +1,6 @@
import { TradeableAsset } from 'uniswap/src/entities/assets'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { FiatNumberType } from 'utilities/src/format/types'
export type TokenOption = {
diff --git a/packages/uniswap/src/components/TokenSelector/utils.tsx b/packages/uniswap/src/components/TokenSelector/utils.tsx
index 391d92d482a..75961041790 100644
--- a/packages/uniswap/src/components/TokenSelector/utils.tsx
+++ b/packages/uniswap/src/components/TokenSelector/utils.tsx
@@ -1,9 +1,15 @@
import { useMemo } from 'react'
-import { TokenOption, TokenOptionSection, TokenSection } from 'uniswap/src/components/TokenSelector/types'
+import {
+ TokenOption,
+ TokenOptionSection,
+ TokenSection,
+ TokenSelectorFlow,
+} from 'uniswap/src/components/TokenSelector/types'
import { tradingApiSwappableTokenToCurrencyInfo } from 'uniswap/src/data/apiClients/tradingApi/utils/tradingApiSwappableTokenToCurrencyInfo'
import { SafetyLevel as GqlSafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
import { GetSwappableTokensResponse, SafetyLevel } from 'uniswap/src/data/tradingApi/__generated__'
import { CurrencyInfo, PortfolioBalance } from 'uniswap/src/features/dataApi/types'
+import { ModalName, ModalNameType } from 'uniswap/src/features/telemetry/constants'
import { areCurrencyIdsEqual } from 'uniswap/src/utils/currencyId'
import { differenceWith } from 'utilities/src/primitives/array'
@@ -210,3 +216,14 @@ export function isSwapListLoading(
): boolean {
return loading && (!portfolioSection || !popularSection)
}
+
+export function flowToModalName(flow: TokenSelectorFlow): ModalNameType | undefined {
+ switch (flow) {
+ case TokenSelectorFlow.Swap:
+ return ModalName.Swap
+ case TokenSelectorFlow.Send:
+ return ModalName.Send
+ default:
+ return undefined
+ }
+}
diff --git a/packages/uniswap/src/components/banners/TestnetModeBanner.tsx b/packages/uniswap/src/components/banners/TestnetModeBanner.tsx
index c567effd69c..4139a7b9f39 100644
--- a/packages/uniswap/src/components/banners/TestnetModeBanner.tsx
+++ b/packages/uniswap/src/components/banners/TestnetModeBanner.tsx
@@ -3,7 +3,9 @@ import { Flex, FlexProps, Text, isWeb } from 'ui/src'
import { Wrench } from 'ui/src/components/icons/Wrench'
// eslint-disable-next-line no-restricted-imports
import { useDeviceInsets } from 'ui/src/hooks/useDeviceInsets'
-import { TESTNET_MODE_BANNER_HEIGHT, useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { zIndices } from 'ui/src/theme'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { TESTNET_MODE_BANNER_HEIGHT } from 'uniswap/src/features/settings/hooks'
import { isInterface, isMobileApp } from 'utilities/src/platform'
export function TestnetModeBanner(props: FlexProps): JSX.Element | null {
@@ -22,7 +24,7 @@ export function TestnetModeBanner(props: FlexProps): JSX.Element | null {
centered
top={top}
position={isMobileApp ? 'absolute' : 'relative'}
- zIndex="$sticky"
+ zIndex={zIndices.fixed}
width={isInterface ? 'auto' : '100%'}
p="$padding12"
gap="$gap8"
diff --git a/packages/uniswap/src/components/dropdowns/ActionSheetDropdown.tsx b/packages/uniswap/src/components/dropdowns/ActionSheetDropdown.tsx
index b40195649ed..02d751d6893 100644
--- a/packages/uniswap/src/components/dropdowns/ActionSheetDropdown.tsx
+++ b/packages/uniswap/src/components/dropdowns/ActionSheetDropdown.tsx
@@ -20,7 +20,7 @@ import { BaseCard } from 'uniswap/src/components/BaseCard/BaseCard'
import { Scrollbar } from 'uniswap/src/components/misc/Scrollbar'
import { MenuItemProp } from 'uniswap/src/components/modals/ActionSheetModal'
import { useAppInsets } from 'uniswap/src/hooks/useAppInsets'
-import { isAndroid, isInterface, isTouchable } from 'utilities/src/platform'
+import { isAndroid, isInterface, isMobileApp, isTouchable } from 'utilities/src/platform'
const DEFAULT_MIN_WIDTH = 225
@@ -178,11 +178,15 @@ const ActionSheetBackdropWithContent = memo(function ActionSheetBackdropWithCont
closeOnSelect: boolean
}): JSX.Element {
/*
- We need to add key to Portal, becuase of a bug in tamagui.
+ We need to add key to Portal on mobile, becuase of a bug in tamagui.
Remove when https://linear.app/uniswap/issue/WALL-4817/tamaguis-portal-stops-reacting-to-re-renders is done
*/
+ const key = useMemo(
+ () => (isMobileApp ? Math.random() : undefined), // eslint-disable-next-line react-hooks/exhaustive-deps
+ [closeDropdown, styles, isOpen, toggleMeasurements, contentProps, closeOnSelect],
+ )
return (
-
+
{isOpen && toggleMeasurements && (
<>
diff --git a/packages/uniswap/src/components/gas/NetworkFee.test.tsx b/packages/uniswap/src/components/gas/NetworkFee.test.tsx
index f3b4e55f13d..1835f62b16c 100644
--- a/packages/uniswap/src/components/gas/NetworkFee.test.tsx
+++ b/packages/uniswap/src/components/gas/NetworkFee.test.tsx
@@ -1,6 +1,6 @@
import { NetworkFee } from 'uniswap/src/components/gas/NetworkFee'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { render } from 'uniswap/src/test/test-utils'
-import { UniverseChainId } from 'uniswap/src/types/chains'
jest.mock('uniswap/src/features/gas/hooks', () => {
return {
diff --git a/packages/uniswap/src/components/gas/NetworkFee.tsx b/packages/uniswap/src/components/gas/NetworkFee.tsx
index 9a545bd26a6..1de2bca5c0a 100644
--- a/packages/uniswap/src/components/gas/NetworkFee.tsx
+++ b/packages/uniswap/src/components/gas/NetworkFee.tsx
@@ -5,6 +5,7 @@ import { UniswapX } from 'ui/src/components/icons/UniswapX'
import { iconSizes } from 'ui/src/theme'
import { NetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo'
import { IndicativeLoadingWrapper } from 'uniswap/src/components/misc/IndicativeLoadingWrapper'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import {
useFormattedUniswapXGasFeeInfo,
useGasFeeFormattedAmounts,
@@ -13,7 +14,6 @@ import {
import { GasFeeResult } from 'uniswap/src/features/gas/types'
import { NetworkFeeWarning } from 'uniswap/src/features/transactions/swap/modals/NetworkFeeWarning'
import { UniswapXGasBreakdown } from 'uniswap/src/features/transactions/swap/types/swapTxAndGasInfo'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { isInterface } from 'utilities/src/platform'
export function NetworkFee({
diff --git a/packages/uniswap/src/components/modals/Modal.native.tsx b/packages/uniswap/src/components/modals/Modal.native.tsx
index 6baae6d9731..5506a8300a7 100644
--- a/packages/uniswap/src/components/modals/Modal.native.tsx
+++ b/packages/uniswap/src/components/modals/Modal.native.tsx
@@ -13,7 +13,7 @@ import { BackHandler, StyleProp, StyleSheet, ViewStyle } from 'react-native'
import Animated, { Extrapolate, interpolate, useAnimatedStyle, useSharedValue } from 'react-native-reanimated'
import { Flex, useIsDarkMode, useMedia, useSporeColors } from 'ui/src'
import { useDeviceDimensions } from 'ui/src/hooks/useDeviceDimensions'
-import { borderRadii, spacing } from 'ui/src/theme'
+import { borderRadii, spacing, zIndices } from 'ui/src/theme'
import { BottomSheetContextProvider } from 'uniswap/src/components/modals/BottomSheetContext'
import { HandleBar } from 'uniswap/src/components/modals/HandleBar'
import { ModalProps } from 'uniswap/src/components/modals/ModalProps'
@@ -93,6 +93,7 @@ function BottomSheetModalContents({
// probably it requires usage of
extendOnKeyboardVisible = false,
hideScrim = false,
+ isBehindFixedBanners = false,
}: ModalProps): JSX.Element {
const dimensions = useDeviceDimensions()
const insets = useAppInsets()
@@ -132,13 +133,14 @@ function BottomSheetModalContents({
(props: BottomSheetBackdropProps) => (
),
- [blurredBackground, hideScrim, isDismissible],
+ [blurredBackground, hideScrim, isDismissible, isBehindFixedBanners],
)
const renderHandleBar = useCallback(
@@ -251,6 +253,7 @@ function BottomSheetModalContents({
{...background}
{...backdrop}
ref={modalRef}
+ containerStyle={[!isBehindFixedBanners && { zIndex: zIndices.modal }]}
animatedPosition={animatedPosition}
backgroundStyle={backgroundStyle}
containerComponent={containerComponent}
diff --git a/packages/uniswap/src/components/modals/ModalProps.tsx b/packages/uniswap/src/components/modals/ModalProps.tsx
index a821aedaae6..42251b15302 100644
--- a/packages/uniswap/src/components/modals/ModalProps.tsx
+++ b/packages/uniswap/src/components/modals/ModalProps.tsx
@@ -28,6 +28,8 @@ export type ModalProps = PropsWithChildren<{
extendOnKeyboardVisible?: boolean
// defaults to `true`
isModalOpen?: boolean
+ // created to allow testnet mode banner to be displayed on mobile
+ isBehindFixedBanners?: boolean
// TODO MOB-2526 refactor Modal to more platform-agnostic
alignment?: 'center' | 'top'
diff --git a/packages/uniswap/src/components/modals/WarningModal/getAlertColor.ts b/packages/uniswap/src/components/modals/WarningModal/getAlertColor.ts
index 7af2208e529..d451c544405 100644
--- a/packages/uniswap/src/components/modals/WarningModal/getAlertColor.ts
+++ b/packages/uniswap/src/components/modals/WarningModal/getAlertColor.ts
@@ -5,36 +5,42 @@ export function getAlertColor(severity?: WarningSeverity): WarningColor {
case WarningSeverity.None:
return {
text: '$neutral2',
+ headerText: '$neutral1',
background: '$neutral2',
buttonTheme: 'secondary',
}
case WarningSeverity.Low:
return {
text: '$neutral2',
+ headerText: '$neutral1',
background: '$surface2',
buttonTheme: 'tertiary',
}
case WarningSeverity.High:
return {
text: '$statusCritical',
+ headerText: '$statusCritical',
background: '$DEP_accentCriticalSoft',
buttonTheme: 'detrimental',
}
case WarningSeverity.Medium:
return {
text: '$DEP_accentWarning',
+ headerText: '$DEP_accentWarning',
background: '$DEP_accentWarningSoft',
buttonTheme: 'warning',
}
case WarningSeverity.Blocked:
return {
text: '$neutral1',
+ headerText: '$neutral1',
background: '$surface3',
buttonTheme: 'secondary',
}
default:
return {
text: '$neutral2',
+ headerText: '$neutral1',
background: '$transparent',
buttonTheme: 'tertiary',
}
diff --git a/packages/uniswap/src/components/modals/WarningModal/types.ts b/packages/uniswap/src/components/modals/WarningModal/types.ts
index 79c0419eae9..8569acc8c2a 100644
--- a/packages/uniswap/src/components/modals/WarningModal/types.ts
+++ b/packages/uniswap/src/components/modals/WarningModal/types.ts
@@ -12,6 +12,7 @@ export enum WarningSeverity {
export type WarningColor = {
text: ColorTokens
+ headerText: ColorTokens
background: ColorTokens
buttonTheme: ThemeNames
}
diff --git a/packages/uniswap/src/components/network/NetworkFilter.test.tsx b/packages/uniswap/src/components/network/NetworkFilter.test.tsx
index a3b04333504..ef83f21c460 100644
--- a/packages/uniswap/src/components/network/NetworkFilter.test.tsx
+++ b/packages/uniswap/src/components/network/NetworkFilter.test.tsx
@@ -2,7 +2,7 @@ import { NetworkFilter } from 'uniswap/src/components/network/NetworkFilter'
import { render } from 'uniswap/src/test/test-utils'
import ReactDOM from 'react-dom'
-import { SUPPORTED_CHAIN_IDS } from 'uniswap/src/types/chains'
+import { SUPPORTED_CHAIN_IDS } from 'uniswap/src/features/chains/types'
ReactDOM.createPortal = jest.fn((element) => {
return element as React.ReactPortal
diff --git a/packages/uniswap/src/components/network/NetworkFilter.tsx b/packages/uniswap/src/components/network/NetworkFilter.tsx
index 9010d2789c9..a43996f703d 100644
--- a/packages/uniswap/src/components/network/NetworkFilter.tsx
+++ b/packages/uniswap/src/components/network/NetworkFilter.tsx
@@ -10,8 +10,8 @@ import {
ActionSheetDropdownStyleProps,
} from 'uniswap/src/components/dropdowns/ActionSheetDropdown'
import { useNetworkOptions } from 'uniswap/src/components/network/hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { isMobileApp } from 'utilities/src/platform'
const ELLIPSIS = 'ellipsis'
diff --git a/packages/uniswap/src/components/network/NetworkLogos.tsx b/packages/uniswap/src/components/network/NetworkLogos.tsx
index 1ee55ab5bfc..fce9631cf56 100644
--- a/packages/uniswap/src/components/network/NetworkLogos.tsx
+++ b/packages/uniswap/src/components/network/NetworkLogos.tsx
@@ -16,10 +16,10 @@ import { X } from 'ui/src/components/icons/X'
import { borderRadii, iconSizes, zIndices } from 'ui/src/theme'
import { Modal } from 'uniswap/src/components/modals/Modal'
import { LearnMoreLink } from 'uniswap/src/components/text/LearnMoreLink'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import { uniswapUrls } from 'uniswap/src/constants/urls'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { isInterface } from 'utilities/src/platform'
export type NetworkLogosProps = {
@@ -38,7 +38,7 @@ export function NetworkLogos({ chains }: NetworkLogosProps): JSX.Element {
() => (
{chains.map((chain) => {
- const { label, logo } = UNIVERSE_CHAIN_INFO[chain]
+ const { label, logo } = getChainInfo(chain)
return (
{
it('renders a NetworkPill without image', () => {
diff --git a/packages/uniswap/src/components/network/NetworkPill.tsx b/packages/uniswap/src/components/network/NetworkPill.tsx
index f3662eb8653..347a0e5cbcf 100644
--- a/packages/uniswap/src/components/network/NetworkPill.tsx
+++ b/packages/uniswap/src/components/network/NetworkPill.tsx
@@ -2,8 +2,8 @@ import { ComponentProps } from 'react'
import { iconSizes } from 'ui/src/theme'
import { NetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo'
import { Pill } from 'uniswap/src/components/pill/Pill'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
+import { getChainLabel } from 'uniswap/src/features/chains/utils'
import { useNetworkColors } from 'uniswap/src/utils/colors'
export type NetworkPillProps = {
@@ -22,7 +22,7 @@ export function NetworkPill({
iconSize = iconSizes.icon16,
...rest
}: NetworkPillProps): JSX.Element {
- const info = UNIVERSE_CHAIN_INFO[chainId]
+ const label = getChainLabel(chainId)
const colors = useNetworkColors(chainId)
return (
@@ -31,7 +31,7 @@ export function NetworkPill({
customBorderColor={showBorder ? colors.foreground : 'transparent'}
foregroundColor={colors.foreground}
icon={showIcon ? : null}
- label={info.label}
+ label={label}
{...rest}
/>
)
diff --git a/packages/uniswap/src/components/network/hooks.tsx b/packages/uniswap/src/components/network/hooks.tsx
index f5ef96af578..e767db97dde 100644
--- a/packages/uniswap/src/components/network/hooks.tsx
+++ b/packages/uniswap/src/components/network/hooks.tsx
@@ -1,7 +1,7 @@
import { useMemo } from 'react'
import { NetworkOption } from 'uniswap/src/components/network/NetworkOption'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { ElementName } from 'uniswap/src/features/telemetry/constants'
-import { UniverseChainId } from 'uniswap/src/types/chains'
export function useNetworkOptions({
onPress,
diff --git a/packages/uniswap/src/components/text/LearnMoreLink.tsx b/packages/uniswap/src/components/text/LearnMoreLink.tsx
index 38cba388e2e..840f7bfcc45 100644
--- a/packages/uniswap/src/components/text/LearnMoreLink.tsx
+++ b/packages/uniswap/src/components/text/LearnMoreLink.tsx
@@ -10,15 +10,17 @@ export const LearnMoreLink = ({
url,
textVariant = 'buttonLabel2',
textColor = '$accent1',
+ centered = false,
}: {
url: string
textVariant?: TextProps['variant']
textColor?: TextProps['color']
+ centered?: boolean
}): JSX.Element => {
const { t } = useTranslation()
return (
=> onPressLearnMore(url)}>
-
+
{t('common.button.learn')}
diff --git a/packages/uniswap/src/components/warnings/WarningIcon.tsx b/packages/uniswap/src/components/warnings/WarningIcon.tsx
index 248c274dcbd..5a0483243ee 100644
--- a/packages/uniswap/src/components/warnings/WarningIcon.tsx
+++ b/packages/uniswap/src/components/warnings/WarningIcon.tsx
@@ -11,6 +11,7 @@ import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
interface Props {
// TODO (WALL-4626): remove SafetyLevel entirely
+ /** @deprecated use severity instead */
safetyLevel?: Maybe
severity?: WarningSeverity
// To override the normally associated safetyLevel<->color mapping
@@ -30,7 +31,7 @@ export default function WarningIcon({
const { color: defaultIconColor, backgroundColor } = getWarningIconColors(severityToUse)
const color = strokeColorOverride ?? defaultIconColor
const Icon = getWarningIcon(severityToUse, tokenProtectionEnabled)
- const icon =
+ const icon = Icon ? : null
return heroIcon ? (
{icon}
diff --git a/packages/uniswap/src/components/warnings/utils.ts b/packages/uniswap/src/components/warnings/utils.ts
index b38d30e183e..24b1668d54a 100644
--- a/packages/uniswap/src/components/warnings/utils.ts
+++ b/packages/uniswap/src/components/warnings/utils.ts
@@ -21,7 +21,11 @@ export function safetyLevelToWarningSeverity(safetyLevel: Maybe): W
}
}
-export function getWarningIcon(severity?: WarningSeverity, tokenProtectionEnabled: boolean = false): GeneratedIcon {
+// eslint-disable-next-line consistent-return
+export function getWarningIcon(
+ severity: WarningSeverity,
+ tokenProtectionEnabled: boolean = false,
+): GeneratedIcon | null {
switch (severity) {
case WarningSeverity.High:
return tokenProtectionEnabled ? OctagonExclamation : AlertTriangleFilled
@@ -30,15 +34,16 @@ export function getWarningIcon(severity?: WarningSeverity, tokenProtectionEnable
case WarningSeverity.Blocked:
return Blocked
case WarningSeverity.Low:
- case WarningSeverity.None:
return InfoCircleFilled
- default:
- return AlertTriangleFilled
+ case WarningSeverity.None:
+ return null
}
}
export function getWarningIconColors(severity?: WarningSeverity): {
color: ColorTokens
+ /** `colorSecondary` used instead of `color` in certain places, such as token selector & mobile search */
+ colorSecondary: ColorTokens | undefined
backgroundColor: ColorTokens
textColor: ColorTokens
} {
@@ -46,21 +51,30 @@ export function getWarningIconColors(severity?: WarningSeverity): {
case WarningSeverity.High:
return {
color: '$statusCritical',
+ colorSecondary: '$statusCritical',
backgroundColor: '$DEP_accentCriticalSoft',
textColor: '$statusCritical',
}
case WarningSeverity.Medium:
return {
color: '$DEP_accentWarning',
+ colorSecondary: '$neutral2',
backgroundColor: '$DEP_accentWarningSoft',
textColor: '$DEP_accentWarning',
}
case WarningSeverity.Blocked:
+ return {
+ color: '$neutral2',
+ colorSecondary: '$neutral2',
+ backgroundColor: '$surface3',
+ textColor: '$neutral1',
+ }
case WarningSeverity.Low:
case WarningSeverity.None:
default:
return {
color: '$neutral2',
+ colorSecondary: undefined,
backgroundColor: '$surface3',
textColor: '$neutral1',
}
@@ -85,17 +99,3 @@ export function getWarningButtonProps(severity?: WarningSeverity): { theme: Them
}
}
}
-
-export function getWarningIconColorOverride(severity?: WarningSeverity): ColorTokens | undefined {
- switch (severity) {
- case WarningSeverity.High:
- return '$statusCritical'
- case WarningSeverity.Medium:
- case WarningSeverity.Blocked:
- return '$neutral2'
- case WarningSeverity.Low:
- case WarningSeverity.None:
- default:
- return undefined
- }
-}
diff --git a/packages/uniswap/src/constants/addresses.ts b/packages/uniswap/src/constants/addresses.ts
index aa1ed39412e..2726043abee 100644
--- a/packages/uniswap/src/constants/addresses.ts
+++ b/packages/uniswap/src/constants/addresses.ts
@@ -1,5 +1,5 @@
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
const POL_MAINNET_ADDRESS = '0x455e53cbb86018ac2b8092fdcd39d8444affc3f6'
const MATIC_MAINNET_ADDRESS = '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0'
@@ -24,9 +24,9 @@ export const BRIDGED_BASE_ADDRESSES = [
]
export function getNativeAddress(chainId: UniverseChainId): string {
- return UNIVERSE_CHAIN_INFO[chainId].nativeCurrency.address
+ return getChainInfo(chainId).nativeCurrency.address
}
export function getWrappedNativeAddress(chainId: UniverseChainId): string {
- return UNIVERSE_CHAIN_INFO[chainId].wrappedNativeCurrency.address
+ return getChainInfo(chainId).wrappedNativeCurrency.address
}
diff --git a/packages/uniswap/src/constants/routing.ts b/packages/uniswap/src/constants/routing.ts
index ee46a590468..2b7b5227106 100644
--- a/packages/uniswap/src/constants/routing.ts
+++ b/packages/uniswap/src/constants/routing.ts
@@ -2,7 +2,6 @@ import { Currency, Token, WETH9 } from '@uniswap/sdk-core'
// eslint-disable-next-line no-restricted-imports
import type { ImageSourcePropType } from 'react-native'
import { CELO_LOGO, ETH_LOGO } from 'ui/src/assets'
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
import {
ARB,
BTC_BSC,
@@ -49,9 +48,10 @@ import {
nativeOnChain,
} from 'uniswap/src/constants/tokens'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
import { buildCurrencyInfo } from 'uniswap/src/features/dataApi/utils'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { isSameAddress } from 'utilities/src/addresses'
type ChainCurrencyList = {
@@ -176,11 +176,11 @@ function getNativeLogoURI(chainId: UniverseChainId = UniverseChainId.Mainnet): I
return ETH_LOGO as ImageSourcePropType
}
- return UNIVERSE_CHAIN_INFO[chainId].nativeCurrency.logo ?? (ETH_LOGO as ImageSourcePropType)
+ return getChainInfo(chainId).nativeCurrency.logo ?? (ETH_LOGO as ImageSourcePropType)
}
function getTokenLogoURI(chainId: UniverseChainId, address: string): ImageSourcePropType | string | undefined {
- const chainInfo = UNIVERSE_CHAIN_INFO[chainId]
+ const chainInfo = getChainInfo(chainId)
const networkName = chainInfo?.assetRepoNetworkName
if (isCelo(chainId) && isSameAddress(address, nativeOnChain(chainId).wrapped.address)) {
diff --git a/packages/uniswap/src/constants/tokens.ts b/packages/uniswap/src/constants/tokens.ts
index 51615dbb170..d524d1db346 100644
--- a/packages/uniswap/src/constants/tokens.ts
+++ b/packages/uniswap/src/constants/tokens.ts
@@ -1,7 +1,7 @@
/* eslint-disable max-lines */
import { Currency, NativeCurrency, Token, UNI_ADDRESSES, WETH9 } from '@uniswap/sdk-core'
import invariant from 'tiny-invariant'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export const USDC_SEPOLIA = new Token(
UniverseChainId.Sepolia,
diff --git a/packages/uniswap/src/constants/urls.ts b/packages/uniswap/src/constants/urls.ts
index 266bfc80522..d3a6d0f0d36 100644
--- a/packages/uniswap/src/constants/urls.ts
+++ b/packages/uniswap/src/constants/urls.ts
@@ -83,7 +83,8 @@ export const uniswapUrls = {
// Feature service URL's
unitagsApiUrl: `${getCloudflareApiBaseUrl(TrafficFlows.Unitags)}/v2/unitags`,
scantasticApiUrl: `${getCloudflareApiBaseUrl(TrafficFlows.Scantastic)}/v2/scantastic`,
- fiatOnRampApiUrl: `${getCloudflareApiBaseUrl(TrafficFlows.FOR)}/v2/fiat-on-ramp`,
+ fiatOnRampApiUrl: `${getCloudflareApiBaseUrl(TrafficFlows.FOR)}/v2/fiat-on-ramp`, // TODO: WALL-5189 - remove this once we finish migrating away from original FOR endpoint service
+ forApiUrl: `${getCloudflareApiBaseUrl(TrafficFlows.FOR)}/v2/FOR.v1.FORService`,
tradingApiUrl: getCloudflareApiBaseUrl(TrafficFlows.TradingApi),
// API Paths
diff --git a/packages/uniswap/src/contexts/UniswapContext.tsx b/packages/uniswap/src/contexts/UniswapContext.tsx
index 3485d243cfa..6780480d904 100644
--- a/packages/uniswap/src/contexts/UniswapContext.tsx
+++ b/packages/uniswap/src/contexts/UniswapContext.tsx
@@ -2,8 +2,8 @@ import { JsonRpcProvider } from '@ethersproject/providers'
import { Signer } from 'ethers/lib/ethers'
import { createContext, PropsWithChildren, useContext, useMemo, useState } from 'react'
import { AccountMeta } from 'uniswap/src/features/accounts/types'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { FiatOnRampCurrency } from 'uniswap/src/features/fiatOnRamp/types'
-import { UniverseChainId } from 'uniswap/src/types/chains'
import { Connector } from 'wagmi'
/** Stores objects/utils that exist on all platforms, abstracting away app-level specifics for each, in order to allow usage in cross-platform code. */
diff --git a/packages/uniswap/src/contexts/UrlContext.tsx b/packages/uniswap/src/contexts/UrlContext.tsx
new file mode 100644
index 00000000000..406a5d8bc4e
--- /dev/null
+++ b/packages/uniswap/src/contexts/UrlContext.tsx
@@ -0,0 +1,43 @@
+import { ParsedQs, parse } from 'qs'
+import { ReactNode, createContext, useContext, useMemo } from 'react'
+import { useLocation } from 'react-router-dom'
+
+interface UrlContext {
+ useParsedQueryString: () => ParsedQs
+}
+
+export const UrlContext = createContext(null)
+
+function useParsedQueryString(): ParsedQs {
+ const { search } = useLocation()
+ return useMemo(() => {
+ const hash = window.location.hash
+ const query = search || hash.substr(hash.indexOf('?'))
+
+ return query && query.length > 1 ? parse(query, { parseArrays: false, ignoreQueryPrefix: true }) : {}
+ }, [search])
+}
+
+export function ReactRouterUrlProvider({ children }: { children: ReactNode | undefined }): JSX.Element {
+ return {children}
+}
+
+export function BlankUrlProvider({ children }: { children: ReactNode | undefined }): JSX.Element {
+ const value = useMemo(() => {
+ return {
+ useParsedQueryString: (): ParsedQs => {
+ return {}
+ },
+ }
+ }, [])
+ return {children}
+}
+
+export function useUrlContext(): UrlContext {
+ const context = useContext(UrlContext)
+ if (!context) {
+ throw new Error('useUrlContext must be used within a UrlProvider')
+ }
+
+ return context
+}
diff --git a/packages/uniswap/src/data/balances/utils.tsx b/packages/uniswap/src/data/balances/utils.tsx
index 03f08491fd0..177bd8224e7 100644
--- a/packages/uniswap/src/data/balances/utils.tsx
+++ b/packages/uniswap/src/data/balances/utils.tsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
import { PortfolioBalancesQueryResult } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { useEnabledChains } from 'uniswap/src/features/settings/hooks'
+import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { logger } from 'utilities/src/logger/logger'
/**
diff --git a/packages/uniswap/src/data/graphql/uniswap-data-api/queries.graphql b/packages/uniswap/src/data/graphql/uniswap-data-api/queries.graphql
index 9c413f63ce3..5512e544159 100644
--- a/packages/uniswap/src/data/graphql/uniswap-data-api/queries.graphql
+++ b/packages/uniswap/src/data/graphql/uniswap-data-api/queries.graphql
@@ -302,6 +302,27 @@ query NftsTab(
}
}
+# We use this fragment to optimize how we render each row in the Tokens tab.
+# We should keep it small, only include the fields we need to render that row,
+# and avoid including fields that might change too often.
+fragment TokenBalanceMainParts on TokenBalance {
+ ...TokenBalanceQuantityParts
+ denominatedValue {
+ currency
+ value
+ }
+ tokenProjectMarket {
+ relativeChange24: pricePercentChange(duration: DAY) {
+ value
+ }
+ }
+}
+
+fragment TokenBalanceQuantityParts on TokenBalance {
+ id
+ quantity
+}
+
query PortfolioBalances(
$ownerAddress: String!
$valueModifiers: [PortfolioValueModifier!]
@@ -328,14 +349,8 @@ query PortfolioBalances(
# Individual portfolio token balances
tokenBalances {
- id
- quantity
+ ...TokenBalanceMainParts
isHidden
- denominatedValue {
- id
- currency
- value
- }
token {
id
address
@@ -361,11 +376,6 @@ query PortfolioBalances(
attackTypes
}
}
- tokenProjectMarket {
- relativeChange24: pricePercentChange(duration: DAY) {
- value
- }
- }
}
}
}
@@ -593,6 +603,14 @@ query TokenProjects($contracts: [ContractInput!]!) {
address
decimals
symbol
+ feeData {
+ buyFeeBps
+ sellFeeBps
+ }
+ protectionInfo {
+ result
+ attackTypes
+ }
}
}
}
@@ -952,6 +970,10 @@ query SearchTokens($searchQuery: String!, $chains: [Chain!]!) {
logoUrl
safetyLevel
}
+ feeData {
+ buyFeeBps
+ sellFeeBps
+ }
protectionInfo {
result
attackTypes
@@ -984,6 +1006,10 @@ query ExploreSearch(
result
attackTypes
}
+ feeData {
+ buyFeeBps
+ sellFeeBps
+ }
}
nftCollections(filter: $nftCollectionsFilter, first: 4) {
edges {
diff --git a/packages/uniswap/src/data/graphql/uniswap-data-api/web/RecentlySearchedAssets.graphql b/packages/uniswap/src/data/graphql/uniswap-data-api/web/RecentlySearchedAssets.graphql
index 972f691e1c2..fb2454733de 100644
--- a/packages/uniswap/src/data/graphql/uniswap-data-api/web/RecentlySearchedAssets.graphql
+++ b/packages/uniswap/src/data/graphql/uniswap-data-api/web/RecentlySearchedAssets.graphql
@@ -32,6 +32,14 @@ query RecentlySearchedAssets(
standard
address
symbol
+ feeData {
+ buyFeeBps
+ sellFeeBps
+ }
+ protectionInfo {
+ attackTypes
+ result
+ }
market(currency: USD) {
id
price {
diff --git a/packages/uniswap/src/data/graphql/uniswap-data-api/web/SimpleToken.graphql b/packages/uniswap/src/data/graphql/uniswap-data-api/web/SimpleToken.graphql
index f6f9301ed8d..2ed43374f65 100644
--- a/packages/uniswap/src/data/graphql/uniswap-data-api/web/SimpleToken.graphql
+++ b/packages/uniswap/src/data/graphql/uniswap-data-api/web/SimpleToken.graphql
@@ -17,4 +17,8 @@ fragment SimpleTokenDetails on Token {
buyFeeBps
sellFeeBps
}
+ protectionInfo {
+ attackTypes
+ result
+ }
}
diff --git a/packages/uniswap/src/data/rest/getPair.ts b/packages/uniswap/src/data/rest/getPair.ts
index 2732b4fc278..9ef90a52455 100644
--- a/packages/uniswap/src/data/rest/getPair.ts
+++ b/packages/uniswap/src/data/rest/getPair.ts
@@ -5,11 +5,11 @@ import { useQuery } from '@connectrpc/connect-query'
import { UseQueryResult } from '@tanstack/react-query'
import { getPair } from '@uniswap/client-pools/dist/pools/v1/api-PoolsService_connectquery'
import { GetPairRequest, GetPairResponse } from '@uniswap/client-pools/dist/pools/v1/api_pb'
-import { getPositionsTestTransport } from 'uniswap/src/data/rest/getPositions'
+import { uniswapGetTransport } from 'uniswap/src/data/rest/base'
export function useGetPair(
input?: PartialMessage,
enabled = true,
): UseQueryResult {
- return useQuery(getPair, input, { transport: getPositionsTestTransport, enabled, retry: false })
+ return useQuery(getPair, input, { transport: uniswapGetTransport, enabled, retry: false })
}
diff --git a/packages/uniswap/src/data/rest/getPools.ts b/packages/uniswap/src/data/rest/getPools.ts
index 3e233199605..228e7b5570d 100644
--- a/packages/uniswap/src/data/rest/getPools.ts
+++ b/packages/uniswap/src/data/rest/getPools.ts
@@ -5,11 +5,11 @@ import { useQuery } from '@connectrpc/connect-query'
import { UseQueryResult } from '@tanstack/react-query'
import { listPools } from '@uniswap/client-pools/dist/pools/v1/api-PoolsService_connectquery'
import { ListPoolsRequest, ListPoolsResponse } from '@uniswap/client-pools/dist/pools/v1/api_pb'
-import { getPositionsTestTransport } from 'uniswap/src/data/rest/getPositions'
+import { uniswapGetTransport } from 'uniswap/src/data/rest/base'
export function useGetPoolsByTokens(
input?: PartialMessage,
enabled = true,
): UseQueryResult {
- return useQuery(listPools, input, { transport: getPositionsTestTransport, enabled })
+ return useQuery(listPools, input, { transport: uniswapGetTransport, enabled })
}
diff --git a/packages/uniswap/src/data/rest/getPosition.ts b/packages/uniswap/src/data/rest/getPosition.ts
index 96207d3c30f..1b8e9a69d16 100644
--- a/packages/uniswap/src/data/rest/getPosition.ts
+++ b/packages/uniswap/src/data/rest/getPosition.ts
@@ -5,10 +5,10 @@ import { useQuery } from '@connectrpc/connect-query'
import { UseQueryResult } from '@tanstack/react-query'
import { getPosition } from '@uniswap/client-pools/dist/pools/v1/api-PoolsService_connectquery'
import { GetPositionRequest, GetPositionResponse } from '@uniswap/client-pools/dist/pools/v1/api_pb'
-import { getPositionsTestTransport } from 'uniswap/src/data/rest/getPositions'
+import { uniswapGetTransport } from 'uniswap/src/data/rest/base'
export function useGetPositionQuery(
input?: PartialMessage,
): UseQueryResult {
- return useQuery(getPosition, input, { transport: getPositionsTestTransport, enabled: !!input })
+ return useQuery(getPosition, input, { transport: uniswapGetTransport, enabled: !!input })
}
diff --git a/packages/uniswap/src/data/rest/getPositions.ts b/packages/uniswap/src/data/rest/getPositions.ts
index bf842c09384..017e6b136da 100644
--- a/packages/uniswap/src/data/rest/getPositions.ts
+++ b/packages/uniswap/src/data/rest/getPositions.ts
@@ -2,18 +2,18 @@
import { PartialMessage } from '@bufbuild/protobuf'
import { ConnectError } from '@connectrpc/connect'
import { useQuery } from '@connectrpc/connect-query'
-import { createConnectTransport } from '@connectrpc/connect-web'
-import { UseQueryResult } from '@tanstack/react-query'
+import { UseQueryResult, keepPreviousData } from '@tanstack/react-query'
import { listPositions } from '@uniswap/client-pools/dist/pools/v1/api-PoolsService_connectquery'
import { ListPositionsRequest, ListPositionsResponse } from '@uniswap/client-pools/dist/pools/v1/api_pb'
-
-export const getPositionsTestTransport = createConnectTransport({
- baseUrl: 'https://9bxqhlmige.execute-api.us-east-2.amazonaws.com', // TODO: replace with the prod url and update in csp.json as well
-})
+import { uniswapGetTransport } from 'uniswap/src/data/rest/base'
export function useGetPositionsQuery(
input?: PartialMessage,
disabled?: boolean,
): UseQueryResult {
- return useQuery(listPositions, input, { transport: getPositionsTestTransport, enabled: !!input && !disabled })
+ return useQuery(listPositions, input, {
+ transport: uniswapGetTransport,
+ enabled: !!input && !disabled,
+ placeholderData: keepPreviousData,
+ })
}
diff --git a/packages/uniswap/src/data/tradingApi/api.json b/packages/uniswap/src/data/tradingApi/api.json
index 6cf5558aaf3..58ae1472b72 100644
--- a/packages/uniswap/src/data/tradingApi/api.json
+++ b/packages/uniswap/src/data/tradingApi/api.json
@@ -1 +1 @@
-{"openapi":"3.0.0","servers":[{"description":"Uniswap trading APIs Beta","url":"https://beta.trade-api.gateway.uniswap.org/v1"},{"description":"Uniswap trading APIs","url":"https://trade-api.gateway.uniswap.org/v1"}],"info":{"version":"1.0.0","title":"Token Trading","description":"Uniswap trading APIs for fungible tokens."},"paths":{"/check_approval":{"post":{"tags":["Approval"],"summary":"Check if token approval is required","description":"Checks if the swapper has the required approval. If the swapper does not have the required approval, then the response will include the transaction to approve the token. If the swapper has the required approval, then the response will be empty. If the parameter `includeGasInfo` is set to `true`, then the response will include the gas fee for the approval transaction.","operationId":"check_approval","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ApprovalSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/ApprovalNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/quote":{"post":{"tags":["Quote"],"summary":"Get a quote","description":"Get a quote according to the provided configuration. Optionally adds a fee to the quote according to the API key being used. The fee is **ALWAYS** taken from the output token. If there is a fee and the trade is `EXACT_INPUT`, then the output amount will **NOT** include the fee subtraction. For `EXACT_INPUT` swaps, use `portionBips` to calculate the fee from the quoted amount. If there is a fee and the trade is `EXACT_OUTPUT`, then the input amount will **NOT** include the fee addition to account for the fee. For `EXACT_OUTPUT` swaps, use `portionAmount` to get the fee. \n \n We also support Wrapping and Unwrapping of native tokens on their respective chains. Wrapping and Unwrapping only works for when `routingPreference` is `CLASSIC`, `BEST_PRICE`, or `BEST_PRICE_V2`. We do not support `UNISWAPX` or `UNISWAPX_V2` for these actions.","operationId":"aggregator_quote","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/universalRouterVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/QuoteSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/order":{"post":{"tags":["Order"],"summary":"Create a gasless order","description":"Submits a new gasless encoded order. The order will be validated and if valid, will be submitted to the filler network. The network will try to fill the order at the quoted `startAmount`, and if not, the amount will start decaying until the `endAmount` is reached. While the order is within `decayEndTime`, the `orderStatus` is `open`. If the order does not get filled after the `decayEndTime` has passed, that is reflected in the `expired` `orderStatus`. then The order will be filled at the best price possible. Once the order is filled, `orderStatus` becomes `filled`.","operationId":"post_order","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderRequest"}}}},"responses":{"201":{"$ref":"#/components/responses/OrderSuccess201"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/orders":{"get":{"tags":["Order"],"summary":"Get gasless orders","description":"Retrieve gasless orders filtered by query param(s). Some fields on the order can be used as query param.","operationId":"get_order","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/orderTypeParam"},{"$ref":"#/components/parameters/orderIdParam"},{"$ref":"#/components/parameters/orderIdsParam"},{"$ref":"#/components/parameters/limitParam"},{"$ref":"#/components/parameters/orderStatusParam"},{"$ref":"#/components/parameters/swapperParam"},{"$ref":"#/components/parameters/sortKeyParam"},{"$ref":"#/components/parameters/sortParam"},{"$ref":"#/components/parameters/fillerParam"},{"$ref":"#/components/parameters/cursorParam"}],"responses":{"200":{"$ref":"#/components/responses/OrdersSuccess200"},"400":{"$ref":"#/components/responses/OrdersBadRequest400"},"404":{"$ref":"#/components/responses/OrdersNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/swap":{"post":{"tags":["Swap"],"summary":"Create swap calldata","description":"Create the calldata for a swap transaction (including wrap/unwrap) against the Uniswap Protocols. If the `quote` parameter includes the fee parameters, then the calldata will include the fee disbursement. The gas estimates will be **more precise** when the the response calldata would be valid if submitted on-chain.","operationId":"create_swap_transaction","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSwapRequest"}}}},"parameters":[{"$ref":"#/components/parameters/universalRouterVersionHeader"}],"responses":{"200":{"$ref":"#/components/responses/CreateSwapSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/SwapUnauthorized401"},"404":{"$ref":"#/components/responses/SwapNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/swaps":{"get":{"tags":["Swap"],"summary":"Get swaps status","description":"Get the status of a swap or bridge transactions.","operationId":"get_swaps","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/transactionHashesParam"},{"$ref":"#/components/parameters/chainIdParam"}],"responses":{"200":{"$ref":"#/components/responses/GetSwapsSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"404":{"$ref":"#/components/responses/SwapNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/indicative_quote":{"post":{"tags":["IndicativeQuote"],"summary":"Get an indicative quote","description":"Get an indicative quote according to the provided configuration. The quote will not include a fee.","operationId":"indicative_quote","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndicativeQuoteRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/IndicativeQuoteSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/send":{"post":{"tags":["Send"],"summary":"Create send calldata","description":"Create the calldata for a send transaction.","operationId":"create_send","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSendRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/CreateSendSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/SendNotFound404"},"429":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/swappable_tokens":{"get":{"tags":["SwappableTokens"],"summary":"Get swappable tokens","description":"Get the swappable tokens for the given configuration. Either tokenIn (with tokenInChainId or (tokenInChainId and tokenOutChainId)) or tokenOut (with tokenOutChainId or (tokenOutChainId and tokenInChainId)) must be provided but not both.","operationId":"get_swappable_tokens","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/tokenInParam"},{"$ref":"#/components/parameters/tokenOutParam"},{"$ref":"#/components/parameters/bridgeTokenInChainIdParam"},{"$ref":"#/components/parameters/bridgeTokenOutChainIdParam"}],"responses":{"200":{"$ref":"#/components/responses/GetSwappableTokensSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"429":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/limit_order_quote":{"post":{"tags":["LimitOrderQuote"],"summary":"Get a limit order quote","description":"Get a quote for a limit order according to the provided configuration.","operationId":"get_limit_order_quote","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitOrderQuoteRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/LimitOrderQuoteSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/approve":{"post":{"tags":["Liquidity"],"summary":"Check if tokens and permits need to be approved to add liquidity","description":"Checks if the wallet address has the required approvals. If the wallet address does not have the required approval, then the response will include the transactions to approve the tokens. If the wallet address has the required approval, then the response will be empty for the corresponding tokens. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the approval transactions.","operationId":"check_approval_lp","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckApprovalLPRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/CheckApprovalLPSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/ApprovalNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/create":{"post":{"tags":["Liquidity"],"summary":"Create pool and position calldata","description":"Create pool and position calldata. If the pool is not yet created, then the response will include the transaction to create the new pool with the initial price. If the pool is already created, then the response will not have the transaction to create the pool. The response will also have the transaction to create the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the creation transactions.","operationId":"create_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/CreateLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/increase":{"post":{"tags":["Liquidity"],"summary":"Increase LP position calldata","description":"The response will also have the transaction to increase the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the increase transaction.","operationId":"increase_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncreaseLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/IncreaseLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/decrease":{"post":{"tags":["Liquidity"],"summary":"Decrease LP position calldata","description":"The response will also have the transaction to decrease the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the decrease transaction.","operationId":"decrease_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecreaseLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/DecreaseLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/claim":{"post":{"tags":["Liquidity"],"summary":"Claim LP fees calldata","description":"The response will also have the transaction to claim the fees for an LP position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the claim transaction.","operationId":"claim_lp_fees","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimLPFeesRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ClaimLPFeesSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/migrate":{"post":{"tags":["Liquidity"],"summary":"Migrate LP position calldata","description":"The response will also have the transaction to migrate the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the migrate transaction.","operationId":"migrate_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrateLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/MigrateLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}}},"components":{"responses":{"OrdersSuccess200":{"description":"The request orders matching the query parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOrdersResponse"}}}},"OrderSuccess201":{"description":"Encoded order submitted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderResponse"}}}},"QuoteSuccess200":{"description":"Quote request successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"LimitOrderQuoteSuccess200":{"description":"Limit Order Quote request successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitOrderQuoteResponse"}}}},"CheckApprovalLPSuccess200":{"description":"Approve LP successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckApprovalLPResponse"}}}},"ApprovalSuccess200":{"description":"Check approval successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalResponse"}}}},"CreateSendSuccess200":{"description":"Create send successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSendResponse"}}}},"CreateSwapSuccess200":{"description":"Create swap successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSwapResponse"}}}},"GetSwapsSuccess200":{"description":"Get swap successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSwapsResponse"}}}},"GetSwappableTokensSuccess200":{"description":"Get swappable tokens successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSwappableTokensResponse"}}}},"CreateLPPositionSuccess200":{"description":"Create LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLPPositionResponse"}}}},"IncreaseLPPositionSuccess200":{"description":"Create LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncreaseLPPositionResponse"}}}},"DecreaseLPPositionSuccess200":{"description":"Decrease LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecreaseLPPositionResponse"}}}},"ClaimLPFeesSuccess200":{"description":"Claim LP Fees successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimLPFeesResponse"}}}},"MigrateLPPositionSuccess200":{"description":"Migrate LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrateLPPositionResponse"}}}},"BadRequest400":{"description":"RequestValidationError, Bad Input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err400"}}}},"ApprovalUnauthorized401":{"description":"UnauthorizedError eg. Account is blocked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err401"}}}},"ApprovalNotFound404":{"description":"ResourceNotFound eg. Token allowance not found or Gas info not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"Unauthorized401":{"description":"UnauthorizedError eg. Account is blocked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err401"}}}},"QuoteNotFound404":{"description":"ResourceNotFound eg. No quotes available or Gas fee/price not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"SendNotFound404":{"description":"ResourceNotFound eg. Gas fee not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"SwapBadRequest400":{"description":"RequestValidationError, Bad Input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err400"}}}},"SwapUnauthorized401":{"description":"UnauthorizedError eg. Account is blocked or Fee is not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err401"}}}},"SwapNotFound404":{"description":"ResourceNotFound eg. No quotes available or Gas fee/price not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"OrdersNotFound404":{"description":"Orders not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"LPNotFound404":{"description":"ResourceNotFound eg. Cant Find LP Position.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"OrdersBadRequest400":{"description":"RequestValidationError eg. Token allowance not valid or Insufficient Funds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err400"}}}},"RateLimitedErr429":{"description":"Ratelimited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err429"}}}},"InternalErr500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err500"}}}},"Timeout504":{"description":"Request duration limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err504"}}}},"IndicativeQuoteSuccess200":{"description":"Indicative quote request successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndicativeQuoteResponse"}}}}},"schemas":{"NullablePermit":{"allOf":[{"$ref":"#/components/schemas/Permit"},{"type":"object","nullable":true}]},"TokenAmount":{"type":"string"},"SwapStatus":{"type":"string","enum":["PENDING","SUCCESS","NOT_FOUND","FAILED","EXPIRED"]},"GetSwapsResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"swaps":{"type":"array","items":{"type":"object","properties":{"swapType":{"$ref":"#/components/schemas/Routing"},"status":{"$ref":"#/components/schemas/SwapStatus"},"txHash":{"type":"string"},"swapId":{"type":"number"}}}}},"required":["requestId","status"]},"GetSwappableTokensResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"tokens":{"type":"array","items":{"type":"object","properties":{"address":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"name":{"type":"string"},"symbol":{"type":"string"},"project":{"$ref":"#/components/schemas/TokenProject"},"isSpam":{"type":"boolean"},"decimals":{"type":"number"}},"required":["address","chainId","name","symbol","project","decimals"]}}},"required":["requestId","tokens"]},"CreateSwapRequest":{"type":"object","description":"The parameters **signature** and **permitData** should only be included if *permitData* was returned from **/quote**.","properties":{"quote":{"oneOf":[{"$ref":"#/components/schemas/ClassicQuote"},{"$ref":"#/components/schemas/WrapUnwrapQuote"},{"$ref":"#/components/schemas/BridgeQuote"}]},"signature":{"type":"string","description":"The signed permit."},"includeGasInfo":{"type":"boolean","default":false,"deprecated":true,"description":"Use `refreshGasPrice` instead."},"refreshGasPrice":{"type":"boolean","default":false,"description":"If true, the gas price will be re-fetched from the network."},"simulateTransaction":{"type":"boolean","default":false,"description":"If true, the transaction will be simulated. If the simulation results on an onchain error, endpoint will return an error."},"permitData":{"allOf":[{"$ref":"#/components/schemas/Permit"}]},"safetyMode":{"$ref":"#/components/schemas/SwapSafetyMode"},"deadline":{"type":"integer","description":"The deadline for the swap in unix timestamp format. If the deadline is not defined OR in the past then the default deadline is 30 minutes."},"urgency":{"$ref":"#/components/schemas/Urgency"}},"required":["quote"]},"CreateSendRequest":{"type":"object","properties":{"sender":{"$ref":"#/components/schemas/Address"},"recipient":{"$ref":"#/components/schemas/Address"},"token":{"$ref":"#/components/schemas/Address"},"amount":{"$ref":"#/components/schemas/TokenAmount"},"chainId":{"$ref":"#/components/schemas/ChainId"},"urgency":{"$ref":"#/components/schemas/Urgency"}},"required":["sender","recipient","token","amount"]},"UniversalRouterVersion":{"type":"string","enum":["1.2","2.0"],"default":"1.2"},"Address":{"type":"string","pattern":"^(0x)?[0-9a-fA-F]{40}$"},"Position":{"type":"object","properties":{"pool":{"$ref":"#/components/schemas/Pool"},"tickLower":{"type":"number"},"tickUpper":{"type":"number"}},"required":["pool"]},"Pool":{"type":"object","properties":{"token0":{"$ref":"#/components/schemas/Address"},"token1":{"$ref":"#/components/schemas/Address"},"fee":{"type":"number"},"tickSpacing":{"type":"number"},"hooks":{"$ref":"#/components/schemas/Address"}},"required":["token0","token1"]},"ClassicGasUseEstimateUSD":{"description":"The gas fee you would pay if you opted for a CLASSIC swap over a Uniswap X order in terms of USD.","type":"string"},"CreateSwapResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"swap":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}},"required":["requestId","swap"]},"CreateSendResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"send":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"},"gasFeeUSD":{"type":"number"}},"required":["requestId","send"]},"QuoteResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"quote":{"$ref":"#/components/schemas/Quote"},"routing":{"$ref":"#/components/schemas/Routing"},"permitData":{"$ref":"#/components/schemas/NullablePermit"}},"required":["routing","quote","permitData","requestId"]},"LimitOrderQuoteResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"quote":{"$ref":"#/components/schemas/DutchQuote"},"routing":{"type":"string","enum":["LIMIT_ORDER"]},"permitData":{"$ref":"#/components/schemas/NullablePermit"}},"required":["routing","quote","permitData","requestId"]},"QuoteRequest":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/TradeType"},"amount":{"type":"string"},"tokenInChainId":{"$ref":"#/components/schemas/ChainId"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"},"tokenIn":{"type":"string"},"tokenOut":{"type":"string"},"swapper":{"$ref":"#/components/schemas/Address"},"slippageTolerance":{"description":"For **Classic** swaps, the slippage tolerance is the maximum amount the price can change between the time the transaction is submitted and the time it is executed. The slippage tolerance is represented as a percentage of the total value of the swap. \n\n Slippage tolerance works differently in **DutchLimit** swaps, it does not set a limit on the Spread in an order. See [here](https://uniswap-docs.readme.io/reference/faqs#why-do-the-uniswapx-quotes-have-more-slippage-than-the-tolerance-i-set) for more information. \n\n **NOTE**: slippage is in terms of trade type. If the trade type is `EXACT_INPUT`, then the slippage is in terms of the output token. If the trade type is `EXACT_OUTPUT`, then the slippage is in terms of the input token.","type":"number"},"autoSlippage":{"$ref":"#/components/schemas/AutoSlippage"},"routingPreference":{"$ref":"#/components/schemas/RoutingPreference"},"protocols":{"$ref":"#/components/schemas/Protocols"},"spreadOptimization":{"$ref":"#/components/schemas/SpreadOptimization"},"urgency":{"$ref":"#/components/schemas/Urgency"}},"required":["type","amount","tokenInChainId","tokenOutChainId","tokenIn","tokenOut","swapper"]},"LimitOrderQuoteRequest":{"type":"object","properties":{"swapper":{"$ref":"#/components/schemas/Address"},"limitPrice":{"type":"string"},"amount":{"type":"string"},"orderDeadline":{"type":"number"},"type":{"$ref":"#/components/schemas/TradeType"},"tokenIn":{"type":"string"},"tokenOut":{"type":"string"},"tokenInChainId":{"$ref":"#/components/schemas/ChainId"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"}},"required":["swapper","type","amount","tokenIn","tokenOut","tokenInChainId","tokenOutChainId"]},"GetOrdersResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"orders":{"type":"array","items":{"$ref":"#/components/schemas/UniswapXOrder"}},"cursor":{"type":"string"}},"required":["orders","requestId"]},"OrderResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"orderId":{"type":"string"},"orderStatus":{"$ref":"#/components/schemas/OrderStatus"}},"required":["requestId","orderId","orderStatus"]},"OrderRequest":{"type":"object","properties":{"signature":{"type":"string","description":"The signed permit."},"quote":{"oneOf":[{"$ref":"#/components/schemas/DutchQuote"},{"$ref":"#/components/schemas/DutchQuoteV2"},{"$ref":"#/components/schemas/PriorityQuote"}]},"routing":{"$ref":"#/components/schemas/Routing"}},"required":["signature","quote"]},"Urgency":{"type":"string","enum":["normal","fast","urgent"],"description":"The urgency determines the urgency of the transaction. The default value is `urgent`.","default":"urgent"},"Protocols":{"type":"array","items":{"$ref":"#/components/schemas/ProtocolItems"},"description":"The protocols to use for the swap/order. If the `protocols` field is defined, then you can only set the `routingPreference` to `BEST_PRICE`"},"Err400":{"type":"object","properties":{"errorCode":{"default":"RequestValidationError","type":"string"},"detail":{"type":"string"}}},"Err401":{"type":"object","properties":{"errorCode":{"default":"UnauthorizedError","type":"string"},"detail":{"type":"string"}}},"Err404":{"type":"object","properties":{"errorCode":{"enum":["ResourceNotFound","QuoteAmountTooLowError"],"type":"string"},"detail":{"type":"string"}}},"Err429":{"type":"object","properties":{"errorCode":{"default":"Ratelimited","type":"string"},"detail":{"type":"string"}}},"Err500":{"type":"object","properties":{"errorCode":{"default":"InternalServerError","type":"string"},"detail":{"type":"string"}}},"Err504":{"type":"object","properties":{"errorCode":{"default":"Timeout","type":"string"},"detail":{"type":"string"}}},"ChainId":{"type":"number","enum":[1,10,56,137,8453,42161,81457,43114,42220,7777777,324,11155111,1301,480]},"OrderInput":{"type":"object","properties":{"token":{"type":"string"},"startAmount":{"type":"string"},"endAmount":{"type":"string"}},"required":["token"]},"OrderOutput":{"type":"object","properties":{"token":{"type":"string"},"startAmount":{"type":"string"},"endAmount":{"type":"string"},"isFeeOutput":{"type":"boolean"},"recipient":{"type":"string"}},"required":["token"]},"CosignerData":{"type":"object","properties":{"decayStartTime":{"type":"number"},"decayEndTime":{"type":"number"},"exclusiveFiller":{"type":"string"},"inputOverride":{"type":"string"},"outputOverrides":{"type":"array","items":{"type":"string"}}}},"SettledAmount":{"type":"object","properties":{"tokenOut":{"$ref":"#/components/schemas/Address"},"amountOut":{"type":"string"},"tokenIn":{"$ref":"#/components/schemas/Address"},"amountIn":{"type":"string"}}},"OrderType":{"type":"string","enum":["DutchLimit","Dutch","Dutch_V2"]},"OrderTypeQuery":{"type":"string","enum":["Dutch","Dutch_V2","Dutch_V1_V2","Limit","Priority"]},"UniswapXOrder":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/OrderType"},"encodedOrder":{"type":"string"},"signature":{"type":"string"},"nonce":{"type":"string"},"orderStatus":{"$ref":"#/components/schemas/OrderStatus"},"orderId":{"type":"string"},"chainId":{"$ref":"#/components/schemas/ChainId"},"quoteId":{"type":"string"},"swapper":{"type":"string"},"txHash":{"type":"string"},"input":{"$ref":"#/components/schemas/OrderInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/OrderOutput"}},"settledAmounts":{"type":"array","items":{"$ref":"#/components/schemas/SettledAmount"}},"cosignature":{"type":"string"},"cosignerData":{"$ref":"#/components/schemas/CosignerData"}},"required":["encodedOrder","signature","nonce","orderId","orderStatus","chainId","type"]},"SortKey":{"type":"string","enum":["createdAt"]},"OrderId":{"type":"string"},"OrderIds":{"type":"string"},"OrderStatus":{"type":"string","enum":["open","expired","error","cancelled","filled","unverified","insufficient-funds"]},"Permit":{"type":"object","properties":{"domain":{"type":"object"},"values":{"type":"object"},"types":{"type":"object"}}},"TokenProject":{"type":"object","properties":{"logo":{"$ref":"#/components/schemas/TokenProjectLogo","nullable":true},"safetyLevel":{"$ref":"#/components/schemas/SafetyLevel"},"isSpam":{"type":"boolean"}},"required":["logo","safetyLevel","isSpam"]},"TokenProjectLogo":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"DutchInput":{"type":"object","properties":{"startAmount":{"type":"string"},"endAmount":{"type":"string"},"token":{"type":"string"}},"required":["startAmount","endAmount","type"]},"DutchOutput":{"type":"object","properties":{"startAmount":{"type":"string"},"endAmount":{"type":"string"},"token":{"type":"string"},"recipient":{"type":"string"}},"required":["startAmount","endAmount","token","recipient"]},"DutchOrderInfo":{"type":"object","properties":{"chainId":{"$ref":"#/components/schemas/ChainId"},"nonce":{"type":"string"},"reactor":{"type":"string"},"swapper":{"type":"string"},"deadline":{"type":"number"},"additionalValidationContract":{"type":"string"},"additionalValidationData":{"type":"string"},"decayStartTime":{"type":"number"},"decayEndTime":{"type":"number"},"exclusiveFiller":{"type":"string"},"exclusivityOverrideBps":{"type":"string"},"input":{"$ref":"#/components/schemas/DutchInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/DutchOutput"}}},"required":["chainId","nonce","reactor","swapper","deadline","validationContract","validationData","startTime","endTime","exclusiveFiller","exclusivityOverrideBps","input","outputs"]},"DutchOrderInfoV2":{"type":"object","properties":{"chainId":{"$ref":"#/components/schemas/ChainId"},"nonce":{"type":"string"},"reactor":{"type":"string"},"swapper":{"type":"string"},"deadline":{"type":"number"},"additionalValidationContract":{"type":"string"},"additionalValidationData":{"type":"string"},"input":{"$ref":"#/components/schemas/DutchInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/DutchOutput"}},"cosigner":{"$ref":"#/components/schemas/Address"}},"required":["chainId","nonce","reactor","swapper","deadline","validationContract","validationData","startTime","endTime","exclusiveFiller","exclusivityOverrideBps","input","outputs"]},"DutchQuote":{"type":"object","properties":{"encodedOrder":{"type":"string"},"orderId":{"type":"string"},"orderInfo":{"$ref":"#/components/schemas/DutchOrderInfo"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"quoteId":{"type":"string"},"slippageTolerance":{"type":"number"},"classicGasUseEstimateUSD":{"$ref":"#/components/schemas/ClassicGasUseEstimateUSD"}},"required":["encodedOrder","orderInfo","orderId"]},"DutchQuoteV2":{"type":"object","properties":{"encodedOrder":{"type":"string"},"orderId":{"type":"string"},"orderInfo":{"$ref":"#/components/schemas/DutchOrderInfoV2"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"quoteId":{"type":"string"},"slippageTolerance":{"type":"number"},"deadlineBufferSecs":{"type":"number"},"classicGasUseEstimateUSD":{"$ref":"#/components/schemas/ClassicGasUseEstimateUSD"}},"required":["encodedOrder","orderInfo","orderId"]},"PriorityInput":{"type":"object","properties":{"amount":{"type":"string"},"token":{"type":"string"},"mpsPerPriorityFeeWei":{"type":"string"}},"required":["amount","token","mpsPerPriorityFeeWei"]},"PriorityOutput":{"type":"object","properties":{"amount":{"type":"string"},"token":{"type":"string"},"recipient":{"type":"string"},"mpsPerPriorityFeeWei":{"type":"string"}},"required":["amount","token","recipient","mpsPerPriorityFeeWei"]},"PriorityOrderInfo":{"type":"object","properties":{"chainId":{"$ref":"#/components/schemas/ChainId"},"nonce":{"type":"string"},"reactor":{"type":"string"},"swapper":{"type":"string"},"deadline":{"type":"number"},"additionalValidationContract":{"type":"string"},"additionalValidationData":{"type":"string"},"auctionStartBlock":{"type":"string"},"baselinePriorityFeeWei":{"type":"string"},"input":{"$ref":"#/components/schemas/PriorityInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/PriorityOutput"}},"cosigner":{"$ref":"#/components/schemas/Address"}},"required":["chainId","nonce","reactor","swapper","deadline","validationContract","validationData","auctionStartBlock","baselinePriorityFeeWei","input","outputs","cosigner"]},"PriorityQuote":{"type":"object","properties":{"encodedOrder":{"type":"string"},"orderId":{"type":"string"},"orderInfo":{"$ref":"#/components/schemas/PriorityOrderInfo"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"quoteId":{"type":"string"},"slippageTolerance":{"type":"number"},"deadlineBufferSecs":{"type":"number"},"classicGasUseEstimateUSD":{"$ref":"#/components/schemas/ClassicGasUseEstimateUSD"}},"required":["encodedOrder","orderInfo","orderId"]},"BridgeQuote":{"type":"object","properties":{"quoteId":{"type":"string"},"chainId":{"$ref":"#/components/schemas/ChainId"},"destinationChainId":{"$ref":"#/components/schemas/ChainId"},"swapper":{"$ref":"#/components/schemas/Address"},"input":{"$ref":"#/components/schemas/ClassicInput"},"output":{"$ref":"#/components/schemas/ClassicOutput"},"tradeType":{"$ref":"#/components/schemas/TradeType"},"quoteTimestamp":{"type":"number"},"gasPrice":{"type":"string"},"maxFeePerGas":{"type":"string"},"maxPriorityFeePerGas":{"type":"string"},"gasFee":{"type":"string"},"gasUseEstimate":{"type":"string"},"gasFeeUSD":{"type":"string"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"estimatedFillTimeMs":{"type":"number"}}},"SafetyLevel":{"type":"string","enum":["BLOCKED","MEDIUM_WARNING","STRONG_WARNING","VERIFIED"]},"TradeType":{"type":"string","enum":["EXACT_INPUT","EXACT_OUTPUT"]},"Routing":{"type":"string","enum":["DUTCH_LIMIT","CLASSIC","DUTCH_V2","BRIDGE","LIMIT_ORDER","PRIORITY"]},"Quote":{"oneOf":[{"$ref":"#/components/schemas/DutchQuote"},{"$ref":"#/components/schemas/ClassicQuote"},{"$ref":"#/components/schemas/WrapUnwrapQuote"},{"$ref":"#/components/schemas/DutchQuoteV2"},{"$ref":"#/components/schemas/BridgeQuote"},{"$ref":"#/components/schemas/PriorityQuote"}]},"CheckApprovalLPRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"token0":{"$ref":"#/components/schemas/Address"},"token1":{"$ref":"#/components/schemas/Address"},"positionToken":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"walletAddress":{"$ref":"#/components/schemas/Address"},"amount0":{"type":"string"},"amount1":{"type":"string"},"positionAmount":{"type":"string"},"simulateTransaction":{"type":"boolean"}}},"CheckApprovalLPResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"token0Approval":{"$ref":"#/components/schemas/TransactionRequest"},"token1Approval":{"$ref":"#/components/schemas/TransactionRequest"},"positionTokenApproval":{"$ref":"#/components/schemas/TransactionRequest"},"permitData":{"$ref":"#/components/schemas/NullablePermit"},"gasFeeToken0Approval":{"type":"string"},"gasFeeToken1Approval":{"type":"string"},"gasFeePositionTokenApproval":{"type":"string"}}},"ApprovalRequest":{"type":"object","properties":{"walletAddress":{"$ref":"#/components/schemas/Address"},"token":{"$ref":"#/components/schemas/Address"},"amount":{"$ref":"#/components/schemas/TokenAmount"},"chainId":{"$ref":"#/components/schemas/ChainId"},"urgency":{"$ref":"#/components/schemas/Urgency"},"includeGasInfo":{"type":"boolean","default":false},"tokenOut":{"$ref":"#/components/schemas/Address"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"}},"required":["walletAddress","token","amount"]},"ApprovalResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"approval":{"$ref":"#/components/schemas/TransactionRequest"},"cancel":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"},"cancelGasFee":{"type":"string"}},"required":["requestId","approval","cancel"]},"ClassicQuote":{"type":"object","properties":{"input":{"$ref":"#/components/schemas/ClassicInput"},"output":{"$ref":"#/components/schemas/ClassicOutput"},"swapper":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"slippage":{"type":"number"},"tradeType":{"$ref":"#/components/schemas/TradeType"},"gasFee":{"type":"string","description":"The gas fee in terms of wei. It does NOT include the additional gas for token approvals."},"gasFeeUSD":{"type":"string","description":"The gas fee in terms of USD. It does NOT include the additional gas for token approvals."},"gasFeeQuote":{"type":"string","description":"The gas fee in terms of the quoted currency. It does NOT include the additional gas for token approvals."},"route":{"type":"array","items":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/V3PoolInRoute"},{"$ref":"#/components/schemas/V2PoolInRoute"},{"$ref":"#/components/schemas/V4PoolInRoute"}]}}},"portionBips":{"type":"number","description":"The portion of the swap that will be taken as a fee. The fee will be taken from the output token."},"portionAmount":{"type":"string","description":"The amount of the swap that will be taken as a fee. The fee will be taken from the output token."},"portionRecipient":{"$ref":"#/components/schemas/Address"},"routeString":{"type":"string","description":"The route in string format."},"quoteId":{"type":"string","description":"The quote id. Used for analytics purposes."},"gasUseEstimate":{"type":"string","description":"The estimated gas use. It does NOT include the additional gas for token approvals."},"blockNumber":{"type":"string","description":"The current block number."},"gasPrice":{"type":"string","description":"The gas price in terms of wei for pre EIP1559 transactions."},"maxFeePerGas":{"type":"string","description":"The maximum fee per gas in terms of wei for EIP1559 transactions."},"maxPriorityFeePerGas":{"type":"string","description":"The maximum priority fee per gas in terms of wei for EIP1559 transactions."},"txFailureReasons":{"type":"array","items":{"$ref":"#/components/schemas/TransactionFailureReason"}},"priceImpact":{"type":"number","description":"The impact the trade has on the market price of the pool, between 0-100 percent"}}},"WrapUnwrapQuote":{"type":"object","properties":{"swapper":{"$ref":"#/components/schemas/Address"},"input":{"$ref":"#/components/schemas/ClassicInput"},"output":{"$ref":"#/components/schemas/ClassicOutput"},"chainId":{"$ref":"#/components/schemas/ChainId"},"tradeType":{"$ref":"#/components/schemas/TradeType"},"gasFee":{"type":"string","description":"The gas fee in terms of wei."},"gasFeeUSD":{"type":"string","description":"The gas fee in terms of USD."},"gasFeeQuote":{"type":"string","description":"The gas fee in terms of the quoted currency."},"gasUseEstimate":{"type":"string","description":"The estimated gas use."},"gasPrice":{"type":"string","description":"The gas price in terms of wei for pre EIP1559 transactions."},"maxFeePerGas":{"type":"string","description":"The maximum fee per gas in terms of wei for EIP1559 transactions."},"maxPriorityFeePerGas":{"type":"string","description":"The maximum priority fee per gas in terms of wei for EIP1559 transactions."}}},"TokenInRoute":{"type":"object","properties":{"address":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"symbol":{"type":"string"},"decimals":{"type":"string"},"buyFeeBps":{"type":"string"},"sellFeeBps":{"type":"string"}}},"V2Reserve":{"type":"object","properties":{"token":{"$ref":"#/components/schemas/TokenInRoute"},"quotient":{"type":"string"}}},"V2PoolInRoute":{"type":"object","properties":{"type":{"type":"string","default":"v2-pool"},"address":{"$ref":"#/components/schemas/Address"},"tokenIn":{"$ref":"#/components/schemas/TokenInRoute"},"tokenOut":{"$ref":"#/components/schemas/TokenInRoute"},"reserve0":{"$ref":"#/components/schemas/V2Reserve"},"reserve1":{"$ref":"#/components/schemas/V2Reserve"},"amountIn":{"type":"string"},"amountOut":{"type":"string"}}},"V3PoolInRoute":{"type":"object","properties":{"type":{"type":"string","default":"v3-pool"},"address":{"$ref":"#/components/schemas/Address"},"tokenIn":{"$ref":"#/components/schemas/TokenInRoute"},"tokenOut":{"$ref":"#/components/schemas/TokenInRoute"},"sqrtRatioX96":{"type":"string"},"liquidity":{"type":"string"},"tickCurrent":{"type":"string"},"fee":{"type":"string"},"amountIn":{"type":"string"},"amountOut":{"type":"string"}}},"V4PoolInRoute":{"type":"object","properties":{"type":{"type":"string","default":"v4-pool"},"address":{"$ref":"#/components/schemas/Address"},"tokenIn":{"$ref":"#/components/schemas/TokenInRoute"},"tokenOut":{"$ref":"#/components/schemas/TokenInRoute"},"sqrtRatioX96":{"type":"string"},"liquidity":{"type":"string"},"tickCurrent":{"type":"string"},"fee":{"type":"string"},"tickSpacing":{"type":"string"},"hooks":{"type":"string"},"amountIn":{"type":"string"},"amountOut":{"type":"string"}},"required":["type","address","tokenIn","tokenOut","sqrtRatioX96","liquidity","tickCurrent","fee","tickSpacing","hooks"]},"TransactionHash":{"type":"string","pattern":"^(0x)?[0-9a-fA-F]{64}$"},"ClassicInput":{"type":"object","properties":{"token":{"$ref":"#/components/schemas/Address"},"amount":{"type":"string"}}},"ClassicOutput":{"type":"object","properties":{"token":{"$ref":"#/components/schemas/Address"},"amount":{"type":"string"},"recipient":{"$ref":"#/components/schemas/Address"}}},"RequestId":{"type":"string"},"SpreadOptimization":{"type":"string","enum":["EXECUTION","PRICE"],"description":"For **Dutch Limit** orders only. When set to `EXECUTION`, quotes optimize for looser spreads at higher fill rates. When set to `PRICE`, quotes optimize for tighter spreads at lower fill rates","default":"EXECUTION"},"AutoSlippage":{"type":"string","enum":["DEFAULT"],"description":"For **Classic** swaps only. The auto slippage strategy to employ. If auto slippage is not defined then we don't compute it. If the auto slippage strategy is `DEFAULT`, then the swap will use the default slippage tolerance computation. You cannot define auto slippage and slippage tolerance at the same time. \n\n **NOTE**: slippage is in terms of trade type. If the trade type is `EXACT_INPUT`, then the slippage is in terms of the output token. If the trade type is `EXACT_OUTPUT`, then the slippage is in terms of the input token.","default":"undefined"},"RoutingPreference":{"type":"string","description":"The routing preference determines which protocol to use for the swap. If the routing preference is `UNISWAPX`, then the swap will be routed through the UniswapX Dutch Auction Protocol. If the routing preference is `CLASSIC`, then the swap will be routed through the Classic Protocol. If the routing preference is `BEST_PRICE`, then the swap will be routed through the protocol that provides the best price. When `UNIXWAPX_V2` is passed, the swap will be routed through the UniswapX V2 Dutch Auction Protocol. When `V3_ONLY` is passed, the swap will be routed ONLY through the Uniswap V3 Protocol. When `V2_ONLY` is passed, the swap will be routed ONLY through the Uniswap V2 Protocol.","enum":["CLASSIC","UNISWAPX","BEST_PRICE","BEST_PRICE_V2","UNISWAPX_V2","V3_ONLY","V2_ONLY"],"default":"BEST_PRICE"},"ProtocolItems":{"type":"string","enum":["V2","V3","V4","UNISWAPX","UNISWAPX_V2","PRIORITY"]},"TransactionRequest":{"type":"object","properties":{"to":{"$ref":"#/components/schemas/Address"},"from":{"$ref":"#/components/schemas/Address"},"data":{"type":"string","description":"The calldata for the transaction."},"value":{"type":"string","description":"The value of the transaction in terms of wei in hex format."},"gasLimit":{"type":"string"},"chainId":{"type":"integer"},"maxFeePerGas":{"type":"string"},"maxPriorityFeePerGas":{"type":"string"},"gasPrice":{"type":"string"}},"required":["to","from","data","value","chainId"]},"TransactionFailureReason":{"type":"string","enum":["SIMULATION_ERROR","UNSUPPORTED_SIMULATION"]},"SwapSafetyMode":{"type":"string","enum":["SAFE"],"description":"The safety mode determines the safety level of the swap. If the safety mode is `SAFE`, then the swap will include a SWEEP for the native token."},"IndicativeQuoteRequest":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/TradeType"},"amount":{"type":"string"},"tokenInChainId":{"$ref":"#/components/schemas/ChainId"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"},"tokenIn":{"type":"string"},"tokenOut":{"type":"string"}},"required":["type","amount","tokenInChainId","tokenOutChainId","tokenIn","tokenOut"]},"IndicativeQuoteResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"input":{"$ref":"#/components/schemas/IndicativeQuoteToken"},"output":{"$ref":"#/components/schemas/IndicativeQuoteToken"},"type":{"$ref":"#/components/schemas/TradeType"}},"required":["requestId","input","output","type"]},"CreateLPPositionRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"position":{"$ref":"#/components/schemas/Position"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"initialPrice":{"type":"string"},"poolLiquidity":{"type":"string"},"currentTick":{"type":"number"},"sqrtRatioX96":{"type":"string"},"amount0":{"type":"string"},"amount1":{"type":"string"},"slippageTolerance":{"type":"string"},"deadline":{"type":"number"},"signature":{"type":"string","description":"The signed permit."},"batchPermitData":{"allOf":[{"$ref":"#/components/schemas/Permit"}]},"simulateTransaction":{"type":"boolean"}}},"CreateLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"create":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"IncreaseLPPositionRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"tokenId":{"type":"number"},"position":{"$ref":"#/components/schemas/Position"},"poolLiquidity":{"type":"string"},"currentTick":{"type":"number"},"sqrtRatioX96":{"type":"string"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"amount0":{"type":"string"},"amount1":{"type":"string"},"slippageTolerance":{"type":"string"},"deadline":{"type":"number"},"signature":{"type":"string","description":"The signed permit."},"batchPermitData":{"allOf":[{"$ref":"#/components/schemas/Permit"}]},"simulateTransaction":{"type":"boolean"}}},"IncreaseLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"increase":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"DecreaseLPPositionRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"tokenId":{"type":"number"},"position":{"$ref":"#/components/schemas/Position"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"liquidityPercentageToDecrease":{"type":"number"},"liquidity0":{"type":"string"},"liquidity1":{"type":"string"},"slippageTolerance":{"type":"string"},"poolLiquidity":{"type":"string"},"currentTick":{"type":"number"},"sqrtRatioX96":{"type":"string"},"positionLiquidity":{"type":"string"},"expectedTokenOwed0RawAmount":{"type":"string"},"expectedTokenOwed1RawAmount":{"type":"string"},"collectAsWETH":{"type":"boolean"},"deadline":{"type":"number"},"simulateTransaction":{"type":"boolean"}}},"DecreaseLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"decrease":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"ClaimLPFeesRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"tokenId":{"type":"number"},"position":{"$ref":"#/components/schemas/Position"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"expectedTokenOwed0RawAmount":{"type":"string"},"expectedTokenOwed1RawAmount":{"type":"string"},"collectAsWETH":{"type":"boolean"},"simulateTransaction":{"type":"boolean"}}},"ClaimLPFeesResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"claim":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"MigrateLPPositionRequest":{"type":"object","properties":{"tokenId":{"type":"number"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"inputProtocol":{"$ref":"#/components/schemas/ProtocolItems"},"inputPosition":{"$ref":"#/components/schemas/Position"},"inputPoolLiquidity":{"type":"string"},"inputCurrentTick":{"type":"number"},"inputSqrtRatioX96":{"type":"string"},"inputPositionLiquidity":{"type":"string"},"signature":{"type":"string"},"amount0":{"type":"string"},"amount1":{"type":"string"},"outputProtocol":{"$ref":"#/components/schemas/ProtocolItems"},"outputPosition":{"$ref":"#/components/schemas/Position"},"initialPrice":{"type":"string"},"outputPoolLiquidity":{"type":"string"},"outputCurrentTick":{"type":"number"},"outputSqrtRatioX96":{"type":"string"},"expectedTokenOwed0RawAmount":{"type":"string"},"expectedTokenOwed1RawAmount":{"type":"string"},"slippageTolerance":{"type":"number"},"deadline":{"type":"number"},"signatureDeadline":{"type":"number"},"simulateTransaction":{"type":"boolean","default":false}},"required":["tokenId","chainId","walletAddress","inputProtocol","inputPosition","inputPoolLiquidity","inputCurrentTick","inputSqrtRatioX96","inputPositionLiquidity","amount0","amount1","outputProtocol","outputPosition","expectedTokenOwed0RawAmount","expectedTokenOwed1RawAmount"]},"MigrateLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"migrate":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"IndicativeQuoteToken":{"type":"object","properties":{"amount":{"type":"string"},"chainId":{"$ref":"#/components/schemas/ChainId"},"token":{"$ref":"#/components/schemas/Address"}}}},"parameters":{"universalRouterVersionHeader":{"name":"x-universal-router-version","in":"header","description":"The version of the Universal Router to use for the swap journey. *MUST* be consistent throughout the API calls.","required":false,"schema":{"$ref":"#/components/schemas/UniversalRouterVersion"}},"addressParam":{"name":"address","in":"path","schema":{"$ref":"#/components/schemas/Address"},"required":true},"tokenIdParam":{"name":"tokenId","in":"path","schema":{"type":"string"},"required":true},"cursorParam":{"name":"cursor","in":"query","schema":{"type":"string"},"required":false},"limitParam":{"name":"limit","in":"query","schema":{"type":"number"},"required":false},"chainIdParam":{"name":"chainId","in":"query","schema":{"$ref":"#/components/schemas/ChainId"},"required":false},"bridgeTokenInChainIdParam":{"name":"tokenInChainId","in":"query","schema":{"$ref":"#/components/schemas/ChainId"},"required":false},"bridgeTokenOutChainIdParam":{"name":"tokenOutChainId","in":"query","schema":{"$ref":"#/components/schemas/ChainId"},"required":false},"tokenInParam":{"name":"tokenIn","in":"query","schema":{"$ref":"#/components/schemas/Address"},"required":false},"tokenOutParam":{"name":"tokenOut","in":"query","schema":{"$ref":"#/components/schemas/Address"},"required":false},"addressPathParam":{"name":"address","in":"query","schema":{"$ref":"#/components/schemas/Address"},"required":false},"orderStatusParam":{"name":"orderStatus","in":"query","description":"Filter by order status.","required":false,"schema":{"$ref":"#/components/schemas/OrderStatus"}},"orderTypeParam":{"name":"orderType","in":"query","description":"The default orderType is Dutch_V1_V2 and will grab both Dutch and Dutch_V2 orders.","required":false,"schema":{"$ref":"#/components/schemas/OrderTypeQuery"}},"orderIdParam":{"name":"orderId","in":"query","required":false,"schema":{"$ref":"#/components/schemas/OrderId"}},"orderIdsParam":{"name":"orderIds","in":"query","required":false,"description":"ids split by commas","schema":{"$ref":"#/components/schemas/OrderIds"}},"swapperParam":{"name":"swapper","in":"query","description":"Filter by swapper address.","required":false,"schema":{"$ref":"#/components/schemas/Address"}},"fillerParam":{"name":"filler","in":"query","description":"Filter by filler address.","required":false,"schema":{"$ref":"#/components/schemas/Address"}},"sortKeyParam":{"name":"sortKey","in":"query","description":"Order the query results by the sort key.","required":false,"schema":{"$ref":"#/components/schemas/SortKey"}},"sortParam":{"name":"sort","in":"query","description":"Sort query. For example: `sort=gt(UNIX_TIMESTAMP)`, `sort=between(1675872827, 1675872930)`, or `lt(1675872930)`.","required":false,"schema":{"type":"string"}},"descParam":{"description":"Sort query results by sortKey in descending order.","name":"desc","in":"query","required":false,"schema":{"type":"string"}},"transactionHashesParam":{"description":"The transaction hashes.","name":"txHashes","in":"query","required":true,"style":"form","explode":false,"schema":{"type":"array","items":{"$ref":"#/components/schemas/TransactionHash"}}}},"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}}},"security":[{"apiKey":[]}]}
\ No newline at end of file
+{"openapi":"3.0.0","servers":[{"description":"Uniswap trading APIs Beta","url":"https://beta.trade-api.gateway.uniswap.org/v1"},{"description":"Uniswap trading APIs","url":"https://trade-api.gateway.uniswap.org/v1"}],"info":{"version":"1.0.0","title":"Token Trading","description":"Uniswap trading APIs for fungible tokens."},"paths":{"/check_approval":{"post":{"tags":["Approval"],"summary":"Check if token approval is required","description":"Checks if the swapper has the required approval. If the swapper does not have the required approval, then the response will include the transaction to approve the token. If the swapper has the required approval, then the response will be empty. If the parameter `includeGasInfo` is set to `true`, then the response will include the gas fee for the approval transaction.","operationId":"check_approval","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ApprovalSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/ApprovalNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/quote":{"post":{"tags":["Quote"],"summary":"Get a quote","description":"Get a quote according to the provided configuration. Optionally adds a fee to the quote according to the API key being used. The fee is **ALWAYS** taken from the output token. If there is a fee and the trade is `EXACT_INPUT`, then the output amount will **NOT** include the fee subtraction. For `EXACT_INPUT` swaps, use `portionBips` to calculate the fee from the quoted amount. If there is a fee and the trade is `EXACT_OUTPUT`, then the input amount will **NOT** include the fee addition to account for the fee. For `EXACT_OUTPUT` swaps, use `portionAmount` to get the fee. \n \n We also support Wrapping and Unwrapping of native tokens on their respective chains. Wrapping and Unwrapping only works for when `routingPreference` is `CLASSIC`, `BEST_PRICE`, or `BEST_PRICE_V2`. We do not support `UNISWAPX` or `UNISWAPX_V2` for these actions.","operationId":"aggregator_quote","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/universalRouterVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/QuoteSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/order":{"post":{"tags":["Order"],"summary":"Create a gasless order","description":"Submits a new gasless encoded order. The order will be validated and if valid, will be submitted to the filler network. The network will try to fill the order at the quoted `startAmount`, and if not, the amount will start decaying until the `endAmount` is reached. While the order is within `decayEndTime`, the `orderStatus` is `open`. If the order does not get filled after the `decayEndTime` has passed, that is reflected in the `expired` `orderStatus`. then The order will be filled at the best price possible. Once the order is filled, `orderStatus` becomes `filled`.","operationId":"post_order","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderRequest"}}}},"responses":{"201":{"$ref":"#/components/responses/OrderSuccess201"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/orders":{"get":{"tags":["Order"],"summary":"Get gasless orders","description":"Retrieve gasless orders filtered by query param(s). Some fields on the order can be used as query param.","operationId":"get_order","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/orderTypeParam"},{"$ref":"#/components/parameters/orderIdParam"},{"$ref":"#/components/parameters/orderIdsParam"},{"$ref":"#/components/parameters/limitParam"},{"$ref":"#/components/parameters/orderStatusParam"},{"$ref":"#/components/parameters/swapperParam"},{"$ref":"#/components/parameters/sortKeyParam"},{"$ref":"#/components/parameters/sortParam"},{"$ref":"#/components/parameters/fillerParam"},{"$ref":"#/components/parameters/cursorParam"}],"responses":{"200":{"$ref":"#/components/responses/OrdersSuccess200"},"400":{"$ref":"#/components/responses/OrdersBadRequest400"},"404":{"$ref":"#/components/responses/OrdersNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/swap":{"post":{"tags":["Swap"],"summary":"Create swap calldata","description":"Create the calldata for a swap transaction (including wrap/unwrap) against the Uniswap Protocols. If the `quote` parameter includes the fee parameters, then the calldata will include the fee disbursement. The gas estimates will be **more precise** when the the response calldata would be valid if submitted on-chain.","operationId":"create_swap_transaction","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSwapRequest"}}}},"parameters":[{"$ref":"#/components/parameters/universalRouterVersionHeader"}],"responses":{"200":{"$ref":"#/components/responses/CreateSwapSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/SwapUnauthorized401"},"404":{"$ref":"#/components/responses/SwapNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/swaps":{"get":{"tags":["Swap"],"summary":"Get swaps status","description":"Get the status of a swap or bridge transactions.","operationId":"get_swaps","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/transactionHashesParam"},{"$ref":"#/components/parameters/chainIdParam"}],"responses":{"200":{"$ref":"#/components/responses/GetSwapsSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"404":{"$ref":"#/components/responses/SwapNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/indicative_quote":{"post":{"tags":["IndicativeQuote"],"summary":"Get an indicative quote","description":"Get an indicative quote according to the provided configuration. The quote will not include a fee.","operationId":"indicative_quote","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndicativeQuoteRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/IndicativeQuoteSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/send":{"post":{"tags":["Send"],"summary":"Create send calldata","description":"Create the calldata for a send transaction.","operationId":"create_send","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSendRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/CreateSendSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/SendNotFound404"},"429":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/swappable_tokens":{"get":{"tags":["SwappableTokens"],"summary":"Get swappable tokens","description":"Get the swappable tokens for the given configuration. Either tokenIn (with tokenInChainId or (tokenInChainId and tokenOutChainId)) or tokenOut (with tokenOutChainId or (tokenOutChainId and tokenInChainId)) must be provided but not both.","operationId":"get_swappable_tokens","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/tokenInParam"},{"$ref":"#/components/parameters/tokenOutParam"},{"$ref":"#/components/parameters/bridgeTokenInChainIdParam"},{"$ref":"#/components/parameters/bridgeTokenOutChainIdParam"}],"responses":{"200":{"$ref":"#/components/responses/GetSwappableTokensSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"429":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/limit_order_quote":{"post":{"tags":["LimitOrderQuote"],"summary":"Get a limit order quote","description":"Get a quote for a limit order according to the provided configuration.","operationId":"get_limit_order_quote","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitOrderQuoteRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/LimitOrderQuoteSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/Unauthorized401"},"404":{"$ref":"#/components/responses/QuoteNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/approve":{"post":{"tags":["Liquidity"],"summary":"Check if tokens and permits need to be approved to add liquidity","description":"Checks if the wallet address has the required approvals. If the wallet address does not have the required approval, then the response will include the transactions to approve the tokens. If the wallet address has the required approval, then the response will be empty for the corresponding tokens. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the approval transactions.","operationId":"check_approval_lp","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckApprovalLPRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/CheckApprovalLPSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/ApprovalNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/create":{"post":{"tags":["Liquidity"],"summary":"Create pool and position calldata","description":"Create pool and position calldata. If the pool is not yet created, then the response will include the transaction to create the new pool with the initial price. If the pool is already created, then the response will not have the transaction to create the pool. The response will also have the transaction to create the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the creation transactions.","operationId":"create_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/CreateLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/increase":{"post":{"tags":["Liquidity"],"summary":"Increase LP position calldata","description":"The response will also have the transaction to increase the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the increase transaction.","operationId":"increase_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncreaseLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/IncreaseLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/decrease":{"post":{"tags":["Liquidity"],"summary":"Decrease LP position calldata","description":"The response will also have the transaction to decrease the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the decrease transaction.","operationId":"decrease_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecreaseLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/DecreaseLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/claim":{"post":{"tags":["Liquidity"],"summary":"Claim LP fees calldata","description":"The response will also have the transaction to claim the fees for an LP position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the claim transaction.","operationId":"claim_lp_fees","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimLPFeesRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ClaimLPFeesSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}},"/lp/migrate":{"post":{"tags":["Liquidity"],"summary":"Migrate LP position calldata","description":"The response will also have the transaction to migrate the position for the corresponding pool. If the parameter `simulateTransaction` is set to `true`, then the response will include the gas fees for the migrate transaction.","operationId":"migrate_lp_position","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrateLPPositionRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/MigrateLPPositionSuccess200"},"400":{"$ref":"#/components/responses/BadRequest400"},"401":{"$ref":"#/components/responses/ApprovalUnauthorized401"},"404":{"$ref":"#/components/responses/LPNotFound404"},"419":{"$ref":"#/components/responses/RateLimitedErr429"},"500":{"$ref":"#/components/responses/InternalErr500"},"504":{"$ref":"#/components/responses/Timeout504"}}}}},"components":{"responses":{"OrdersSuccess200":{"description":"The request orders matching the query parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOrdersResponse"}}}},"OrderSuccess201":{"description":"Encoded order submitted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderResponse"}}}},"QuoteSuccess200":{"description":"Quote request successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"LimitOrderQuoteSuccess200":{"description":"Limit Order Quote request successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitOrderQuoteResponse"}}}},"CheckApprovalLPSuccess200":{"description":"Approve LP successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckApprovalLPResponse"}}}},"ApprovalSuccess200":{"description":"Check approval successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalResponse"}}}},"CreateSendSuccess200":{"description":"Create send successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSendResponse"}}}},"CreateSwapSuccess200":{"description":"Create swap successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSwapResponse"}}}},"GetSwapsSuccess200":{"description":"Get swap successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSwapsResponse"}}}},"GetSwappableTokensSuccess200":{"description":"Get swappable tokens successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSwappableTokensResponse"}}}},"CreateLPPositionSuccess200":{"description":"Create LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLPPositionResponse"}}}},"IncreaseLPPositionSuccess200":{"description":"Create LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncreaseLPPositionResponse"}}}},"DecreaseLPPositionSuccess200":{"description":"Decrease LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecreaseLPPositionResponse"}}}},"ClaimLPFeesSuccess200":{"description":"Claim LP Fees successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimLPFeesResponse"}}}},"MigrateLPPositionSuccess200":{"description":"Migrate LP Position successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrateLPPositionResponse"}}}},"BadRequest400":{"description":"RequestValidationError, Bad Input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err400"}}}},"ApprovalUnauthorized401":{"description":"UnauthorizedError eg. Account is blocked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err401"}}}},"ApprovalNotFound404":{"description":"ResourceNotFound eg. Token allowance not found or Gas info not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"Unauthorized401":{"description":"UnauthorizedError eg. Account is blocked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err401"}}}},"QuoteNotFound404":{"description":"ResourceNotFound eg. No quotes available or Gas fee/price not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"SendNotFound404":{"description":"ResourceNotFound eg. Gas fee not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"SwapBadRequest400":{"description":"RequestValidationError, Bad Input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err400"}}}},"SwapUnauthorized401":{"description":"UnauthorizedError eg. Account is blocked or Fee is not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err401"}}}},"SwapNotFound404":{"description":"ResourceNotFound eg. No quotes available or Gas fee/price not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"OrdersNotFound404":{"description":"Orders not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"LPNotFound404":{"description":"ResourceNotFound eg. Cant Find LP Position.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err404"}}}},"OrdersBadRequest400":{"description":"RequestValidationError eg. Token allowance not valid or Insufficient Funds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err400"}}}},"RateLimitedErr429":{"description":"Ratelimited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err429"}}}},"InternalErr500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err500"}}}},"Timeout504":{"description":"Request duration limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Err504"}}}},"IndicativeQuoteSuccess200":{"description":"Indicative quote request successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndicativeQuoteResponse"}}}}},"schemas":{"NullablePermit":{"allOf":[{"$ref":"#/components/schemas/Permit"},{"type":"object","nullable":true}]},"TokenAmount":{"type":"string"},"SwapStatus":{"type":"string","enum":["PENDING","SUCCESS","NOT_FOUND","FAILED","EXPIRED"]},"GetSwapsResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"swaps":{"type":"array","items":{"type":"object","properties":{"swapType":{"$ref":"#/components/schemas/Routing"},"status":{"$ref":"#/components/schemas/SwapStatus"},"txHash":{"type":"string"},"swapId":{"type":"number"}}}}},"required":["requestId","status"]},"GetSwappableTokensResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"tokens":{"type":"array","items":{"type":"object","properties":{"address":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"name":{"type":"string"},"symbol":{"type":"string"},"project":{"$ref":"#/components/schemas/TokenProject"},"isSpam":{"type":"boolean"},"decimals":{"type":"number"}},"required":["address","chainId","name","symbol","project","decimals"]}}},"required":["requestId","tokens"]},"CreateSwapRequest":{"type":"object","description":"The parameters **signature** and **permitData** should only be included if *permitData* was returned from **/quote**.","properties":{"quote":{"oneOf":[{"$ref":"#/components/schemas/ClassicQuote"},{"$ref":"#/components/schemas/WrapUnwrapQuote"},{"$ref":"#/components/schemas/BridgeQuote"}]},"signature":{"type":"string","description":"The signed permit."},"includeGasInfo":{"type":"boolean","default":false,"deprecated":true,"description":"Use `refreshGasPrice` instead."},"refreshGasPrice":{"type":"boolean","default":false,"description":"If true, the gas price will be re-fetched from the network."},"simulateTransaction":{"type":"boolean","default":false,"description":"If true, the transaction will be simulated. If the simulation results on an onchain error, endpoint will return an error."},"permitData":{"allOf":[{"$ref":"#/components/schemas/Permit"}]},"safetyMode":{"$ref":"#/components/schemas/SwapSafetyMode"},"deadline":{"type":"integer","description":"The deadline for the swap in unix timestamp format. If the deadline is not defined OR in the past then the default deadline is 30 minutes."},"urgency":{"$ref":"#/components/schemas/Urgency"}},"required":["quote"]},"CreateSendRequest":{"type":"object","properties":{"sender":{"$ref":"#/components/schemas/Address"},"recipient":{"$ref":"#/components/schemas/Address"},"token":{"$ref":"#/components/schemas/Address"},"amount":{"$ref":"#/components/schemas/TokenAmount"},"chainId":{"$ref":"#/components/schemas/ChainId"},"urgency":{"$ref":"#/components/schemas/Urgency"}},"required":["sender","recipient","token","amount"]},"UniversalRouterVersion":{"type":"string","enum":["1.2","2.0"],"default":"1.2"},"Address":{"type":"string","pattern":"^(0x)?[0-9a-fA-F]{40}$"},"Position":{"type":"object","properties":{"pool":{"$ref":"#/components/schemas/Pool"},"tickLower":{"type":"number"},"tickUpper":{"type":"number"}},"required":["pool"]},"Pool":{"type":"object","properties":{"token0":{"$ref":"#/components/schemas/Address"},"token1":{"$ref":"#/components/schemas/Address"},"fee":{"type":"number"},"tickSpacing":{"type":"number"},"hooks":{"$ref":"#/components/schemas/Address"}},"required":["token0","token1"]},"ClassicGasUseEstimateUSD":{"description":"The gas fee you would pay if you opted for a CLASSIC swap over a Uniswap X order in terms of USD.","type":"string"},"CreateSwapResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"swap":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}},"required":["requestId","swap"]},"CreateSendResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"send":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"},"gasFeeUSD":{"type":"number"}},"required":["requestId","send"]},"QuoteResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"quote":{"$ref":"#/components/schemas/Quote"},"routing":{"$ref":"#/components/schemas/Routing"},"permitData":{"$ref":"#/components/schemas/NullablePermit"}},"required":["routing","quote","permitData","requestId"]},"LimitOrderQuoteResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"quote":{"$ref":"#/components/schemas/DutchQuote"},"routing":{"type":"string","enum":["LIMIT_ORDER"]},"permitData":{"$ref":"#/components/schemas/NullablePermit"}},"required":["routing","quote","permitData","requestId"]},"QuoteRequest":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/TradeType"},"amount":{"type":"string"},"tokenInChainId":{"$ref":"#/components/schemas/ChainId"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"},"tokenIn":{"type":"string"},"tokenOut":{"type":"string"},"swapper":{"$ref":"#/components/schemas/Address"},"slippageTolerance":{"description":"For **Classic** swaps, the slippage tolerance is the maximum amount the price can change between the time the transaction is submitted and the time it is executed. The slippage tolerance is represented as a percentage of the total value of the swap. \n\n Slippage tolerance works differently in **DutchLimit** swaps, it does not set a limit on the Spread in an order. See [here](https://uniswap-docs.readme.io/reference/faqs#why-do-the-uniswapx-quotes-have-more-slippage-than-the-tolerance-i-set) for more information. \n\n **NOTE**: slippage is in terms of trade type. If the trade type is `EXACT_INPUT`, then the slippage is in terms of the output token. If the trade type is `EXACT_OUTPUT`, then the slippage is in terms of the input token.","type":"number"},"autoSlippage":{"$ref":"#/components/schemas/AutoSlippage"},"routingPreference":{"$ref":"#/components/schemas/RoutingPreference"},"protocols":{"$ref":"#/components/schemas/Protocols"},"spreadOptimization":{"$ref":"#/components/schemas/SpreadOptimization"},"urgency":{"$ref":"#/components/schemas/Urgency"}},"required":["type","amount","tokenInChainId","tokenOutChainId","tokenIn","tokenOut","swapper"]},"LimitOrderQuoteRequest":{"type":"object","properties":{"swapper":{"$ref":"#/components/schemas/Address"},"limitPrice":{"type":"string"},"amount":{"type":"string"},"orderDeadline":{"type":"number"},"type":{"$ref":"#/components/schemas/TradeType"},"tokenIn":{"type":"string"},"tokenOut":{"type":"string"},"tokenInChainId":{"$ref":"#/components/schemas/ChainId"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"}},"required":["swapper","type","amount","tokenIn","tokenOut","tokenInChainId","tokenOutChainId"]},"GetOrdersResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"orders":{"type":"array","items":{"$ref":"#/components/schemas/UniswapXOrder"}},"cursor":{"type":"string"}},"required":["orders","requestId"]},"OrderResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"orderId":{"type":"string"},"orderStatus":{"$ref":"#/components/schemas/OrderStatus"}},"required":["requestId","orderId","orderStatus"]},"OrderRequest":{"type":"object","properties":{"signature":{"type":"string","description":"The signed permit."},"quote":{"oneOf":[{"$ref":"#/components/schemas/DutchQuote"},{"$ref":"#/components/schemas/DutchQuoteV2"},{"$ref":"#/components/schemas/PriorityQuote"}]},"routing":{"$ref":"#/components/schemas/Routing"}},"required":["signature","quote"]},"Urgency":{"type":"string","enum":["normal","fast","urgent"],"description":"The urgency determines the urgency of the transaction. The default value is `urgent`.","default":"urgent"},"Protocols":{"type":"array","items":{"$ref":"#/components/schemas/ProtocolItems"},"description":"The protocols to use for the swap/order. If the `protocols` field is defined, then you can only set the `routingPreference` to `BEST_PRICE`"},"Err400":{"type":"object","properties":{"errorCode":{"default":"RequestValidationError","type":"string"},"detail":{"type":"string"}}},"Err401":{"type":"object","properties":{"errorCode":{"default":"UnauthorizedError","type":"string"},"detail":{"type":"string"}}},"Err404":{"type":"object","properties":{"errorCode":{"enum":["ResourceNotFound","QuoteAmountTooLowError"],"type":"string"},"detail":{"type":"string"}}},"Err429":{"type":"object","properties":{"errorCode":{"default":"Ratelimited","type":"string"},"detail":{"type":"string"}}},"Err500":{"type":"object","properties":{"errorCode":{"default":"InternalServerError","type":"string"},"detail":{"type":"string"}}},"Err504":{"type":"object","properties":{"errorCode":{"default":"Timeout","type":"string"},"detail":{"type":"string"}}},"ChainId":{"type":"number","enum":[1,10,56,137,8453,42161,81457,43114,42220,7777777,324,11155111,1301,480]},"OrderInput":{"type":"object","properties":{"token":{"type":"string"},"startAmount":{"type":"string"},"endAmount":{"type":"string"}},"required":["token"]},"OrderOutput":{"type":"object","properties":{"token":{"type":"string"},"startAmount":{"type":"string"},"endAmount":{"type":"string"},"isFeeOutput":{"type":"boolean"},"recipient":{"type":"string"}},"required":["token"]},"CosignerData":{"type":"object","properties":{"decayStartTime":{"type":"number"},"decayEndTime":{"type":"number"},"exclusiveFiller":{"type":"string"},"inputOverride":{"type":"string"},"outputOverrides":{"type":"array","items":{"type":"string"}}}},"SettledAmount":{"type":"object","properties":{"tokenOut":{"$ref":"#/components/schemas/Address"},"amountOut":{"type":"string"},"tokenIn":{"$ref":"#/components/schemas/Address"},"amountIn":{"type":"string"}}},"OrderType":{"type":"string","enum":["DutchLimit","Dutch","Dutch_V2"]},"OrderTypeQuery":{"type":"string","enum":["Dutch","Dutch_V2","Dutch_V1_V2","Limit","Priority"]},"UniswapXOrder":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/OrderType"},"encodedOrder":{"type":"string"},"signature":{"type":"string"},"nonce":{"type":"string"},"orderStatus":{"$ref":"#/components/schemas/OrderStatus"},"orderId":{"type":"string"},"chainId":{"$ref":"#/components/schemas/ChainId"},"quoteId":{"type":"string"},"swapper":{"type":"string"},"txHash":{"type":"string"},"input":{"$ref":"#/components/schemas/OrderInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/OrderOutput"}},"settledAmounts":{"type":"array","items":{"$ref":"#/components/schemas/SettledAmount"}},"cosignature":{"type":"string"},"cosignerData":{"$ref":"#/components/schemas/CosignerData"}},"required":["encodedOrder","signature","nonce","orderId","orderStatus","chainId","type"]},"SortKey":{"type":"string","enum":["createdAt"]},"OrderId":{"type":"string"},"OrderIds":{"type":"string"},"OrderStatus":{"type":"string","enum":["open","expired","error","cancelled","filled","unverified","insufficient-funds"]},"Permit":{"type":"object","properties":{"domain":{"type":"object"},"values":{"type":"object"},"types":{"type":"object"}}},"TokenProject":{"type":"object","properties":{"logo":{"$ref":"#/components/schemas/TokenProjectLogo","nullable":true},"safetyLevel":{"$ref":"#/components/schemas/SafetyLevel"},"isSpam":{"type":"boolean"}},"required":["logo","safetyLevel","isSpam"]},"TokenProjectLogo":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"DutchInput":{"type":"object","properties":{"startAmount":{"type":"string"},"endAmount":{"type":"string"},"token":{"type":"string"}},"required":["startAmount","endAmount","type"]},"DutchOutput":{"type":"object","properties":{"startAmount":{"type":"string"},"endAmount":{"type":"string"},"token":{"type":"string"},"recipient":{"type":"string"}},"required":["startAmount","endAmount","token","recipient"]},"DutchOrderInfo":{"type":"object","properties":{"chainId":{"$ref":"#/components/schemas/ChainId"},"nonce":{"type":"string"},"reactor":{"type":"string"},"swapper":{"type":"string"},"deadline":{"type":"number"},"additionalValidationContract":{"type":"string"},"additionalValidationData":{"type":"string"},"decayStartTime":{"type":"number"},"decayEndTime":{"type":"number"},"exclusiveFiller":{"type":"string"},"exclusivityOverrideBps":{"type":"string"},"input":{"$ref":"#/components/schemas/DutchInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/DutchOutput"}}},"required":["chainId","nonce","reactor","swapper","deadline","validationContract","validationData","startTime","endTime","exclusiveFiller","exclusivityOverrideBps","input","outputs"]},"DutchOrderInfoV2":{"type":"object","properties":{"chainId":{"$ref":"#/components/schemas/ChainId"},"nonce":{"type":"string"},"reactor":{"type":"string"},"swapper":{"type":"string"},"deadline":{"type":"number"},"additionalValidationContract":{"type":"string"},"additionalValidationData":{"type":"string"},"input":{"$ref":"#/components/schemas/DutchInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/DutchOutput"}},"cosigner":{"$ref":"#/components/schemas/Address"}},"required":["chainId","nonce","reactor","swapper","deadline","validationContract","validationData","startTime","endTime","exclusiveFiller","exclusivityOverrideBps","input","outputs"]},"DutchQuote":{"type":"object","properties":{"encodedOrder":{"type":"string"},"orderId":{"type":"string"},"orderInfo":{"$ref":"#/components/schemas/DutchOrderInfo"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"quoteId":{"type":"string"},"slippageTolerance":{"type":"number"},"classicGasUseEstimateUSD":{"$ref":"#/components/schemas/ClassicGasUseEstimateUSD"}},"required":["encodedOrder","orderInfo","orderId"]},"DutchQuoteV2":{"type":"object","properties":{"encodedOrder":{"type":"string"},"orderId":{"type":"string"},"orderInfo":{"$ref":"#/components/schemas/DutchOrderInfoV2"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"quoteId":{"type":"string"},"slippageTolerance":{"type":"number"},"deadlineBufferSecs":{"type":"number"},"classicGasUseEstimateUSD":{"$ref":"#/components/schemas/ClassicGasUseEstimateUSD"}},"required":["encodedOrder","orderInfo","orderId"]},"PriorityInput":{"type":"object","properties":{"amount":{"type":"string"},"token":{"type":"string"},"mpsPerPriorityFeeWei":{"type":"string"}},"required":["amount","token","mpsPerPriorityFeeWei"]},"PriorityOutput":{"type":"object","properties":{"amount":{"type":"string"},"token":{"type":"string"},"recipient":{"type":"string"},"mpsPerPriorityFeeWei":{"type":"string"}},"required":["amount","token","recipient","mpsPerPriorityFeeWei"]},"PriorityOrderInfo":{"type":"object","properties":{"chainId":{"$ref":"#/components/schemas/ChainId"},"nonce":{"type":"string"},"reactor":{"type":"string"},"swapper":{"type":"string"},"deadline":{"type":"number"},"additionalValidationContract":{"type":"string"},"additionalValidationData":{"type":"string"},"auctionStartBlock":{"type":"string"},"baselinePriorityFeeWei":{"type":"string"},"input":{"$ref":"#/components/schemas/PriorityInput"},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/PriorityOutput"}},"cosigner":{"$ref":"#/components/schemas/Address"}},"required":["chainId","nonce","reactor","swapper","deadline","validationContract","validationData","auctionStartBlock","baselinePriorityFeeWei","input","outputs","cosigner"]},"PriorityQuote":{"type":"object","properties":{"encodedOrder":{"type":"string"},"orderId":{"type":"string"},"orderInfo":{"$ref":"#/components/schemas/PriorityOrderInfo"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"quoteId":{"type":"string"},"slippageTolerance":{"type":"number"},"deadlineBufferSecs":{"type":"number"},"classicGasUseEstimateUSD":{"$ref":"#/components/schemas/ClassicGasUseEstimateUSD"},"expectedAmountIn":{"type":"string"},"expectedAmountOut":{"type":"string"}},"required":["encodedOrder","orderInfo","orderId"]},"BridgeQuote":{"type":"object","properties":{"quoteId":{"type":"string"},"chainId":{"$ref":"#/components/schemas/ChainId"},"destinationChainId":{"$ref":"#/components/schemas/ChainId"},"swapper":{"$ref":"#/components/schemas/Address"},"input":{"$ref":"#/components/schemas/ClassicInput"},"output":{"$ref":"#/components/schemas/ClassicOutput"},"tradeType":{"$ref":"#/components/schemas/TradeType"},"quoteTimestamp":{"type":"number"},"gasPrice":{"type":"string"},"maxFeePerGas":{"type":"string"},"maxPriorityFeePerGas":{"type":"string"},"gasFee":{"type":"string"},"gasUseEstimate":{"type":"string"},"gasFeeUSD":{"type":"string"},"portionBips":{"type":"number"},"portionAmount":{"type":"string"},"portionRecipient":{"$ref":"#/components/schemas/Address"},"estimatedFillTimeMs":{"type":"number"}}},"SafetyLevel":{"type":"string","enum":["BLOCKED","MEDIUM_WARNING","STRONG_WARNING","VERIFIED"]},"TradeType":{"type":"string","enum":["EXACT_INPUT","EXACT_OUTPUT"]},"Routing":{"type":"string","enum":["DUTCH_LIMIT","CLASSIC","DUTCH_V2","BRIDGE","LIMIT_ORDER","PRIORITY"]},"Quote":{"oneOf":[{"$ref":"#/components/schemas/DutchQuote"},{"$ref":"#/components/schemas/ClassicQuote"},{"$ref":"#/components/schemas/WrapUnwrapQuote"},{"$ref":"#/components/schemas/DutchQuoteV2"},{"$ref":"#/components/schemas/BridgeQuote"},{"$ref":"#/components/schemas/PriorityQuote"}]},"CheckApprovalLPRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"token0":{"$ref":"#/components/schemas/Address"},"token1":{"$ref":"#/components/schemas/Address"},"positionToken":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"walletAddress":{"$ref":"#/components/schemas/Address"},"amount0":{"type":"string"},"amount1":{"type":"string"},"positionAmount":{"type":"string"},"simulateTransaction":{"type":"boolean"}}},"CheckApprovalLPResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"token0Approval":{"$ref":"#/components/schemas/TransactionRequest"},"token1Approval":{"$ref":"#/components/schemas/TransactionRequest"},"positionTokenApproval":{"$ref":"#/components/schemas/TransactionRequest"},"permitData":{"$ref":"#/components/schemas/NullablePermit"},"gasFeeToken0Approval":{"type":"string"},"gasFeeToken1Approval":{"type":"string"},"gasFeePositionTokenApproval":{"type":"string"}}},"ApprovalRequest":{"type":"object","properties":{"walletAddress":{"$ref":"#/components/schemas/Address"},"token":{"$ref":"#/components/schemas/Address"},"amount":{"$ref":"#/components/schemas/TokenAmount"},"chainId":{"$ref":"#/components/schemas/ChainId"},"urgency":{"$ref":"#/components/schemas/Urgency"},"includeGasInfo":{"type":"boolean","default":false},"tokenOut":{"$ref":"#/components/schemas/Address"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"}},"required":["walletAddress","token","amount"]},"ApprovalResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"approval":{"$ref":"#/components/schemas/TransactionRequest"},"cancel":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"},"cancelGasFee":{"type":"string"}},"required":["requestId","approval","cancel"]},"ClassicQuote":{"type":"object","properties":{"input":{"$ref":"#/components/schemas/ClassicInput"},"output":{"$ref":"#/components/schemas/ClassicOutput"},"swapper":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"slippage":{"type":"number"},"tradeType":{"$ref":"#/components/schemas/TradeType"},"gasFee":{"type":"string","description":"The gas fee in terms of wei. It does NOT include the additional gas for token approvals."},"gasFeeUSD":{"type":"string","description":"The gas fee in terms of USD. It does NOT include the additional gas for token approvals."},"gasFeeQuote":{"type":"string","description":"The gas fee in terms of the quoted currency. It does NOT include the additional gas for token approvals."},"route":{"type":"array","items":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/V3PoolInRoute"},{"$ref":"#/components/schemas/V2PoolInRoute"},{"$ref":"#/components/schemas/V4PoolInRoute"}]}}},"portionBips":{"type":"number","description":"The portion of the swap that will be taken as a fee. The fee will be taken from the output token."},"portionAmount":{"type":"string","description":"The amount of the swap that will be taken as a fee. The fee will be taken from the output token."},"portionRecipient":{"$ref":"#/components/schemas/Address"},"routeString":{"type":"string","description":"The route in string format."},"quoteId":{"type":"string","description":"The quote id. Used for analytics purposes."},"gasUseEstimate":{"type":"string","description":"The estimated gas use. It does NOT include the additional gas for token approvals."},"blockNumber":{"type":"string","description":"The current block number."},"gasPrice":{"type":"string","description":"The gas price in terms of wei for pre EIP1559 transactions."},"maxFeePerGas":{"type":"string","description":"The maximum fee per gas in terms of wei for EIP1559 transactions."},"maxPriorityFeePerGas":{"type":"string","description":"The maximum priority fee per gas in terms of wei for EIP1559 transactions."},"txFailureReasons":{"type":"array","items":{"$ref":"#/components/schemas/TransactionFailureReason"}},"priceImpact":{"type":"number","description":"The impact the trade has on the market price of the pool, between 0-100 percent"}}},"WrapUnwrapQuote":{"type":"object","properties":{"swapper":{"$ref":"#/components/schemas/Address"},"input":{"$ref":"#/components/schemas/ClassicInput"},"output":{"$ref":"#/components/schemas/ClassicOutput"},"chainId":{"$ref":"#/components/schemas/ChainId"},"tradeType":{"$ref":"#/components/schemas/TradeType"},"gasFee":{"type":"string","description":"The gas fee in terms of wei."},"gasFeeUSD":{"type":"string","description":"The gas fee in terms of USD."},"gasFeeQuote":{"type":"string","description":"The gas fee in terms of the quoted currency."},"gasUseEstimate":{"type":"string","description":"The estimated gas use."},"gasPrice":{"type":"string","description":"The gas price in terms of wei for pre EIP1559 transactions."},"maxFeePerGas":{"type":"string","description":"The maximum fee per gas in terms of wei for EIP1559 transactions."},"maxPriorityFeePerGas":{"type":"string","description":"The maximum priority fee per gas in terms of wei for EIP1559 transactions."}}},"TokenInRoute":{"type":"object","properties":{"address":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"symbol":{"type":"string"},"decimals":{"type":"string"},"buyFeeBps":{"type":"string"},"sellFeeBps":{"type":"string"}}},"V2Reserve":{"type":"object","properties":{"token":{"$ref":"#/components/schemas/TokenInRoute"},"quotient":{"type":"string"}}},"V2PoolInRoute":{"type":"object","properties":{"type":{"type":"string","default":"v2-pool"},"address":{"$ref":"#/components/schemas/Address"},"tokenIn":{"$ref":"#/components/schemas/TokenInRoute"},"tokenOut":{"$ref":"#/components/schemas/TokenInRoute"},"reserve0":{"$ref":"#/components/schemas/V2Reserve"},"reserve1":{"$ref":"#/components/schemas/V2Reserve"},"amountIn":{"type":"string"},"amountOut":{"type":"string"}}},"V3PoolInRoute":{"type":"object","properties":{"type":{"type":"string","default":"v3-pool"},"address":{"$ref":"#/components/schemas/Address"},"tokenIn":{"$ref":"#/components/schemas/TokenInRoute"},"tokenOut":{"$ref":"#/components/schemas/TokenInRoute"},"sqrtRatioX96":{"type":"string"},"liquidity":{"type":"string"},"tickCurrent":{"type":"string"},"fee":{"type":"string"},"amountIn":{"type":"string"},"amountOut":{"type":"string"}}},"V4PoolInRoute":{"type":"object","properties":{"type":{"type":"string","default":"v4-pool"},"address":{"$ref":"#/components/schemas/Address"},"tokenIn":{"$ref":"#/components/schemas/TokenInRoute"},"tokenOut":{"$ref":"#/components/schemas/TokenInRoute"},"sqrtRatioX96":{"type":"string"},"liquidity":{"type":"string"},"tickCurrent":{"type":"string"},"fee":{"type":"string"},"tickSpacing":{"type":"string"},"hooks":{"type":"string"},"amountIn":{"type":"string"},"amountOut":{"type":"string"}},"required":["type","address","tokenIn","tokenOut","sqrtRatioX96","liquidity","tickCurrent","fee","tickSpacing","hooks"]},"TransactionHash":{"type":"string","pattern":"^(0x)?[0-9a-fA-F]{64}$"},"ClassicInput":{"type":"object","properties":{"token":{"$ref":"#/components/schemas/Address"},"amount":{"type":"string"}}},"ClassicOutput":{"type":"object","properties":{"token":{"$ref":"#/components/schemas/Address"},"amount":{"type":"string"},"recipient":{"$ref":"#/components/schemas/Address"}}},"RequestId":{"type":"string"},"SpreadOptimization":{"type":"string","enum":["EXECUTION","PRICE"],"description":"For **Dutch Limit** orders only. When set to `EXECUTION`, quotes optimize for looser spreads at higher fill rates. When set to `PRICE`, quotes optimize for tighter spreads at lower fill rates","default":"EXECUTION"},"AutoSlippage":{"type":"string","enum":["DEFAULT"],"description":"For **Classic** swaps only. The auto slippage strategy to employ. If auto slippage is not defined then we don't compute it. If the auto slippage strategy is `DEFAULT`, then the swap will use the default slippage tolerance computation. You cannot define auto slippage and slippage tolerance at the same time. \n\n **NOTE**: slippage is in terms of trade type. If the trade type is `EXACT_INPUT`, then the slippage is in terms of the output token. If the trade type is `EXACT_OUTPUT`, then the slippage is in terms of the input token.","default":"undefined"},"RoutingPreference":{"type":"string","description":"The routing preference determines which protocol to use for the swap. If the routing preference is `UNISWAPX`, then the swap will be routed through the UniswapX Dutch Auction Protocol. If the routing preference is `CLASSIC`, then the swap will be routed through the Classic Protocol. If the routing preference is `BEST_PRICE`, then the swap will be routed through the protocol that provides the best price. When `UNIXWAPX_V2` is passed, the swap will be routed through the UniswapX V2 Dutch Auction Protocol. When `V3_ONLY` is passed, the swap will be routed ONLY through the Uniswap V3 Protocol. When `V2_ONLY` is passed, the swap will be routed ONLY through the Uniswap V2 Protocol.","enum":["CLASSIC","UNISWAPX","BEST_PRICE","BEST_PRICE_V2","UNISWAPX_V2","V3_ONLY","V2_ONLY"],"default":"BEST_PRICE"},"ProtocolItems":{"type":"string","enum":["V2","V3","V4","UNISWAPX","UNISWAPX_V2","PRIORITY"]},"TransactionRequest":{"type":"object","properties":{"to":{"$ref":"#/components/schemas/Address"},"from":{"$ref":"#/components/schemas/Address"},"data":{"type":"string","description":"The calldata for the transaction."},"value":{"type":"string","description":"The value of the transaction in terms of wei in hex format."},"gasLimit":{"type":"string"},"chainId":{"type":"integer"},"maxFeePerGas":{"type":"string"},"maxPriorityFeePerGas":{"type":"string"},"gasPrice":{"type":"string"}},"required":["to","from","data","value","chainId"]},"TransactionFailureReason":{"type":"string","enum":["SIMULATION_ERROR","UNSUPPORTED_SIMULATION"]},"SwapSafetyMode":{"type":"string","enum":["SAFE"],"description":"The safety mode determines the safety level of the swap. If the safety mode is `SAFE`, then the swap will include a SWEEP for the native token."},"IndicativeQuoteRequest":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/TradeType"},"amount":{"type":"string"},"tokenInChainId":{"$ref":"#/components/schemas/ChainId"},"tokenOutChainId":{"$ref":"#/components/schemas/ChainId"},"tokenIn":{"type":"string"},"tokenOut":{"type":"string"}},"required":["type","amount","tokenInChainId","tokenOutChainId","tokenIn","tokenOut"]},"IndicativeQuoteResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"input":{"$ref":"#/components/schemas/IndicativeQuoteToken"},"output":{"$ref":"#/components/schemas/IndicativeQuoteToken"},"type":{"$ref":"#/components/schemas/TradeType"}},"required":["requestId","input","output","type"]},"CreateLPPositionRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"position":{"$ref":"#/components/schemas/Position"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"initialPrice":{"type":"string"},"poolLiquidity":{"type":"string"},"currentTick":{"type":"number"},"sqrtRatioX96":{"type":"string"},"amount0":{"type":"string"},"amount1":{"type":"string"},"slippageTolerance":{"type":"string"},"deadline":{"type":"number"},"signature":{"type":"string","description":"The signed permit."},"batchPermitData":{"allOf":[{"$ref":"#/components/schemas/Permit"}]},"simulateTransaction":{"type":"boolean"}}},"CreateLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"create":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"IncreaseLPPositionRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"tokenId":{"type":"number"},"position":{"$ref":"#/components/schemas/Position"},"poolLiquidity":{"type":"string"},"currentTick":{"type":"number"},"sqrtRatioX96":{"type":"string"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"amount0":{"type":"string"},"amount1":{"type":"string"},"slippageTolerance":{"type":"string"},"deadline":{"type":"number"},"signature":{"type":"string","description":"The signed permit."},"batchPermitData":{"allOf":[{"$ref":"#/components/schemas/Permit"}]},"simulateTransaction":{"type":"boolean"}}},"IncreaseLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"increase":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"DecreaseLPPositionRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"tokenId":{"type":"number"},"position":{"$ref":"#/components/schemas/Position"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"liquidityPercentageToDecrease":{"type":"number"},"liquidity0":{"type":"string"},"liquidity1":{"type":"string"},"slippageTolerance":{"type":"string"},"poolLiquidity":{"type":"string"},"currentTick":{"type":"number"},"sqrtRatioX96":{"type":"string"},"positionLiquidity":{"type":"string"},"expectedTokenOwed0RawAmount":{"type":"string"},"expectedTokenOwed1RawAmount":{"type":"string"},"collectAsWETH":{"type":"boolean"},"deadline":{"type":"number"},"simulateTransaction":{"type":"boolean"}}},"DecreaseLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"decrease":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"ClaimLPFeesRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ProtocolItems"},"tokenId":{"type":"number"},"position":{"$ref":"#/components/schemas/Position"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"expectedTokenOwed0RawAmount":{"type":"string"},"expectedTokenOwed1RawAmount":{"type":"string"},"collectAsWETH":{"type":"boolean"},"simulateTransaction":{"type":"boolean"}}},"ClaimLPFeesResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"claim":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"MigrateLPPositionRequest":{"type":"object","properties":{"tokenId":{"type":"number"},"walletAddress":{"$ref":"#/components/schemas/Address"},"chainId":{"$ref":"#/components/schemas/ChainId"},"inputProtocol":{"$ref":"#/components/schemas/ProtocolItems"},"inputPosition":{"$ref":"#/components/schemas/Position"},"inputPoolLiquidity":{"type":"string"},"inputCurrentTick":{"type":"number"},"inputSqrtRatioX96":{"type":"string"},"inputPositionLiquidity":{"type":"string"},"signature":{"type":"string"},"amount0":{"type":"string"},"amount1":{"type":"string"},"outputProtocol":{"$ref":"#/components/schemas/ProtocolItems"},"outputPosition":{"$ref":"#/components/schemas/Position"},"initialPrice":{"type":"string"},"outputPoolLiquidity":{"type":"string"},"outputCurrentTick":{"type":"number"},"outputSqrtRatioX96":{"type":"string"},"expectedTokenOwed0RawAmount":{"type":"string"},"expectedTokenOwed1RawAmount":{"type":"string"},"slippageTolerance":{"type":"number"},"deadline":{"type":"number"},"signatureDeadline":{"type":"number"},"simulateTransaction":{"type":"boolean","default":false}},"required":["tokenId","chainId","walletAddress","inputProtocol","inputPosition","inputPoolLiquidity","inputCurrentTick","inputSqrtRatioX96","inputPositionLiquidity","amount0","amount1","outputProtocol","outputPosition","expectedTokenOwed0RawAmount","expectedTokenOwed1RawAmount"]},"MigrateLPPositionResponse":{"type":"object","properties":{"requestId":{"$ref":"#/components/schemas/RequestId"},"migrate":{"$ref":"#/components/schemas/TransactionRequest"},"gasFee":{"type":"string"}}},"IndicativeQuoteToken":{"type":"object","properties":{"amount":{"type":"string"},"chainId":{"$ref":"#/components/schemas/ChainId"},"token":{"$ref":"#/components/schemas/Address"}}}},"parameters":{"universalRouterVersionHeader":{"name":"x-universal-router-version","in":"header","description":"The version of the Universal Router to use for the swap journey. *MUST* be consistent throughout the API calls.","required":false,"schema":{"$ref":"#/components/schemas/UniversalRouterVersion"}},"addressParam":{"name":"address","in":"path","schema":{"$ref":"#/components/schemas/Address"},"required":true},"tokenIdParam":{"name":"tokenId","in":"path","schema":{"type":"string"},"required":true},"cursorParam":{"name":"cursor","in":"query","schema":{"type":"string"},"required":false},"limitParam":{"name":"limit","in":"query","schema":{"type":"number"},"required":false},"chainIdParam":{"name":"chainId","in":"query","schema":{"$ref":"#/components/schemas/ChainId"},"required":false},"bridgeTokenInChainIdParam":{"name":"tokenInChainId","in":"query","schema":{"$ref":"#/components/schemas/ChainId"},"required":false},"bridgeTokenOutChainIdParam":{"name":"tokenOutChainId","in":"query","schema":{"$ref":"#/components/schemas/ChainId"},"required":false},"tokenInParam":{"name":"tokenIn","in":"query","schema":{"$ref":"#/components/schemas/Address"},"required":false},"tokenOutParam":{"name":"tokenOut","in":"query","schema":{"$ref":"#/components/schemas/Address"},"required":false},"addressPathParam":{"name":"address","in":"query","schema":{"$ref":"#/components/schemas/Address"},"required":false},"orderStatusParam":{"name":"orderStatus","in":"query","description":"Filter by order status.","required":false,"schema":{"$ref":"#/components/schemas/OrderStatus"}},"orderTypeParam":{"name":"orderType","in":"query","description":"The default orderType is Dutch_V1_V2 and will grab both Dutch and Dutch_V2 orders.","required":false,"schema":{"$ref":"#/components/schemas/OrderTypeQuery"}},"orderIdParam":{"name":"orderId","in":"query","required":false,"schema":{"$ref":"#/components/schemas/OrderId"}},"orderIdsParam":{"name":"orderIds","in":"query","required":false,"description":"ids split by commas","schema":{"$ref":"#/components/schemas/OrderIds"}},"swapperParam":{"name":"swapper","in":"query","description":"Filter by swapper address.","required":false,"schema":{"$ref":"#/components/schemas/Address"}},"fillerParam":{"name":"filler","in":"query","description":"Filter by filler address.","required":false,"schema":{"$ref":"#/components/schemas/Address"}},"sortKeyParam":{"name":"sortKey","in":"query","description":"Order the query results by the sort key.","required":false,"schema":{"$ref":"#/components/schemas/SortKey"}},"sortParam":{"name":"sort","in":"query","description":"Sort query. For example: `sort=gt(UNIX_TIMESTAMP)`, `sort=between(1675872827, 1675872930)`, or `lt(1675872930)`.","required":false,"schema":{"type":"string"}},"descParam":{"description":"Sort query results by sortKey in descending order.","name":"desc","in":"query","required":false,"schema":{"type":"string"}},"transactionHashesParam":{"description":"The transaction hashes.","name":"txHashes","in":"query","required":true,"style":"form","explode":false,"schema":{"type":"array","items":{"$ref":"#/components/schemas/TransactionHash"}}}},"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}}},"security":[{"apiKey":[]}]}
\ No newline at end of file
diff --git a/packages/uniswap/src/entities/assets.ts b/packages/uniswap/src/entities/assets.ts
index 4331aee6848..1829b00d633 100644
--- a/packages/uniswap/src/entities/assets.ts
+++ b/packages/uniswap/src/entities/assets.ts
@@ -1,4 +1,4 @@
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
export type TradeableAsset = CurrencyAsset | NFTAsset
diff --git a/packages/uniswap/src/features/address/ExplorerView.tsx b/packages/uniswap/src/features/address/ExplorerView.tsx
deleted file mode 100644
index 8d2475bb5a6..00000000000
--- a/packages/uniswap/src/features/address/ExplorerView.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { SharedEventName } from '@uniswap/analytics-events'
-import { Currency } from '@uniswap/sdk-core'
-import { useState } from 'react'
-import { useDispatch } from 'react-redux'
-import { Anchor, Flex, Text, TouchableArea } from 'ui/src'
-import { CheckCircleFilled } from 'ui/src/components/icons/CheckCircleFilled'
-import { CopyAlt } from 'ui/src/components/icons/CopyAlt'
-import { ExternalLink } from 'ui/src/components/icons/ExternalLink'
-import { MicroConfirmation } from 'uniswap/src/components/MicroConfirmation'
-import { pushNotification } from 'uniswap/src/features/notifications/slice'
-import { AppNotificationType, CopyNotificationType } from 'uniswap/src/features/notifications/types'
-import { ElementName } from 'uniswap/src/features/telemetry/constants'
-import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
-import { WarningModalInfoContainer } from 'uniswap/src/features/tokens/TokenWarningModal'
-import { useTranslation } from 'uniswap/src/i18n'
-import { setClipboard } from 'uniswap/src/utils/clipboard'
-import { ExplorerDataType, getExplorerLink } from 'uniswap/src/utils/linking'
-import { isInterface } from 'utilities/src/platform'
-
-export function ExplorerView({ currency, modalName }: { currency: Currency; modalName: string }): JSX.Element | null {
- const { t } = useTranslation()
- const dispatch = useDispatch()
-
- const [showTooltip, setShowTooltip] = useState(false)
- if (currency) {
- const explorerLink = getExplorerLink(
- currency.chainId,
- currency.isToken ? currency.address : '',
- currency.isToken ? ExplorerDataType.TOKEN : ExplorerDataType.NATIVE,
- )
- const onPressCopyAddress = async (): Promise => {
- await setClipboard(explorerLink)
-
- if (isInterface) {
- setShowTooltip(true)
- setTimeout(() => {
- setShowTooltip(false)
- }, 1000)
- } else {
- dispatch(
- pushNotification({ type: AppNotificationType.Copied, copyType: CopyNotificationType.BlockExplorerUrl }),
- )
- }
-
- sendAnalyticsEvent(SharedEventName.ELEMENT_CLICKED, {
- element: ElementName.Copy,
- modal: modalName,
- })
- }
-
- return (
-
-
-
-
-
- {explorerLink}
-
-
-
-
-
-
-
- }
- showTooltip={showTooltip}
- trigger={
-
-
-
- }
- />
-
- )
- } else {
- return null
- }
-}
diff --git a/packages/uniswap/src/features/address/TokenAddressView.tsx b/packages/uniswap/src/features/address/TokenAddressView.tsx
new file mode 100644
index 00000000000..84ba1737049
--- /dev/null
+++ b/packages/uniswap/src/features/address/TokenAddressView.tsx
@@ -0,0 +1,73 @@
+import { SharedEventName } from '@uniswap/analytics-events'
+import { Currency } from '@uniswap/sdk-core'
+import { useState } from 'react'
+import { useDispatch } from 'react-redux'
+import { Flex, Text, TouchableArea } from 'ui/src'
+import { CheckCircleFilled } from 'ui/src/components/icons/CheckCircleFilled'
+import { CopyAlt } from 'ui/src/components/icons/CopyAlt'
+import { MicroConfirmation } from 'uniswap/src/components/MicroConfirmation'
+import { pushNotification } from 'uniswap/src/features/notifications/slice'
+import { AppNotificationType, CopyNotificationType } from 'uniswap/src/features/notifications/types'
+import { ElementName } from 'uniswap/src/features/telemetry/constants'
+import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
+import { WarningModalInfoContainer } from 'uniswap/src/features/tokens/WarningInfoModalContainer'
+import { useTranslation } from 'uniswap/src/i18n'
+import { setClipboard } from 'uniswap/src/utils/clipboard'
+import { isInterface } from 'utilities/src/platform'
+
+export function TokenAddressView({
+ currency,
+ modalName,
+}: {
+ currency: Currency
+ modalName: string
+}): JSX.Element | null {
+ const { t } = useTranslation()
+ const dispatch = useDispatch()
+
+ const [showTooltip, setShowTooltip] = useState(false)
+
+ if (!currency || !currency.isToken) {
+ return null
+ }
+
+ const onPressCopyAddress = async (): Promise => {
+ await setClipboard(currency.address)
+
+ if (isInterface) {
+ setShowTooltip(true)
+ setTimeout(() => {
+ setShowTooltip(false)
+ }, 1000)
+ } else {
+ dispatch(pushNotification({ type: AppNotificationType.Copied, copyType: CopyNotificationType.ContractAddress }))
+ }
+
+ sendAnalyticsEvent(SharedEventName.ELEMENT_CLICKED, {
+ element: ElementName.Copy,
+ modal: modalName,
+ })
+ }
+
+ return (
+
+
+
+
+ {currency.address}
+
+
+ }
+ showTooltip={showTooltip}
+ trigger={
+
+
+
+ }
+ />
+
+
+ )
+}
diff --git a/packages/uniswap/src/features/bridging/constants.ts b/packages/uniswap/src/features/bridging/constants.ts
index 2c31fbd5fa2..a4000ac9ecf 100644
--- a/packages/uniswap/src/features/bridging/constants.ts
+++ b/packages/uniswap/src/features/bridging/constants.ts
@@ -1,5 +1,5 @@
-import { UNIVERSE_CHAIN_INFO } from 'uniswap/src/constants/chains'
-import { UniverseChainId } from 'uniswap/src/types/chains'
+import { getChainInfo } from 'uniswap/src/features/chains/chainInfo'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { extractBaseUrl } from 'utilities/src/format/urls'
/*
@@ -66,7 +66,7 @@ export const BRIDGING_DAPP_URLS = [
export function getCanonicalBridgingDappUrls(chainIds: UniverseChainId[]): string[] {
const canonicalUrls = chainIds
.map((chainId) => {
- const chainInfo = UNIVERSE_CHAIN_INFO[chainId]
+ const chainInfo = getChainInfo(chainId)
return chainInfo?.bridge ? extractBaseUrl(chainInfo.bridge) : undefined
})
.filter((url): url is string => url !== undefined)
diff --git a/packages/uniswap/src/features/bridging/hooks/chains.ts b/packages/uniswap/src/features/bridging/hooks/chains.ts
index e894266386c..a21081e2aa2 100644
--- a/packages/uniswap/src/features/bridging/hooks/chains.ts
+++ b/packages/uniswap/src/features/bridging/hooks/chains.ts
@@ -1,12 +1,12 @@
import { useMemo } from 'react'
import { useTradingApiSwappableTokensQuery } from 'uniswap/src/data/apiClients/tradingApi/useTradingApiSwappableTokensQuery'
import { ChainId } from 'uniswap/src/data/tradingApi/__generated__'
+import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { toSupportedChainId } from 'uniswap/src/features/chains/utils'
import {
NATIVE_ADDRESS_FOR_TRADING_API,
toTradingApiSupportedChainId,
} from 'uniswap/src/features/transactions/swap/utils/tradingApi'
-import { UniverseChainId } from 'uniswap/src/types/chains'
const FALLBACK_NUM_CHAINS = 8
diff --git a/packages/uniswap/src/features/bridging/hooks/tokens.ts b/packages/uniswap/src/features/bridging/hooks/tokens.ts
index ac6e6feb584..7d5057de5ce 100644
--- a/packages/uniswap/src/features/bridging/hooks/tokens.ts
+++ b/packages/uniswap/src/features/bridging/hooks/tokens.ts
@@ -1,6 +1,6 @@
import { useCallback, useMemo } from 'react'
import { filter } from 'uniswap/src/components/TokenSelector/filter'
-import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks'
+import { usePortfolioBalancesForAddressById } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioBalancesForAddressById'
import { TokenOption } from 'uniswap/src/components/TokenSelector/types'
import { createEmptyTokenOptionFromBridgingToken } from 'uniswap/src/components/TokenSelector/utils'
import { useTradingApiSwappableTokensQuery } from 'uniswap/src/data/apiClients/tradingApi/useTradingApiSwappableTokensQuery'
@@ -10,17 +10,15 @@ import { useTokenProjectsQuery } from 'uniswap/src/data/graphql/uniswap-data-api
import { GetSwappableTokensResponse } from 'uniswap/src/data/tradingApi/__generated__'
import { GqlResult } from 'uniswap/src/data/types'
import { TradeableAsset } from 'uniswap/src/entities/assets'
+import { ALL_CHAIN_IDS, UniverseChainId } from 'uniswap/src/features/chains/types'
import { toSupportedChainId } from 'uniswap/src/features/chains/utils'
import { CurrencyInfo, PortfolioBalance } from 'uniswap/src/features/dataApi/types'
import { currencyIdToContractInput } from 'uniswap/src/features/dataApi/utils'
-import { FeatureFlags } from 'uniswap/src/features/gating/flags'
-import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import {
NATIVE_ADDRESS_FOR_TRADING_API,
getTokenAddressFromChainForTradingApi,
toTradingApiSupportedChainId,
} from 'uniswap/src/features/transactions/swap/utils/tradingApi'
-import { COMBINED_CHAIN_IDS, UniverseChainId } from 'uniswap/src/types/chains'
import { buildCurrencyId, buildNativeCurrencyId } from 'uniswap/src/utils/currencyId'
import { logger } from 'utilities/src/logger/logger'
@@ -39,8 +37,6 @@ export function useBridgingTokenWithHighestBalance({
currencyInfo: CurrencyInfo
}
| undefined {
- const isBridgingEnabled = useFeatureFlag(FeatureFlags.Bridging)
-
const currencyId = buildCurrencyId(currencyChainId, currencyAddress)
const tokenIn = currencyAddress ? getTokenAddressFromChainForTradingApi(currencyAddress, currencyChainId) : undefined
const tokenInChainId = toTradingApiSupportedChainId(currencyChainId)
@@ -59,7 +55,7 @@ export function useBridgingTokenWithHighestBalance({
const { data: bridgingTokens } = useTradingApiSwappableTokensQuery({
params:
- otherChainBalances && otherChainBalances?.length > 0 && tokenIn && tokenInChainId && isBridgingEnabled
+ otherChainBalances && otherChainBalances?.length > 0 && tokenIn && tokenInChainId
? {
tokenIn,
tokenInChainId,
@@ -119,8 +115,6 @@ export function useBridgingTokensOptions({
walletAddress: Address | undefined
chainFilter: UniverseChainId | null
}): GqlResult & { shouldNest?: boolean } {
- const isBridgingEnabled = useFeatureFlag(FeatureFlags.Bridging)
-
const tokenIn = input?.address ? getTokenAddressFromChainForTradingApi(input.address, input.chainId) : undefined
const tokenInChainId = toTradingApiSupportedChainId(input?.chainId)
@@ -131,7 +125,7 @@ export function useBridgingTokensOptions({
refetch: refetchBridgingTokens,
} = useTradingApiSwappableTokensQuery({
params:
- tokenIn && tokenInChainId && isBridgingEnabled
+ tokenIn && tokenInChainId
? {
tokenIn,
tokenInChainId,
@@ -145,7 +139,7 @@ export function useBridgingTokensOptions({
error: portfolioBalancesByIdError,
refetch: portfolioBalancesByIdRefetch,
loading: loadingPorfolioBalancesById,
- } = usePortfolioBalancesForAddressById(isBridgingEnabled ? walletAddress : undefined)
+ } = usePortfolioBalancesForAddressById(walletAddress)
const tokenOptions = useBridgingTokensToTokenOptions(bridgingTokens?.tokens, portfolioBalancesById)
// Filter out tokens that are not on the current chain, unless the input token is the same as the current chain
@@ -159,20 +153,9 @@ export function useBridgingTokensOptions({
const error = (!portfolioBalancesById && portfolioBalancesByIdError) || (!tokenOptions && errorBridgingTokens)
const refetch = useCallback(async () => {
- if (isBridgingEnabled) {
- portfolioBalancesByIdRefetch?.()
- await refetchBridgingTokens?.()
- }
- }, [portfolioBalancesByIdRefetch, refetchBridgingTokens, isBridgingEnabled])
-
- if (!isBridgingEnabled) {
- return {
- data: undefined,
- loading: false,
- error: undefined,
- refetch: undefined,
- }
- }
+ portfolioBalancesByIdRefetch?.()
+ await refetchBridgingTokens?.()
+ }, [portfolioBalancesByIdRefetch, refetchBridgingTokens])
return {
data: filteredTokenOptions,
@@ -193,7 +176,7 @@ function useBridgingTokensToTokenOptions(
}
// We sort the tokens by chain in the same order chains in the network selector
- const chainOrder = COMBINED_CHAIN_IDS
+ const chainOrder = ALL_CHAIN_IDS
const sortedBridgingTokens = [...bridgingTokens].sort((a, b) => {
if (!a || !b) {
return 0
diff --git a/packages/uniswap/src/constants/chains.ts b/packages/uniswap/src/features/chains/chainInfo.ts
similarity index 87%
rename from packages/uniswap/src/constants/chains.ts
rename to packages/uniswap/src/features/chains/chainInfo.ts
index cb3b5d66e51..d79f8256942 100644
--- a/packages/uniswap/src/constants/chains.ts
+++ b/packages/uniswap/src/features/chains/chainInfo.ts
@@ -39,15 +39,15 @@ import {
USDT,
} from 'uniswap/src/constants/tokens'
import { Chain as BackendChainId } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
-import { ElementName } from 'uniswap/src/features/telemetry/constants'
import {
- InterfaceGqlChain,
+ GqlChainId,
NetworkLayer,
RPCType,
RetryOptions,
UniverseChainId,
UniverseChainInfo,
-} from 'uniswap/src/types/chains'
+} from 'uniswap/src/features/chains/types'
+import { ElementName } from 'uniswap/src/features/telemetry/constants'
import { isInterface } from 'utilities/src/platform'
import { ONE_MINUTE_MS } from 'utilities/src/time/time'
import {
@@ -71,6 +71,10 @@ export const DEFAULT_RETRY_OPTIONS: RetryOptions = { n: 10, minWait: 250, maxWai
export const DEFAULT_MS_BEFORE_WARNING = ONE_MINUTE_MS * 10
+export function getChainInfo(chainId: UniverseChainId): UniverseChainInfo {
+ return UNIVERSE_CHAIN_INFO[chainId]
+}
+
export const UNIVERSE_CHAIN_INFO: Record = {
[UniverseChainId.Mainnet]: {
...mainnet,
@@ -78,7 +82,7 @@ export const UNIVERSE_CHAIN_INFO: Record = {
sdkId: UniswapSDKChainId.MAINNET,
assetRepoNetworkName: 'ethereum',
backendChain: {
- chain: BackendChainId.Ethereum as InterfaceGqlChain,
+ chain: BackendChainId.Ethereum as GqlChainId,
backendSupported: true,
isSecondaryChain: false,
nativeTokenBackendAddress: undefined,
@@ -117,13 +121,13 @@ export const UNIVERSE_CHAIN_INFO: Record = {
[RPCType.Public]: {
http: [config.quicknodeMainnetRpcUrl],
},
- default: {
+ [RPCType.Default]: {
http: ['https://cloudflare-eth.com'],
},
- fallback: {
+ [RPCType.Fallback]: {
http: ['https://rpc.ankr.com/eth', 'https://eth-mainnet.public.blastapi.io'],
},
- appOnly: {
+ [RPCType.Interface]: {
http: [`https://mainnet.infura.io/v3/${config.infuraKey}`, config.quicknodeMainnetRpcUrl],
},
},
@@ -131,7 +135,7 @@ export const UNIVERSE_CHAIN_INFO: Record = {
statusPage: undefined,
spotPriceStablecoinAmount: CurrencyAmount.fromRawAmount(USDC, 100_000e6),
stablecoins: [USDC, DAI, USDT],
- supportsClientSideRouting: true,
+ supportsInterfaceClientSideRouting: true,
supportsGasEstimates: true,
wrappedNativeCurrency: {
name: 'Wrapped Ether',
@@ -146,7 +150,7 @@ export const UNIVERSE_CHAIN_INFO: Record = {
sdkId: UniswapSDKChainId.SEPOLIA,
assetRepoNetworkName: undefined,
backendChain: {
- chain: BackendChainId.EthereumSepolia as InterfaceGqlChain,
+ chain: BackendChainId.EthereumSepolia as GqlChainId,
backendSupported: true,
isSecondaryChain: false,
nativeTokenBackendAddress: undefined,
@@ -182,10 +186,10 @@ export const UNIVERSE_CHAIN_INFO: Record = {
[RPCType.Public]: {
http: [config.quicknodeSepoliaRpcUrl],
},
- default: {
+ [RPCType.Default]: {
http: ['https://rpc.sepolia.org/'],
},
- fallback: {
+ [RPCType.Fallback]: {
http: [
'https://rpc.sepolia.org/',
'https://rpc2.sepolia.org/',
@@ -195,12 +199,12 @@ export const UNIVERSE_CHAIN_INFO: Record = {
'https://rpc.bordel.wtf/sepolia',
],
},
- appOnly: { http: [`https://sepolia.infura.io/v3/${config.infuraKey}`] },
+ [RPCType.Interface]: { http: [`https://sepolia.infura.io/v3/${config.infuraKey}`] },
},
spotPriceStablecoinAmount: CurrencyAmount.fromRawAmount(USDC_SEPOLIA, 100e6),
stablecoins: [USDC_SEPOLIA],
statusPage: undefined,
- supportsClientSideRouting: true,
+ supportsInterfaceClientSideRouting: true,
supportsGasEstimates: false,
urlParam: 'ethereum_sepolia',
wrappedNativeCurrency: {
@@ -216,7 +220,7 @@ export const UNIVERSE_CHAIN_INFO: Record = {
sdkId: UniswapSDKChainId.ARBITRUM_ONE,
assetRepoNetworkName: 'arbitrum',
backendChain: {
- chain: BackendChainId.Arbitrum as InterfaceGqlChain,
+ chain: BackendChainId.Arbitrum as GqlChainId,
backendSupported: true,
isSecondaryChain: false,
nativeTokenBackendAddress: undefined,
@@ -251,14 +255,14 @@ export const UNIVERSE_CHAIN_INFO: Record