kabu_execution_multicaller/
swap_encoder.rs1use crate::MulticallerSwapEncoder;
2use alloy_primitives::{Address, BlockNumber, Bytes, U256};
3use eyre::{eyre, OptionExt, Result};
4use kabu_types_blockchain::MulticallerCalls;
5use kabu_types_entities::tips::{tips_and_value_for_swap_type, Tips};
6use kabu_types_entities::{Swap, SwapEncoder, SwapStep};
7use tracing::{debug, error, trace};
8
9impl SwapEncoder for MulticallerSwapEncoder {
10 fn set_address(&mut self, multicaller_address: Address) {
11 self.multicaller_address = multicaller_address;
12 self.swap_step_encoder.multicaller_address = multicaller_address;
13 self.swap_step_encoder.swap_line_encoder.multicaller_address = multicaller_address;
14 }
15
16 fn address(&self) -> Address {
17 self.multicaller_address
18 }
19
20 fn encode(
21 &self,
22 swap: Swap,
23 tips_pct: Option<u32>,
24 _next_block_number: Option<BlockNumber>,
25 gas_cost: Option<U256>,
26 sender_address: Option<Address>,
27 sender_eth_balance: Option<U256>,
28 ) -> Result<(Address, Option<U256>, Bytes, Vec<Tips>)> {
29 let swap_vec = match &swap {
30 Swap::BackrunSwapLine(_) | Swap::BackrunSwapSteps(_) => {
31 vec![swap.to_swap_steps(self.swap_step_encoder.get_contract_address()).ok_or_eyre("SWAP_TYPE_NOTE_COVERED")?]
32 }
33 Swap::Multiple(swap_vec) => {
34 let mut ret: Vec<(SwapStep, SwapStep)> = Vec::new();
35 for s in swap_vec.iter() {
36 ret.push(s.to_swap_steps(self.swap_step_encoder.get_contract_address()).ok_or_eyre("AA")?);
37 }
38 ret
39 }
40 Swap::ExchangeSwapLine(_) => vec![],
41 Swap::None => {
42 vec![]
43 }
44 };
45
46 let mut swap_steps = "".to_string();
47 for (level, (sp0, sp1)) in swap_vec.iter().enumerate() {
48 swap_steps.push_str(format!("{}{} \n{}\t-> {}\n", "\t".repeat(level), sp0, "\t".repeat(level), sp1).as_str());
49 }
50 debug!("Swaps:\n{}", swap_steps);
51
52 let mut swap_opcodes = if swap_vec.is_empty() {
53 match &swap {
54 Swap::ExchangeSwapLine(swap_line) => {
55 trace!("START: exchange swap line");
56 match self.swap_step_encoder.swap_line_encoder.encode_swap_line_in_amount(swap_line, None) {
57 Ok(calls) => calls,
58 Err(e) => {
59 error!("swap_line_encoder.encode_swap_line_in_amount : {}", e);
60 return Err(eyre!("ENCODING_FAILED"));
61 }
62 }
63 }
64 _ => return Err(eyre!("NO_SWAP_STEPS")),
65 }
66 } else if swap_vec.len() == 1 {
67 trace!("START: encode_swap_steps two-hop");
68 let sp0 = &swap_vec[0].0;
69 let sp1 = &swap_vec[0].1;
70 self.swap_step_encoder.encode_swap_steps(sp0, sp1)?
71 } else {
72 trace!("START: encode_swap_steps multi-hop");
73 let mut ret = MulticallerCalls::new();
74 for (sp0, sp1) in swap_vec.iter() {
75 ret = self.swap_step_encoder.encode_do_calls(ret, self.swap_step_encoder.encode_swap_steps(sp0, sp1)?)?;
76 }
77 ret
78 };
79 trace!("END: swap_opcodes");
80
81 let tips_vec =
82 if let (Some(tips_pct), Some(sender_address), Some(sender_eth_balance)) = (tips_pct, sender_address, sender_eth_balance) {
83 let (tips_vec, _call_value) = tips_and_value_for_swap_type(&swap, Some(tips_pct), gas_cost, sender_eth_balance)?;
84 for tips in &tips_vec {
85 swap_opcodes = self.swap_step_encoder.encode_tips(
86 swap_opcodes,
87 tips.token_in.get_address(),
88 tips.min_change,
89 tips.tips,
90 sender_address,
91 )?;
92 }
93 tips_vec
94 } else {
95 vec![]
96 };
97
98 let (to, call_data) = self.swap_step_encoder.to_call_data(&swap_opcodes)?;
99
100 Ok((to, None, call_data, tips_vec))
101 }
102}