degenbot.curve.curve_stableswap_liquidity_pool ============================================== .. py:module:: degenbot.curve.curve_stableswap_liquidity_pool .. autoapi-nested-parse:: Curve StableSwap liquidity pool implementation. Implements the Curve StableSwap invariant for V1-style pools including plain pools, metapools, lending pools, and crypto pools. Module Contents --------------- .. py:class:: CurveStableswapPool(*args: Any, **kwargs: Any) Bases: :py:obj:`degenbot.curve.stableswap_pool_state.StableswapPoolState`, :py:obj:`degenbot.types.abstract.AbstractLiquidityPool` CurveStableswapPool class. .. py:type:: PoolState :canonical: CurveStableswapPoolState .. py:attribute:: PRECISION_DECIMALS :type: int :value: 18 .. py:attribute:: PRECISION :type: int :value: 1000000000000000000 .. py:attribute:: address :type: degenbot.types.chain.ChecksummedAddress .. py:attribute:: FEE_DENOMINATOR :type: int :value: 10000000000 .. py:attribute:: A_PRECISION :type: int :value: 100 .. py:method:: from_handle(py_pool: degenbot.types.Pool) -> Self :classmethod: Wrap a Rust-owned ``Pool`` handle as a Python companion. Single-arg seam (ADR-005): reads *every* identity field + the stored data-provider trait object off the handle. The cross-pool references (base pool companion + underlying/LP tokens) are recovered from the handle too — the base pool via the Rust go-between ``curve_base_pool()`` (same shared ``BotState``, no Python registry), wrapped in a :class:`_LazyBasePool` that memoises construction. :returns: The companion wrapping the handle. :raises DegenbotValueError: If the handle is not a Curve stableswap pool, or its tokens are not registered in the handle's Bot. .. py:property:: balances :type: tuple[int, ...] Balances. Read from the Rust core via the ``Pool`` handle (ADR-005 slice 11b). Rust ``BotState`` is the single source of truth for the mutable ``balances`` slot; this getter returns the live tuple. .. py:property:: state :type: degenbot.curve.types.CurveStableswapPoolState State. Built from one atomic Rust snapshot (``snapshot_curve()`` — ``(balances, block)``) so callers see a coherent tuple (no torn read mid-``external_update``). Mirrors V3/V4's ``snapshot_v3()`` contract. :raises DegenbotValueError: If the Rust snapshot is absent (the pool is not registered in Rust as a Curve pool — unreachable for a companion built over a registered handle). .. py:property:: update_block :type: degenbot.types.aliases.BlockNumber Update block (from Rust via the handle). .. py:property:: requires_io_at_calculation_time :type: bool Whether this pool may call data_provider during swap calculations. Returns True for pools that need per-block on-chain data (D, gamma, price_scale, lending rates, admin balances, virtual price for metapools, block timestamps for A ramping). Returns False only for plain pools with static rate multipliers and no A ramping. .. py:method:: external_update(update: degenbot.curve.types.CurveStableswapPoolExternalUpdate) -> None Apply an external state update with new balances. Delegates to the Rust core (``Pool.apply_curve_balance_update``) which journals the prior balances (genesis-anchor V2-style discipline) and lands the new balances + ``update_block`` atomically (ADR-005 slice 11b). The ``StateCache`` temporal-navigation layer it used to write is gone — the Rust reorg journal handles rollback now. :raises DegenbotValueError: If the Rust core rejects the update (the pool is not registered as a Curve pool — unreachable for a companion built over a registered handle). .. py:method:: calc_token_amount(*, amounts: collections.abc.Sequence[int], deposit: bool, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None) -> int Simplified method to calculate addition or reduction in token supply at. deposit or withdrawal without taking fees into account (but looking at slippage). Needed to prevent front-running, not for precise calculations! :returns: The computed integer value. .. py:method:: calc_withdraw_one_coin(_token_amount: int, i: int, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None) -> tuple[int, ...] Calc withdraw one coin. :returns: The computed value. .. py:method:: get_dy(i: int, j: int, dx: int, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None, override_state: degenbot.curve.types.CurveStableswapPoolState | None = None) -> int @notice Calculate the current output dy given input dx. @dev Index values can be found via the `coins` public getter method @param i Index value for the coin to send @param j Index value of the coin to recieve @param dx Amount of `i` being exchanged @return Amount of `j` predicted. Reference: https://github.com/curveresearch/notes/blob/main/stableswap.pdf Delegates to the Rust-owned `Pool.curve_get_dy`: the I/O orchestration (amp/rates/xp + provider fetches) and the pure dy math both run in the Rust core, so this is a single handle call with no Python provider / cache / calculator on the swap path. :returns: The computed integer value. :raises EVMRevertError: See function documentation. .. py:method:: calculate_tokens_out_from_tokens_in(token_in: degenbot.erc20.Erc20Token, token_out: degenbot.erc20.Erc20Token, token_in_quantity: int, override_state: degenbot.curve.types.CurveStableswapPoolState | None = None, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None) -> int Calculate the expected token OUTPUT for a target INPUT at current pool reserves. :returns: The computed integer value. :raises DegenbotValueError: See function documentation. :raises InvalidSwapInputAmount: See function documentation. :raises NoLiquidity: See function documentation.