kabu_execution_multicaller/pool_opcodes_encoder/
wsteth.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;
11use kabu_types_swap::SwapAmountType;
12
13pub struct WstEthSwapEncoder {}
14
15impl SwapOpcodesEncoderTrait for WstEthSwapEncoder {
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_address = match cur_pool.get_address() {
30 kabu_types_market::PoolId::Address(addr) => addr,
31 kabu_types_market::PoolId::B256(_) => return Err(eyre!("Pool ID is B256, expected Address")),
32 };
33
34 if token_from_address == TokenAddressEth::WETH && token_to_address == TokenAddressEth::WSTETH {
35 let weth_withdraw_opcode =
36 MulticallerCall::new_call(token_from_address, &AbiEncoderHelper::encode_weth_withdraw(amount_in.unwrap_or_default()));
37 let mut 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 if next_pool.is_some() {
51 swap_opcode.set_return_stack(true, 0, 0, 0x20);
52 }
53
54 let opcodes_vec = vec![(weth_withdraw_opcode, 0x4, 0x20), (swap_opcode, 0x0, 0x20)];
55
56 swap_opcodes.merge(OpcodesHelpers::build_multiple_stack(amount_in, opcodes_vec, Some(token_from_address))?);
57
58 return Ok(());
59 }
60
61 if token_from_address == TokenAddressEth::STETH && token_to_address == TokenAddressEth::WSTETH
62 || token_from_address == TokenAddressEth::WSTETH && token_to_address == TokenAddressEth::STETH
63 {
64 let steth_approve_opcode = MulticallerCall::new_call(
65 token_from_address,
66 &AbiEncoderHelper::encode_erc20_approve(token_to_address, amount_in.unwrap_or_default()),
67 );
68
69 let mut swap_opcode = MulticallerCall::new_call(
70 pool_address,
71 &abi_encoder.encode_swap_in_amount_provided(
72 cur_pool,
73 token_from_address,
74 token_to_address,
75 amount_in.unwrap_or_default(),
76 multicaller,
77 Bytes::new(),
78 )?,
79 );
80 if next_pool.is_some() {
81 swap_opcode.set_return_stack(true, 0, 0, 0x20);
82 }
83 let opcodes_vec = vec![(steth_approve_opcode, 0x24, 0x20), (swap_opcode, 0x04, 0x20)];
84
85 swap_opcodes.merge(OpcodesHelpers::build_multiple_stack(amount_in, opcodes_vec, Some(token_from_address))?);
86
87 return Ok(());
88 }
89
90 Err(eyre!("CANNOT_ENCODE_WSTETH_SWAP"))
91 }
92
93 fn encode_swap_out_amount_provided(
94 &self,
95 _swap_opcodes: &mut MulticallerCalls,
96 _abi_encoder: &dyn ProtocolAbiSwapEncoderTrait,
97 _token_from_address: Address,
98 _token_to_address: Address,
99 _amount_out: SwapAmountType,
100 _cur_pool: &dyn Pool,
101 _next_pool: Option<&dyn Pool>,
102 _payload: MulticallerOpcodesPayload,
103 _multicaller_address: Address,
104 ) -> Result<()> {
105 Err(eyre!("NOT_IMPLEMENTED"))
106 }
107}