kabu_execution_multicaller/pool_opcodes_encoder/
wsteth.rs

1use crate::opcodes_helpers::OpcodesHelpers;
2use crate::pool_abi_encoder::ProtocolAbiSwapEncoderTrait;
3use crate::pool_opcodes_encoder::SwapOpcodesEncoderTrait;
4use crate::pool_opcodes_encoder::swap_opcodes_encoders::MulticallerOpcodesPayload;
5use alloy_primitives::{Address, Bytes};
6use eyre::{Result, eyre};
7use kabu_defi_abi::AbiEncoderHelper;
8use kabu_defi_address_book::TokenAddressEth;
9use kabu_types_blockchain::{MulticallerCall, MulticallerCalls};
10use kabu_types_market::Pool;
11use kabu_types_swap::SwapAmountType;
12
13pub struct WstEthSwapEncoder {}
14
15impl SwapOpcodesEncoderTrait for WstEthSwapEncoder {
16    #[allow(clippy::too_many_arguments)]
17    fn encode_swap_in_amount_provided(
18        &self,
19        swap_opcodes: &mut MulticallerCalls,
20        abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
21        token_from_address: Address,
22        token_to_address: Address,
23        amount_in: SwapAmountType,
24        cur_pool: &dyn Pool,
25        next_pool: Option<&dyn Pool>,
26        _payload: MulticallerOpcodesPayload,
27        multicaller: Address,
28    ) -> Result<()> {
29        let pool_address = match cur_pool.get_address() {
30            kabu_types_market::PoolId::Address(addr) => addr,
31            kabu_types_market::PoolId::B256(_) => return Err(eyre!("Pool ID is B256, expected Address")),
32        };
33
34        if token_from_address == TokenAddressEth::WETH && token_to_address == TokenAddressEth::WSTETH {
35            let weth_withdraw_opcode =
36                MulticallerCall::new_call(token_from_address, &AbiEncoderHelper::encode_weth_withdraw(amount_in.unwrap_or_default()));
37            let mut swap_opcode = MulticallerCall::new_call_with_value(
38                pool_address,
39                &abi_encoder.encode_swap_in_amount_provided(
40                    cur_pool,
41                    token_from_address,
42                    token_to_address,
43                    amount_in.unwrap_or_default(),
44                    multicaller,
45                    Bytes::new(),
46                )?,
47                amount_in.unwrap_or_default(),
48            );
49
50            if next_pool.is_some() {
51                swap_opcode.set_return_stack(true, 0, 0, 0x20);
52            }
53
54            let opcodes_vec = vec![(weth_withdraw_opcode, 0x4, 0x20), (swap_opcode, 0x0, 0x20)];
55
56            swap_opcodes.merge(OpcodesHelpers::build_multiple_stack(amount_in, opcodes_vec, Some(token_from_address))?);
57
58            return Ok(());
59        }
60
61        if token_from_address == TokenAddressEth::STETH && token_to_address == TokenAddressEth::WSTETH
62            || token_from_address == TokenAddressEth::WSTETH && token_to_address == TokenAddressEth::STETH
63        {
64            let steth_approve_opcode = MulticallerCall::new_call(
65                token_from_address,
66                &AbiEncoderHelper::encode_erc20_approve(token_to_address, amount_in.unwrap_or_default()),
67            );
68
69            let mut swap_opcode = MulticallerCall::new_call(
70                pool_address,
71                &abi_encoder.encode_swap_in_amount_provided(
72                    cur_pool,
73                    token_from_address,
74                    token_to_address,
75                    amount_in.unwrap_or_default(),
76                    multicaller,
77                    Bytes::new(),
78                )?,
79            );
80            if next_pool.is_some() {
81                swap_opcode.set_return_stack(true, 0, 0, 0x20);
82            }
83            let opcodes_vec = vec![(steth_approve_opcode, 0x24, 0x20), (swap_opcode, 0x04, 0x20)];
84
85            swap_opcodes.merge(OpcodesHelpers::build_multiple_stack(amount_in, opcodes_vec, Some(token_from_address))?);
86
87            return Ok(());
88        }
89
90        Err(eyre!("CANNOT_ENCODE_WSTETH_SWAP"))
91    }
92
93    fn encode_swap_out_amount_provided(
94        &self,
95        _swap_opcodes: &mut MulticallerCalls,
96        _abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
97        _token_from_address: Address,
98        _token_to_address: Address,
99        _amount_out: SwapAmountType,
100        _cur_pool: &dyn Pool,
101        _next_pool: Option<&dyn Pool>,
102        _payload: MulticallerOpcodesPayload,
103        _multicaller_address: Address,
104    ) -> Result<()> {
105        Err(eyre!("NOT_IMPLEMENTED"))
106    }
107}