2021-04-23 01:36:11 +03:00
|
|
|
import { useSingleCallResult } from 'state/multicall/hooks'
|
2021-05-10 23:30:02 +03:00
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
import { useV3NFTPositionManagerContract } from './useContract'
|
2021-04-23 01:36:11 +03:00
|
|
|
import { BigNumber } from '@ethersproject/bignumber'
|
2021-05-10 23:30:02 +03:00
|
|
|
import { Pool } from '@uniswap/v3-sdk'
|
2021-05-13 21:49:54 +03:00
|
|
|
import { CurrencyAmount, Token, currencyEquals, ETHER, Ether } from '@uniswap/sdk-core'
|
2021-05-10 23:30:02 +03:00
|
|
|
import { useBlockNumber } from 'state/application/hooks'
|
2021-05-13 21:49:54 +03:00
|
|
|
import { unwrappedToken } from 'utils/wrappedCurrency'
|
2021-04-23 01:36:11 +03:00
|
|
|
|
2021-05-10 23:30:02 +03:00
|
|
|
const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1)
|
2021-04-23 01:36:11 +03:00
|
|
|
|
|
|
|
// compute current + counterfactual fees for a v3 position
|
|
|
|
export function useV3PositionFees(
|
|
|
|
pool?: Pool,
|
2021-05-13 21:49:54 +03:00
|
|
|
tokenId?: BigNumber,
|
|
|
|
asWETH = false
|
|
|
|
): [CurrencyAmount<Token | Ether>, CurrencyAmount<Token | Ether>] | [undefined, undefined] {
|
2021-05-10 23:59:11 +03:00
|
|
|
const positionManager = useV3NFTPositionManagerContract(false)
|
2021-05-12 19:20:20 +03:00
|
|
|
const owner = useSingleCallResult(tokenId ? positionManager : null, 'ownerOf', [tokenId]).result?.[0]
|
2021-05-10 23:30:02 +03:00
|
|
|
|
2021-05-12 19:20:20 +03:00
|
|
|
const tokenIdHexString = tokenId?.toHexString()
|
2021-05-10 23:30:02 +03:00
|
|
|
const latestBlockNumber = useBlockNumber()
|
|
|
|
|
|
|
|
// TODO find a way to get this into multicall
|
2021-05-12 19:20:20 +03:00
|
|
|
// because these amounts don't ever go down, we don't actually need to clear this state
|
|
|
|
// latestBlockNumber is included to ensure data stays up-to-date every block
|
2021-05-10 23:30:02 +03:00
|
|
|
const [amounts, setAmounts] = useState<[BigNumber, BigNumber]>()
|
|
|
|
useEffect(() => {
|
2021-05-12 19:20:20 +03:00
|
|
|
if (positionManager && tokenIdHexString && owner && typeof latestBlockNumber === 'number') {
|
2021-05-10 23:30:02 +03:00
|
|
|
positionManager.callStatic
|
|
|
|
.collect(
|
|
|
|
{
|
2021-05-12 19:20:20 +03:00
|
|
|
tokenId: tokenIdHexString,
|
2021-05-10 23:30:02 +03:00
|
|
|
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
|
2021-04-23 01:36:11 +03:00
|
|
|
)
|
2021-05-10 23:30:02 +03:00
|
|
|
.then((results) => {
|
|
|
|
setAmounts([results.amount0, results.amount1])
|
|
|
|
})
|
|
|
|
}
|
2021-05-12 19:20:20 +03:00
|
|
|
}, [positionManager, tokenIdHexString, owner, latestBlockNumber])
|
2021-04-23 01:36:11 +03:00
|
|
|
|
2021-05-12 19:20:20 +03:00
|
|
|
if (pool && amounts) {
|
2021-04-23 01:36:11 +03:00
|
|
|
return [
|
2021-05-13 21:49:54 +03:00
|
|
|
!asWETH && currencyEquals(unwrappedToken(pool.token0), ETHER)
|
|
|
|
? 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()),
|
2021-04-23 01:36:11 +03:00
|
|
|
]
|
|
|
|
} else {
|
|
|
|
return [undefined, undefined]
|
|
|
|
}
|
|
|
|
}
|