Skip to main content

tycho_simulation/price_level_stream/
config.rs

1use std::str::FromStr;
2
3use num_bigint::BigUint;
4use tycho_common::Bytes;
5
6/// Protocol system family name of components sourced from the pAMM price level stream.
7///
8/// The full protocol system of a component is `pricelevelstream:{pamm}`, where `{pamm}` is the
9/// configured venue name (e.g. `pricelevelstream:fermiswap`) or, for auto-detected venues, the
10/// venue address (e.g. `pricelevelstream:0x5979…`); see the [module documentation](super) for
11/// details.
12pub const PRICE_LEVEL_STREAM_FAMILY: &str = "pricelevelstream";
13
14/// Protocol system family of components executed through Tycho's `TychoFallbackRouter`, which
15/// retries a reverted pAMM swap on the fallback pool the solver names in the swap's `user_data`.
16///
17/// Must match `tycho-execution`'s `FALLBACK_KEY`.
18pub const FALLBACK_FAMILY: &str = "fallback";
19
20/// Configuration of a single pAMM to be served from the price level stream.
21#[derive(Debug, Clone)]
22pub struct PriceLevelStreamConfig {
23    /// Bare pAMM name (e.g. `fermiswap`); the emitted components carry
24    /// `pricelevelstream:{protocol}` as their protocol system.
25    pub protocol: String,
26    /// The pAMM venue address under which Titan streams its quotes.
27    pub address: Bytes,
28    /// Constant per-swap gas cost estimate reported for every quote of this pAMM.
29    pub gas_cost: BigUint,
30}
31
32impl PriceLevelStreamConfig {
33    pub fn new(protocol: impl Into<String>, address: Bytes, gas_cost: BigUint) -> Self {
34        Self { protocol: protocol.into(), address, gas_cost }
35    }
36
37    /// The configuration an auto-detected pAMM (streamed by Titan but not otherwise configured)
38    /// is served under: named by its full lowercase hex address, with the given per-swap gas
39    /// cost.
40    pub(super) fn auto_detected(address: Bytes, gas_cost: BigUint) -> Self {
41        let protocol = address.to_string();
42        Self::new(protocol, address, gas_cost)
43    }
44
45    /// The protocol system identifier of components emitted for this pAMM.
46    pub fn protocol_system(&self) -> String {
47        format!("{PRICE_LEVEL_STREAM_FAMILY}:{}", self.protocol)
48    }
49
50    /// The protocol system identifier when this pAMM executes through `TychoFallbackRouter`.
51    pub fn fallback_protocol_system(&self) -> String {
52        format!("{FALLBACK_FAMILY}:{}", self.protocol)
53    }
54}
55
56/// Per-swap gas estimate for auto-detected pAMMs whose venue has not been measured: the maximum
57/// over the known venue profiles (see [`default_served_pamms`]), as the conservative choice.
58/// Overridable per stream via
59/// [`auto_detected_gas_cost`](super::stream::PriceLevelStreamBuilder::auto_detected_gas_cost).
60pub const DEFAULT_AUTO_DETECTED_GAS_COST: u64 = 335_000;
61
62/// The pAMMs known to be served by the Titan price level stream (as of 2026-09-11): FermiSwap,
63/// Kipseli, Metric, Bebop, TaurusFi, and Tempest.
64///
65/// Registered on a builder via
66/// [`with_known_pamms`](super::stream::PriceLevelStreamBuilder::with_known_pamms), so their
67/// components carry the venue name instead of the raw address; an
68/// [`add_pamm`](super::stream::PriceLevelStreamBuilder::add_pamm) call for one of these
69/// addresses overrides the corresponding entry.
70///
71/// Only the venues' router addresses are registered — the keys the price level stream has been
72/// observed to use — because the streamed key doubles as the execution target
73/// ([`PAMM_ADDRESS_ATTRIBUTE`](super::stream::PAMM_ADDRESS_ATTRIBUTE)): unlike the state-override
74/// stream, which also publishes frames under non-executable oracle aliases, an entry here must
75/// be an address a swap can be sent to.
76pub fn default_served_pamms() -> Vec<PriceLevelStreamConfig> {
77    // The venues' `IPropAMM::swap` gas, calibrated by replaying real fills on the live venues at
78    // fresh-oracle blocks via `debug_traceCall`, plus a small headroom. Deliberately excludes
79    // router-level overhead (user/input/fee transfers): tycho-execution's gas estimator accounts
80    // for those on top of this per-swap value.
81    let pamms = [
82        // The FermiSwapper router. Measured ~177k-182k (2026-08-18).
83        ("fermiswap", "0x5979458912f80b96d30d4220af8e2e4925a33320", 185_000u64),
84        // The KipseliPropAMMWrapper router. Measured ~308k-329k (2026-08-18). Titan's venue docs
85        // list a newer Kipseli router (0x342b8458…), but the stream still keys Kipseli
86        // quotes by this address and the newer one has no activity.
87        ("kipseli", "0x71e790dd841c8a9061487cb3e78c288e75ce0b3d", 335_000u64),
88        // The Metric router (unverified; identified via its pools' pricing reads of the Metric
89        // oracle 0x28d9cced…). Measured ~225k (2026-08-18).
90        ("metric", "0xe715dc29d2c273d0fc5a03e5cca9ccb0abb1dcdb", 230_000u64),
91        // The BopAMM (Bebop) router, per Titan's venue docs. Measured ~133k-136k (2026-08-18).
92        ("bebop", "0xb09aaa5614916d7aeb59c295c52c92ca82addd76", 140_000u64),
93        // The TaurusFi router, per Titan's venue docs. Measured ~105k (2026-08-18).
94        ("taurusfi", "0x217d58931a8549ca539426aa8152e33dafc3d95a", 110_000u64),
95        // The Tempest router (unverified), per Titan's venue docs. Measured ~120k-155k
96        // (2026-09-11).
97        ("tempest", "0x00000003f1ec2379e79f58e12ec6c4f51ee92149", 160_000u64),
98    ];
99    pamms
100        .into_iter()
101        .map(|(protocol, address, gas_cost)| {
102            PriceLevelStreamConfig::new(
103                protocol,
104                Bytes::from_str(address).expect("hardcoded pAMM address must parse"),
105                BigUint::from(gas_cost),
106            )
107        })
108        .collect()
109}
110
111/// The streamed venues known NOT to be executable through the generic executor, excluded from
112/// auto-detection via
113/// [`with_known_pamms`](super::stream::PriceLevelStreamBuilder::with_known_pamms): quoting them
114/// would advertise liquidity every routed swap reverts on. An
115/// [`add_pamm`](super::stream::PriceLevelStreamBuilder::add_pamm) entry for one of these
116/// addresses overrides the denial.
117pub fn default_denied_pamms() -> Vec<Bytes> {
118    // No streamed venue is currently known to reject the executor's swap. This is where one
119    // goes that gates settlement — on a taker allowlist, say — or otherwise reverts a swap sent
120    // by an arbitrary caller.
121    Vec::new()
122}