According to the whitepaper, when a position is in range

uncollected fees = liquidity( feeGrowthGlobal - feeGrowthOutsidelowerTick - feeGrowthOutsideUpperTick - feeGrowthInside)

But for stable coins feeGrowthGlobal - feeGrowthOutsideLowerTick - feeGrowthOutsideUpperTick seems negative, resulting in negative uncollected fees.


        "id": "149982",
        "liquidity": "70751535817529022692995",
        "pool": {
          "feeGrowthGlobal0X128": "1218682304163016184766177108699434636279"
        "tickLower": {
          "feeGrowthOutside0X128": "1145577432605598277662216874263285465942"
        "tickUpper": {
          "feeGrowthOutside0X128": "1125981180184479101654443162252506477054"
        "token0": {
          "symbol": "DAI"
        "token1": {
          "symbol": "WETH"

1218682304163016184766177108699434636279 - 1145577432605598277662216874263285465942 - 1125981180184479101654443162252506477054 = -1052876308627061194550482927816357306717

2 Answers 2


My two cents:

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(

    const feesGenerated = await nonfungible.callStatic.collect(params)
    return feesGenerated
  } catch (error) {
    console.log(error.message, "calculate fees error")

For amount0Maxand amount1Maxyou can use this:

const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1)

This function will return to you the uncollected fees :)


You need to account for potential under- or over-flow when doing math on the unsigned integer values. More specifically, the Uniswap V3 contract expects the feeGrowthGlobal - feeGrowthOutsideLowerTick - feeGrowthOutsideUpperTick formula to wrap-around 256 bits (i.e. modulo), which can be surprising if your language implements BigInts natively (e.g. Python). My Python library Pyuv3 handles this correctly, for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.