degenbot.balancer.pools¶
Balancer V2 weighted pool implementation.
Module Contents¶
- degenbot.balancer.pools.detect_pow_version(bytecode: str) degenbot.balancer.libraries.constants.PowVersion¶
Detect which FixedPoint library version a pool contract uses from its bytecode.
V2 (WeightedPool) contracts include fast paths for y == ONE, TWO, FOUR in powDown/powUp. These reference the TWO and FOUR constants, which are absent from V1 (WeightedPool2Tokens) bytecode.
The detection works by checking for the TWO constant (0x1bc16d674ec80000) in the deployed bytecode. This constant is used in the y == TWO fast-path comparison and does not appear in V1 contracts.
- Returns:
The computed value.
- class degenbot.balancer.pools.BalancerV2Pool(*args: Any, **kwargs: Any)¶
Bases:
degenbot.types.abstract.AbstractLiquidityPoolBalancerV2Pool class.
- type PoolState = BalancerV2PoolState¶
- FEE_DENOMINATOR = 1000000000000000000¶
- fee: fractions.Fraction¶
- pow_version: degenbot.balancer.libraries.constants.PowVersion¶
- classmethod from_handle(py_pool: degenbot.types.Pool) Self¶
Wrap a Rust-owned
Poolhandle as a Python companion.Internal seam (ADR-005, Polars-style
_from_pydfpattern). Every identity field (vault, pool_id, tokens, weights, scaling_factors, swap_fee, pow_version, address) is read off the handle.- Returns:
A
clsinstance wrappingpy_pool.- Raises:
DegenbotValueError – If the handle is not a Balancer weighted pool or any token is not registered.
- property balances: tuple[int, ...]¶
Balances.
Read from the Rust core via the
Poolhandle (ADR-005 slice 12b). RustBotStateis the single source of truth for the mutablebalancesslot; this getter returns the live tuple.
- property state: PoolState¶
State.
Built from one atomic Rust snapshot (
snapshot_balancer_weighted()—(balances, block)) so callers see a coherent tuple (no torn read mid-external_update). Mirrors V3/V4’ssnapshot_v3()and Curve’ssnapshot_curve()contract.- Raises:
DegenbotValueError – If the Rust snapshot is absent (the pool is not registered in Rust as a Balancer weighted pool — unreachable for a companion built over a registered handle).
- property tokens: tuple[degenbot.erc20.Erc20Token, ...]¶
Tokens.
- calculate_tokens_out_from_tokens_in(token_in: degenbot.erc20.Erc20Token, token_out: degenbot.erc20.Erc20Token, token_in_quantity: int, override_state: PoolState | None = None) int¶
Calculate tokens out from tokens in.
Thin driver shell over the Rust core: token resolution stays Python-side, the swap math is fully Rust-owned.
- Returns:
The computed integer value.
- calculate_tokens_in_from_tokens_out(token_in: degenbot.erc20.Erc20Token, token_out: degenbot.erc20.Erc20Token, token_out_quantity: int, override_state: PoolState | None = None) int¶
Compute how many tokens must be sent to take token_out_quantity out.
Thin driver shell over the Rust core.
- Returns:
The computed integer value.
- external_update(update: degenbot.balancer.types.BalancerV2WeightedPoolExternalUpdate) None¶
Apply an external state update with new balances.
Delegates to the Rust core (
Pool.apply_balancer_weighted_balance_update) which journals the prior balances (genesis-anchor V2-style discipline) and lands the new balances +update_blockatomically (ADR-005 slice 12b). The_state_lock+ double-check-after-acquire pattern it used to apply is gone — Rust’s internal write lock handles atomicity; the registration-state precondition is enforced by the Rust core’s silent-no-op-on-older-block contract.- Raises:
DegenbotValueError – If the Rust core rejects the update (the pool is not registered as a Balancer weighted pool — unreachable for a companion built over a registered handle).