Skip to main content
Pre-Release Documentation

This describes a pre-release version of LBAMM. Interfaces and behavior may change.

Verify the exact repository commit before building production integrations.

Pool Abstraction

LBAMM supports heterogeneous pool types under a unified execution and enforcement framework.

At a high level:

  • AMM Core owns token custody, hook execution, and invariant enforcement.
  • Pool Types provide pricing logic, position logic, and pool-specific state.
  • Pools are identified by a deterministic poolId that encodes key parameters.

This page defines the contract boundary between core and pool types.


What a Pool Is

A pool in LBAMM consists of:

  • token0 and token1 (canonical ordering enforced at creation)
  • A poolType contract (execution logic module)
  • A pool fee (fixed BPS or dynamic sentinel)
  • An optional poolHook
  • Deterministic poolId

Multiple pools may share the same token pair. They are distinguished by:

  • poolType
  • fee
  • poolHook
  • poolParams (pool-type-specific initialization data)

Core vs Pool Type Responsibilities

Core Responsibilities

Core:

  • Custodies reserves
  • Tracks LP fee balances
  • Tracks protocol fees
  • Executes token, position, and pool hooks
  • Performs all token transfers
  • Enforces invariants on returned values

Core is invariant-aware.


Pool Type Responsibilities

Pool types:

  • Implement pricing and liquidity logic
  • Maintain pool-specific state
  • Compute swap outcomes
  • Compute LP and protocol fee amounts
  • Return deterministic outputs to core

Pool types:

  • Do not transfer tokens
  • Do not custody reserves
  • Do not mutate core accounting

They return values. Core settles.


Core Pool State

Core stores a minimal, pool-agnostic structure:

struct PoolState {
address token0;
address token1;
address poolHook;
uint128 reserve0;
uint128 reserve1;
uint128 feeBalance0;
uint128 feeBalance1;
}

Meaning:

  • reserve0 / reserve1 are canonical reserves.
  • feeBalance0 / feeBalance1 represent unclaimed LP fees only.
  • Protocol fees are stored separately.
  • poolHook is immutable after creation.

Pool types may maintain additional internal state keyed by poolId.


poolId Encoding

poolId is deterministic and bit-packed.

/// poolId is a packed value of the pool type address,
/// hash of creation details, and pool-specific packed data.
///
/// Bits 0 to 15 - pool fee in BPS.
/// Bits 16 to 143 - creation details hash (may include pool-specific params).
/// Bits 144 to 255 - pool type address (must have 6 leading zero bytes).

Constraints:

  • Pool type addresses must have 6 leading zero bytes.
  • Encoded pool type must match details.poolType.
  • Encoded fee must match details.fee.

Core validates both during creation.


PoolDecoder Utilities

Core extracts encoded components using PoolDecoder:

library PoolDecoder {
function getPoolType(bytes32 poolId) internal pure returns (address poolType) {
assembly ("memory-safe") {
poolType := shr(POOL_ID_TYPE_ADDRESS_SHIFT, poolId)
}
}

function getPoolFee(bytes32 poolId) internal pure returns (uint16 fee) {
fee = uint16(uint256(poolId) >> POOL_ID_FEE_SHIFT);
}
}

poolId is the canonical routing and indexing key.


Pool Creation

Creation parameters:

struct PoolCreationDetails {
address poolType;
uint16 fee;
address token0;
address token1;
address poolHook;
bytes poolParams;
}

Creation flow:

  1. Validate token contracts.
  2. Enforce canonical ordering (token0 < token1).
  3. Validate fee:
    • ≤ 10,000 BPS
    • or dynamic sentinel
  4. Delegate to pool type:
    poolId = poolType.createPool(details);
  5. Validate returned poolId encoding.
  6. Store PoolState.
  7. Execute token and pool creation hooks.
  8. Emit PoolCreated.

Event:

event PoolCreated(
address indexed poolType,
address indexed token0,
address indexed token1,
bytes32 poolId,
address poolHook
);

Dynamic Fee Sentinel

Dynamic fee pools use:

uint16 constant DYNAMIC_POOL_FEE_BPS = 55_555;

If this sentinel is used:

  • A non-zero poolHook must be provided.
  • The pool hook participates in dynamic fee calculation.

Pool Type Interface

All pool types must implement ILimitBreakAMMPoolType.


Swap Boundary Guarantees

For swaps:

  • Pool type returns computed amounts.
  • Core validates LP fee and protocol fee correctness.
  • Core updates reserves.
  • Core performs token transfers.
  • Pool types never move tokens directly.

Multi-hop swaps are decomposed by core into sequential swapByInput or swapByOutput calls per hop.


Read Surfaces

getCurrentPriceX96

function getCurrentPriceX96(address amm, bytes32 poolId)
external
view
returns (uint160 sqrtPriceX96);

Provides a standardized price read surface across heterogeneous pool types.

poolTypeManifestUri

function poolTypeManifestUri()
external
view
returns (string memory manifestUri);

Provides integration metadata for applications and SDKs.

If updated, pool types must emit:

event PoolTypeManifestUriUpdated(string uri);

Determinism Model

Pool types may:

  • Use oracle accumulators
  • Use volatility metrics
  • Use time-dependent state

As long as:

  • Outputs are deterministic given onchain state and inputs
  • Returned values are consistent with encoded fee rates
  • Invariants on reserves and fees are respected

Core enforces accounting correctness.


Summary

LBAMM separates:

  • Execution & custody (core)
  • Pricing & liquidity logic (pool types)

poolId encodes:

  • Pool type
  • Fee
  • Creation parameters

This architecture enables heterogeneous liquidity models to coexist safely under unified invariant enforcement.

Limit Break

TwitterLimitBreak.comMedium

© 2026 Limit Break International, Inc. All rights reserved.

Privacy PolicyTerms of ServiceCookie PolicyDo Not Sell My Info