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