degenbot.arbitrage.policy¶
Path-composition rejection predicates.
A EngineRegistry can refuse an
register_path() candidate by
policy — token denylist/allowlist, hop-count min/max, min-liquidity gate,
duplicate-pool guard. This is the distinct, policy-layer concern; the Rust
core’s pool admission floor (hooked/dynamic-fee V4 refusal, surfaced as
HookedPoolRejectedError / DynamicFeePoolRejectedError) stays in the
Rust core (ADR-005 standalone-core constraint).
Rejections surface as the typed PathRejectedError
family (subclassing ArbitrageError, NOT
ValueError) so callers classify by type — mirroring the Plan 102
typed-exception pattern now used for pool admission + verification.
The predicate is a pluggable protocol: callers inject a
PathPolicy (or any structural implementation of
PathCompositionPredicate) into EngineRegistry.
Module Contents¶
- class degenbot.arbitrage.policy.PathCompositionPredicate¶
Bases:
ProtocolPluggable path-composition policy.
Evaluate a path candidate
(pool, zero_for_one)sequence. Accept by returningNone; reject by raising aPathRejectedErrorsubtype. Rejections propagate out ofregister_path()so callers classify by type.- evaluate(pools_and_zfos: collections.abc.Sequence[tuple[ArbPathPool, bool]]) None¶
Evaluate the path; raise
PathRejectedErrorto reject.
- class degenbot.arbitrage.policy.NoOpPathPredicate¶
Default predicate — accepts every path (no policy enforced).
- evaluate(pools_and_zfos: collections.abc.Sequence[tuple[ArbPathPool, bool]]) None¶
Accept the path (no-op).
- degenbot.arbitrage.policy.touched_tokens(pools_and_zfos: collections.abc.Sequence[tuple[ArbPathPool, bool]]) list[str]¶
Return the ordered, de-duplicated token addresses a path touches.
Captures the input token (first hop’s
token_in) + every hop’stoken_out(which includes all intermediate connecting tokens and the final profit token). Order: input first, then each hop’s output in path order; duplicates removed preserving first occurrence.- Returns:
The ordered, de-duplicated list of touched checksummed token addresses (input + intermediates + profit token).
- class degenbot.arbitrage.policy.PathPolicy¶
Composable path-composition policy implementing the predicate protocol.
Every rule is opt-in via its fields; the defaults accept any path. Rules evaluate in a fixed order so the first violation raises (deterministic for callers’ classification):
hop-count bounds (min then max)
token denylist / allowlist
duplicate-pool guard
min-liquidity gate (only when
liquidity_ofis supplied)
Token-address inputs are normalized by checksum so denylist/allowlist entries supplied in any case match the pool’s checksummed token addresses.
The library deliberately does NOT encode pool-type-specific liquidity math (V2 reserves vs. V3/V4
liquidity/sqrt_price_x96). Supply aliquidity_ofcallable that returns the liquidity proxy for a pool, or leave itNoneto skip the gate.- liquidity_of: collections.abc.Callable[[ArbPathPool], int] | None = None¶
- evaluate(pools_and_zfos: collections.abc.Sequence[tuple[ArbPathPool, bool]]) None¶
Evaluate all enabled rules; raise on the first violation.
- Raises:
HopCountInsufficientError – If the hop count is below
min_hops.HopCountExceededError – If the hop count exceeds
max_hops.TokenDenylistedError – If a touched token is denylisted, or (when an allowlist is set) absent from the allowlist.
DuplicatePoolError – If the same pool appears more than once and
reject_duplicate_poolsis set.InsufficientLiquidityError – If a pool’s
liquidity_ofproxy is belowmin_liquidity(only whenliquidity_ofis set).