loom_execution_multicaller/
multicaller_encoder.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use alloy_primitives::{Address, Bytes};
use eyre::{eyre, OptionExt, Result};
use tracing::error;

use loom_types_blockchain::MulticallerCalls;
use loom_types_entities::Swap;

use crate::SwapStepEncoder;

pub trait MulticallerEncoder {
    fn encode_calls(&self, calls: MulticallerCalls) -> Result<(Address, Bytes)>;
    fn add_internal_calls(&self, opcodes: MulticallerCalls, inside_opcodes: MulticallerCalls) -> Result<MulticallerCalls>;
    fn make_calls(&self, swap: &Swap) -> Result<MulticallerCalls>;
}

#[derive(Clone)]
pub struct MulticallerSwapEncoder {
    pub multicaller_address: Address,
    pub swap_step_encoder: SwapStepEncoder,
}

impl MulticallerSwapEncoder {
    pub fn new(multicaller_address: Address) -> Self {
        Self { multicaller_address, swap_step_encoder: SwapStepEncoder::new(multicaller_address) }
    }

    pub fn get_contract_address(&self) -> Address {
        self.multicaller_address
    }
}

impl MulticallerEncoder for MulticallerSwapEncoder {
    fn encode_calls(&self, calls: MulticallerCalls) -> Result<(Address, Bytes)> {
        self.swap_step_encoder.to_call_data(&calls)
    }

    fn add_internal_calls(&self, opcodes: MulticallerCalls, inside_opcodes: MulticallerCalls) -> Result<MulticallerCalls> {
        self.swap_step_encoder.encode_do_calls(opcodes, inside_opcodes)
    }

    fn make_calls(&self, swap: &Swap) -> Result<MulticallerCalls> {
        match swap {
            Swap::BackrunSwapLine(swap_line) => {
                let (swap_step_0, swap_step_1) = swap_line.to_swap_steps(self.multicaller_address).ok_or_eyre("SWAP_TYPE_NOT_COVERED")?;
                self.swap_step_encoder.encode_swap_steps(&swap_step_0, &swap_step_1)
            }
            Swap::BackrunSwapSteps((swap_step_0, swap_step_1)) => self.swap_step_encoder.encode_swap_steps(swap_step_0, swap_step_1),
            Swap::Multiple(swap_vec) => {
                if swap_vec.len() == 1 {
                    self.make_calls(&swap_vec[0])
                } else {
                    let mut multicaller_calls = MulticallerCalls::new();
                    for swap in swap_vec {
                        multicaller_calls = self.add_internal_calls(multicaller_calls, self.make_calls(swap)?)?;
                    }
                    Ok(multicaller_calls)
                }
            }
            _ => {
                error!("Swap type not supported");
                Err(eyre!("SWAP_TYPE_NOT_SUPPORTED"))
            }
        }
    }
}