Skip to content

Core Primitives

Core Primitives are the cross-protocol execution dispatchers that have been the recommended DeFiPy interface since v1.0. They handle pool initialization, swapping, liquidity management, and quoting across Uniswap V2/V3, Balancer, and Stableswap through a single abstract interface.

These primitives mutate pool state — they are execution operations (mint, burn, swap, zap). For read-only analytics (position analysis, risk assessment, price scenarios), see The Primitive Interface.

Availability

OperationUniswap V2Uniswap V3BalancerStableswap
Join()
Swap()
AddLiquidity()
RemoveLiquidity()
SwapDeposit()
WithdrawSwap()
LPQuote()🔜🔜

Operation descriptions

  • Join() — Initialize a pool with starting liquidity. V2/V3 take token amounts (amount0, amount1); V3 also requires lwr_tick and upr_tick. Balancer takes a pool_shares quantity against an already-funded vault. Stableswap takes the amplification coefficient A.
  • Swap() — Exchange one token for another. V2/V3 are binary pools — token_in is enough to determine the output. Balancer and Stableswap may have N ≥ 2 assets, so both token_in and token_out must be named.
  • AddLiquidity() — Single-token-in deposit into an initialized pool. V2/V3 auto-balance the matching second-token amount via lp.quote(...) at the current price. Balancer accepts a kind constructor flag for token-amount vs target-shares semantics. Stableswap takes a token amount and absorbs the imbalance against the invariant.
  • RemoveLiquidity() — Burn LP shares. V2/V3 return both tokens at the pool’s current ratio (use WithdrawSwap() for single-asset exits). Balancer and Stableswap return only the specified token_out because the invariant absorbs the imbalance.
  • SwapDeposit() — V2/V3 single-asset zap-in. Solves for the optimal swap fraction (closed-form on V2, scipy.optimize on V3), swaps that portion, then deposits both balances. Balancer/Stableswap don’t need this primitive — their AddLiquidity() is already single-asset.
  • WithdrawSwap() — V2/V3 single-asset zap-out. Burns the optimal LP fraction, then swaps the unwanted side back into token_out. Balancer/Stableswap don’t need this primitive — their RemoveLiquidity() already takes token_out.
  • LPQuote() — Read-only quoting class with named methods (get_price, get_reserve, get_amount, get_amount_from_lp, get_lp_from_amount, get_liquidity, get_opposing_token). Recommended cross-protocol entry point for state reads — lp.get_amount_out and lp.get_reserve are V2-specific and raise AttributeError on V3, but LPQuote dispatches correctly. V2/V3 today; Balancer/Stableswap planned for v2.1 (add-only).

Relationship to other sections

Core Primitives and The Primitive Interface are both abstract — they dispatch across protocols without the caller knowing protocol details. The distinction is what they do:

  • Core Primitives mutate pool state (execution: mint, burn, swap, zap)
  • Agentic Primitives read pool state and return analytics (position analysis, risk, scenarios)

For the protocol-specific exchange classes underneath both layers, see Protocol API → Uniswap V2 and siblings.

For the full Core API reference — class signatures, parameters, and runnable examples — see Core API.