kabu_types_swap/
swap.rs

1use std::fmt::{Display, Formatter};
2use std::sync::Arc;
3
4use crate::{SwapLine, SwapStep};
5use alloy_primitives::{Address, U256};
6use kabu_types_market::{PoolId, PoolWrapper, Token};
7
8#[derive(Clone, Debug)]
9pub enum Swap {
10    None,
11    ExchangeSwapLine(SwapLine),
12    BackrunSwapSteps((SwapStep, SwapStep)),
13    BackrunSwapLine(SwapLine),
14    Multiple(Vec<Swap>),
15}
16
17impl Display for Swap {
18    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
19        match self {
20            Swap::ExchangeSwapLine(path) => write!(f, "{path}"),
21            Swap::BackrunSwapLine(path) => write!(f, "{path}"),
22            Swap::BackrunSwapSteps((sp0, sp1)) => write!(f, "{sp0} {sp1}"),
23            Swap::Multiple(_) => write!(f, "MULTIPLE_SWAP"),
24            Swap::None => write!(f, "UNKNOWN_SWAP_TYPE"),
25        }
26    }
27}
28
29impl Swap {
30    pub fn to_swap_steps(self: &Swap, multicaller: Address) -> Option<(SwapStep, SwapStep)> {
31        match self {
32            Swap::BackrunSwapLine(swap_line) => swap_line.to_swap_steps(multicaller),
33            Swap::BackrunSwapSteps((sp0, sp1)) => Some((sp0.clone(), sp1.clone())),
34            _ => None,
35        }
36    }
37
38    pub fn arb_profit(&self) -> U256 {
39        match self {
40            Swap::BackrunSwapLine(path) => path.abs_profit(),
41            Swap::BackrunSwapSteps((sp0, sp1)) => SwapStep::arb_profit(sp0, sp1),
42            Swap::Multiple(swap_vec) => swap_vec.iter().map(|x| x.arb_profit()).sum(),
43            Swap::None => U256::ZERO,
44            Swap::ExchangeSwapLine(_) => U256::ZERO,
45        }
46    }
47
48    pub fn pre_estimate_gas(&self) -> u64 {
49        match self {
50            Swap::ExchangeSwapLine(path) => path.gas_used.unwrap_or_default(),
51            Swap::BackrunSwapLine(path) => path.gas_used.unwrap_or_default(),
52            Swap::BackrunSwapSteps((sp0, sp1)) => {
53                sp0.swap_line_vec().iter().map(|i| i.gas_used.unwrap_or_default()).sum::<u64>()
54                    + sp1.swap_line_vec().iter().map(|i| i.gas_used.unwrap_or_default()).sum::<u64>()
55            }
56            Swap::Multiple(swap_vec) => swap_vec.iter().map(|x| x.pre_estimate_gas()).sum(),
57            Swap::None => 0,
58        }
59    }
60
61    pub fn arb_profit_eth(&self) -> U256 {
62        match self {
63            Swap::ExchangeSwapLine(_) => U256::ZERO,
64            Swap::BackrunSwapLine(path) => path.abs_profit_eth(),
65            Swap::BackrunSwapSteps((sp0, sp1)) => SwapStep::arb_profit_eth(sp0, sp1),
66            Swap::Multiple(swap_vec) => swap_vec.iter().map(|x| x.arb_profit_eth()).sum(),
67            Swap::None => U256::ZERO,
68        }
69    }
70
71    pub fn get_first_token(&self) -> Option<&Arc<Token>> {
72        match self {
73            Swap::ExchangeSwapLine(swap_path) => swap_path.get_first_token(),
74            Swap::BackrunSwapLine(swap_path) => swap_path.get_first_token(),
75            Swap::BackrunSwapSteps((sp0, _sp1)) => sp0.get_first_token(),
76            Swap::Multiple(_) => None,
77            Swap::None => None,
78        }
79    }
80
81    pub fn get_pool_id_vec(&self) -> Vec<PoolId> {
82        match self {
83            Swap::ExchangeSwapLine(swap_line) => swap_line.pools().iter().map(|item| item.get_pool_id()).collect(),
84            Swap::BackrunSwapLine(swap_line) => swap_line.pools().iter().map(|item| item.get_pool_id()).collect(),
85            Swap::BackrunSwapSteps((sp0, sp1)) => {
86                let mut swap_line_vec = sp0.swap_line_vec().clone();
87                swap_line_vec.extend(sp1.swap_line_vec().clone());
88                swap_line_vec.iter().flat_map(|item| item.pools().iter().map(|p| p.get_pool_id()).collect::<Vec<_>>()).collect()
89            }
90            Swap::Multiple(swap_vec) => swap_vec.iter().flat_map(|x| x.get_pool_id_vec()).collect(),
91            Swap::None => Vec::new(),
92        }
93    }
94
95    pub fn get_pool_address_vec(&self) -> Vec<PoolId> {
96        match self {
97            Swap::ExchangeSwapLine(swap_line) => swap_line.pools().iter().map(|item| item.get_address()).collect(),
98            Swap::BackrunSwapLine(swap_line) => swap_line.pools().iter().map(|item| item.get_address()).collect(),
99            Swap::BackrunSwapSteps((sp0, sp1)) => {
100                let mut swap_line_vec = sp0.swap_line_vec().clone();
101                swap_line_vec.extend(sp1.swap_line_vec().clone());
102                swap_line_vec.iter().flat_map(|item| item.pools().iter().map(|p| p.get_address()).collect::<Vec<_>>()).collect()
103            }
104            Swap::Multiple(swap_vec) => swap_vec.iter().flat_map(|x| x.get_pool_address_vec()).collect(),
105            Swap::None => Vec::new(),
106        }
107    }
108
109    pub fn get_pools_vec(&self) -> Vec<PoolWrapper> {
110        match self {
111            Swap::ExchangeSwapLine(swap_line) => swap_line.pools().clone(),
112            Swap::BackrunSwapLine(swap_line) => swap_line.pools().clone(),
113            Swap::BackrunSwapSteps((sp0, sp1)) => {
114                let mut swap_line_vec = sp0.swap_line_vec().clone();
115                swap_line_vec.extend(sp1.swap_line_vec().clone());
116                swap_line_vec.iter().flat_map(|item| item.pools().iter().cloned()).collect::<Vec<_>>().to_vec()
117            }
118            Swap::Multiple(swap_vec) => swap_vec.iter().flat_map(|x| x.get_pools_vec()).collect(),
119            Swap::None => Vec::new(),
120        }
121    }
122}