kabu_execution_multicaller/pool_opcodes_encoder/
steth.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, PoolId};
11use kabu_types_swap::SwapAmountType;
12
13pub struct StEthSwapEncoder();
14
15impl SwapOpcodesEncoderTrait for StEthSwapEncoder {
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_id = cur_pool.get_address();
30        let pool_address = match pool_id {
31            PoolId::Address(addr) => addr,
32            PoolId::B256(_) => return Err(eyre!("stETH pool address must be an Address, not B256")),
33        };
34
35        if token_from_address == TokenAddressEth::WETH && token_to_address == TokenAddressEth::STETH {
36            let weth_withdraw_opcode =
37                MulticallerCall::new_call(token_from_address, &AbiEncoderHelper::encode_weth_withdraw(amount_in.unwrap_or_default()));
38            let swap_opcode = MulticallerCall::new_call_with_value(
39                pool_address,
40                &abi_encoder.encode_swap_in_amount_provided(
41                    cur_pool,
42                    token_from_address,
43                    token_to_address,
44                    amount_in.unwrap_or_default(),
45                    multicaller,
46                    Bytes::new(),
47                )?,
48                amount_in.unwrap_or_default(),
49            );
50
51            let opcodes_vec = vec![(weth_withdraw_opcode, 0x4, 0x20), (swap_opcode, 0x0, 0)];
52
53            swap_opcodes.merge(OpcodesHelpers::build_multiple_stack(amount_in, opcodes_vec, Some(token_from_address))?);
54
55            if next_pool.is_some() {
56                let mut steth_balance_opcode =
57                    MulticallerCall::new_static_call(token_to_address, &AbiEncoderHelper::encode_erc20_balance_of(multicaller));
58                steth_balance_opcode.set_return_stack(true, 0, 0, 0x20);
59                swap_opcodes.add(steth_balance_opcode);
60            }
61
62            return Ok(());
63        }
64
65        Err(eyre!("CANNOT_ENCODE_STETH_SWAP"))
66    }
67
68    fn encode_swap_out_amount_provided(
69        &self,
70        _swap_opcodes: &mut MulticallerCalls,
71        _abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
72        _token_from_address: Address,
73        _token_to_address: Address,
74        _amount_out: SwapAmountType,
75        _cur_pool: &dyn Pool,
76        _next_pool: Option<&dyn Pool>,
77        _payload: MulticallerOpcodesPayload,
78        _multicaller_address: Address,
79    ) -> Result<()> {
80        Err(eyre!("NOT_IMPLEMENTED"))
81    }
82}