uniswap-interface-uncensored/src/hooks/useV3PositionFees.ts
guil-lambert 5967cf5d9d
fix: bug where user cannot burn lp position if fetching fee values fails. (#3633)
* fix: can burn position even if fetching fees fails.

* Revert "fix: can burn position even if fetching fees fails."

This reverts commit a96f7178e55a264c32a3cf8c1b6562785cbd50d4.

* recover more gracefully from failed fee fetch

Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
2022-04-12 11:41:31 -04:00

56 lines
2.1 KiB
TypeScript

import { BigNumber } from '@ethersproject/bignumber'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { Pool } from '@uniswap/v3-sdk'
import { useSingleCallResult } from 'lib/hooks/multicall'
import useBlockNumber from 'lib/hooks/useBlockNumber'
import { useEffect, useState } from 'react'
import { unwrappedToken } from 'utils/unwrappedToken'
import { useV3NFTPositionManagerContract } from './useContract'
const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1)
// compute current + counterfactual fees for a v3 position
export function useV3PositionFees(
pool?: Pool,
tokenId?: BigNumber,
asWETH = false
): [CurrencyAmount<Currency>, CurrencyAmount<Currency>] | [undefined, undefined] {
const positionManager = useV3NFTPositionManagerContract(false)
const owner: string | undefined = useSingleCallResult(tokenId ? positionManager : null, 'ownerOf', [tokenId])
.result?.[0]
const tokenIdHexString = tokenId?.toHexString()
const latestBlockNumber = useBlockNumber()
// we can't use multicall for this because we need to simulate the call from a specific address
// latestBlockNumber is included to ensure data stays up-to-date every block
const [amounts, setAmounts] = useState<[BigNumber, BigNumber] | undefined>()
useEffect(() => {
if (positionManager && tokenIdHexString && owner) {
positionManager.callStatic
.collect(
{
tokenId: tokenIdHexString,
recipient: owner, // some tokens might fail if transferred to address(0)
amount0Max: MAX_UINT128,
amount1Max: MAX_UINT128,
},
{ from: owner } // need to simulate the call as the owner
)
.then((results) => {
setAmounts([results.amount0, results.amount1])
})
}
}, [positionManager, tokenIdHexString, owner, latestBlockNumber])
if (pool && amounts) {
return [
CurrencyAmount.fromRawAmount(asWETH ? pool.token0 : unwrappedToken(pool.token0), amounts[0].toString()),
CurrencyAmount.fromRawAmount(asWETH ? pool.token1 : unwrappedToken(pool.token1), amounts[1].toString()),
]
} else {
return [undefined, undefined]
}
}