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}