kabu_execution_multicaller/pool_opcodes_encoder/
wsteth.rs

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