kabu_execution_multicaller/pool_abi_encoder/pools/
pancake3.rs

1use crate::pool_abi_encoder::ProtocolAbiSwapEncoderTrait;
2use alloy_primitives::{Address, Bytes, I256, U160, U256};
3use alloy_sol_types::SolInterface;
4use kabu_defi_abi::uniswap3::IUniswapV3Pool;
5use kabu_types_entities::Pool;
6use lazy_static::lazy_static;
7use std::ops::Sub;
8
9lazy_static! {
10    static ref LOWER_LIMIT: U160 = U160::from(4295128740u64);
11    static ref UPPER_LIMIT: U160 = U160::from_str_radix("1461446703485210103287273052203988822378723970341", 10).unwrap();
12}
13pub struct PancakeV3ProtocolAbiEncoder;
14
15impl PancakeV3ProtocolAbiEncoder {
16    pub fn get_zero_for_one(token_address_from: &Address, token_address_to: &Address) -> bool {
17        token_address_from < token_address_to
18    }
19
20    pub fn get_price_limit(token_address_from: &Address, token_address_to: &Address) -> U160 {
21        if token_address_from < token_address_to {
22            *LOWER_LIMIT
23        } else {
24            *UPPER_LIMIT
25        }
26    }
27}
28
29impl ProtocolAbiSwapEncoderTrait for PancakeV3ProtocolAbiEncoder {
30    fn encode_swap_in_amount_provided(
31        &self,
32        _pool: &dyn Pool,
33        token_from_address: Address,
34        token_to_address: Address,
35        amount: U256,
36        recipient: Address,
37        payload: Bytes,
38    ) -> eyre::Result<Bytes> {
39        let zero_for_one = PancakeV3ProtocolAbiEncoder::get_zero_for_one(&token_from_address, &token_to_address);
40        let sqrt_price_limit_x96 = PancakeV3ProtocolAbiEncoder::get_price_limit(&token_from_address, &token_to_address);
41        let swap_call = IUniswapV3Pool::swapCall {
42            recipient,
43            zeroForOne: zero_for_one,
44            sqrtPriceLimitX96: sqrt_price_limit_x96,
45            amountSpecified: I256::from_raw(amount),
46            data: payload,
47        };
48
49        Ok(Bytes::from(IUniswapV3Pool::IUniswapV3PoolCalls::swap(swap_call).abi_encode()))
50    }
51
52    fn encode_swap_out_amount_provided(
53        &self,
54        _pool: &dyn Pool,
55        token_from_address: Address,
56        token_to_address: Address,
57        amount: U256,
58        recipient: Address,
59        payload: Bytes,
60    ) -> eyre::Result<Bytes> {
61        let zero_for_one = PancakeV3ProtocolAbiEncoder::get_zero_for_one(&token_from_address, &token_to_address);
62        let sqrt_price_limit_x96 = PancakeV3ProtocolAbiEncoder::get_price_limit(&token_from_address, &token_to_address);
63        let swap_call = IUniswapV3Pool::swapCall {
64            recipient,
65            zeroForOne: zero_for_one,
66            sqrtPriceLimitX96: sqrt_price_limit_x96,
67            amountSpecified: I256::ZERO.sub(I256::from_raw(amount)),
68            data: payload,
69        };
70
71        Ok(Bytes::from(IUniswapV3Pool::IUniswapV3PoolCalls::swap(swap_call).abi_encode()))
72    }
73
74    fn swap_in_amount_offset(&self, _pool: &dyn Pool, _token_from_address: Address, _token_to_address: Address) -> Option<u32> {
75        Some(0x44)
76    }
77
78    fn swap_out_amount_offset(&self, _pool: &dyn Pool, _token_from_address: Address, _token_to_address: Address) -> Option<u32> {
79        Some(0x44)
80    }
81
82    fn swap_out_amount_return_offset(&self, _pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<u32> {
83        if PancakeV3ProtocolAbiEncoder::get_zero_for_one(&token_from_address, &token_to_address) {
84            Some(0x20)
85        } else {
86            Some(0x0)
87        }
88    }
89
90    fn swap_in_amount_return_offset(&self, _pool: &dyn Pool, token_from_address: Address, token_to_address: Address) -> Option<u32> {
91        if PancakeV3ProtocolAbiEncoder::get_zero_for_one(&token_from_address, &token_to_address) {
92            Some(0x20)
93        } else {
94            Some(0x0)
95        }
96    }
97
98    fn swap_out_amount_return_script(&self, _pool: &dyn Pool, _token_from_address: Address, _token_to_address: Address) -> Option<Bytes> {
99        None
100    }
101
102    fn swap_in_amount_return_script(&self, _pool: &dyn Pool, _token_from_address: Address, _token_to_address: Address) -> Option<Bytes> {
103        Some(Bytes::from(vec![0x8, 0x2A, 0x00]))
104    }
105}