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