feat: add support for 0.01% tier (#2769)
* chore: add support for 0.01% tier * only show 1bps on mainnet * rename VERY_LOW to LOWEST * upgrade to v3-sdk 3.7.0 * add snapshot testing for lowest tier * fix integration test * fix integration test * use ALL_SUPPORTED_CHAIN_IDS over string all * consider 0.01% tier in pool (#2770) * merge main and only consider lowest tier for mainnet
This commit is contained in:
parent
8a99bad736
commit
408c907870
@ -5,6 +5,11 @@
|
||||
}
|
||||
},
|
||||
"asToken0": [
|
||||
{
|
||||
"feeTier": "100",
|
||||
"totalValueLockedToken0": "0",
|
||||
"totalValueLockedToken1": "3"
|
||||
},
|
||||
{
|
||||
"feeTier": "500",
|
||||
"totalValueLockedToken0": "0",
|
||||
@ -13,7 +18,7 @@
|
||||
{
|
||||
"feeTier": "3000",
|
||||
"totalValueLockedToken0": "0",
|
||||
"totalValueLockedToken1": "7"
|
||||
"totalValueLockedToken1": "4"
|
||||
},
|
||||
{
|
||||
"feeTier": "10000",
|
||||
|
@ -58,7 +58,7 @@ describe('Add Liquidity', () => {
|
||||
cy.wait('@feeTierDistributionQuery')
|
||||
|
||||
cy.get('#add-liquidity-selected-fee .selected-fee-label').should('contain.text', '0.3% fee tier')
|
||||
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '70%')
|
||||
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '40%')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -66,7 +66,7 @@
|
||||
"@uniswap/v2-sdk": "^3.0.0-alpha.2",
|
||||
"@uniswap/v3-core": "1.0.0",
|
||||
"@uniswap/v3-periphery": "^1.1.1",
|
||||
"@uniswap/v3-sdk": "3.6.3",
|
||||
"@uniswap/v3-sdk": "^3.7.1",
|
||||
"@web3-react/core": "^6.0.9",
|
||||
"@web3-react/fortmatic-connector": "^6.0.9",
|
||||
"@web3-react/injected-connector": "^6.0.7",
|
||||
|
@ -315,8 +315,8 @@ const ActiveOutlined = styled(ButtonOutlined)`
|
||||
`
|
||||
|
||||
const Circle = styled.div`
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
height: 17px;
|
||||
width: 17px;
|
||||
border-radius: 50%;
|
||||
background-color: ${({ theme }) => theme.primary1};
|
||||
display: flex;
|
||||
@ -325,11 +325,11 @@ const Circle = styled.div`
|
||||
`
|
||||
|
||||
const CheckboxWrapper = styled.div`
|
||||
width: 30px;
|
||||
width: 20px;
|
||||
padding: 0 10px;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
top: 11px;
|
||||
right: 15px;
|
||||
`
|
||||
|
||||
const ResponsiveCheck = styled(Check)`
|
||||
|
51
src/components/FeeSelector/FeeOption.tsx
Normal file
51
src/components/FeeSelector/FeeOption.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { FeeAmount } from '@uniswap/v3-sdk'
|
||||
import { ButtonRadioChecked } from 'components/Button'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { useFeeTierDistribution } from 'hooks/useFeeTierDistribution'
|
||||
import { PoolState } from 'hooks/usePools'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components/macro'
|
||||
import { TYPE } from 'theme'
|
||||
|
||||
import { FeeTierPercentageBadge } from './FeeTierPercentageBadge'
|
||||
import { FEE_AMOUNT_DETAIL } from './shared'
|
||||
|
||||
const ResponsiveText = styled(TYPE.label)`
|
||||
line-height: 16px;
|
||||
font-size: 14px;
|
||||
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
`};
|
||||
`
|
||||
|
||||
interface FeeOptionProps {
|
||||
feeAmount: FeeAmount
|
||||
active: boolean
|
||||
distributions: ReturnType<typeof useFeeTierDistribution>['distributions']
|
||||
poolState: PoolState
|
||||
onClick: () => void
|
||||
}
|
||||
|
||||
export function FeeOption({ feeAmount, active, poolState, distributions, onClick }: FeeOptionProps) {
|
||||
return (
|
||||
<ButtonRadioChecked active={active} onClick={onClick}>
|
||||
<AutoColumn gap="sm" justify="flex-start">
|
||||
<AutoColumn justify="flex-start" gap="6px">
|
||||
<ResponsiveText>
|
||||
<Trans>{FEE_AMOUNT_DETAIL[feeAmount].label}%</Trans>
|
||||
</ResponsiveText>
|
||||
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
|
||||
{FEE_AMOUNT_DETAIL[feeAmount].description}
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
|
||||
{distributions && (
|
||||
<FeeTierPercentageBadge distributions={distributions} feeAmount={feeAmount} poolState={poolState} />
|
||||
)}
|
||||
</AutoColumn>
|
||||
</ButtonRadioChecked>
|
||||
)
|
||||
}
|
31
src/components/FeeSelector/FeeTierPercentageBadge.tsx
Normal file
31
src/components/FeeSelector/FeeTierPercentageBadge.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { FeeAmount } from '@uniswap/v3-sdk'
|
||||
import Badge from 'components/Badge'
|
||||
import { useFeeTierDistribution } from 'hooks/useFeeTierDistribution'
|
||||
import { PoolState } from 'hooks/usePools'
|
||||
import React from 'react'
|
||||
import { TYPE } from 'theme'
|
||||
|
||||
export function FeeTierPercentageBadge({
|
||||
feeAmount,
|
||||
distributions,
|
||||
poolState,
|
||||
}: {
|
||||
feeAmount: FeeAmount
|
||||
distributions: ReturnType<typeof useFeeTierDistribution>['distributions']
|
||||
poolState: PoolState
|
||||
}) {
|
||||
return (
|
||||
<Badge>
|
||||
<TYPE.label fontSize={11}>
|
||||
{!distributions || poolState === PoolState.NOT_EXISTS || poolState === PoolState.INVALID ? (
|
||||
<Trans>Not created</Trans>
|
||||
) : distributions[feeAmount] !== undefined ? (
|
||||
<Trans>{distributions[feeAmount]?.toFixed(0)}% select</Trans>
|
||||
) : (
|
||||
<Trans>No data</Trans>
|
||||
)}
|
||||
</TYPE.label>
|
||||
</Badge>
|
||||
)
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { Currency } from '@uniswap/sdk-core'
|
||||
import { FeeAmount } from '@uniswap/v3-sdk'
|
||||
import Badge from 'components/Badge'
|
||||
import { ButtonGray, ButtonRadioChecked } from 'components/Button'
|
||||
import { ButtonGray } from 'components/Button'
|
||||
import Card from 'components/Card'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { RowBetween } from 'components/Row'
|
||||
import { useFeeTierDistribution } from 'hooks/useFeeTierDistribution'
|
||||
import { PoolState, usePools } from 'hooks/usePools'
|
||||
import usePrevious from 'hooks/usePrevious'
|
||||
import { useActiveWeb3React } from 'hooks/web3'
|
||||
import { DynamicSection } from 'pages/AddLiquidity/styled'
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import ReactGA from 'react-ga'
|
||||
@ -16,6 +16,10 @@ import { Box } from 'rebass'
|
||||
import styled, { keyframes } from 'styled-components/macro'
|
||||
import { TYPE } from 'theme'
|
||||
|
||||
import { FeeOption } from './FeeOption'
|
||||
import { FeeTierPercentageBadge } from './FeeTierPercentageBadge'
|
||||
import { FEE_AMOUNT_DETAIL } from './shared'
|
||||
|
||||
const pulse = (color: string) => keyframes`
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 ${color};
|
||||
@ -29,60 +33,18 @@ const pulse = (color: string) => keyframes`
|
||||
box-shadow: 0 0 0 0 ${color};
|
||||
}
|
||||
`
|
||||
|
||||
const ResponsiveText = styled(TYPE.label)`
|
||||
line-height: 16px;
|
||||
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
`};
|
||||
`
|
||||
|
||||
const FocusedOutlineCard = styled(Card)<{ pulsing: boolean }>`
|
||||
border: 1px solid ${({ theme }) => theme.bg2};
|
||||
animation: ${({ pulsing, theme }) => pulsing && pulse(theme.primary1)} 0.6s linear;
|
||||
align-self: center;
|
||||
`
|
||||
|
||||
const FeeAmountLabel = {
|
||||
[FeeAmount.LOW]: {
|
||||
label: '0.05',
|
||||
description: <Trans>Best for stable pairs.</Trans>,
|
||||
},
|
||||
[FeeAmount.MEDIUM]: {
|
||||
label: '0.3',
|
||||
description: <Trans>Best for most pairs.</Trans>,
|
||||
},
|
||||
[FeeAmount.HIGH]: {
|
||||
label: '1',
|
||||
description: <Trans>Best for exotic pairs.</Trans>,
|
||||
},
|
||||
}
|
||||
|
||||
function FeeTierPercentageBadge({
|
||||
feeAmount,
|
||||
distributions,
|
||||
poolState,
|
||||
}: {
|
||||
feeAmount: FeeAmount
|
||||
distributions: ReturnType<typeof useFeeTierDistribution>['distributions']
|
||||
poolState: PoolState
|
||||
}) {
|
||||
return (
|
||||
<Badge>
|
||||
<TYPE.label fontSize={12}>
|
||||
{!distributions || poolState === PoolState.NOT_EXISTS || poolState === PoolState.INVALID ? (
|
||||
<Trans>Not created</Trans>
|
||||
) : distributions[feeAmount] !== undefined ? (
|
||||
<Trans>{distributions[feeAmount]?.toFixed(0)}% select</Trans>
|
||||
) : (
|
||||
<Trans>No data</Trans>
|
||||
)}
|
||||
</TYPE.label>
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
const Select = styled.div`
|
||||
align-items: flex-start;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-gap: 8px;
|
||||
`
|
||||
|
||||
export default function FeeSelector({
|
||||
disabled = false,
|
||||
@ -97,16 +59,19 @@ export default function FeeSelector({
|
||||
currencyA?: Currency | undefined
|
||||
currencyB?: Currency | undefined
|
||||
}) {
|
||||
const { chainId } = useActiveWeb3React()
|
||||
|
||||
const { isLoading, isError, largestUsageFeeTier, distributions } = useFeeTierDistribution(currencyA, currencyB)
|
||||
|
||||
// get pool data on-chain for latest states
|
||||
const pools = usePools([
|
||||
[currencyA, currencyB, FeeAmount.LOWEST],
|
||||
[currencyA, currencyB, FeeAmount.LOW],
|
||||
[currencyA, currencyB, FeeAmount.MEDIUM],
|
||||
[currencyA, currencyB, FeeAmount.HIGH],
|
||||
])
|
||||
|
||||
const poolsByFeeTier = useMemo(
|
||||
const poolsByFeeTier: Record<FeeAmount, PoolState> = useMemo(
|
||||
() =>
|
||||
pools.reduce(
|
||||
(acc, [curPoolState, curPool]) => {
|
||||
@ -118,6 +83,7 @@ export default function FeeSelector({
|
||||
},
|
||||
{
|
||||
// default all states to NOT_EXISTS
|
||||
[FeeAmount.LOWEST]: PoolState.NOT_EXISTS,
|
||||
[FeeAmount.LOW]: PoolState.NOT_EXISTS,
|
||||
[FeeAmount.MEDIUM]: PoolState.NOT_EXISTS,
|
||||
[FeeAmount.HIGH]: PoolState.NOT_EXISTS,
|
||||
@ -134,7 +100,7 @@ export default function FeeSelector({
|
||||
const recommended = useRef(false)
|
||||
|
||||
const handleFeePoolSelectWithEvent = useCallback(
|
||||
(fee) => {
|
||||
(fee: FeeAmount) => {
|
||||
ReactGA.event({
|
||||
category: 'FeePoolSelect',
|
||||
action: 'Manual',
|
||||
@ -193,7 +159,7 @@ export default function FeeSelector({
|
||||
) : (
|
||||
<>
|
||||
<TYPE.label className="selected-fee-label">
|
||||
<Trans>{FeeAmountLabel[feeAmount].label}% fee tier</Trans>
|
||||
<Trans>{FEE_AMOUNT_DETAIL[feeAmount].label}% fee tier</Trans>
|
||||
</TYPE.label>
|
||||
<Box style={{ width: 'fit-content', marginTop: '8px' }} className="selected-fee-percentage">
|
||||
{distributions && (
|
||||
@ -214,81 +180,25 @@ export default function FeeSelector({
|
||||
</RowBetween>
|
||||
</FocusedOutlineCard>
|
||||
|
||||
{showOptions && (
|
||||
<RowBetween>
|
||||
<ButtonRadioChecked
|
||||
width="32%"
|
||||
active={feeAmount === FeeAmount.LOW}
|
||||
onClick={() => handleFeePoolSelectWithEvent(FeeAmount.LOW)}
|
||||
>
|
||||
<AutoColumn gap="sm" justify="flex-start">
|
||||
<AutoColumn justify="flex-start" gap="6px">
|
||||
<ResponsiveText>
|
||||
<Trans>0.05% fee</Trans>
|
||||
</ResponsiveText>
|
||||
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
|
||||
<Trans>Best for stable pairs.</Trans>
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
|
||||
{distributions && (
|
||||
<FeeTierPercentageBadge
|
||||
{chainId && showOptions && (
|
||||
<Select>
|
||||
{[FeeAmount.LOWEST, FeeAmount.LOW, FeeAmount.MEDIUM, FeeAmount.HIGH].map((_feeAmount, i) => {
|
||||
const { supportedChains } = FEE_AMOUNT_DETAIL[_feeAmount]
|
||||
if (supportedChains.includes(chainId)) {
|
||||
return (
|
||||
<FeeOption
|
||||
feeAmount={_feeAmount}
|
||||
active={feeAmount === _feeAmount}
|
||||
onClick={() => handleFeePoolSelectWithEvent(_feeAmount)}
|
||||
distributions={distributions}
|
||||
feeAmount={FeeAmount.LOW}
|
||||
poolState={poolsByFeeTier[FeeAmount.LOW]}
|
||||
poolState={poolsByFeeTier[_feeAmount]}
|
||||
key={i}
|
||||
/>
|
||||
)}
|
||||
</AutoColumn>
|
||||
</ButtonRadioChecked>
|
||||
<ButtonRadioChecked
|
||||
width="32%"
|
||||
active={feeAmount === FeeAmount.MEDIUM}
|
||||
onClick={() => handleFeePoolSelectWithEvent(FeeAmount.MEDIUM)}
|
||||
>
|
||||
<AutoColumn gap="sm" justify="flex-start">
|
||||
<AutoColumn justify="flex-start" gap="4px">
|
||||
<ResponsiveText>
|
||||
<Trans>0.3% fee</Trans>
|
||||
</ResponsiveText>
|
||||
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
|
||||
<Trans>Best for most pairs.</Trans>
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
|
||||
{distributions && (
|
||||
<FeeTierPercentageBadge
|
||||
distributions={distributions}
|
||||
feeAmount={FeeAmount.MEDIUM}
|
||||
poolState={poolsByFeeTier[FeeAmount.MEDIUM]}
|
||||
/>
|
||||
)}
|
||||
</AutoColumn>
|
||||
</ButtonRadioChecked>
|
||||
<ButtonRadioChecked
|
||||
width="32%"
|
||||
active={feeAmount === FeeAmount.HIGH}
|
||||
onClick={() => handleFeePoolSelectWithEvent(FeeAmount.HIGH)}
|
||||
>
|
||||
<AutoColumn gap="sm" justify="flex-start">
|
||||
<AutoColumn justify="flex-start" gap="4px">
|
||||
<ResponsiveText>
|
||||
<Trans>1% fee</Trans>
|
||||
</ResponsiveText>
|
||||
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
|
||||
<Trans>Best for exotic pairs.</Trans>
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
|
||||
{distributions && (
|
||||
<FeeTierPercentageBadge
|
||||
distributions={distributions}
|
||||
feeAmount={FeeAmount.HIGH}
|
||||
poolState={poolsByFeeTier[FeeAmount.HIGH]}
|
||||
/>
|
||||
)}
|
||||
</AutoColumn>
|
||||
</ButtonRadioChecked>
|
||||
</RowBetween>
|
||||
)
|
||||
}
|
||||
return null
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</DynamicSection>
|
||||
</AutoColumn>
|
||||
|
30
src/components/FeeSelector/shared.tsx
Normal file
30
src/components/FeeSelector/shared.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { FeeAmount } from '@uniswap/v3-sdk'
|
||||
import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from 'constants/chains'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
export const FEE_AMOUNT_DETAIL: Record<
|
||||
FeeAmount,
|
||||
{ label: string; description: ReactNode; supportedChains: SupportedChainId[] }
|
||||
> = {
|
||||
[FeeAmount.LOWEST]: {
|
||||
label: '0.01',
|
||||
description: <Trans>Best for very stable pairs.</Trans>,
|
||||
supportedChains: [SupportedChainId.MAINNET],
|
||||
},
|
||||
[FeeAmount.LOW]: {
|
||||
label: '0.05',
|
||||
description: <Trans>Best for stable pairs.</Trans>,
|
||||
supportedChains: ALL_SUPPORTED_CHAIN_IDS,
|
||||
},
|
||||
[FeeAmount.MEDIUM]: {
|
||||
label: '0.3',
|
||||
description: <Trans>Best for most pairs.</Trans>,
|
||||
supportedChains: ALL_SUPPORTED_CHAIN_IDS,
|
||||
},
|
||||
[FeeAmount.HIGH]: {
|
||||
label: '1',
|
||||
description: <Trans>Best for exotic pairs.</Trans>,
|
||||
supportedChains: ALL_SUPPORTED_CHAIN_IDS,
|
||||
},
|
||||
}
|
@ -20,6 +20,12 @@ import { useDensityChartData } from './hooks'
|
||||
import { ZoomLevels } from './types'
|
||||
|
||||
const ZOOM_LEVELS: Record<FeeAmount, ZoomLevels> = {
|
||||
[FeeAmount.LOWEST]: {
|
||||
initialMin: 0.999,
|
||||
initialMax: 1.001,
|
||||
min: 0.00001,
|
||||
max: 1.5,
|
||||
},
|
||||
[FeeAmount.LOW]: {
|
||||
initialMin: 0.999,
|
||||
initialMax: 1.001,
|
||||
|
@ -10,7 +10,7 @@ const percent = (strings: TemplateStringsArray) => new Percent(parseInt(strings[
|
||||
const singleRoute: RoutingDiagramEntry = { percent: percent`100`, path: [[USDC, DAI, FeeAmount.LOW]] }
|
||||
|
||||
const multiRoute: RoutingDiagramEntry[] = [
|
||||
{ percent: percent`75`, path: [[USDC, DAI, FeeAmount.LOW]] },
|
||||
{ percent: percent`75`, path: [[USDC, DAI, FeeAmount.LOWEST]] },
|
||||
{
|
||||
percent: percent`25`,
|
||||
path: [
|
||||
|
@ -47,7 +47,7 @@ exports[`renders multi route 1`] = `
|
||||
<div
|
||||
class="theme__TextWrapper-sc-18nh1jk-0 cWOfab css-15li2d9"
|
||||
>
|
||||
0.05%
|
||||
0.01%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,11 +19,7 @@ interface FeeTierDistribution {
|
||||
largestUsageFeeTier?: FeeAmount | undefined
|
||||
|
||||
// distributions as percentages of overall liquidity
|
||||
distributions?: {
|
||||
[FeeAmount.LOW]: number | undefined
|
||||
[FeeAmount.MEDIUM]: number | undefined
|
||||
[FeeAmount.HIGH]: number | undefined
|
||||
}
|
||||
distributions?: Record<FeeAmount, number | undefined>
|
||||
}
|
||||
|
||||
export function useFeeTierDistribution(
|
||||
@ -36,6 +32,7 @@ export function useFeeTierDistribution(
|
||||
)
|
||||
|
||||
// fetch all pool states to determine pool state
|
||||
const [poolStateVeryLow] = usePool(currencyA, currencyB, FeeAmount.LOWEST)
|
||||
const [poolStateLow] = usePool(currencyA, currencyB, FeeAmount.LOW)
|
||||
const [poolStateMedium] = usePool(currencyA, currencyB, FeeAmount.MEDIUM)
|
||||
const [poolStateHigh] = usePool(currencyA, currencyB, FeeAmount.HIGH)
|
||||
@ -58,10 +55,13 @@ export function useFeeTierDistribution(
|
||||
!isLoading &&
|
||||
!isError &&
|
||||
distributions &&
|
||||
poolStateVeryLow !== PoolState.LOADING &&
|
||||
poolStateLow !== PoolState.LOADING &&
|
||||
poolStateMedium !== PoolState.LOADING &&
|
||||
poolStateHigh !== PoolState.LOADING
|
||||
? {
|
||||
[FeeAmount.LOWEST]:
|
||||
poolStateVeryLow === PoolState.EXISTS ? (distributions[FeeAmount.LOWEST] ?? 0) * 100 : undefined,
|
||||
[FeeAmount.LOW]: poolStateLow === PoolState.EXISTS ? (distributions[FeeAmount.LOW] ?? 0) * 100 : undefined,
|
||||
[FeeAmount.MEDIUM]:
|
||||
poolStateMedium === PoolState.EXISTS ? (distributions[FeeAmount.MEDIUM] ?? 0) * 100 : undefined,
|
||||
@ -76,7 +76,17 @@ export function useFeeTierDistribution(
|
||||
distributions: percentages,
|
||||
largestUsageFeeTier: largestUsageFeeTier === -1 ? undefined : largestUsageFeeTier,
|
||||
}
|
||||
}, [isLoading, isFetching, isUninitialized, isError, distributions, poolStateLow, poolStateMedium, poolStateHigh])
|
||||
}, [
|
||||
isLoading,
|
||||
isFetching,
|
||||
isUninitialized,
|
||||
isError,
|
||||
distributions,
|
||||
poolStateVeryLow,
|
||||
poolStateLow,
|
||||
poolStateMedium,
|
||||
poolStateHigh,
|
||||
])
|
||||
}
|
||||
|
||||
function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
|
||||
@ -124,10 +134,11 @@ function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
|
||||
return acc
|
||||
},
|
||||
{
|
||||
[FeeAmount.LOWEST]: [undefined, undefined],
|
||||
[FeeAmount.LOW]: [undefined, undefined],
|
||||
[FeeAmount.MEDIUM]: [undefined, undefined],
|
||||
[FeeAmount.HIGH]: [undefined, undefined],
|
||||
}
|
||||
} as Record<FeeAmount, [number | undefined, number | undefined]>
|
||||
)
|
||||
|
||||
// sum total tvl for token0 and token1
|
||||
@ -144,7 +155,13 @@ function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
|
||||
const mean = (tvl0: number | undefined, sumTvl0: number, tvl1: number | undefined, sumTvl1: number) =>
|
||||
tvl0 === undefined && tvl1 === undefined ? undefined : ((tvl0 ?? 0) + (tvl1 ?? 0)) / (sumTvl0 + sumTvl1) || 0
|
||||
|
||||
const distributions = {
|
||||
const distributions: Record<FeeAmount, number | undefined> = {
|
||||
[FeeAmount.LOWEST]: mean(
|
||||
tvlByFeeTier[FeeAmount.LOWEST][0],
|
||||
sumToken0Tvl,
|
||||
tvlByFeeTier[FeeAmount.LOWEST][1],
|
||||
sumToken1Tvl
|
||||
),
|
||||
[FeeAmount.LOW]: mean(tvlByFeeTier[FeeAmount.LOW][0], sumToken0Tvl, tvlByFeeTier[FeeAmount.LOW][1], sumToken1Tvl),
|
||||
[FeeAmount.MEDIUM]: mean(
|
||||
tvlByFeeTier[FeeAmount.MEDIUM][0],
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { Currency, Token } from '@uniswap/sdk-core'
|
||||
import { FeeAmount, Pool } from '@uniswap/v3-sdk'
|
||||
import { SupportedChainId } from 'constants/chains'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { useAllCurrencyCombinations } from './useAllCurrencyCombinations'
|
||||
import { PoolState, usePools } from './usePools'
|
||||
import { useActiveWeb3React } from './web3'
|
||||
|
||||
/**
|
||||
* Returns all the existing pools that should be considered for swapping between an input currency and an output currency
|
||||
@ -17,18 +19,27 @@ export function useV3SwapPools(
|
||||
pools: Pool[]
|
||||
loading: boolean
|
||||
} {
|
||||
const { chainId } = useActiveWeb3React()
|
||||
|
||||
const allCurrencyCombinations = useAllCurrencyCombinations(currencyIn, currencyOut)
|
||||
|
||||
const allCurrencyCombinationsWithAllFees: [Token, Token, FeeAmount][] = useMemo(
|
||||
() =>
|
||||
allCurrencyCombinations.reduce<[Token, Token, FeeAmount][]>((list, [tokenA, tokenB]) => {
|
||||
return list.concat([
|
||||
[tokenA, tokenB, FeeAmount.LOW],
|
||||
[tokenA, tokenB, FeeAmount.MEDIUM],
|
||||
[tokenA, tokenB, FeeAmount.HIGH],
|
||||
])
|
||||
return chainId === SupportedChainId.MAINNET
|
||||
? list.concat([
|
||||
[tokenA, tokenB, FeeAmount.LOW],
|
||||
[tokenA, tokenB, FeeAmount.MEDIUM],
|
||||
[tokenA, tokenB, FeeAmount.HIGH],
|
||||
])
|
||||
: list.concat([
|
||||
[tokenA, tokenB, FeeAmount.LOWEST],
|
||||
[tokenA, tokenB, FeeAmount.LOW],
|
||||
[tokenA, tokenB, FeeAmount.MEDIUM],
|
||||
[tokenA, tokenB, FeeAmount.HIGH],
|
||||
])
|
||||
}, []),
|
||||
[allCurrencyCombinations]
|
||||
[allCurrencyCombinations, chainId]
|
||||
)
|
||||
|
||||
const pools = usePools(allCurrencyCombinationsWithAllFees)
|
||||
|
@ -4666,10 +4666,10 @@
|
||||
base64-sol "1.0.1"
|
||||
hardhat-watcher "^2.1.1"
|
||||
|
||||
"@uniswap/v3-sdk@3.6.3":
|
||||
version "3.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.6.3.tgz#f2fca86cfde1450976581028195fc0ee4b11036d"
|
||||
integrity sha512-nepNTZMpM1uwLJAlQaUUEDMFrSujS1sOqyVD739zoPWsVHAUPvqVAKQN0GlgZcLXOqeCMKjO3lteaNHEXef1XA==
|
||||
"@uniswap/v3-sdk@^3.7.1":
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.7.1.tgz#8a3740ff6302d8069e7ce4a38b7588721398048b"
|
||||
integrity sha512-/0FBsrRijfAEOVO0ejCQX36MwaKzjKCaInUA1dNqFyDNZ5dthvv6jUhMADYuNXZnhN6NcSdIj6xhlc/cpgPm9Q==
|
||||
dependencies:
|
||||
"@ethersproject/abi" "^5.0.12"
|
||||
"@ethersproject/solidity" "^5.0.9"
|
||||
|
Loading…
Reference in New Issue
Block a user