kabu_execution_multicaller/
opcodes_helpers.rs

1use alloy_primitives::{Address, U256};
2use eyre::Result;
3use kabu_defi_abi::AbiEncoderHelper;
4use kabu_types_blockchain::{MulticallerCall, MulticallerCalls};
5use kabu_types_entities::SwapAmountType;
6
7pub struct OpcodesHelpers {}
8
9impl OpcodesHelpers {
10    pub fn build_log_stack(size: usize) -> Result<MulticallerCalls> {
11        let mut calls = MulticallerCalls::new();
12
13        for i in 0..size {
14            calls.add(MulticallerCall::new_internal_call(&AbiEncoderHelper::encode_multicaller_log_stack_offset(U256::from(i))));
15        }
16
17        Ok(calls)
18    }
19
20    pub fn build_call_stack(
21        amount: SwapAmountType,
22        call: MulticallerCall,
23        offset: u32,
24        len: usize,
25        balance_of_token: Option<Address>,
26    ) -> Result<MulticallerCalls> {
27        let mut calls = MulticallerCalls::new();
28        let mut call = call;
29
30        match amount {
31            SwapAmountType::Set(_value) => {}
32            SwapAmountType::Balance(balance_of_owner) => {
33                let mut balance_opcode = MulticallerCall::new_static_call(
34                    balance_of_token.unwrap(),
35                    &AbiEncoderHelper::encode_erc20_balance_of(balance_of_owner),
36                );
37                balance_opcode.set_return_stack(true, 0, 0x0, 0x20);
38                calls.add(balance_opcode);
39
40                call.set_call_stack(true, 0, offset, len);
41            }
42            SwapAmountType::RelativeStack(stack_offset) => {
43                call.set_call_stack(true, stack_offset, offset, len);
44            }
45            SwapAmountType::NotSet => {
46                call.set_call_stack(true, 0, offset, len);
47            }
48            SwapAmountType::Stack0 => {
49                call.set_call_stack(false, 0, offset, len);
50            }
51        }
52        calls.add(call);
53
54        Ok(calls)
55    }
56
57    pub fn build_multiple_stack(
58        amount: SwapAmountType,
59        calls: Vec<(MulticallerCall, u32, usize)>,
60        balance_of_token: Option<Address>,
61    ) -> Result<MulticallerCalls> {
62        let mut multicaller_calls = MulticallerCalls::new();
63
64        if let SwapAmountType::Balance(balance_of_owner) = amount {
65            let mut balance_opcode =
66                MulticallerCall::new_static_call(balance_of_token.unwrap(), &AbiEncoderHelper::encode_erc20_balance_of(balance_of_owner));
67            balance_opcode.set_return_stack(true, 0, 0x0, 0x20);
68            multicaller_calls.add(balance_opcode);
69        }
70
71        for (call, offset, len) in calls {
72            let mut call = call;
73            match amount {
74                SwapAmountType::Set(_value) => {}
75                SwapAmountType::Balance(_balance_of_owner) => {
76                    call.set_call_stack(true, 0, offset, len);
77                }
78                SwapAmountType::RelativeStack(stack_offset) => {
79                    call.set_call_stack(true, stack_offset, offset, len);
80                }
81                SwapAmountType::NotSet => {
82                    call.set_call_stack(true, 0, offset, len);
83                }
84                SwapAmountType::Stack0 => {
85                    call.set_call_stack(false, 0, offset, len);
86                }
87            }
88            multicaller_calls.add(call);
89        }
90
91        Ok(multicaller_calls)
92    }
93}