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_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}