Commit b40163ce authored by Noah Zinsmeister's avatar Noah Zinsmeister Committed by GitHub

allow fee collection/liquidity removal in weth (#1553)

* add dummy flags for burn/collect as weth

* add toggles

* clean up toggle position

* only show weth toggle if collection is possible
parent 809902ef
...@@ -3,16 +3,18 @@ import { useEffect, useState } from 'react' ...@@ -3,16 +3,18 @@ import { useEffect, useState } from 'react'
import { useV3NFTPositionManagerContract } from './useContract' import { useV3NFTPositionManagerContract } from './useContract'
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { Pool } from '@uniswap/v3-sdk' import { Pool } from '@uniswap/v3-sdk'
import { CurrencyAmount, Token } from '@uniswap/sdk-core' import { CurrencyAmount, Token, currencyEquals, ETHER, Ether } from '@uniswap/sdk-core'
import { useBlockNumber } from 'state/application/hooks' import { useBlockNumber } from 'state/application/hooks'
import { unwrappedToken } from 'utils/wrappedCurrency'
const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1) const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1)
// compute current + counterfactual fees for a v3 position // compute current + counterfactual fees for a v3 position
export function useV3PositionFees( export function useV3PositionFees(
pool?: Pool, pool?: Pool,
tokenId?: BigNumber tokenId?: BigNumber,
): [CurrencyAmount<Token>, CurrencyAmount<Token>] | [undefined, undefined] { asWETH = false
): [CurrencyAmount<Token | Ether>, CurrencyAmount<Token | Ether>] | [undefined, undefined] {
const positionManager = useV3NFTPositionManagerContract(false) const positionManager = useV3NFTPositionManagerContract(false)
const owner = useSingleCallResult(tokenId ? positionManager : null, 'ownerOf', [tokenId]).result?.[0] const owner = useSingleCallResult(tokenId ? positionManager : null, 'ownerOf', [tokenId]).result?.[0]
...@@ -43,8 +45,12 @@ export function useV3PositionFees( ...@@ -43,8 +45,12 @@ export function useV3PositionFees(
if (pool && amounts) { if (pool && amounts) {
return [ return [
CurrencyAmount.fromRawAmount(pool.token0, amounts[0].toString()), !asWETH && currencyEquals(unwrappedToken(pool.token0), ETHER)
CurrencyAmount.fromRawAmount(pool.token1, amounts[1].toString()), ? CurrencyAmount.ether(amounts[0].toString())
: CurrencyAmount.fromRawAmount(pool.token0, amounts[0].toString()),
!asWETH && currencyEquals(unwrappedToken(pool.token1), ETHER)
? CurrencyAmount.ether(amounts[1].toString())
: CurrencyAmount.fromRawAmount(pool.token1, amounts[1].toString()),
] ]
} else { } else {
return [undefined, undefined] return [undefined, undefined]
......
...@@ -5,7 +5,7 @@ import { PoolState, usePool } from 'hooks/usePools' ...@@ -5,7 +5,7 @@ import { PoolState, usePool } from 'hooks/usePools'
import { useToken } from 'hooks/Tokens' import { useToken } from 'hooks/Tokens'
import { useV3PositionFromTokenId } from 'hooks/useV3Positions' import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { Link, RouteComponentProps } from 'react-router-dom' import { Link, RouteComponentProps } from 'react-router-dom'
import { unwrappedToken } from 'utils/wrappedCurrency' import { unwrappedToken, wrappedCurrencyAmount } from 'utils/wrappedCurrency'
import { usePositionTokenURI } from '../../hooks/usePositionTokenURI' import { usePositionTokenURI } from '../../hooks/usePositionTokenURI'
import { LoadingRows } from './styleds' import { LoadingRows } from './styleds'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
...@@ -23,7 +23,7 @@ import { currencyId } from 'utils/currencyId' ...@@ -23,7 +23,7 @@ import { currencyId } from 'utils/currencyId'
import { formatTokenAmount } from 'utils/formatTokenAmount' import { formatTokenAmount } from 'utils/formatTokenAmount'
import { useV3PositionFees } from 'hooks/useV3PositionFees' import { useV3PositionFees } from 'hooks/useV3PositionFees'
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { Token, WETH9, Currency, CurrencyAmount, Percent, Fraction, Price, currencyEquals } from '@uniswap/sdk-core' import { Token, Currency, CurrencyAmount, Percent, Fraction, Price, Ether } from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks' import { useActiveWeb3React } from 'hooks'
import { useV3NFTPositionManagerContract } from 'hooks/useContract' import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import { useIsTransactionPending, useTransactionAdder } from 'state/transactions/hooks' import { useIsTransactionPending, useTransactionAdder } from 'state/transactions/hooks'
...@@ -38,6 +38,7 @@ import { useSingleCallResult } from 'state/multicall/hooks' ...@@ -38,6 +38,7 @@ import { useSingleCallResult } from 'state/multicall/hooks'
import RangeBadge from '../../components/Badge/RangeBadge' import RangeBadge from '../../components/Badge/RangeBadge'
import useUSDCPrice from 'hooks/useUSDCPrice' import useUSDCPrice from 'hooks/useUSDCPrice'
import Loader from 'components/Loader' import Loader from 'components/Loader'
import Toggle from 'components/Toggle'
const PageWrapper = styled.div` const PageWrapper = styled.div`
min-width: 800px; min-width: 800px;
...@@ -269,8 +270,11 @@ export function PositionPage({ ...@@ -269,8 +270,11 @@ export function PositionPage({
const currency0 = token0 ? unwrappedToken(token0) : undefined const currency0 = token0 ? unwrappedToken(token0) : undefined
const currency1 = token1 ? unwrappedToken(token1) : undefined const currency1 = token1 ? unwrappedToken(token1) : undefined
// flag for receiving WETH
const [receiveWETH, setReceiveWETH] = useState(false)
// construct Position from details returned // construct Position from details returned
const [poolState, pool] = usePool(currency0 ?? undefined, currency1 ?? undefined, feeAmount) const [poolState, pool] = usePool(token0 ?? undefined, token1 ?? undefined, feeAmount)
const position = useMemo(() => { const position = useMemo(() => {
if (pool && liquidity && typeof tickLower === 'number' && typeof tickUpper === 'number') { if (pool && liquidity && typeof tickLower === 'number' && typeof tickUpper === 'number') {
return new Position({ pool, liquidity: liquidity.toString(), tickLower, tickUpper }) return new Position({ pool, liquidity: liquidity.toString(), tickLower, tickUpper })
...@@ -304,7 +308,7 @@ export function PositionPage({ ...@@ -304,7 +308,7 @@ export function PositionPage({
}, [inverted, pool, priceLower, priceUpper]) }, [inverted, pool, priceLower, priceUpper])
// fees // fees
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, positionDetails?.tokenId) const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, positionDetails?.tokenId, receiveWETH)
const [collecting, setCollecting] = useState<boolean>(false) const [collecting, setCollecting] = useState<boolean>(false)
const [collectMigrationHash, setCollectMigrationHash] = useState<string | null>(null) const [collectMigrationHash, setCollectMigrationHash] = useState<string | null>(null)
...@@ -320,12 +324,8 @@ export function PositionPage({ ...@@ -320,12 +324,8 @@ export function PositionPage({
const { calldata, value } = NonfungiblePositionManager.collectCallParameters({ const { calldata, value } = NonfungiblePositionManager.collectCallParameters({
tokenId: tokenId.toString(), tokenId: tokenId.toString(),
expectedCurrencyOwed0: currencyEquals(feeValue0.currency, WETH9[chainId]) expectedCurrencyOwed0: feeValue0,
? CurrencyAmount.ether(feeValue0.quotient) expectedCurrencyOwed1: feeValue1,
: feeValue0,
expectedCurrencyOwed1: currencyEquals(feeValue1.currency, WETH9[chainId])
? CurrencyAmount.ether(feeValue1.quotient)
: feeValue1,
recipient: account, recipient: account,
}) })
...@@ -371,15 +371,23 @@ export function PositionPage({ ...@@ -371,15 +371,23 @@ export function PositionPage({
const owner = useSingleCallResult(!!tokenId ? positionManager : null, 'ownerOf', [tokenId]).result?.[0] const owner = useSingleCallResult(!!tokenId ? positionManager : null, 'ownerOf', [tokenId]).result?.[0]
const ownsNFT = owner === account || positionDetails?.operator === account const ownsNFT = owner === account || positionDetails?.operator === account
// usdc prices always in terms of tokens
const price0 = useUSDCPrice(token0 ?? undefined) const price0 = useUSDCPrice(token0 ?? undefined)
const price1 = useUSDCPrice(token1 ?? undefined) const price1 = useUSDCPrice(token1 ?? undefined)
const fiatValueOfFees: CurrencyAmount<Token> | null = useMemo(() => { const fiatValueOfFees: CurrencyAmount<Token | Ether> | null = useMemo(() => {
if (!price0 || !price1 || !feeValue0 || !feeValue1) return null if (!price0 || !price1 || !feeValue0 || !feeValue1) return null
const amount0 = price0.quote(feeValue0)
const amount1 = price1.quote(feeValue1) // we wrap because it doesn't matter, the quote returns a USDC amount
const feeValue0Wrapped = wrappedCurrencyAmount(feeValue0, chainId)
const feeValue1Wrapped = wrappedCurrencyAmount(feeValue1, chainId)
if (!feeValue0Wrapped || !feeValue1Wrapped) return null
const amount0 = price0.quote(feeValue0Wrapped)
const amount1 = price1.quote(feeValue1Wrapped)
return amount0.add(amount1) return amount0.add(amount1)
}, [price0, price1, feeValue0, feeValue1]) }, [price0, price1, feeValue0, feeValue1, chainId])
const fiatValueOfLiquidity: CurrencyAmount<Token> | null = useMemo(() => { const fiatValueOfLiquidity: CurrencyAmount<Token> | null = useMemo(() => {
if (!price0 || !price1 || !position) return null if (!price0 || !price1 || !position) return null
...@@ -388,6 +396,9 @@ export function PositionPage({ ...@@ -388,6 +396,9 @@ export function PositionPage({
return amount0.add(amount1) return amount0.add(amount1)
}, [price0, price1, position]) }, [price0, price1, position])
const feeValueUpper = inverted ? feeValue0 : feeValue1
const feeValueLower = inverted ? feeValue1 : feeValue0
function modalHeader() { function modalHeader() {
return ( return (
<AutoColumn gap={'md'} style={{ marginTop: '20px' }}> <AutoColumn gap={'md'} style={{ marginTop: '20px' }}>
...@@ -395,33 +406,17 @@ export function PositionPage({ ...@@ -395,33 +406,17 @@ export function PositionPage({
<AutoColumn gap="md"> <AutoColumn gap="md">
<RowBetween> <RowBetween>
<RowFixed> <RowFixed>
<CurrencyLogo currency={currencyQuote} size={'20px'} style={{ marginRight: '0.5rem' }} /> <CurrencyLogo currency={feeValueUpper?.currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main> <TYPE.main>{feeValueUpper ? formatTokenAmount(feeValueUpper, 4) : '-'}</TYPE.main>
{inverted
? feeValue0
? formatTokenAmount(feeValue0, 4)
: '-'
: feeValue1
? formatTokenAmount(feeValue1, 4)
: '-'}
</TYPE.main>
</RowFixed> </RowFixed>
<TYPE.main>{currencyQuote?.symbol}</TYPE.main> <TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
</RowBetween> </RowBetween>
<RowBetween> <RowBetween>
<RowFixed> <RowFixed>
<CurrencyLogo currency={currencyBase} size={'20px'} style={{ marginRight: '0.5rem' }} /> <CurrencyLogo currency={feeValueLower?.currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main> <TYPE.main>{feeValueLower ? formatTokenAmount(feeValueLower, 4) : '-'}</TYPE.main>
{inverted
? feeValue0
? formatTokenAmount(feeValue1, 4)
: '-'
: feeValue1
? formatTokenAmount(feeValue0, 4)
: '-'}
</TYPE.main>
</RowFixed> </RowFixed>
<TYPE.main>{currencyBase?.symbol}</TYPE.main> <TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
</RowBetween> </RowBetween>
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
...@@ -640,40 +635,44 @@ export function PositionPage({ ...@@ -640,40 +635,44 @@ export function PositionPage({
<AutoColumn gap="md"> <AutoColumn gap="md">
<RowBetween> <RowBetween>
<RowFixed> <RowFixed>
<CurrencyLogo currency={currencyQuote} size={'20px'} style={{ marginRight: '0.5rem' }} /> <CurrencyLogo
<TYPE.main>{currencyQuote?.symbol}</TYPE.main> currency={feeValueUpper?.currency}
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
</RowFixed> </RowFixed>
<RowFixed> <RowFixed>
<TYPE.main> <TYPE.main>{feeValueUpper ? formatTokenAmount(feeValueUpper, 4) : '-'}</TYPE.main>
{inverted
? feeValue0
? formatTokenAmount(feeValue0, 4)
: '-'
: feeValue1
? formatTokenAmount(feeValue1, 4)
: '-'}
</TYPE.main>
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowBetween> <RowBetween>
<RowFixed> <RowFixed>
<CurrencyLogo currency={currencyBase} size={'20px'} style={{ marginRight: '0.5rem' }} /> <CurrencyLogo
<TYPE.main>{currencyBase?.symbol}</TYPE.main> currency={feeValueLower?.currency}
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
</RowFixed> </RowFixed>
<RowFixed> <RowFixed>
<TYPE.main> <TYPE.main>{feeValueLower ? formatTokenAmount(feeValueLower, 4) : '-'}</TYPE.main>
{inverted
? feeValue0
? formatTokenAmount(feeValue1, 4)
: '-'
: feeValue1
? formatTokenAmount(feeValue0, 4)
: '-'}
</TYPE.main>
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
{ownsNFT && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) && !collectMigrationHash ? (
<AutoColumn gap="md">
<RowBetween>
<TYPE.main>Collect as WETH</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
/>
</RowBetween>
</AutoColumn>
) : null}
</AutoColumn> </AutoColumn>
</DarkCard> </DarkCard>
</AutoColumn> </AutoColumn>
......
...@@ -21,12 +21,10 @@ import ReactGA from 'react-ga' ...@@ -21,12 +21,10 @@ import ReactGA from 'react-ga'
import { useActiveWeb3React } from 'hooks' import { useActiveWeb3React } from 'hooks'
import { TransactionResponse } from '@ethersproject/providers' import { TransactionResponse } from '@ethersproject/providers'
import { useTransactionAdder } from 'state/transactions/hooks' import { useTransactionAdder } from 'state/transactions/hooks'
import { WETH9, CurrencyAmount, currencyEquals, Percent } from '@uniswap/sdk-core' import { Percent } from '@uniswap/sdk-core'
import { TYPE } from 'theme' import { TYPE } from 'theme'
import { Wrapper, SmallMaxButton, ResponsiveHeaderText } from './styled' import { Wrapper, SmallMaxButton, ResponsiveHeaderText } from './styled'
import Loader from 'components/Loader' import Loader from 'components/Loader'
import { useToken } from 'hooks/Tokens'
import { unwrappedToken } from 'utils/wrappedCurrency'
import DoubleCurrencyLogo from 'components/DoubleLogo' import DoubleCurrencyLogo from 'components/DoubleLogo'
import { Break } from 'components/earn/styled' import { Break } from 'components/earn/styled'
import { NonfungiblePositionManager } from '@uniswap/v3-sdk' import { NonfungiblePositionManager } from '@uniswap/v3-sdk'
...@@ -34,6 +32,7 @@ import { calculateGasMargin } from 'utils' ...@@ -34,6 +32,7 @@ import { calculateGasMargin } from 'utils'
import useTheme from 'hooks/useTheme' import useTheme from 'hooks/useTheme'
import { AddRemoveTabs } from 'components/NavigationTabs' import { AddRemoveTabs } from 'components/NavigationTabs'
import RangeBadge from 'components/Badge/RangeBadge' import RangeBadge from 'components/Badge/RangeBadge'
import Toggle from 'components/Toggle'
export const UINT128MAX = BigNumber.from(2).pow(128).sub(1) export const UINT128MAX = BigNumber.from(2).pow(128).sub(1)
...@@ -65,11 +64,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -65,11 +64,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
const theme = useTheme() const theme = useTheme()
const { account, chainId, library } = useActiveWeb3React() const { account, chainId, library } = useActiveWeb3React()
// currencies from position // flag for receiving WETH
const token0 = useToken(position?.token0) const [receiveWETH, setReceiveWETH] = useState(false)
const token1 = useToken(position?.token1)
const currency0 = token0 ? unwrappedToken(token0) : undefined
const currency1 = token1 ? unwrappedToken(token1) : undefined
// burn state // burn state
const { percent } = useBurnV3State() const { percent } = useBurnV3State()
...@@ -82,7 +78,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -82,7 +78,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
feeValue1, feeValue1,
outOfRange, outOfRange,
error, error,
} = useDerivedV3BurnInfo(position) } = useDerivedV3BurnInfo(position, receiveWETH)
const { onPercentSelect } = useBurnV3ActionHandlers() const { onPercentSelect } = useBurnV3ActionHandlers()
const removed = position?.liquidity?.eq(0) const removed = position?.liquidity?.eq(0)
...@@ -122,12 +118,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -122,12 +118,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
slippageTolerance: allowedSlippage, slippageTolerance: allowedSlippage,
deadline: deadline.toString(), deadline: deadline.toString(),
collectOptions: { collectOptions: {
expectedCurrencyOwed0: currencyEquals(liquidityValue0.currency, WETH9[chainId]) expectedCurrencyOwed0: feeValue0,
? CurrencyAmount.ether(feeValue0.quotient) expectedCurrencyOwed1: feeValue1,
: feeValue0,
expectedCurrencyOwed1: currencyEquals(liquidityValue1.currency, WETH9[chainId])
? CurrencyAmount.ether(feeValue1.quotient)
: feeValue1,
recipient: account, recipient: account,
}, },
}) })
...@@ -195,32 +187,32 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -195,32 +187,32 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
}, [onPercentSelectForSlider, txnHash]) }, [onPercentSelectForSlider, txnHash])
const pendingText = `Removing ${liquidityValue0?.toSignificant(6)} ${ const pendingText = `Removing ${liquidityValue0?.toSignificant(6)} ${
currency0?.symbol liquidityValue0?.currency?.symbol
} and ${liquidityValue1?.toSignificant(6)} ${currency1?.symbol}` } and ${liquidityValue1?.toSignificant(6)} ${liquidityValue1?.currency?.symbol}`
function modalHeader() { function modalHeader() {
return ( return (
<AutoColumn gap={'sm'} style={{ padding: '16px' }}> <AutoColumn gap={'sm'} style={{ padding: '16px' }}>
<RowBetween align="flex-end"> <RowBetween align="flex-end">
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
{currency0?.symbol}: Pooled {liquidityValue0?.currency?.symbol}:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{liquidityValue0 && <FormattedCurrencyAmount currencyAmount={liquidityValue0} />} {liquidityValue0 && <FormattedCurrencyAmount currencyAmount={liquidityValue0} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue0?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowBetween align="flex-end"> <RowBetween align="flex-end">
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
{currency1?.symbol}: Pooled {liquidityValue1?.currency?.symbol}:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{liquidityValue1 && <FormattedCurrencyAmount currencyAmount={liquidityValue1} />} {liquidityValue1 && <FormattedCurrencyAmount currencyAmount={liquidityValue1} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue1?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
{feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? ( {feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? (
...@@ -230,24 +222,24 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -230,24 +222,24 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</TYPE.italic> </TYPE.italic>
<RowBetween> <RowBetween>
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
{currency0?.symbol} from fees: {feeValue0?.currency?.symbol} Fees Earned:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{feeValue0 && <FormattedCurrencyAmount currencyAmount={feeValue0} />} {feeValue0 && <FormattedCurrencyAmount currencyAmount={feeValue0} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue0?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowBetween> <RowBetween>
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
{currency1?.symbol} from fees: {feeValue1?.currency?.symbol} Fees Earned:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{feeValue1 && <FormattedCurrencyAmount currencyAmount={feeValue1} />} {feeValue1 && <FormattedCurrencyAmount currencyAmount={feeValue1} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue1?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
</> </>
...@@ -287,8 +279,16 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -287,8 +279,16 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<AutoColumn gap="lg"> <AutoColumn gap="lg">
<RowBetween> <RowBetween>
<RowFixed> <RowFixed>
<DoubleCurrencyLogo currency0={currency1} currency1={currency0} size={20} margin={true} /> <DoubleCurrencyLogo
<TYPE.label ml="10px" fontSize="20px">{`${currency0?.symbol}/${currency1?.symbol}`}</TYPE.label> currency0={feeValue0?.currency}
currency1={feeValue1?.currency}
size={20}
margin={true}
/>
<TYPE.label
ml="10px"
fontSize="20px"
>{`${feeValue0?.currency?.symbol}/${feeValue1?.currency?.symbol}`}</TYPE.label>
</RowFixed> </RowFixed>
<RangeBadge removed={removed} inRange={!outOfRange} /> <RangeBadge removed={removed} inRange={!outOfRange} />
</RowBetween> </RowBetween>
...@@ -319,24 +319,24 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -319,24 +319,24 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<AutoColumn gap="md"> <AutoColumn gap="md">
<RowBetween> <RowBetween>
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
Pooled {currency0?.symbol}: Pooled {liquidityValue0?.currency?.symbol}:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{liquidityValue0 && <FormattedCurrencyAmount currencyAmount={liquidityValue0} />} {liquidityValue0 && <FormattedCurrencyAmount currencyAmount={liquidityValue0} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue0?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowBetween> <RowBetween>
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
Pooled {currency1?.symbol}: Pooled {liquidityValue1?.currency?.symbol}:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{liquidityValue1 && <FormattedCurrencyAmount currencyAmount={liquidityValue1} />} {liquidityValue1 && <FormattedCurrencyAmount currencyAmount={liquidityValue1} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue1?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
{feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? ( {feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? (
...@@ -344,30 +344,40 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -344,30 +344,40 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<Break /> <Break />
<RowBetween> <RowBetween>
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
{currency0?.symbol} Fees Earned: {feeValue0?.currency?.symbol} Fees Earned:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{feeValue0 && <FormattedCurrencyAmount currencyAmount={feeValue0} />} {feeValue0 && <FormattedCurrencyAmount currencyAmount={feeValue0} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue0?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowBetween> <RowBetween>
<Text fontSize={16} fontWeight={500}> <Text fontSize={16} fontWeight={500}>
{currency1?.symbol} Fees Earned: {feeValue1?.currency?.symbol} Fees Earned:
</Text> </Text>
<RowFixed> <RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
{feeValue1 && <FormattedCurrencyAmount currencyAmount={feeValue1} />} {feeValue1 && <FormattedCurrencyAmount currencyAmount={feeValue1} />}
</Text> </Text>
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} /> <CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue1?.currency} />
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
</> </>
) : null} ) : null}
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
<RowBetween>
<TYPE.main>Collect as WETH</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
/>
</RowBetween>
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<AutoColumn gap="12px" style={{ flex: '1' }}> <AutoColumn gap="12px" style={{ flex: '1' }}>
<ButtonConfirmed <ButtonConfirmed
......
import { Token, CurrencyAmount, Percent } from '@uniswap/sdk-core' import { Token, CurrencyAmount, Percent, Ether, currencyEquals, ETHER } from '@uniswap/sdk-core'
import { Position } from '@uniswap/v3-sdk' import { Position } from '@uniswap/v3-sdk'
import { usePool } from 'hooks/usePools' import { usePool } from 'hooks/usePools'
import { useActiveWeb3React } from 'hooks' import { useActiveWeb3React } from 'hooks'
...@@ -10,20 +10,22 @@ import { PositionDetails } from 'types/position' ...@@ -10,20 +10,22 @@ import { PositionDetails } from 'types/position'
import { AppDispatch, AppState } from '../../index' import { AppDispatch, AppState } from '../../index'
import { selectPercent } from './actions' import { selectPercent } from './actions'
import { unwrappedToken } from 'utils/wrappedCurrency'
export function useBurnV3State(): AppState['burnV3'] { export function useBurnV3State(): AppState['burnV3'] {
return useSelector<AppState, AppState['burnV3']>((state) => state.burnV3) return useSelector<AppState, AppState['burnV3']>((state) => state.burnV3)
} }
export function useDerivedV3BurnInfo( export function useDerivedV3BurnInfo(
position?: PositionDetails position?: PositionDetails,
asWETH = false
): { ): {
position?: Position position?: Position
liquidityPercentage?: Percent liquidityPercentage?: Percent
liquidityValue0?: CurrencyAmount<Token> liquidityValue0?: CurrencyAmount<Token | Ether>
liquidityValue1?: CurrencyAmount<Token> liquidityValue1?: CurrencyAmount<Token | Ether>
feeValue0?: CurrencyAmount<Token> feeValue0?: CurrencyAmount<Token | Ether>
feeValue1?: CurrencyAmount<Token> feeValue1?: CurrencyAmount<Token | Ether>
outOfRange: boolean outOfRange: boolean
error?: string error?: string
} { } {
...@@ -50,20 +52,27 @@ export function useDerivedV3BurnInfo( ...@@ -50,20 +52,27 @@ export function useDerivedV3BurnInfo(
const liquidityPercentage = new Percent(percent, 100) const liquidityPercentage = new Percent(percent, 100)
const discountedAmount0 = positionSDK
? liquidityPercentage.multiply(positionSDK.amount0.quotient).quotient
: undefined
const discountedAmount1 = positionSDK
? liquidityPercentage.multiply(positionSDK.amount1.quotient).quotient
: undefined
const liquidityValue0 = const liquidityValue0 =
positionSDK && token0 && discountedAmount0
CurrencyAmount.fromRawAmount( ? currencyEquals(unwrappedToken(token0), ETHER) && !asWETH
positionSDK.amount0.currency, ? CurrencyAmount.ether(discountedAmount0)
liquidityPercentage.multiply(positionSDK.amount0.quotient).quotient : CurrencyAmount.fromRawAmount(token0, discountedAmount0)
) : undefined
const liquidityValue1 = const liquidityValue1 =
positionSDK && token1 && discountedAmount1
CurrencyAmount.fromRawAmount( ? currencyEquals(unwrappedToken(token1), ETHER) && !asWETH
positionSDK.amount1.currency, ? CurrencyAmount.ether(discountedAmount1)
liquidityPercentage.multiply(positionSDK.amount1.quotient).quotient : CurrencyAmount.fromRawAmount(token1, discountedAmount1)
) : undefined
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, position?.tokenId) const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, position?.tokenId, asWETH)
const outOfRange = const outOfRange =
pool && position ? pool.tickCurrent < position.tickLower || pool.tickCurrent > position.tickUpper : false pool && position ? pool.tickCurrent < position.tickLower || pool.tickCurrent > position.tickUpper : false
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment