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'
|
2021-04-23 01:36:11 +03:00
|
|
|
import { PositionDetails } from 'types/position'
|
2021-05-10 23:30:02 +03:00
|
|
|
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-04-23 01:36:11 +03:00
|
|
|
import { TokenAmount } from '@uniswap/sdk-core'
|
2021-05-10 23:30:02 +03:00
|
|
|
import { useBlockNumber } from 'state/application/hooks'
|
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-04-23 05:58:03 +03:00
|
|
|
positionDetails?: PositionDetails
|
2021-04-23 01:36:11 +03:00
|
|
|
): [TokenAmount, TokenAmount] | [undefined, undefined] {
|
2021-05-10 23:30:02 +03:00
|
|
|
const positionManager = useV3NFTPositionManagerContract()
|
|
|
|
const owner = useSingleCallResult(positionDetails?.tokenId ? positionManager : null, 'ownerOf', [
|
|
|
|
positionDetails?.tokenId,
|
|
|
|
]).result?.[0]
|
|
|
|
|
|
|
|
const tokenId = positionDetails?.tokenId?.toHexString()
|
|
|
|
const latestBlockNumber = useBlockNumber()
|
|
|
|
|
|
|
|
// TODO find a way to get this into multicall
|
|
|
|
// because fees don't ever go down, we don't actually need to clear this state
|
|
|
|
// latestBlockNumber is included to ensure data stays up-to-date fresh
|
|
|
|
const [amounts, setAmounts] = useState<[BigNumber, BigNumber]>()
|
|
|
|
useEffect(() => {
|
|
|
|
if (positionManager && tokenId && owner && typeof latestBlockNumber === 'number') {
|
|
|
|
positionManager.callStatic
|
|
|
|
.collect(
|
|
|
|
{
|
|
|
|
tokenId,
|
|
|
|
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])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}, [positionManager, tokenId, owner, latestBlockNumber])
|
2021-04-23 01:36:11 +03:00
|
|
|
|
2021-05-10 23:30:02 +03:00
|
|
|
if (pool && positionDetails && amounts) {
|
2021-04-23 01:36:11 +03:00
|
|
|
return [
|
2021-05-10 23:30:02 +03:00
|
|
|
new TokenAmount(pool.token0, positionDetails.tokensOwed0.add(amounts[0]).toString()),
|
|
|
|
new TokenAmount(pool.token1, positionDetails.tokensOwed1.add(amounts[1]).toString()),
|
2021-04-23 01:36:11 +03:00
|
|
|
]
|
|
|
|
} else {
|
|
|
|
return [undefined, undefined]
|
|
|
|
}
|
|
|
|
}
|