I wrote a function that perform a static call passing the maximum collectable value in other to see how much is pending to be collected.
export const calculatePendingFees = async (
tokenId: number,
recipient: string,
amount0Max: BigNumber,
amount1Max: BigNumber,
chainId: number
) => {
try {
const params = {
tokenId: tokenId,
recipient: recipient,
amount0Max: amount0Max,
amount1Max: amount1Max,
}
const nonfungible = new ethers.Contract(
NONFUNGIBLE_POSITION_MANAGER_ADDRESS[chainId],
Nonfungiblepositionmanager.abi,
PROVIDER[chainId]
)
const feesGenerated = await nonfungible.callStatic.collect(params)
return feesGenerated
} catch (error) {
console.log(error.message, "calculate fees error")
}
}
For amount0Max
and amount1Max
you can use this:
const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1)
This function will return to you the uncollected fees :)
The number of token0
and token1
can be retrieved through these functions:
export const calcAmount0 = (
liquidity: number,
currentPrice: number,
priceUpper: number,
token0Decimals: number,
token1Decimals: number
) => {
const decimalAdjustment = 10 ** (token0Decimals - token1Decimals)
const mathCurrentPrice = currentPrice / decimalAdjustment
const mathPriceUpper = priceUpper / decimalAdjustment
const math =
liquidity *
((Math.sqrt(mathPriceUpper) - Math.sqrt(mathCurrentPrice)) /
(Math.sqrt(mathCurrentPrice) * Math.sqrt(mathPriceUpper)))
const adjustedMath = math > 0 ? math : 0
return adjustedMath
}
export const calcAmount1 = (
liquidity: number,
currentPrice: number,
priceLower: number,
token0Decimals: number,
token1Decimals: number
) => {
const decimalAdjustment = 10 ** (token0Decimals - token1Decimals)
const mathCurrentPrice = currentPrice / decimalAdjustment
const mathPriceLower = priceLower / decimalAdjustment
const math =
liquidity * (Math.sqrt(mathCurrentPrice) - Math.sqrt(mathPriceLower))
const adjustedMath = math > 0 ? math : 0
return adjustedMath
}
The price lower and price upper can be retrieved through this:
const priceLower = tickToPrice(tickLower, decimalsA, decimalsB)
const priceUpper = tickToPrice(tickUpper, decimalsA, decimalsB)
Till i know unfortunatelly we only have V3-SDK on npm so you will have plenty work writing anything.
In Uniswap V2, all liquidity provider (LP) positions fall in the price range [pa, pb] = [0, Infinity]
. The value for liquidity is fungible across all positions and is calculated as follows:
This means that the value of liquidity is directly proportional to the values of x
and y
tokens provided, and the only way to get the same exact value of liquidity is to provide an amount of underlying tokens that falls on the curve described by the formula above.
In Uniswap V3, LP positions are more fine-tuned and have an additional level of depth. Uniswap V3 introduces the concept of concentrated liquidity, where positions are not only described by the amount of liquidity provided but also the price range [pa, pb]
over which that liquidity is provided. Liquidity is described by the following formulas:
By examining the Uniswap V3 formulas, we see that the value of liquidity is directly proportional to the values of x
and y
and inversely proportional to the width of the price range. If we calculate the amount of liquidity that results from providing an amount of tokens x1
and y1
across a price range [pa, pb]
, it should be possible to get the same exact value of liquidity by providing a smaller amount of both tokens x2
and y2
across a narrower price range [pc, pd]
.
Therefore, in Uniswap V3, the liquidity units are not fungible across positions with different price ranges and are only locally fungible within positions that lie within the same price range.
Best Answer
This article discusses when making a price range decision, you should consider the degree to which you think prices will move over the course of your position's lifetime. You should also consider your willingness to actively manage the position as the market evolves, and the economics of transactions required to actively manage a position:
https://support.uniswap.org/hc/en-us/articles/7423194619661-How-to-provide-liquidity-on-Uniswap-V3
Some other resources:
Creating new uniswap v3 pool - ideal Min/Max price
https://blog.tylerbuchea.com/liqudity-pools/