kabu_types_blockchain/
opcodes.rs

1use alloy_primitives::{Address, Bytes, U256};
2use tracing::debug;
3
4#[derive(Clone, Debug, Eq, PartialEq)]
5pub enum CallType {
6    Unknown,
7    Call,
8    DelegateCall,
9    StaticCall,
10    InternalCall,
11    CalculationCall,
12    CustomCall,
13}
14
15#[derive(Clone, Debug)]
16pub struct CallStack {
17    pub is_relative: bool,
18    pub stack_offset: u32,
19    pub data_offset: u32,
20    pub data_len: usize,
21}
22
23impl CallStack {
24    pub fn new(is_relative: bool, stack_offset: u32, data_offset: u32, data_len: usize) -> Self {
25        Self { is_relative, stack_offset, data_offset, data_len }
26    }
27}
28
29#[derive(Clone, Debug)]
30pub struct MulticallerCall {
31    pub call_type: CallType,
32    pub call_data: Bytes,
33    pub to: Address,
34    pub value: Option<U256>,
35    pub call_stack: Option<CallStack>,
36    pub return_stack: Option<CallStack>,
37}
38
39impl MulticallerCall {
40    pub fn new(opcode_type: CallType, to: Address, call_data: &Bytes, value: Option<U256>) -> MulticallerCall {
41        MulticallerCall { call_type: opcode_type, to, call_data: call_data.clone(), value, call_stack: None, return_stack: None }
42    }
43
44    pub fn new_call(to: Address, call_data: &Bytes) -> MulticallerCall {
45        MulticallerCall::new(CallType::Call, to, call_data, None)
46    }
47
48    pub fn new_call_with_value(to: Address, call_data: &Bytes, value: U256) -> MulticallerCall {
49        MulticallerCall::new(CallType::Call, to, call_data, Some(value))
50    }
51    pub fn new_internal_call(call_data: &Bytes) -> MulticallerCall {
52        MulticallerCall::new(CallType::InternalCall, Address::ZERO, call_data, None)
53    }
54
55    pub fn new_calculation_call(call_data: &Bytes) -> MulticallerCall {
56        MulticallerCall::new(CallType::CalculationCall, Address::ZERO, call_data, None)
57    }
58
59    pub fn new_delegate_call(to: Address, call_data: &Bytes) -> MulticallerCall {
60        MulticallerCall::new(CallType::DelegateCall, to, call_data, None)
61    }
62
63    pub fn new_static_call(to: Address, call_data: &Bytes) -> MulticallerCall {
64        MulticallerCall::new(CallType::StaticCall, to, call_data, None)
65    }
66
67    pub fn new_custom_call(call_data: &Bytes) -> MulticallerCall {
68        MulticallerCall::new(CallType::CustomCall, Address::ZERO, call_data, None)
69    }
70
71    /*fn encode_data_offset(is_relative: bool, stack_offset: u32, data_offset: u32, data_len: usize) -> u32 {
72        let mut ret = if is_relative { 0x800000 } else { 0x0 };
73        ret |= (stack_offset & 0x7) << 20;
74        ret |= (data_len as u32 & 0xFF) << 12;
75        ret |= data_offset & 0xFFF;
76        ret
77    }
78     */
79
80    pub fn set_call_stack(&mut self, is_relative: bool, stack_offset: u32, data_offset: u32, data_len: usize) -> &mut Self {
81        /*self.call_stack = match self.call_type {
82            CallType::InternalCall | CallType::CalculationCall => {
83                MulticallerCall::encode_data_offset(is_relative, stack_offset, data_offset + 0xC, data_len)
84            }
85            _ => MulticallerCall::encode_data_offset(is_relative, stack_offset, data_offset + 0x20, data_len),
86        };*/
87        self.call_stack = Some(CallStack::new(is_relative, stack_offset, data_offset, data_len));
88        self
89    }
90
91    /*
92    pub fn set_uniswap2_swap_out_amount_stack(&mut self, is_relative : bool, stack_offset : u32, zeroforone : bool) -> &mut Self{
93        self.call_stack = if zeroforone {
94            Opcode::encode_data_offset(is_relative, stack_offset, 0x20+ 0x24, 0x20)
95        }else{
96            Opcode::encode_data_offset(is_relative, stack_offset, 0x20+ 0x04, 0x20)
97        };
98
99        self
100    }
101
102     */
103
104    pub fn set_return_stack(&mut self, is_relative: bool, stack_offset: u32, data_offset: u32, data_len: usize) -> &mut Self {
105        //self.return_stack = MulticallerCall::encode_data_offset(is_relative, stack_offset, data_offset, data_len);
106        self.return_stack = Some(CallStack::new(is_relative, stack_offset, data_offset, data_len));
107        self
108    }
109
110    /*
111    pub fn set_uniswap3_return_stack(&mut self, is_relative : bool, stack_offset : u32, zeroforone : bool) -> &mut Self{
112        self.return_stack = if zeroforone {
113            Opcode::encode_data_offset(is_relative, stack_offset, 0x20, 0x20)
114        }else{
115            Opcode::encode_data_offset(is_relative, stack_offset, 0x0, 0x20)
116        };
117        self
118    }
119     */
120}
121
122#[derive(Clone, Debug, Default)]
123pub struct MulticallerCalls {
124    pub opcodes_vec: Vec<MulticallerCall>,
125}
126
127impl MulticallerCalls {
128    pub fn new() -> Self {
129        Self::default()
130    }
131
132    pub fn len(&self) -> usize {
133        self.opcodes_vec.len()
134    }
135
136    pub fn is_empty(&self) -> bool {
137        self.opcodes_vec.is_empty()
138    }
139
140    pub fn log(&self) {
141        for (i, o) in self.opcodes_vec.iter().enumerate() {
142            debug!("{} {:?}", i, o);
143        }
144    }
145
146    pub fn clean(&mut self) -> &mut Self {
147        self.opcodes_vec = Vec::new();
148        self
149    }
150
151    pub fn add(&mut self, opcode: MulticallerCall) -> &mut Self {
152        self.opcodes_vec.push(opcode);
153        self
154    }
155
156    pub fn insert(&mut self, opcode: MulticallerCall) -> &mut Self {
157        self.opcodes_vec.insert(0, opcode);
158        self
159    }
160
161    pub fn merge(&mut self, opcodes: MulticallerCalls) -> &mut Self {
162        self.opcodes_vec.extend(opcodes.opcodes_vec);
163        self
164    }
165
166    pub fn get(&self, idx: usize) -> Option<&MulticallerCall> {
167        self.opcodes_vec.get(idx)
168    }
169}