Skip to content

LPQuote

LPQuote is the read-only quoting class for V2/V3 LP state. Unlike the other Core primitives, it doesn’t follow the ClassName().apply(...) shape — it exposes a small set of named methods, each answering a specific question about an existing pool. It never mutates state.

LPQuote(quote_opposing=True, include_fee=False)
ParameterTypeDescription
quote_opposingboolWhen True (default), get_amount returns the opposing-token amount. When False, it returns the input amount unchanged — useful as a passthrough in code that conditionally quotes.
include_feeboolV2-only. When True, get_amount uses fee-aware lp.get_amount_out0/1. When False (default), it uses the no-fee proportional formula (amount_in * res_other) / res_in — the paper value. See the paper-vs-settlement note below.

LPQuote exposes seven methods, grouped here by the question each one answers:

QuestionMethodReturns
What’s the spot price of tkn?get_price(lp, tkn, lwr_tick=None, upr_tick=None)floattkn price in opposing-token units
How much of tkn is in the pool?get_reserve(lp, tkn, lwr_tick=None, upr_tick=None)float — V2 reserve or V3 virtual reserve
Token amount → opposing-token amount?get_amount(lp, tkn, amount_in, lwr_tick=None, upr_tick=None)float — opposing-token output
LP shares → opposing-token amount?get_amount_from_lp(lp, tkn, amount_lp_in, lwr_tick=None, upr_tick=None)float — opposing-token equivalent
Token amount → LP shares?get_lp_from_amount(lp, tkn, amount_in, lwr_tick=None, upr_tick=None)float — LP-share equivalent
Token amount → liquidity (raw L)?get_liquidity(lp, tkn, amount_in)float — pool-share-scaled liquidity
What’s the other token in the pair?get_opposing_token(lp, tkn)ERC20
ParameterTypeDescription
lpExchangeInitialized V2 or V3 pool with active liquidity.
tknERC20The “input” or “anchor” token for the quote. The opposing token is inferred from the pool.
lwr_tick, upr_tickint (optional, V3 only)The tick range to quote against. Required for V3 amount queries; defaulted to None for V2 calls.

The remaining parameter on each method is the input amount, with semantics named in the method (token amount, LP-share amount, etc.).

get_price(lp, tkn, lwr_tick=None, upr_tick=None)

Section titled “get_price(lp, tkn, lwr_tick=None, upr_tick=None)”

Spot price of tkn, expressed in opposing-token units. Computed as reserve_opposing / reserve_tkn. Returns 0 if either reserve is zero (degenerate pool).

from defipy import LPQuote
# V2: price of ETH in DAI
price = LPQuote().get_price(lp, eth)
# V3: same call, ticks not required because pool's slot0 carries the spot
price = LPQuote().get_price(lp_v3, eth)

get_reserve(lp, tkn, lwr_tick=None, upr_tick=None)

Section titled “get_reserve(lp, tkn, lwr_tick=None, upr_tick=None)”

The amount of tkn in the pool. V2 returns the actual reserve in human units; V3 returns the virtual reserve — the amount the pool would hold if all in-range liquidity were collapsed into a constant-product position at the current sqrt-price. Tick-range arguments are accepted but only used by indexed-token paths (when tkn.type == 'index').

reserve = LPQuote().get_reserve(lp, eth)
# V3 virtual reserve when lp is a UniswapV3Exchange
reserve = LPQuote().get_reserve(lp_v3, eth, lwr_tick, upr_tick)

get_amount(lp, tkn, amount_in, lwr_tick=None, upr_tick=None)

Section titled “get_amount(lp, tkn, amount_in, lwr_tick=None, upr_tick=None)”

How much of the opposing token would amount_in of tkn exchange for? V2 uses either the no-fee proportional formula or the fee-aware lp.get_amount_out0/1 depending on include_fee. V3 routes through UniV3Helper().quote(lp, tkn, amount_in, lwr_tick, upr_tick) — ticks are required.

# V2 paper value (no fee)
out = LPQuote().get_amount(lp, dai, 1000)
# V2 settlement value (fee-aware)
out = LPQuote(include_fee=True).get_amount(lp, dai, 1000)
# V3 — ticks required
out = LPQuote().get_amount(lp_v3, dai, 1000, lwr_tick, upr_tick)

get_amount_from_lp(lp, tkn, amount_lp_in, lwr_tick=None, upr_tick=None)

Section titled “get_amount_from_lp(lp, tkn, amount_lp_in, lwr_tick=None, upr_tick=None)”

Given a quantity of LP shares, return the equivalent amount of the opposing token (or, if quote_opposing=False, the equivalent amount of tkn itself). Composes RebaseIndexToken for the LP→token leg, then get_amount for the token→opposing-token leg.

opposing_amt = LPQuote().get_amount_from_lp(lp, eth, 100)
# 100 LP shares; how much DAI does that translate to?

get_lp_from_amount(lp, tkn, amount_in, lwr_tick=None, upr_tick=None)

Section titled “get_lp_from_amount(lp, tkn, amount_in, lwr_tick=None, upr_tick=None)”

The inverse of get_amount_from_lp. Given a token amount, return the LP-share quantity it corresponds to via SettlementLPToken().apply(...).

lp_shares = LPQuote().get_lp_from_amount(lp, dai, 1000)

Compute the proportional LP-share amount for a given token reserve quantity using the V2-style formula amount_in * total_supply / reserve_token. V2-natural; on V3 the result is structural (uses lp.total_supply and lp.reserve0/reserve1 if present), but in practice the more useful V3 query is get_lp_from_amount.

Returns the other ERC20 in the pool’s pair. Helper used internally by the amount methods, exposed so user code doesn’t have to inspect lp.token0 / lp.token1 directly.

ProtocolStatus
Uniswap V2✅ All methods
Uniswap V3✅ All methods (amount-style methods require lwr_tick / upr_tick)
Balancer🔜 v2.1 — see “What’s coming in v2.1” below
Stableswap🔜 v2.1

The architectural intent is full cross-protocol LPQuote — same call shapes, dispatching to Balancer and Stableswap pools through the existing methods. The API surface will be add-only: existing V2/V3 calls won’t change, and existing user code won’t break. The Core Primitives availability matrix on Core Primitives tracks the wiring status.

How LPQuote interacts with the rest of the pipeline

Section titled “How LPQuote interacts with the rest of the pipeline”

LPQuote is read-only, so it has no place in the mutate-the-pool pipeline. It’s the read substrate every other primitive sits on:

  • The Agentic Primitives (AnalyzePosition, SimulatePriceMove, etc.) all reach through LPQuote for cross-protocol-safe state reads rather than calling lp.get_amount_out directly.
  • SwapDeposit and WithdrawSwap use LPQuote to project the post-swap state during the closed-form / numeric solves for the optimal fraction.
  • Tutorials lean on LPQuote.get_price and get_reserve for any state read in code samples that should work on both V2 and V3.

When v2.1 lands, LPQuote will work the same way against LiveProvider-built twins (i.e. real chain reads) as it does against MockProvider snapshots today.