kabu_execution_multicaller/pool_opcodes_encoder/
steth.rs1use 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}