loom_execution_multicaller/poolencoders/
steth.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use alloy_primitives::{Address, Bytes, U256};
use eyre::{eyre, Result};
use loom_defi_address_book::TokenAddress;
use loom_types_blockchain::{MulticallerCall, MulticallerCalls};
use loom_types_entities::{PoolWrapper, SwapAmountType};

use crate::helpers::EncoderHelper;

pub struct StEthSwapEncoder {}

impl StEthSwapEncoder {
    pub fn encode_swap_in_amount_provided(
        token_from_address: Address,
        token_to_address: Address,
        amount_in: SwapAmountType,
        swap_opcodes: &mut MulticallerCalls,
        cur_pool: &PoolWrapper,
        next_pool: Option<&PoolWrapper>,
        multicaller: Address,
    ) -> Result<()> {
        let pool_encoder = cur_pool.get_encoder();
        let pool_address = cur_pool.get_address();

        if token_from_address == TokenAddress::WETH && token_to_address == TokenAddress::STETH {
            match amount_in {
                SwapAmountType::Set(amount) => {
                    let weth_withdraw_opcode = MulticallerCall::new_call(token_from_address, &EncoderHelper::encode_weth_withdraw(amount));
                    let swap_opcode = MulticallerCall::new_call_with_value(
                        pool_address,
                        &pool_encoder.encode_swap_in_amount_provided(
                            token_from_address,
                            token_to_address,
                            amount,
                            multicaller,
                            Bytes::new(),
                        )?,
                        amount,
                    );

                    //let steth_balance_opcode = Opcode::new_static_call( token_to_address, &EncoderHelper::encode_erc20_balance_of(multicaller) );

                    swap_opcodes.add(weth_withdraw_opcode).add(swap_opcode);
                    //.add(steth_balance_opcode);
                }
                SwapAmountType::Stack0 => {
                    let mut weth_withdraw_opcode =
                        MulticallerCall::new_call(token_from_address, &EncoderHelper::encode_weth_withdraw(U256::ZERO));
                    weth_withdraw_opcode.set_call_stack(false, 0, 0x4, 0x20);

                    let mut swap_opcode = MulticallerCall::new_call_with_value(pool_address, &Bytes::new(), U256::ZERO);
                    swap_opcode.set_call_stack(false, 0, 0x4, 0x0);

                    swap_opcodes.add(weth_withdraw_opcode).add(swap_opcode);
                }

                SwapAmountType::RelativeStack(stack_offset) => {
                    let mut weth_withdraw_opcode =
                        MulticallerCall::new_call(token_from_address, &EncoderHelper::encode_weth_withdraw(U256::ZERO));
                    weth_withdraw_opcode.set_call_stack(true, stack_offset, 0x4, 0x20);

                    let mut swap_opcode = MulticallerCall::new_call_with_value(pool_address, &Bytes::new(), U256::ZERO);
                    swap_opcode.set_call_stack(true, stack_offset, 0, 0);

                    swap_opcodes.add(weth_withdraw_opcode).add(swap_opcode);
                }
                SwapAmountType::Balance(addr) => {
                    let mut weth_balance_opcode =
                        MulticallerCall::new_static_call(token_from_address, &EncoderHelper::encode_erc20_balance_of(addr));
                    weth_balance_opcode.set_return_stack(true, 0, 0, 0x20);

                    let mut weth_withdraw_opcode =
                        MulticallerCall::new_call(token_from_address, &EncoderHelper::encode_weth_withdraw(U256::ZERO));
                    weth_withdraw_opcode.set_call_stack(true, 0, 0x4, 0x20);

                    let mut swap_opcode = MulticallerCall::new_call_with_value(pool_address, &Bytes::new(), U256::ZERO);
                    swap_opcode.set_call_stack(true, 0, 0, 0);

                    swap_opcodes.add(weth_balance_opcode).add(weth_withdraw_opcode).add(swap_opcode);
                }
                _ => {
                    return Err(eyre!("CANNOT_ENCODE_STETH_SWAP"));
                }
            }

            if next_pool.is_some() {
                let mut steth_balance_opcode =
                    MulticallerCall::new_static_call(token_to_address, &EncoderHelper::encode_erc20_balance_of(multicaller));
                steth_balance_opcode.set_return_stack(true, 0, 0, 0x20);
                swap_opcodes.add(steth_balance_opcode);
            }

            return Ok(());
        }

        Err(eyre!("CANNOT_ENCODE_STETH_SWAP"))
    }
}