Skip to main content
Global, outside, and position checkpoint fee growth use u256::U256 in Q128.128 form.

Growth per unit of liquidity

The input-token global accumulator increases by this value. The addition wraps modulo 2^256. A tick crossing replaces each token’s outside-growth checkpoint with global - outside, also modulo 2^256.

Growth inside a range

The contract derives growth below and above the position from global growth, each boundary’s outside growth, and the current tick. It subtracts both from global growth to get inside growth. Crossing an initialized tick flips its outside accumulator relative to current global growth. This makes the same boundary work in either crossing direction.

Owed amount

The subtraction wraps modulo 2^256. The wide product is shifted by 128 bits. The result must fit u128. The contract stores u256::U256 directly. It does not declare a separate FeeGrowth struct. Client code can use a semantic wrapper type, but its wire parser must match { hi, lo }.

Calculate from a state snapshot

Read the position, pool slot, and both boundary ticks from the same deployment at the same state height. Use an indexer or stored snapshot that preserves that height. Separate calls for the latest mapping values do not guarantee a consistent snapshot. Run the following calculation once per token. All inputs are required and have no defaults. Parse Leo integer literals into bigint in Typescript or int in Python first; each hi and lo must fit u128. The SDKs derive this arithmetic for their position reads. The implementation below lets you inspect a saved snapshot without an SDK or network connection. Run your language’s blocks in order in an .mts file with Node.js 24 or later, or a .py file with Python 3.11 or later.

Step 1: Define the calculation

Step 2: Calculate the snapshot’s balances

Continue with the definitions from step 1. This illustrative token0 snapshot has zero outside growth and a zero previous checkpoint.
Both print:
For token1, supply token1’s global growth, outside growth, checkpoint, and owed balance. Keep the same range, current tick, and liquidity. Apply each token’s decimals only when formatting the returned base units.

Boundary and rounding checks

A range that is out of range now can still have fees earned earlier. The boundary calculation determines its cumulative entitlement; returning zero solely because the current tick is outside the range would lose those fees. An overflow check cannot establish that a snapshot is consistent. A mixed-height checkpoint can also produce an incorrect result that fits u128. See LP fee entitlements for the fee split, settlement events, and the distinction between newly accrued fees and total collectible funds.