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