kabu_execution_multicaller/
multicaller_encoder.rs1use 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}