degenbot.uniswap.v3_liquidity_pool ================================== .. py:module:: degenbot.uniswap.v3_liquidity_pool .. autoapi-nested-parse:: UniswapV3Pool: concentrated liquidity AMM companion over a Pool handle. ADR-005 slice 8b — the V3 companion rewritten over the same `Pool` handle topology as the V2 `UniswapV2Pool`. Rust `BotState` is the single source of truth for V3 mutable state (scalars, tick data, reorg journal); this companion reads it through `self._py_pool` (the atomic `snapshot_v3()` for scalars + `tick_data_snapshot()`/`tick_bitmap_snapshot()` for the tick maps) and delegates `external_update` (Swap) / `update_liquidity_map` (Mint/Burn) / `update_tick_data` (sparse-map backfill) / discard / restore to the handle. Immutable identity (tokens, factory, fee, tick_spacing) stays Python-side — matches V2 (calc lives in the `UniswapV3PoolCalc` mixin). `_state_mgr` / `_state_cache` / `state_cache_depth` are dropped — the `StateCache` temporal-navigation layer lives in Rust now (journal + discard/restore). V2 already has none; V3 follows. Sparse-map bitmap note: Rust's tick bitmap is DERIVED from `tick_data` keys (no separate bitmap store), and the CHECKED words are tracked in Rust (`known_bitmap_words` — seeded at Sparse registration, grown by fetch-merge / full-sync, and grown by the `update_tick_data` FFI seam from the caller's tick_bitmap KEYS — Sparse only, never Tracked). `tick_bitmap_snapshot()` surfaces a known-but-empty word as `(0, block)`, so the simulator sees it as present-but-zero (not missing) and the fetch loop breaks with no client-side shadow. A word ABSENT from the snapshot is indeterminate on a Sparse pool (fetch it) and known-empty on a Tracked pool (complete map). Module Contents --------------- .. py:class:: LiquidityAtTickAsDict Bases: :py:obj:`TypedDict` Serialized form of ``LiquidityAtTick`` for tick data interchange. .. py:attribute:: liquidity_net :type: int .. py:attribute:: liquidity_gross :type: int .. py:attribute:: block :type: degenbot.types.aliases.BlockNumber .. py:class:: BitmapAtWordAsDict Bases: :py:obj:`TypedDict` Serialized form of ``BitmapAtWord`` for tick bitmap interchange. .. py:attribute:: bitmap :type: int .. py:attribute:: block :type: degenbot.types.aliases.BlockNumber .. py:class:: UniswapV3Pool(*args: Any, **kwargs: Any) Bases: :py:obj:`degenbot.uniswap.v3_pool_state.V3PoolState`, :py:obj:`degenbot.uniswap.v3_pool_calc.UniswapV3PoolCalc`, :py:obj:`degenbot.uniswap.cl_companion.ConcentratedLiquidityCompanion` A Uniswap V3 concentrated-liquidity pool companion over a ``Pool`` handle. Rust owns the mutable state (scalars + tick data + reorg journal) as ``V3PoolState``; this companion reads it through ``self._py_pool`` (one atomic ``snapshot_v3()`` for scalars + ``tick_data_snapshot()`` / ``tick_bitmap_snapshot()`` for the tick maps) and delegates ``external_update`` (Swap) / ``update_liquidity_map`` (Mint/Burn) / ``update_tick_data`` (sparse-map backfill) / discard / restore to the handle. Immutable identity (tokens, factory, fee, tick_spacing) stays Python-side — matches V2. Construct via ``Bot.build_pool()`` (which registers in Rust and hands the handle here); tests use ``make_v3_pool``. .. py:attribute:: variant :type: ClassVar[str | None] :value: None .. py:type:: PoolState :canonical: UniswapV3PoolState .. py:attribute:: address :type: degenbot.types.chain.ChecksummedAddress .. py:attribute:: factory :type: degenbot.types.chain.ChecksummedAddress .. py:attribute:: init_hash :type: str .. py:attribute:: deployer_address :type: degenbot.types.chain.ChecksummedAddress .. py:attribute:: name :type: str .. py:attribute:: TICK_STRUCT_TYPES :value: ('uint128', 'int128', 'uint256', 'uint256', 'int56', 'uint160', 'uint32', 'bool') .. py:attribute:: SLOT0_STRUCT_TYPES :value: ('uint160', 'int24', 'uint16', 'uint16', 'uint16', 'uint8', 'bool') .. py:method:: from_handle(py_pool: degenbot.types.Pool) -> Self :classmethod: Wrap a Rust-owned ``Pool`` handle as a Python companion. Internal seam (ADR-005, Polars-style ``_from_pydf`` pattern). The handle is self-describing: every identity field (address, factory, fee, tick_spacing, tokens) is read off it — no identity is passed as constructor args. Rust owns the mutable state (slot0 + tick_data + reorg journal) as ``V3PoolState`` and the immutable registration metadata as ``V3PoolIdentity``; this companion reads both through ``self._py_pool``. The sparse-tick fetcher is stored Rust-side on ``V3PoolState`` (ADR-006 I/O trait object) — not a constructor arg. Checked words (bitmap words the caller has verified) live in Rust ``known_bitmap_words``; ``tick_bitmap_snapshot()`` surfaces them, so there is no client-side bitmap shadow. :returns: A ``cls`` instance wrapping ``py_pool``. :raises DegenbotValueError: If the handle is not a V3-family pool (``py_pool.pool_family`` is not ``"v3"``). .. py:property:: state :type: PoolState State. :returns: The current pool state, built from one atomic Rust scalar snapshot (``_py_pool.snapshot_v3()``) + the tick-map snapshots. The scalars (sqrt_price/liquidity/tick/block) cannot tear; the tick maps are deep-copied snapshots the simulation path can mutate freely. :raises DegenbotValueError: If the pool is not registered in Rust. .. py:method:: simulate_exact_input_swap(token_in: degenbot.erc20.Erc20Token, token_in_quantity: int, sqrt_price_limit_x96: int | None = None, override_state: PoolState | None = None) -> degenbot.uniswap.v3_types.UniswapV3PoolSimulationResult Simulate an exact input swap. :returns: The simulation result with delta amounts and state transitions. :raises DegenbotValueError: If token_in is unknown. :raises LiquidityPoolError: If the simulated execution reverts. .. py:method:: simulate_exact_output_swap(token_out: degenbot.erc20.Erc20Token, token_out_quantity: int, sqrt_price_limit_x96: int | None = None, override_state: PoolState | None = None) -> degenbot.uniswap.v3_types.UniswapV3PoolSimulationResult Simulate an exact output swap. :returns: The simulation result with delta amounts and state transitions. :raises DegenbotValueError: If token_out is unknown. :raises LiquidityPoolError: If the simulated execution reverts.