solana_central/types/
pool.rs

1use crate::CentralContext;
2use crate::types::pools::Pools;
3use crate::types::swap_direction::SwapDirection;
4use solana_sdk::pubkey::Pubkey;
5use std::any::Any;
6use std::sync::Arc;
7
8/// Base pool information shared by all pool types. Contains the essential addresses and
9/// identifiers that every pool implementation requires. Protocol-specific pool structs will embed
10/// this as an `info` field.
11#[derive(Debug)]
12pub struct Pool {
13  pub pool_address: Pubkey,
14  pub token_a_address: Pubkey,
15  pub token_b_address: Pubkey,
16  pub token_a_vault_address: Pubkey,
17  pub token_b_vault_address: Pubkey,
18  pub pool_type: Pools,
19}
20
21/// Trait for all pool types, providing a unified interface for DEX pools. All pools implement this
22/// trait to provide common functionality like price queries, fee calculations, and reserve
23/// lookups.
24pub trait PoolTrait: Any + Send + Sync {
25  /// Get the pool's on-chain address
26  fn pool_address(&self) -> &Pubkey;
27  /// Get the address of token A
28  fn token_a_address(&self) -> &Pubkey;
29  /// Get the address of token B
30  fn token_b_address(&self) -> &Pubkey;
31  /// Get the vault address for token A
32  fn token_a_vault_address(&self) -> &Pubkey;
33  /// Get the vault address for token B
34  fn token_b_vault_address(&self) -> &Pubkey;
35  /// Get the pool type enum variant
36  fn pool_type(&self) -> &Pools;
37  
38  /// Get the total swap fee in lamports (10^9 lamports = 1 SOL)
39  fn total_swap_fee_lp(&self, central_context: &Arc<CentralContext>) -> u64;
40
41  /// Get a reference to the pool as `Any` for type downcasting
42  fn as_any(&self) -> &dyn Any;
43  /// Get a mutable reference to the pool as `Any` for type downcasting
44  fn as_any_mut(&mut self) -> &mut dyn Any;
45
46  /// Calculate the price of token A in terms of token B. Fx ticker equivalent: B/A. Returns how
47  /// many units of token A are needed to buy 1 unit of token B, in lamports. For AMMs, typically
48  /// calculated as: (A reserves * LAMPORTS_PER_SOL) / B reserves
49  fn price_a_over_b_lp(&self) -> u128;
50
51  /// Calculate the price of token B in terms of token A. Fx ticker equivalent: A/B. Returns how
52  /// many units of token A are needed to buy 1 unit of token B, in lamports. For AMMs, typically
53  /// calculated as: (B reserves * LAMPORTS_PER_SOL) / A reserves. Inverse of `price_a_over_b_lp`.
54  fn price_b_over_a_lp(&self) -> u128;
55
56  /// Fetch and update pool state from JSON RPC and immediately overrides the in-memory pool state.
57  /// Should not be used in production in favor of using gRPC streams.
58  fn fetch_market_state_from_rpc(&mut self, central_context: &Arc<CentralContext>);
59
60  /// Get the actual amount of token A in the pool, in token units. This is calculated dynamically
61  /// because some protocols (like Meteora) derive real token balances from LP token balances
62  /// rather than storing them directly in the pool account, and other protocols require excluding
63  /// collected fees from raw reserves.
64  fn token_a_amount_units(&self) -> u64;
65  
66  /// Get the actual amount of token B in the pool, in token units. See `token_a_amount_units`
67  /// for details on why this is calculated dynamically.
68  fn token_b_amount_units(&self) -> u64;
69
70  /// Get directional swap fees as fractions for a given swap direction
71  ///
72  /// Returns `(fee_a_fraction, fee_b_fraction)` where each value is between 0.0 and 1.0
73  /// (e.g., 0.003 = 0.3%). The fees may differ based on swap direction for protocols
74  /// with asymmetric fee structures.
75  /// * `central_context` with updated current slot value - Needed for time-based fee calculations
76  /// in Meteora DAMMv2 and DBC
77  fn directional_fees(
78    &self,
79    direction: SwapDirection,
80    central_context: &Arc<CentralContext>,
81  ) -> (f64, f64);
82}