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