kabu_execution_multicaller/pool_opcodes_encoder/
swap_opcodes_encoders.rs

1use crate::pool_abi_encoder::ProtocolAbiSwapEncoderTrait;
2use crate::pool_opcodes_encoder::{
3    CurveSwapOpcodesEncoder, SwapOpcodesEncoderTrait, UniswapV2SwapOpcodesEncoder, UniswapV3SwapOpcodesEncoder,
4};
5use crate::{OpcodesEncoder, OpcodesEncoderV2};
6use alloy_primitives::{Address, Bytes};
7use eyre::OptionExt;
8use eyre::Result;
9use kabu_types_blockchain::MulticallerCalls;
10use kabu_types_market::{Pool, PoolClass};
11use kabu_types_swap::SwapAmountType;
12use std::collections::HashMap;
13use std::sync::Arc;
14
15#[derive(Clone, Default)]
16pub enum MulticallerOpcodesPayload {
17    #[default]
18    Empty,
19    Opcodes(MulticallerCalls),
20    Bytes(Bytes),
21    Address(Address),
22}
23
24impl MulticallerOpcodesPayload {
25    pub fn is_empty(&self) -> bool {
26        match self {
27            Self::Empty => true,
28            Self::Bytes(b) => b.is_empty(),
29            Self::Address(_) => false,
30            Self::Opcodes(o) => o.is_empty(),
31        }
32    }
33}
34
35impl MulticallerOpcodesPayload {
36    pub fn encode(&self) -> Result<Bytes> {
37        match self {
38            Self::Empty => Ok(Bytes::default()),
39            Self::Opcodes(opcodes) => OpcodesEncoderV2::pack_do_calls_data(opcodes),
40            Self::Bytes(bytes) => Ok(bytes.clone()),
41            Self::Address(address) => Ok(Bytes::from(address.to_vec())),
42        }
43    }
44}
45
46#[derive(Clone)]
47pub struct ProtocolSwapOpcodesEncoderV2 {
48    pool_classes: HashMap<PoolClass, Arc<dyn SwapOpcodesEncoderTrait>>,
49}
50
51impl Default for ProtocolSwapOpcodesEncoderV2 {
52    fn default() -> Self {
53        let mut pool_classes: HashMap<PoolClass, Arc<dyn SwapOpcodesEncoderTrait>> = HashMap::new();
54
55        let uni2_opcodes_encoder = Arc::new(UniswapV2SwapOpcodesEncoder {});
56        let uni3_opcodes_encoder = Arc::new(UniswapV3SwapOpcodesEncoder {});
57        let curve_opcodes_encoder = Arc::new(CurveSwapOpcodesEncoder {});
58
59        pool_classes.insert(PoolClass::UniswapV2, uni2_opcodes_encoder.clone());
60        pool_classes.insert(PoolClass::Maverick, uni3_opcodes_encoder.clone());
61        pool_classes.insert(PoolClass::UniswapV3, uni3_opcodes_encoder.clone());
62        pool_classes.insert(PoolClass::PancakeV3, uni3_opcodes_encoder.clone());
63        pool_classes.insert(PoolClass::Curve, curve_opcodes_encoder.clone());
64
65        Self { pool_classes }
66    }
67}
68
69impl SwapOpcodesEncoderTrait for ProtocolSwapOpcodesEncoderV2 {
70    fn encode_swap_in_amount_provided(
71        &self,
72        swap_opcodes: &mut MulticallerCalls,
73        abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
74        token_from_address: Address,
75        token_to_address: Address,
76        amount_in: SwapAmountType,
77        cur_pool: &dyn Pool,
78        next_pool: Option<&dyn Pool>,
79        payload: MulticallerOpcodesPayload,
80        multicaller_address: Address,
81    ) -> eyre::Result<()> {
82        let opcodes_encoder = self.pool_classes.get(&cur_pool.get_class()).ok_or_eyre("OPCODES_ENCODER_NOT_FOUND")?;
83        opcodes_encoder.encode_swap_in_amount_provided(
84            swap_opcodes,
85            abi_encoder,
86            token_from_address,
87            token_to_address,
88            amount_in,
89            cur_pool,
90            next_pool,
91            payload,
92            multicaller_address,
93        )
94    }
95
96    fn encode_swap_out_amount_provided(
97        &self,
98        swap_opcodes: &mut MulticallerCalls,
99        abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
100        token_from_address: Address,
101        token_to_address: Address,
102        amount_out: SwapAmountType,
103        cur_pool: &dyn Pool,
104        next_pool: Option<&dyn Pool>,
105        payload: MulticallerOpcodesPayload,
106        multicaller_address: Address,
107    ) -> eyre::Result<()> {
108        let opcodes_encoder = self.pool_classes.get(&cur_pool.get_class()).ok_or_eyre("OPCODES_ENCODER_NOT_FOUND")?;
109        opcodes_encoder.encode_swap_out_amount_provided(
110            swap_opcodes,
111            abi_encoder,
112            token_from_address,
113            token_to_address,
114            amount_out,
115            cur_pool,
116            next_pool,
117            payload,
118            multicaller_address,
119        )
120    }
121
122    fn encode_flash_swap_in_amount_provided(
123        &self,
124        swap_opcodes: &mut MulticallerCalls,
125        abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
126        token_from_address: Address,
127        token_to_address: Address,
128        amount_in: SwapAmountType,
129        flash_pool: &dyn Pool,
130        prev_pool: Option<&dyn Pool>,
131        payload: MulticallerOpcodesPayload,
132        multicaller_address: Address,
133    ) -> Result<()> {
134        let opcodes_encoder = self.pool_classes.get(&flash_pool.get_class()).ok_or_eyre("OPCODES_ENCODER_NOT_FOUND")?;
135        opcodes_encoder.encode_flash_swap_in_amount_provided(
136            swap_opcodes,
137            abi_encoder,
138            token_from_address,
139            token_to_address,
140            amount_in,
141            flash_pool,
142            prev_pool,
143            payload,
144            multicaller_address,
145        )
146    }
147
148    fn encode_flash_swap_out_amount_provided(
149        &self,
150        swap_opcodes: &mut MulticallerCalls,
151        abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
152        token_from_address: Address,
153        token_to_address: Address,
154        amount_out: SwapAmountType,
155        flash_pool: &dyn Pool,
156        next_pool: Option<&dyn Pool>,
157        payload: MulticallerOpcodesPayload,
158        multicaller_address: Address,
159    ) -> Result<()> {
160        let opcodes_encoder = self.pool_classes.get(&flash_pool.get_class()).ok_or_eyre("OPCODES_ENCODER_NOT_FOUND")?;
161        opcodes_encoder.encode_flash_swap_out_amount_provided(
162            swap_opcodes,
163            abi_encoder,
164            token_from_address,
165            token_to_address,
166            amount_out,
167            flash_pool,
168            next_pool,
169            payload,
170            multicaller_address,
171        )
172    }
173}