kabu_execution_multicaller/
multicaller_encoder.rs

1use alloy_primitives::{Address, Bytes};
2use eyre::{eyre, OptionExt, Result};
3use std::sync::Arc;
4use tracing::error;
5
6use crate::pool_abi_encoder::ProtocolABIEncoderV2;
7use crate::pool_opcodes_encoder::ProtocolSwapOpcodesEncoderV2;
8use crate::{SwapLineEncoder, SwapStepEncoder, DEFAULT_VIRTUAL_ADDRESS};
9use kabu_types_blockchain::MulticallerCalls;
10use kabu_types_entities::Swap;
11
12pub trait MulticallerEncoder {
13    fn encode_calls(&self, calls: MulticallerCalls) -> Result<(Address, Bytes)>;
14    fn add_internal_calls(&self, opcodes: MulticallerCalls, inside_opcodes: MulticallerCalls) -> Result<MulticallerCalls>;
15    fn make_calls(&self, swap: &Swap) -> Result<MulticallerCalls>;
16}
17
18#[derive(Clone)]
19pub struct MulticallerSwapEncoder {
20    pub multicaller_address: Address,
21    pub swap_step_encoder: SwapStepEncoder,
22}
23
24impl MulticallerSwapEncoder {
25    pub fn new(multicaller_address: Address, swap_step_encoder: SwapStepEncoder) -> Self {
26        Self { multicaller_address, swap_step_encoder }
27    }
28
29    pub fn default_with_address(multicaller_address: Address) -> Self {
30        let abi_encoder = ProtocolABIEncoderV2::default();
31        let opcodes_encoder = ProtocolSwapOpcodesEncoderV2::default();
32
33        let swap_line_encoder = SwapLineEncoder::new(multicaller_address, Arc::new(abi_encoder), Arc::new(opcodes_encoder));
34
35        let swap_step_encoder = SwapStepEncoder::new(multicaller_address, swap_line_encoder);
36
37        Self { multicaller_address, swap_step_encoder }
38    }
39
40    pub fn get_contract_address(&self) -> Address {
41        self.multicaller_address
42    }
43}
44
45impl MulticallerEncoder for MulticallerSwapEncoder {
46    fn encode_calls(&self, calls: MulticallerCalls) -> Result<(Address, Bytes)> {
47        self.swap_step_encoder.to_call_data(&calls)
48    }
49
50    fn add_internal_calls(&self, opcodes: MulticallerCalls, inside_opcodes: MulticallerCalls) -> Result<MulticallerCalls> {
51        self.swap_step_encoder.encode_do_calls(opcodes, inside_opcodes)
52    }
53
54    fn make_calls(&self, swap: &Swap) -> Result<MulticallerCalls> {
55        match swap {
56            Swap::BackrunSwapLine(swap_line) => {
57                let (swap_step_0, swap_step_1) = swap_line.to_swap_steps(self.multicaller_address).ok_or_eyre("SWAP_TYPE_NOT_COVERED")?;
58                self.swap_step_encoder.encode_swap_steps(&swap_step_0, &swap_step_1)
59            }
60            Swap::BackrunSwapSteps((swap_step_0, swap_step_1)) => self.swap_step_encoder.encode_swap_steps(swap_step_0, swap_step_1),
61            Swap::Multiple(swap_vec) => {
62                if swap_vec.len() == 1 {
63                    self.make_calls(&swap_vec[0])
64                } else {
65                    let mut multicaller_calls = MulticallerCalls::new();
66                    for swap in swap_vec {
67                        multicaller_calls = self.add_internal_calls(multicaller_calls, self.make_calls(swap)?)?;
68                    }
69                    Ok(multicaller_calls)
70                }
71            }
72            _ => {
73                error!("Swap type not supported");
74                Err(eyre!("SWAP_TYPE_NOT_SUPPORTED"))
75            }
76        }
77    }
78}
79
80impl Default for MulticallerSwapEncoder {
81    fn default() -> Self {
82        MulticallerSwapEncoder::default_with_address(DEFAULT_VIRTUAL_ADDRESS)
83    }
84}