kabu_execution_multicaller/pool_abi_encoder/
abi_encoder.rs1use crate::pool_abi_encoder::pools::{
2 CurveProtocolAbiEncoder, MaverickProtocolAbiEncoder, PancakeV3ProtocolAbiEncoder, UniswapV2ProtocolAbiEncoder,
3 UniswapV3ProtocolAbiEncoder,
4};
5use crate::pool_abi_encoder::ProtocolAbiSwapEncoderTrait;
6use alloy_primitives::{Address, Bytes, U256};
7use eyre::OptionExt;
8use kabu_types_entities::{Pool, PoolClass};
9use std::collections::HashMap;
10use std::sync::Arc;
11
12#[derive(Clone)]
13pub struct ProtocolABIEncoderV2 {
14 pool_classes: HashMap<PoolClass, Arc<dyn ProtocolAbiSwapEncoderTrait>>,
15}
16
17impl Default for ProtocolABIEncoderV2 {
18 fn default() -> Self {
19 let pool_classes: HashMap<PoolClass, Arc<dyn ProtocolAbiSwapEncoderTrait>> = [
20 (PoolClass::UniswapV3, Arc::new(UniswapV3ProtocolAbiEncoder) as Arc<dyn ProtocolAbiSwapEncoderTrait>),
21 (PoolClass::UniswapV2, Arc::new(UniswapV2ProtocolAbiEncoder) as Arc<dyn ProtocolAbiSwapEncoderTrait>),
22 (PoolClass::Maverick, Arc::new(MaverickProtocolAbiEncoder) as Arc<dyn ProtocolAbiSwapEncoderTrait>),
23 (PoolClass::PancakeV3, Arc::new(PancakeV3ProtocolAbiEncoder) as Arc<dyn ProtocolAbiSwapEncoderTrait>),
24 (PoolClass::Curve, Arc::new(CurveProtocolAbiEncoder) as Arc<dyn ProtocolAbiSwapEncoderTrait>),
25 ]
26 .into_iter()
27 .collect();
28
29 Self { pool_classes }
30 }
31}
32
33impl ProtocolABIEncoderV2 {}
34
35impl ProtocolAbiSwapEncoderTrait for ProtocolABIEncoderV2 {
36 fn encode_swap_in_amount_provided(
37 &self,
38 pool: &dyn Pool,
39 token_from_address: Address,
40 token_to_address: Address,
41 amount: U256,
42 recipient: Address,
43 payload: Bytes,
44 ) -> eyre::Result<Bytes> {
45 self.pool_classes.get(&pool.get_class()).ok_or_eyre("CLASS_NOT_SUPPORTED")?.encode_swap_in_amount_provided(
46 pool,
47 token_from_address,
48 token_to_address,
49 amount,
50 recipient,
51 payload,
52 )
53 }
54
55 fn encode_swap_out_amount_provided(
56 &self,
57 pool: &dyn Pool,
58 token_from_address: Address,
59 token_to_address: Address,
60 amount: U256,
61 recipient: Address,
62 payload: Bytes,
63 ) -> eyre::Result<Bytes> {
64 self.pool_classes.get(&pool.get_class()).ok_or_eyre("CLASS_NOT_SUPPORTED")?.encode_swap_out_amount_provided(
65 pool,
66 token_from_address,
67 token_to_address,
68 amount,
69 recipient,
70 payload,
71 )
72 }
73
74 fn swap_in_amount_offset(&self, pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<u32> {
75 self.pool_classes
76 .get(&pool.get_class())
77 .and_then(|encoder| encoder.swap_in_amount_offset(pool, token_from_address, token_to_address))
78 }
79
80 fn swap_out_amount_offset(&self, pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<u32> {
81 self.pool_classes
82 .get(&pool.get_class())
83 .and_then(|encoder| encoder.swap_out_amount_offset(pool, token_from_address, token_to_address))
84 }
85
86 fn swap_in_amount_return_offset(&self, pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<u32> {
87 self.pool_classes
88 .get(&pool.get_class())
89 .and_then(|encoder| encoder.swap_in_amount_return_offset(pool, token_from_address, token_to_address))
90 }
91 fn swap_out_amount_return_offset(&self, pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<u32> {
92 self.pool_classes
93 .get(&pool.get_class())
94 .and_then(|encoder| encoder.swap_out_amount_return_offset(pool, token_from_address, token_to_address))
95 }
96
97 fn swap_in_amount_return_script(&self, pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<Bytes> {
98 self.pool_classes
99 .get(&pool.get_class())
100 .and_then(|encoder| encoder.swap_in_amount_return_script(pool, token_from_address, token_to_address))
101 }
102 fn swap_out_amount_return_script(&self, pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<Bytes> {
103 self.pool_classes
104 .get(&pool.get_class())
105 .and_then(|encoder| encoder.swap_out_amount_return_script(pool, token_from_address, token_to_address))
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use kabu_defi_pools::UniswapV3Pool;
113 use kabu_types_entities::PreswapRequirement;
114
115 #[test]
116 fn test_default() {
117 let abi_encoder_v2 = ProtocolABIEncoderV2::default();
118 assert_eq!(abi_encoder_v2.pool_classes.len(), 5);
119 }
120
121 #[test]
122 fn test_preswap_requirement() {
123 let uni3 = UniswapV3Pool::new(Address::random());
124
125 let pr = uni3.preswap_requirement();
126
127 assert_eq!(pr, PreswapRequirement::Callback)
128 }
129}