1use std::sync::Arc;
18
19use alloy_dyn_abi::DynSolValue;
20use alloy_primitives::{Address, B256, I256, U256};
21use eyre::{bail, Result};
22use revm::database::CacheDB;
23use revm::{Database, DatabaseCommit, DatabaseRef};
24use solang_parser::pt::{Expression, Identifier, Loc, Parameter, Type};
25
26use crate::eval::handlers::debug::create_debug_handlers;
27use crate::eval::handlers::edb::EdbHandler;
28use crate::EngineContext;
29
30use super::handlers::EvaluatorHandlers;
31use super::utils::parse_input;
32
33#[derive(Clone)]
80pub struct ExpressionEvaluator {
81 handlers: EvaluatorHandlers,
82}
83
84impl ExpressionEvaluator {
85 pub fn new(handlers: EvaluatorHandlers) -> Self {
87 Self { handlers }
88 }
89
90 pub fn new_default() -> Self {
92 Self { handlers: EvaluatorHandlers::new() }
93 }
94
95 pub fn new_debug() -> Self {
97 let handlers = create_debug_handlers();
98 Self { handlers }
99 }
100
101 pub fn new_edb<DB>(context: Arc<EngineContext<DB>>) -> Self
103 where
104 DB: Database + DatabaseCommit + DatabaseRef + Clone + Send + Sync + 'static,
105 <CacheDB<DB> as Database>::Error: Clone + Send + Sync,
106 <DB as Database>::Error: Clone + Send + Sync,
107 {
108 let handlers = EdbHandler::create_handlers(context);
109 Self { handlers }
110 }
111
112 pub fn eval(&self, expr: &str, snapshot_id: usize) -> Result<DynSolValue> {
114 let parsed_expr =
116 parse_input(expr).map_err(|_| eyre::eyre!("Invalid expression \"{expr}\""))?;
117
118 let value = self.evaluate_expression(&parsed_expr, snapshot_id)?;
120
121 if let Some(validation_handler) = &self.handlers.validation_handler {
123 validation_handler.validate_value(value)
124 } else {
125 Ok(value)
126 }
127 }
128
129 fn evaluate_expression(&self, expr: &Expression, snapshot_id: usize) -> Result<DynSolValue> {
131 match expr {
132 Expression::NumberLiteral(_, value, _, ident) => {
134 if ident.is_none() {
135 self.evaluate_number_literal(value)
136 } else {
137 bail!("Invalid number literal")
138 }
139 }
140 Expression::HexNumberLiteral(_, value, ident) => {
141 if ident.is_none() {
142 self.evaluate_number_literal(value)
143 } else {
144 bail!("Invalid hex number literal")
145 }
146 }
147 Expression::StringLiteral(literals) => self.evaluate_string_literal(literals),
148 Expression::BoolLiteral(_, value) => Ok(DynSolValue::Bool(*value)),
149 Expression::AddressLiteral(_, addr) => self.evaluate_address_literal(addr),
150
151 Expression::Variable(ident) => self.evaluate_variable(ident, snapshot_id),
153 Expression::MemberAccess(_, base, member) => {
154 self.evaluate_member_access(base, member, snapshot_id)
155 }
156
157 Expression::ArraySubscript(_, array, index) => self.evaluate_array_or_mapping_access(
159 array,
160 index.as_ref().map(|v| &**v),
161 snapshot_id,
162 ),
163
164 Expression::FunctionCall(_, func, args) => {
166 self.evaluate_function_call(func, args, snapshot_id)
167 }
168
169 Expression::Add(_, left, right) => {
171 self.evaluate_binary_arithmetic(left, right, snapshot_id, ArithmeticOp::Add)
172 }
173 Expression::Subtract(_, left, right) => {
174 self.evaluate_binary_arithmetic(left, right, snapshot_id, ArithmeticOp::Subtract)
175 }
176 Expression::Multiply(_, left, right) => {
177 self.evaluate_binary_arithmetic(left, right, snapshot_id, ArithmeticOp::Multiply)
178 }
179 Expression::Divide(_, left, right) => {
180 self.evaluate_binary_arithmetic(left, right, snapshot_id, ArithmeticOp::Divide)
181 }
182 Expression::Modulo(_, left, right) => {
183 self.evaluate_binary_arithmetic(left, right, snapshot_id, ArithmeticOp::Modulo)
184 }
185 Expression::Power(_, base, exp) => {
186 self.evaluate_binary_arithmetic(base, exp, snapshot_id, ArithmeticOp::Power)
187 }
188
189 Expression::BitwiseAnd(_, left, right) => {
191 self.evaluate_bitwise(left, right, snapshot_id, BitwiseOp::And)
192 }
193 Expression::BitwiseOr(_, left, right) => {
194 self.evaluate_bitwise(left, right, snapshot_id, BitwiseOp::Or)
195 }
196 Expression::BitwiseXor(_, left, right) => {
197 self.evaluate_bitwise(left, right, snapshot_id, BitwiseOp::Xor)
198 }
199 Expression::BitwiseNot(_, operand) => self.evaluate_bitwise_not(operand, snapshot_id),
200 Expression::ShiftLeft(_, left, right) => {
201 self.evaluate_bitwise(left, right, snapshot_id, BitwiseOp::ShiftLeft)
202 }
203 Expression::ShiftRight(_, left, right) => {
204 self.evaluate_bitwise(left, right, snapshot_id, BitwiseOp::ShiftRight)
205 }
206
207 Expression::Equal(_, left, right) => {
209 self.evaluate_comparison(left, right, snapshot_id, ComparisonOp::Equal)
210 }
211 Expression::NotEqual(_, left, right) => {
212 self.evaluate_comparison(left, right, snapshot_id, ComparisonOp::NotEqual)
213 }
214 Expression::Less(_, left, right) => {
215 self.evaluate_comparison(left, right, snapshot_id, ComparisonOp::Less)
216 }
217 Expression::More(_, left, right) => {
218 self.evaluate_comparison(left, right, snapshot_id, ComparisonOp::Greater)
219 }
220 Expression::LessEqual(_, left, right) => {
221 self.evaluate_comparison(left, right, snapshot_id, ComparisonOp::LessEqual)
222 }
223 Expression::MoreEqual(_, left, right) => {
224 self.evaluate_comparison(left, right, snapshot_id, ComparisonOp::GreaterEqual)
225 }
226
227 Expression::And(_, left, right) => {
229 self.evaluate_logical(left, right, snapshot_id, LogicalOp::And)
230 }
231 Expression::Or(_, left, right) => {
232 self.evaluate_logical(left, right, snapshot_id, LogicalOp::Or)
233 }
234 Expression::Not(_, operand) => self.evaluate_logical_not(operand, snapshot_id),
235
236 Expression::UnaryPlus(_, operand) => self.evaluate_expression(operand, snapshot_id),
238 Expression::Negate(_, operand) => self.evaluate_unary_minus(operand, snapshot_id),
239
240 Expression::ConditionalOperator(_, condition, true_expr, false_expr) => {
242 self.evaluate_conditional(condition, true_expr, false_expr, snapshot_id)
243 }
244
245 Expression::Parenthesis(_, inner) => self.evaluate_expression(inner, snapshot_id),
247
248 Expression::ArraySlice(_, array, start, end) => {
250 self.evaluate_array_slice(array, start.as_deref(), end.as_deref(), snapshot_id)
251 }
252
253 Expression::HexLiteral(literals) => self.evaluate_hex_literal(literals),
255
256 Expression::ArrayLiteral(_, elements) => {
258 self.evaluate_array_literal(elements, snapshot_id)
259 }
260
261 Expression::List(_, parameters) => {
263 self.evaluate_list_parameters(parameters, snapshot_id)
264 }
265
266 Expression::New(..)
267 | Expression::Delete(..)
268 | Expression::PostDecrement(..)
269 | Expression::PostIncrement(..)
270 | Expression::PreDecrement(..)
271 | Expression::PreIncrement(..)
272 | Expression::Assign(..)
273 | Expression::AssignAdd(..)
274 | Expression::AssignSubtract(..)
275 | Expression::AssignMultiply(..)
276 | Expression::AssignDivide(..)
277 | Expression::AssignModulo(..)
278 | Expression::AssignShiftLeft(..)
279 | Expression::AssignShiftRight(..)
280 | Expression::AssignAnd(..)
281 | Expression::AssignOr(..)
282 | Expression::AssignXor(..)
283 | Expression::FunctionCallBlock(..)
284 | Expression::NamedFunctionCall(..)
285 | Expression::RationalNumberLiteral(..)
286 | Expression::Type(..) => bail!("Unsupported expression type: {:?}", expr),
287 }
288 }
289
290 fn evaluate_number_literal(&self, value: &str) -> Result<DynSolValue> {
292 let cleaned = value.replace('_', "");
294
295 let val = if cleaned.starts_with("0x") || cleaned.starts_with("0X") {
297 U256::from_str_radix(&cleaned[2..], 16)?
298 } else {
299 U256::from_str_radix(&cleaned, 10)?
300 };
301
302 Ok(DynSolValue::Uint(val, 256))
303 }
304
305 fn evaluate_string_literal(
307 &self,
308 literals: &[solang_parser::pt::StringLiteral],
309 ) -> Result<DynSolValue> {
310 let mut result = String::new();
311 for lit in literals {
312 result.push_str(&lit.string);
313 }
314 Ok(DynSolValue::String(result))
315 }
316
317 fn evaluate_address_literal(&self, addr: &str) -> Result<DynSolValue> {
319 let address = addr.parse::<Address>()?;
320 Ok(DynSolValue::Address(address))
321 }
322
323 fn evaluate_variable(&self, ident: &Identifier, snapshot_id: usize) -> Result<DynSolValue> {
325 match ident.name.as_str() {
326 "msg" | "tx" | "block" => {
327 bail!("Cannot evaluate {} directly, use member access", ident.name)
329 }
330 name => {
331 self.get_variable_value(name, snapshot_id)
333 }
334 }
335 }
336
337 fn evaluate_member_access(
339 &self,
340 base: &Expression,
341 member: &Identifier,
342 snapshot_id: usize,
343 ) -> Result<DynSolValue> {
344 if let Expression::Variable(base_ident) = base {
346 match (base_ident.name.as_str(), member.name.as_str()) {
347 ("msg", "sender") => return self.get_msg_sender(snapshot_id),
348 ("msg", "value") => return self.get_msg_value(snapshot_id),
349 ("tx", "origin") => return self.get_tx_origin(snapshot_id),
350 ("block", "number") => return self.get_block_number(snapshot_id),
351 ("block", "timestamp") => return self.get_block_timestamp(snapshot_id),
352 _ => {}
355 }
356 }
357
358 let base_value = self.evaluate_expression(base, snapshot_id)?;
360
361 if let Some(builtin_result) = self.handle_builtin_property(&base_value, &member.name)? {
363 return Ok(builtin_result);
364 }
365
366 if let DynSolValue::CustomStruct { name, prop_names, tuple } = base_value {
368 if let Some((idx, _)) = prop_names.iter().enumerate().find(|(_, n)| *n == &member.name)
369 {
370 if let Some(value) = tuple.get(idx) {
371 return Ok(value.clone());
372 } else {
373 bail!("Struct {} has no member named {}", name, member.name);
374 }
375 } else {
376 bail!("Struct {} has no member named {}", name, member.name);
377 }
378 }
379
380 self.access_member(base_value, &member.name, snapshot_id)
381 }
382
383 fn evaluate_array_or_mapping_access(
385 &self,
386 base: &Expression,
387 index: Option<&Expression>,
388 snapshot_id: usize,
389 ) -> Result<DynSolValue> {
390 let index = index.ok_or_else(|| eyre::eyre!("Array/mapping access requires an index"))?;
391
392 let (root, indices) = self.collect_access_chain(base, vec![index], snapshot_id)?;
394
395 self.get_mapping_or_array_value(root, indices, snapshot_id)
397 }
398
399 fn collect_access_chain<'a>(
401 &self,
402 expr: &'a Expression,
403 mut indices: Vec<&'a Expression>,
404 snapshot_id: usize,
405 ) -> Result<(DynSolValue, Vec<DynSolValue>)> {
406 match expr {
407 Expression::ArraySubscript(_, base, Some(index)) => {
408 indices.insert(0, index);
409 self.collect_access_chain(base, indices, snapshot_id)
410 }
411 _ => {
412 let root = self.evaluate_expression(expr, snapshot_id)?;
414 let evaluated_indices = indices
415 .into_iter()
416 .map(|idx| self.evaluate_expression(idx, snapshot_id))
417 .collect::<Result<Vec<_>>>()?;
418 Ok((root, evaluated_indices))
419 }
420 }
421 }
422
423 fn evaluate_function_call(
425 &self,
426 func: &Expression,
427 args: &[Expression],
428 snapshot_id: usize,
429 ) -> Result<DynSolValue> {
430 let arg_values = args
432 .iter()
433 .map(|arg| self.evaluate_expression(arg, snapshot_id))
434 .collect::<Result<Vec<_>>>()?;
435
436 let (func_name, callee) = match func {
438 Expression::Variable(ident) => (ident.name.clone(), None),
439 Expression::MemberAccess(_, base, member) => {
440 let callee = self.evaluate_expression(base, snapshot_id)?;
441
442 if let Some(result) =
444 self.handle_builtin_member_call(&member.name, &callee, &arg_values)?
445 {
446 return Ok(result);
447 }
448
449 (member.name.clone(), Some(callee))
450 }
451 Expression::Type(_, ty) if arg_values.len() == 1 => {
452 let arg = arg_values.into_iter().next().unwrap();
454 return self.evaluate_type_casting(ty, arg);
455 }
456 _ => bail!("Unsupported function call expression: {}", func),
457 };
458
459 self.call_function(&func_name, &arg_values, callee.as_ref(), snapshot_id)
461 }
462
463 fn handle_builtin_property(
465 &self,
466 value: &DynSolValue,
467 property_name: &str,
468 ) -> Result<Option<DynSolValue>> {
469 match (property_name, value) {
470 ("length", DynSolValue::String(s)) => {
472 Ok(Some(DynSolValue::Uint(U256::from(s.len()), 256)))
473 }
474 ("length", DynSolValue::Bytes(b)) => {
475 Ok(Some(DynSolValue::Uint(U256::from(b.len()), 256)))
476 }
477 ("length", DynSolValue::FixedBytes(_, size)) => {
478 Ok(Some(DynSolValue::Uint(U256::from(*size), 256)))
479 }
480 ("length", DynSolValue::Tuple(arr)) => {
481 Ok(Some(DynSolValue::Uint(U256::from(arr.len()), 256)))
482 }
483
484 ("balance", DynSolValue::Address(_)) => {
488 Ok(None)
490 }
491 ("code", DynSolValue::Address(_)) => {
492 Ok(None)
494 }
495 ("codehash", DynSolValue::Address(_)) => {
496 Ok(None)
498 }
499 ("codesize", DynSolValue::Address(_)) => {
500 Ok(None)
502 }
503
504 ("abs", DynSolValue::Int(val, bits)) => {
506 let abs_val = if val.is_negative() { val.wrapping_neg() } else { *val };
508 Ok(Some(DynSolValue::Uint(abs_val.into_raw(), *bits)))
509 }
510
511 ("isZero", DynSolValue::Uint(val, _bits)) => Ok(Some(DynSolValue::Bool(val.is_zero()))),
513 ("isZero", DynSolValue::Int(val, _bits)) => Ok(Some(DynSolValue::Bool(val.is_zero()))),
514 ("isZero", DynSolValue::Address(addr)) => {
515 Ok(Some(DynSolValue::Bool(*addr == Address::ZERO)))
516 }
517
518 _ => Ok(None), }
520 }
521
522 fn handle_builtin_member_call(
524 &self,
525 member_name: &str,
526 callee: &DynSolValue,
527 args: &[DynSolValue],
528 ) -> Result<Option<DynSolValue>> {
529 match (member_name, callee, args.len()) {
530 ("push", DynSolValue::Tuple(arr), 1) => {
536 let new_length = arr.len() + 1;
537 Ok(Some(DynSolValue::Uint(U256::from(new_length), 256)))
538 }
539 ("push", DynSolValue::Tuple(arr), 0) => {
541 let new_length = arr.len() + 1;
542 Ok(Some(DynSolValue::Uint(U256::from(new_length), 256)))
543 }
544 ("pop", DynSolValue::Tuple(arr), 0) => {
546 if arr.is_empty() {
547 bail!("Cannot pop from empty array")
548 } else {
549 Ok(Some(arr.last().unwrap().clone()))
551 }
552 }
553
554 ("concat", DynSolValue::String(s), 1) => {
558 if let DynSolValue::String(other) = &args[0] {
559 Ok(Some(DynSolValue::String(format!("{s}{other}"))))
560 } else {
561 Ok(None)
562 }
563 }
564 ("slice", DynSolValue::String(s), 1) => {
566 if let DynSolValue::Uint(start, _) = &args[0] {
567 let start_idx = start.to::<usize>();
568 if start_idx <= s.len() {
569 Ok(Some(DynSolValue::String(s[start_idx..].to_string())))
570 } else {
571 Ok(Some(DynSolValue::String(String::new())))
572 }
573 } else {
574 Ok(None)
575 }
576 }
577 ("slice", DynSolValue::String(s), 2) => {
579 if let (DynSolValue::Uint(start, _), DynSolValue::Uint(end, _)) =
580 (&args[0], &args[1])
581 {
582 let start_idx = start.to::<usize>();
583 let end_idx = end.to::<usize>();
584 if start_idx <= end_idx && end_idx <= s.len() {
585 Ok(Some(DynSolValue::String(s[start_idx..end_idx].to_string())))
586 } else {
587 Ok(Some(DynSolValue::String(String::new())))
588 }
589 } else {
590 Ok(None)
591 }
592 }
593
594 ("concat", DynSolValue::Bytes(b1), 1) => {
598 if let DynSolValue::Bytes(b2) = &args[0] {
599 let mut result = b1.clone();
600 result.extend_from_slice(b2);
601 Ok(Some(DynSolValue::Bytes(result)))
602 } else {
603 Ok(None)
604 }
605 }
606 ("slice", DynSolValue::Bytes(b), 1) => {
608 if let DynSolValue::Uint(start, _) = &args[0] {
609 let start_idx = start.to::<usize>();
610 if start_idx <= b.len() {
611 Ok(Some(DynSolValue::Bytes(b[start_idx..].to_vec())))
612 } else {
613 Ok(Some(DynSolValue::Bytes(Vec::new())))
614 }
615 } else {
616 Ok(None)
617 }
618 }
619 ("slice", DynSolValue::Bytes(b), 2) => {
621 if let (DynSolValue::Uint(start, _), DynSolValue::Uint(end, _)) =
622 (&args[0], &args[1])
623 {
624 let start_idx = start.to::<usize>();
625 let end_idx = end.to::<usize>();
626 if start_idx <= end_idx && end_idx <= b.len() {
627 Ok(Some(DynSolValue::Bytes(b[start_idx..end_idx].to_vec())))
628 } else {
629 Ok(Some(DynSolValue::Bytes(Vec::new())))
630 }
631 } else {
632 Ok(None)
633 }
634 }
635
636 ("min", DynSolValue::Uint(a, bits), 1) => {
640 if let DynSolValue::Uint(b, _) = &args[0] {
641 Ok(Some(DynSolValue::Uint((*a).min(*b), *bits)))
642 } else {
643 Ok(None)
644 }
645 }
646 ("max", DynSolValue::Uint(a, bits), 1) => {
648 if let DynSolValue::Uint(b, _) = &args[0] {
649 Ok(Some(DynSolValue::Uint((*a).max(*b), *bits)))
650 } else {
651 Ok(None)
652 }
653 }
654
655 ("isEmpty", DynSolValue::String(s), 0) => Ok(Some(DynSolValue::Bool(s.is_empty()))),
659 ("isEmpty", DynSolValue::Bytes(b), 0) => Ok(Some(DynSolValue::Bool(b.is_empty()))),
661 ("isEmpty", DynSolValue::Tuple(arr), 0) => Ok(Some(DynSolValue::Bool(arr.is_empty()))),
663
664 _ => Ok(None), }
666 }
667
668 fn evaluate_binary_arithmetic(
670 &self,
671 left: &Expression,
672 right: &Expression,
673 snapshot_id: usize,
674 op: ArithmeticOp,
675 ) -> Result<DynSolValue> {
676 let left_val = self.evaluate_expression(left, snapshot_id)?;
677 let right_val = self.evaluate_expression(right, snapshot_id)?;
678
679 self.apply_arithmetic_op(left_val, right_val, op)
680 }
681
682 fn apply_arithmetic_op(
684 &self,
685 left: DynSolValue,
686 right: DynSolValue,
687 op: ArithmeticOp,
688 ) -> Result<DynSolValue> {
689 match (left, right) {
690 (DynSolValue::Uint(l, bits1), DynSolValue::Uint(r, bits2)) => {
691 let bits = bits1.max(bits2);
692 let result = match op {
693 ArithmeticOp::Add => l.saturating_add(r),
694 ArithmeticOp::Subtract => l.saturating_sub(r),
695 ArithmeticOp::Multiply => l.saturating_mul(r),
696 ArithmeticOp::Divide => {
697 if r.is_zero() {
698 bail!("Division by zero");
699 }
700 l / r
701 }
702 ArithmeticOp::Modulo => {
703 if r.is_zero() {
704 bail!("Modulo by zero");
705 }
706 l % r
707 }
708 ArithmeticOp::Power => l.saturating_pow(r),
709 };
710 Ok(DynSolValue::Uint(result, bits))
711 }
712 (DynSolValue::Int(l, bits1), DynSolValue::Int(r, bits2)) => {
713 let bits = bits1.max(bits2);
714 let result = match op {
715 ArithmeticOp::Add => l.saturating_add(r),
716 ArithmeticOp::Subtract => l.saturating_sub(r),
717 ArithmeticOp::Multiply => l.saturating_mul(r),
718 ArithmeticOp::Divide => {
719 if r.is_zero() {
720 bail!("Division by zero");
721 }
722 l / r
723 }
724 ArithmeticOp::Modulo => {
725 if r.is_zero() {
726 bail!("Modulo by zero");
727 }
728 l % r
729 }
730 ArithmeticOp::Power => {
731 let base_u = U256::from_le_bytes(l.to_le_bytes::<32>());
733 let exp_u = U256::from_le_bytes(r.to_le_bytes::<32>());
734 let result_u = base_u.saturating_pow(exp_u);
735 I256::from_le_bytes(result_u.to_le_bytes::<32>())
736 }
737 };
738 Ok(DynSolValue::Int(result, bits))
739 }
740 _ => bail!("Cannot apply arithmetic operation to non-numeric types"),
741 }
742 }
743
744 fn evaluate_bitwise(
746 &self,
747 left: &Expression,
748 right: &Expression,
749 snapshot_id: usize,
750 op: BitwiseOp,
751 ) -> Result<DynSolValue> {
752 let left_val = self.evaluate_expression(left, snapshot_id)?;
753 let right_val = self.evaluate_expression(right, snapshot_id)?;
754
755 self.apply_bitwise_op(left_val, right_val, op)
756 }
757
758 fn apply_bitwise_op(
760 &self,
761 left: DynSolValue,
762 right: DynSolValue,
763 op: BitwiseOp,
764 ) -> Result<DynSolValue> {
765 match (left, right) {
766 (DynSolValue::Uint(l, bits1), DynSolValue::Uint(r, bits2)) => {
767 let bits = bits1.max(bits2);
768 let result = match op {
769 BitwiseOp::And => l & r,
770 BitwiseOp::Or => l | r,
771 BitwiseOp::Xor => l ^ r,
772 BitwiseOp::ShiftLeft => l << r,
773 BitwiseOp::ShiftRight => l >> r,
774 };
775 Ok(DynSolValue::Uint(result, bits))
776 }
777 _ => bail!("Bitwise operations require unsigned integer types"),
778 }
779 }
780
781 fn evaluate_bitwise_not(
783 &self,
784 operand: &Expression,
785 snapshot_id: usize,
786 ) -> Result<DynSolValue> {
787 let val = self.evaluate_expression(operand, snapshot_id)?;
788 match val {
789 DynSolValue::Uint(v, bits) => Ok(DynSolValue::Uint(!v, bits)),
790 _ => bail!("Bitwise NOT requires unsigned integer type"),
791 }
792 }
793
794 fn evaluate_comparison(
796 &self,
797 left: &Expression,
798 right: &Expression,
799 snapshot_id: usize,
800 op: ComparisonOp,
801 ) -> Result<DynSolValue> {
802 let left_val = self.evaluate_expression(left, snapshot_id)?;
803 let right_val = self.evaluate_expression(right, snapshot_id)?;
804
805 let result = self.apply_comparison_op(left_val, right_val, op)?;
806 Ok(DynSolValue::Bool(result))
807 }
808
809 fn apply_comparison_op(
811 &self,
812 left: DynSolValue,
813 right: DynSolValue,
814 op: ComparisonOp,
815 ) -> Result<bool> {
816 match (left, right) {
817 (DynSolValue::Uint(l, _), DynSolValue::Uint(r, _)) => Ok(match op {
818 ComparisonOp::Equal => l == r,
819 ComparisonOp::NotEqual => l != r,
820 ComparisonOp::Less => l < r,
821 ComparisonOp::Greater => l > r,
822 ComparisonOp::LessEqual => l <= r,
823 ComparisonOp::GreaterEqual => l >= r,
824 }),
825 (DynSolValue::Int(l, _), DynSolValue::Int(r, _)) => Ok(match op {
826 ComparisonOp::Equal => l == r,
827 ComparisonOp::NotEqual => l != r,
828 ComparisonOp::Less => l < r,
829 ComparisonOp::Greater => l > r,
830 ComparisonOp::LessEqual => l <= r,
831 ComparisonOp::GreaterEqual => l >= r,
832 }),
833 (DynSolValue::Bool(l), DynSolValue::Bool(r)) => Ok(match op {
834 ComparisonOp::Equal => l == r,
835 ComparisonOp::NotEqual => l != r,
836 _ => bail!("Cannot compare booleans with <, >, <=, >="),
837 }),
838 (DynSolValue::Address(l), DynSolValue::Address(r)) => Ok(match op {
839 ComparisonOp::Equal => l == r,
840 ComparisonOp::NotEqual => l != r,
841 _ => bail!("Cannot compare addresses with <, >, <=, >="),
842 }),
843 (DynSolValue::String(l), DynSolValue::String(r)) => Ok(match op {
844 ComparisonOp::Equal => l == r,
845 ComparisonOp::NotEqual => l != r,
846 _ => bail!("Cannot compare strings with <, >, <=, >="),
847 }),
848 _ => bail!("Cannot compare values of different types"),
849 }
850 }
851
852 fn evaluate_logical(
854 &self,
855 left: &Expression,
856 right: &Expression,
857 snapshot_id: usize,
858 op: LogicalOp,
859 ) -> Result<DynSolValue> {
860 let left_val = self.evaluate_expression(left, snapshot_id)?;
861
862 match op {
864 LogicalOp::And => {
865 if !self.to_bool(&left_val)? {
866 return Ok(DynSolValue::Bool(false));
867 }
868 let right_val = self.evaluate_expression(right, snapshot_id)?;
869 Ok(DynSolValue::Bool(self.to_bool(&right_val)?))
870 }
871 LogicalOp::Or => {
872 if self.to_bool(&left_val)? {
873 return Ok(DynSolValue::Bool(true));
874 }
875 let right_val = self.evaluate_expression(right, snapshot_id)?;
876 Ok(DynSolValue::Bool(self.to_bool(&right_val)?))
877 }
878 }
879 }
880
881 fn evaluate_logical_not(
883 &self,
884 operand: &Expression,
885 snapshot_id: usize,
886 ) -> Result<DynSolValue> {
887 let val = self.evaluate_expression(operand, snapshot_id)?;
888 Ok(DynSolValue::Bool(!self.to_bool(&val)?))
889 }
890
891 fn to_bool(&self, val: &DynSolValue) -> Result<bool> {
893 match val {
894 DynSolValue::Bool(b) => Ok(*b),
895 DynSolValue::Uint(v, _) => Ok(!v.is_zero()),
896 DynSolValue::Int(v, _) => Ok(!v.is_zero()),
897 _ => bail!("Cannot convert {:?} to boolean", val),
898 }
899 }
900
901 fn evaluate_unary_minus(
903 &self,
904 operand: &Expression,
905 snapshot_id: usize,
906 ) -> Result<DynSolValue> {
907 let val = self.evaluate_expression(operand, snapshot_id)?;
908 match val {
909 DynSolValue::Uint(v, bits) => {
910 let signed = I256::from_raw(v);
912 Ok(DynSolValue::Int(-signed, bits))
913 }
914 DynSolValue::Int(v, bits) => Ok(DynSolValue::Int(-v, bits)),
915 _ => bail!("Unary minus requires numeric type"),
916 }
917 }
918
919 fn evaluate_conditional(
921 &self,
922 condition: &Expression,
923 true_expr: &Expression,
924 false_expr: &Expression,
925 snapshot_id: usize,
926 ) -> Result<DynSolValue> {
927 let cond_val = self.evaluate_expression(condition, snapshot_id)?;
928
929 if self.to_bool(&cond_val)? {
930 self.evaluate_expression(true_expr, snapshot_id)
931 } else {
932 self.evaluate_expression(false_expr, snapshot_id)
933 }
934 }
935
936 fn evaluate_array_slice(
938 &self,
939 array: &Expression,
940 start: Option<&Expression>,
941 end: Option<&Expression>,
942 snapshot_id: usize,
943 ) -> Result<DynSolValue> {
944 let array_val = self.evaluate_expression(array, snapshot_id)?;
945
946 let elements = match array_val {
948 DynSolValue::Array(elements) => elements,
949 DynSolValue::FixedArray(elements) => elements,
950 _ => bail!("Array slice can only be applied to arrays, got {:?}", array_val),
951 };
952
953 let start_idx = if let Some(start_expr) = start {
955 let start_val = self.evaluate_expression(start_expr, snapshot_id)?;
956 match start_val {
957 DynSolValue::Uint(v, _) => v.to::<usize>(),
958 _ => bail!("Array slice start index must be an unsigned integer"),
959 }
960 } else {
961 0
962 };
963
964 let end_idx = if let Some(end_expr) = end {
965 let end_val = self.evaluate_expression(end_expr, snapshot_id)?;
966 match end_val {
967 DynSolValue::Uint(v, _) => v.to::<usize>(),
968 _ => bail!("Array slice end index must be an unsigned integer"),
969 }
970 } else {
971 elements.len()
972 };
973
974 if start_idx > end_idx {
976 bail!("Array slice start index {} is greater than end index {}", start_idx, end_idx);
977 }
978 if end_idx > elements.len() {
979 bail!("Array slice end index {} exceeds array length {}", end_idx, elements.len());
980 }
981
982 let slice = elements[start_idx..end_idx].to_vec();
984 Ok(DynSolValue::Array(slice))
985 }
986
987 fn evaluate_hex_literal(
989 &self,
990 literals: &[solang_parser::pt::HexLiteral],
991 ) -> Result<DynSolValue> {
992 let mut bytes = Vec::new();
993
994 for lit in literals {
995 let hex_str = &lit.hex;
997 let cleaned = hex_str.replace(['_', ' '], "");
999
1000 let hex = if cleaned.len() % 2 != 0 { format!("0{cleaned}") } else { cleaned };
1002
1003 for chunk in hex.as_bytes().chunks(2) {
1005 let hex_byte = std::str::from_utf8(chunk)?;
1006 let byte = u8::from_str_radix(hex_byte, 16)?;
1007 bytes.push(byte);
1008 }
1009 }
1010
1011 Ok(DynSolValue::Bytes(bytes))
1012 }
1013
1014 fn evaluate_array_literal(
1016 &self,
1017 elements: &[Expression],
1018 snapshot_id: usize,
1019 ) -> Result<DynSolValue> {
1020 let mut values = Vec::new();
1021
1022 for element in elements {
1023 let val = self.evaluate_expression(element, snapshot_id)?;
1024 values.push(val);
1025 }
1026
1027 Ok(DynSolValue::Array(values))
1028 }
1029
1030 fn evaluate_list_parameters(
1032 &self,
1033 parameters: &[(Loc, Option<Parameter>)],
1034 snapshot_id: usize,
1035 ) -> Result<DynSolValue> {
1036 let mut values = Vec::new();
1037
1038 for (_, param_opt) in parameters {
1039 if let Some(param) = param_opt {
1040 values.push(self.evaluate_expression(¶m.ty, snapshot_id)?);
1041 } else {
1042 bail!("Invalid none parameter in list");
1043 }
1044 }
1045
1046 Ok(DynSolValue::Tuple(values))
1047 }
1048
1049 fn evaluate_type_casting(&self, target_type: &Type, value: DynSolValue) -> Result<DynSolValue> {
1051 match target_type {
1052 Type::Address => match value {
1054 DynSolValue::Address(addr) => Ok(DynSolValue::Address(addr)),
1055 DynSolValue::Uint(val, _) => {
1056 let addr_bytes = val.to_be_bytes::<32>();
1058 let addr = Address::from_slice(&addr_bytes[12..]);
1059 Ok(DynSolValue::Address(addr))
1060 }
1061 DynSolValue::FixedBytes(bytes, 20) => {
1062 let addr = Address::from_slice(&bytes[..20]);
1063 Ok(DynSolValue::Address(addr))
1064 }
1065 _ => bail!("Cannot cast {:?} to address", value),
1066 },
1067
1068 Type::Uint(bits) => {
1070 let target_bits = *bits as usize;
1071 let mask = if target_bits >= 256 {
1073 U256::MAX
1074 } else {
1075 (U256::from(1) << target_bits) - U256::from(1)
1076 };
1077 match value {
1078 DynSolValue::Uint(val, _) => {
1079 let truncated = val & mask;
1080 Ok(DynSolValue::Uint(truncated, target_bits))
1081 }
1082 DynSolValue::Int(val, _) => {
1083 let unsigned = val.into_raw() & mask;
1084 Ok(DynSolValue::Uint(unsigned, target_bits))
1085 }
1086 DynSolValue::Address(addr) => {
1087 let val = U256::from_be_slice(addr.as_slice()) & mask;
1088 Ok(DynSolValue::Uint(val, target_bits))
1089 }
1090 DynSolValue::Bool(b) => {
1091 let val = if b { U256::from(1) } else { U256::ZERO };
1092 Ok(DynSolValue::Uint(val, target_bits))
1093 }
1094 _ => bail!("Cannot cast {:?} to uint{}", value, target_bits),
1095 }
1096 }
1097
1098 Type::Int(bits) => {
1100 let target_bits = *bits as usize;
1101 let truncate_signed = |val: I256| -> I256 {
1103 if target_bits >= 256 {
1104 return val;
1105 }
1106 let mask = (U256::from(1) << target_bits) - U256::from(1);
1108 let truncated = val.into_raw() & mask;
1109
1110 let sign_bit = U256::from(1) << (target_bits - 1);
1112 if truncated & sign_bit != U256::ZERO {
1113 let extension = U256::MAX ^ mask;
1115 I256::from_raw(truncated | extension)
1116 } else {
1117 I256::from_raw(truncated)
1119 }
1120 };
1121
1122 match value {
1123 DynSolValue::Int(val, _) => {
1124 let truncated = truncate_signed(val);
1125 Ok(DynSolValue::Int(truncated, target_bits))
1126 }
1127 DynSolValue::Uint(val, _) => {
1128 let signed = I256::from_raw(val);
1129 let truncated = truncate_signed(signed);
1130 Ok(DynSolValue::Int(truncated, target_bits))
1131 }
1132 DynSolValue::Bool(b) => {
1133 let val = if b { I256::from_raw(U256::from(1)) } else { I256::ZERO };
1134 Ok(DynSolValue::Int(val, target_bits))
1135 }
1136 _ => bail!("Cannot cast {:?} to int{}", value, target_bits),
1137 }
1138 }
1139
1140 Type::Bool => match value {
1142 DynSolValue::Bool(b) => Ok(DynSolValue::Bool(b)),
1143 DynSolValue::Uint(val, _) => Ok(DynSolValue::Bool(!val.is_zero())),
1144 DynSolValue::Int(val, _) => Ok(DynSolValue::Bool(!val.is_zero())),
1145 _ => bail!("Cannot cast {:?} to bool", value),
1146 },
1147
1148 Type::Bytes(size) => {
1150 let target_size = *size as usize;
1151 match value {
1152 DynSolValue::Bytes(bytes) => {
1153 let mut fixed_bytes = vec![0u8; 32];
1155 let copy_len = bytes.len().min(target_size);
1156 fixed_bytes[..copy_len].copy_from_slice(&bytes[..copy_len]);
1157 Ok(DynSolValue::FixedBytes(B256::from_slice(&fixed_bytes), target_size))
1158 }
1159 DynSolValue::FixedBytes(bytes, _) => {
1160 let mut fixed_bytes = vec![0u8; 32];
1162 let copy_len = bytes.len().min(target_size).min(32);
1163 fixed_bytes[..copy_len].copy_from_slice(&bytes[..copy_len]);
1164 Ok(DynSolValue::FixedBytes(B256::from_slice(&fixed_bytes), target_size))
1165 }
1166 DynSolValue::String(s) => {
1167 let bytes = s.as_bytes();
1169 let mut fixed_bytes = vec![0u8; 32];
1170 let copy_len = bytes.len().min(target_size);
1171 fixed_bytes[..copy_len].copy_from_slice(&bytes[..copy_len]);
1172 Ok(DynSolValue::FixedBytes(B256::from_slice(&fixed_bytes), target_size))
1173 }
1174 DynSolValue::Uint(val, _) => {
1175 let mut fixed_bytes = vec![0u8; 32];
1177 let be_bytes = val.to_be_bytes::<32>();
1178 if target_size < 32 {
1179 let src_start = 32 - target_size;
1181 fixed_bytes[..target_size].copy_from_slice(&be_bytes[src_start..]);
1182 } else {
1183 fixed_bytes = be_bytes.to_vec();
1184 }
1185 Ok(DynSolValue::FixedBytes(B256::from_slice(&fixed_bytes), target_size))
1186 }
1187 _ => bail!("Cannot cast {:?} to bytes{}", value, target_size),
1188 }
1189 }
1190
1191 Type::DynamicBytes => match value {
1193 DynSolValue::Bytes(bytes) => Ok(DynSolValue::Bytes(bytes)),
1194 DynSolValue::FixedBytes(bytes, _) => Ok(DynSolValue::Bytes(bytes.to_vec())),
1195 DynSolValue::String(s) => Ok(DynSolValue::Bytes(s.into_bytes())),
1196 DynSolValue::Uint(val, _) => Ok(DynSolValue::Bytes(val.to_be_bytes_vec())),
1197 _ => bail!("Cannot cast {:?} to bytes", value),
1198 },
1199
1200 Type::String => match value {
1202 DynSolValue::String(s) => Ok(DynSolValue::String(s)),
1203 DynSolValue::Bytes(bytes) => {
1204 let s =
1205 String::from_utf8(bytes).map_err(|_| eyre::eyre!("Invalid UTF-8 bytes"))?;
1206 Ok(DynSolValue::String(s))
1207 }
1208 DynSolValue::FixedBytes(bytes, _) => {
1209 let s = String::from_utf8(bytes.to_vec())
1210 .map_err(|_| eyre::eyre!("Invalid UTF-8 bytes"))?;
1211 Ok(DynSolValue::String(s))
1212 }
1213 _ => bail!("Cannot cast {:?} to string", value),
1214 },
1215
1216 _ => bail!("Type casting to {:?} is not yet supported", target_type),
1218 }
1219 }
1220
1221 fn get_variable_value(&self, name: &str, snapshot_id: usize) -> Result<DynSolValue> {
1226 match &self.handlers.variable_handler {
1227 Some(handler) => handler.get_variable_value(name, snapshot_id),
1228 None => bail!("No variable handler configured"),
1229 }
1230 }
1231
1232 fn get_mapping_or_array_value(
1234 &self,
1235 root: DynSolValue,
1236 indices: Vec<DynSolValue>,
1237 snapshot_id: usize,
1238 ) -> Result<DynSolValue> {
1239 match &self.handlers.mapping_array_handler {
1240 Some(handler) => handler.get_mapping_or_array_value(root, indices, snapshot_id),
1241 None => bail!("No mapping/array handler configured"),
1242 }
1243 }
1244
1245 fn call_function(
1247 &self,
1248 name: &str,
1249 args: &[DynSolValue],
1250 callee: Option<&DynSolValue>,
1251 snapshot_id: usize,
1252 ) -> Result<DynSolValue> {
1253 match &self.handlers.function_call_handler {
1254 Some(handler) => handler.call_function(name, args, callee, snapshot_id),
1255 None => bail!("No function call handler configured"),
1256 }
1257 }
1258
1259 fn access_member(
1261 &self,
1262 value: DynSolValue,
1263 member: &str,
1264 snapshot_id: usize,
1265 ) -> Result<DynSolValue> {
1266 match &self.handlers.member_access_handler {
1269 Some(handler) => handler.access_member(value, member, snapshot_id),
1270 None => bail!("No member access handler configured"),
1271 }
1272 }
1273
1274 fn get_msg_sender(&self, snapshot_id: usize) -> Result<DynSolValue> {
1276 match &self.handlers.msg_handler {
1277 Some(handler) => handler.get_msg_sender(snapshot_id),
1278 None => bail!("No msg handler configured"),
1279 }
1280 }
1281
1282 fn get_msg_value(&self, snapshot_id: usize) -> Result<DynSolValue> {
1284 match &self.handlers.msg_handler {
1285 Some(handler) => handler.get_msg_value(snapshot_id),
1286 None => bail!("No msg handler configured"),
1287 }
1288 }
1289
1290 fn get_tx_origin(&self, snapshot_id: usize) -> Result<DynSolValue> {
1292 match &self.handlers.tx_handler {
1293 Some(handler) => handler.get_tx_origin(snapshot_id),
1294 None => bail!("No tx handler configured"),
1295 }
1296 }
1297
1298 fn get_block_number(&self, snapshot_id: usize) -> Result<DynSolValue> {
1300 match &self.handlers.block_handler {
1301 Some(handler) => handler.get_block_number(snapshot_id),
1302 None => bail!("No block handler configured"),
1303 }
1304 }
1305
1306 fn get_block_timestamp(&self, snapshot_id: usize) -> Result<DynSolValue> {
1308 match &self.handlers.block_handler {
1309 Some(handler) => handler.get_block_timestamp(snapshot_id),
1310 None => bail!("No block handler configured"),
1311 }
1312 }
1313}
1314
1315#[derive(Debug)]
1317enum ArithmeticOp {
1318 Add,
1319 Subtract,
1320 Multiply,
1321 Divide,
1322 Modulo,
1323 Power,
1324}
1325
1326#[derive(Debug)]
1327enum BitwiseOp {
1328 And,
1329 Or,
1330 Xor,
1331 ShiftLeft,
1332 ShiftRight,
1333}
1334
1335#[derive(Debug)]
1336enum ComparisonOp {
1337 Equal,
1338 NotEqual,
1339 Less,
1340 Greater,
1341 LessEqual,
1342 GreaterEqual,
1343}
1344
1345#[derive(Debug)]
1346enum LogicalOp {
1347 And,
1348 Or,
1349}
1350
1351#[cfg(test)]
1352mod tests {
1353 use super::*;
1354 use crate::eval::handlers::debug::{create_debug_handlers, create_simulation_debug_handlers};
1355 use crate::eval::handlers::{MappingArrayHandler, MemberAccessHandler};
1356 use alloy_primitives::{address, U256};
1357
1358 #[test]
1359 fn test_evaluate_number_literal() {
1360 let evaluator = ExpressionEvaluator::new_default();
1365
1366 let result = evaluator.evaluate_number_literal("0x1234");
1368 assert!(result.is_ok());
1369 if let Ok(DynSolValue::Uint(val, bits)) = result {
1370 assert_eq!(val, U256::from(0x1234));
1371 assert_eq!(bits, 256);
1372 }
1373
1374 let result = evaluator.evaluate_number_literal("42");
1376 assert!(result.is_ok());
1377 if let Ok(DynSolValue::Uint(val, bits)) = result {
1378 assert_eq!(val, U256::from(42));
1379 assert_eq!(bits, 256);
1380 }
1381
1382 let result = evaluator.evaluate_number_literal("1_000_000");
1384 assert!(result.is_ok());
1385 if let Ok(DynSolValue::Uint(val, bits)) = result {
1386 assert_eq!(val, U256::from(1000000));
1387 assert_eq!(bits, 256);
1388 }
1389 }
1390
1391 #[test]
1392 fn test_apply_arithmetic_ops() {
1393 let evaluator = ExpressionEvaluator::new_default();
1394
1395 let left = DynSolValue::Uint(U256::from(10), 256);
1397 let right = DynSolValue::Uint(U256::from(20), 256);
1398 let result = evaluator.apply_arithmetic_op(left, right, ArithmeticOp::Add);
1399 assert!(result.is_ok());
1400 if let Ok(DynSolValue::Uint(val, _)) = result {
1401 assert_eq!(val, U256::from(30));
1402 }
1403
1404 let left = DynSolValue::Uint(U256::from(30), 256);
1406 let right = DynSolValue::Uint(U256::from(10), 256);
1407 let result = evaluator.apply_arithmetic_op(left, right, ArithmeticOp::Subtract);
1408 assert!(result.is_ok());
1409 if let Ok(DynSolValue::Uint(val, _)) = result {
1410 assert_eq!(val, U256::from(20));
1411 }
1412
1413 let left = DynSolValue::Uint(U256::from(5), 256);
1415 let right = DynSolValue::Uint(U256::from(6), 256);
1416 let result = evaluator.apply_arithmetic_op(left, right, ArithmeticOp::Multiply);
1417 assert!(result.is_ok());
1418 if let Ok(DynSolValue::Uint(val, _)) = result {
1419 assert_eq!(val, U256::from(30));
1420 }
1421
1422 let left = DynSolValue::Uint(U256::from(100), 256);
1424 let right = DynSolValue::Uint(U256::from(5), 256);
1425 let result = evaluator.apply_arithmetic_op(left, right, ArithmeticOp::Divide);
1426 assert!(result.is_ok());
1427 if let Ok(DynSolValue::Uint(val, _)) = result {
1428 assert_eq!(val, U256::from(20));
1429 }
1430
1431 let left = DynSolValue::Uint(U256::from(100), 256);
1433 let right = DynSolValue::Uint(U256::from(0), 256);
1434 let result = evaluator.apply_arithmetic_op(left, right, ArithmeticOp::Divide);
1435 assert!(result.is_err());
1436 }
1437
1438 #[test]
1439 fn test_comparison_ops() {
1440 let evaluator = ExpressionEvaluator::new_default();
1441
1442 let left = DynSolValue::Uint(U256::from(10), 256);
1444 let right = DynSolValue::Uint(U256::from(10), 256);
1445 let result = evaluator.apply_comparison_op(left, right, ComparisonOp::Equal);
1446 assert_eq!(result.unwrap(), true);
1447
1448 let left = DynSolValue::Uint(U256::from(10), 256);
1450 let right = DynSolValue::Uint(U256::from(20), 256);
1451 let result = evaluator.apply_comparison_op(left, right, ComparisonOp::NotEqual);
1452 assert_eq!(result.unwrap(), true);
1453
1454 let left = DynSolValue::Uint(U256::from(10), 256);
1456 let right = DynSolValue::Uint(U256::from(20), 256);
1457 let result = evaluator.apply_comparison_op(left, right, ComparisonOp::Less);
1458 assert_eq!(result.unwrap(), true);
1459
1460 let left = DynSolValue::Uint(U256::from(30), 256);
1462 let right = DynSolValue::Uint(U256::from(20), 256);
1463 let result = evaluator.apply_comparison_op(left, right, ComparisonOp::Greater);
1464 assert_eq!(result.unwrap(), true);
1465 }
1466
1467 #[test]
1468 fn test_to_bool() {
1469 let evaluator = ExpressionEvaluator::new_default();
1470
1471 assert_eq!(evaluator.to_bool(&DynSolValue::Bool(true)).unwrap(), true);
1473 assert_eq!(evaluator.to_bool(&DynSolValue::Bool(false)).unwrap(), false);
1474
1475 assert_eq!(evaluator.to_bool(&DynSolValue::Uint(U256::from(1), 256)).unwrap(), true);
1477 assert_eq!(evaluator.to_bool(&DynSolValue::Uint(U256::from(0), 256)).unwrap(), false);
1478 assert_eq!(evaluator.to_bool(&DynSolValue::Uint(U256::from(100), 256)).unwrap(), true);
1479
1480 assert_eq!(
1482 evaluator.to_bool(&DynSolValue::Int(I256::from_raw(U256::from(1)), 256)).unwrap(),
1483 true
1484 );
1485 assert_eq!(
1486 evaluator.to_bool(&DynSolValue::Int(I256::from_raw(U256::from(0)), 256)).unwrap(),
1487 false
1488 );
1489 assert_eq!(
1490 evaluator
1491 .to_bool(&DynSolValue::Int(I256::from_raw(U256::from(1)).wrapping_neg(), 256))
1492 .unwrap(),
1493 true
1494 );
1495 }
1496
1497 #[test]
1500 fn test_eval_number_literals() {
1501 let evaluator = ExpressionEvaluator::new_default();
1502
1503 let result = evaluator.eval("42", 0);
1505 assert!(result.is_ok());
1506 if let Ok(DynSolValue::Uint(val, bits)) = result {
1507 assert_eq!(val, U256::from(42));
1508 assert_eq!(bits, 256);
1509 }
1510
1511 let result = evaluator.eval("0x1234", 0);
1513 assert!(result.is_ok());
1514 if let Ok(DynSolValue::Uint(val, bits)) = result {
1515 assert_eq!(val, U256::from(0x1234));
1516 assert_eq!(bits, 256);
1517 }
1518
1519 let result = evaluator.eval("1_000_000", 0);
1521 assert!(result.is_ok());
1522 if let Ok(DynSolValue::Uint(val, bits)) = result {
1523 assert_eq!(val, U256::from(1_000_000));
1524 assert_eq!(bits, 256);
1525 }
1526
1527 let result =
1529 evaluator.eval("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 0);
1530 assert!(result.is_ok());
1531 if let Ok(DynSolValue::Uint(val, bits)) = result {
1532 assert_eq!(val, U256::MAX);
1533 assert_eq!(bits, 256);
1534 }
1535 }
1536
1537 #[test]
1538 fn test_eval_string_literals() {
1539 let evaluator = ExpressionEvaluator::new_default();
1540
1541 let result = evaluator.eval("\"hello world\"", 0);
1543 assert!(result.is_ok());
1544 if let Ok(DynSolValue::String(s)) = result {
1545 assert_eq!(s, "hello world");
1546 }
1547
1548 let result = evaluator.eval("\"\"", 0);
1550 assert!(result.is_ok());
1551 if let Ok(DynSolValue::String(s)) = result {
1552 assert_eq!(s, "");
1553 }
1554 }
1555
1556 #[test]
1557 fn test_eval_bool_literals() {
1558 let evaluator = ExpressionEvaluator::new_default();
1559
1560 let result = evaluator.eval("true", 0);
1562 assert!(result.is_ok());
1563 if let Ok(DynSolValue::Bool(b)) = result {
1564 assert_eq!(b, true);
1565 }
1566
1567 let result = evaluator.eval("false", 0);
1569 assert!(result.is_ok());
1570 if let Ok(DynSolValue::Bool(b)) = result {
1571 assert_eq!(b, false);
1572 }
1573 }
1574
1575 #[test]
1576 fn test_eval_arithmetic_expressions() {
1577 let evaluator = ExpressionEvaluator::new_default();
1578
1579 let result = evaluator.eval("10 + 20", 0);
1581 assert!(result.is_ok());
1582 if let Ok(DynSolValue::Uint(val, _)) = result {
1583 assert_eq!(val, U256::from(30));
1584 }
1585
1586 let result = evaluator.eval("50 - 20", 0);
1588 assert!(result.is_ok());
1589 if let Ok(DynSolValue::Uint(val, _)) = result {
1590 assert_eq!(val, U256::from(30));
1591 }
1592
1593 let result = evaluator.eval("6 * 7", 0);
1595 assert!(result.is_ok());
1596 if let Ok(DynSolValue::Uint(val, _)) = result {
1597 assert_eq!(val, U256::from(42));
1598 }
1599
1600 let result = evaluator.eval("100 / 5", 0);
1602 assert!(result.is_ok());
1603 if let Ok(DynSolValue::Uint(val, _)) = result {
1604 assert_eq!(val, U256::from(20));
1605 }
1606
1607 let result = evaluator.eval("17 % 5", 0);
1609 assert!(result.is_ok());
1610 if let Ok(DynSolValue::Uint(val, _)) = result {
1611 assert_eq!(val, U256::from(2));
1612 }
1613
1614 let result = evaluator.eval("2 ** 8", 0);
1616 assert!(result.is_ok());
1617 if let Ok(DynSolValue::Uint(val, _)) = result {
1618 assert_eq!(val, U256::from(256));
1619 }
1620 }
1621
1622 #[test]
1623 fn test_eval_complex_arithmetic() {
1624 let evaluator = ExpressionEvaluator::new_default();
1625
1626 let result = evaluator.eval("2 + 3 * 4", 0);
1628 assert!(result.is_ok());
1629 if let Ok(DynSolValue::Uint(val, _)) = result {
1630 assert_eq!(val, U256::from(14));
1631 }
1632
1633 let result = evaluator.eval("(2 + 3) * 4", 0);
1635 assert!(result.is_ok());
1636 if let Ok(DynSolValue::Uint(val, _)) = result {
1637 assert_eq!(val, U256::from(20));
1638 }
1639
1640 let result = evaluator.eval("(10 + 5) * 2 - 8 / 4", 0);
1642 assert!(result.is_ok());
1643 if let Ok(DynSolValue::Uint(val, _)) = result {
1644 assert_eq!(val, U256::from(28));
1645 }
1646 }
1647
1648 #[test]
1649 fn test_eval_unary_operations() {
1650 let evaluator = ExpressionEvaluator::new_default();
1651
1652 let result = evaluator.eval("+42", 0);
1654 assert!(result.is_ok());
1655 if let Ok(DynSolValue::Uint(val, _)) = result {
1656 assert_eq!(val, U256::from(42));
1657 }
1658
1659 let result = evaluator.eval("-42", 0);
1661 assert!(result.is_ok());
1662 if let Ok(DynSolValue::Int(val, _)) = result {
1663 assert_eq!(val, I256::from_raw(U256::from(42)).wrapping_neg());
1664 }
1665
1666 let result = evaluator.eval("!true", 0);
1668 assert!(result.is_ok());
1669 if let Ok(DynSolValue::Bool(b)) = result {
1670 assert_eq!(b, false);
1671 }
1672
1673 let result = evaluator.eval("!42", 0);
1675 assert!(result.is_ok());
1676 if let Ok(DynSolValue::Bool(b)) = result {
1677 assert_eq!(b, false);
1678 }
1679
1680 let result = evaluator.eval("!0", 0);
1682 assert!(result.is_ok());
1683 if let Ok(DynSolValue::Bool(b)) = result {
1684 assert_eq!(b, true);
1685 }
1686 }
1687
1688 #[test]
1689 fn test_eval_comparison_operations() {
1690 let evaluator = ExpressionEvaluator::new_default();
1691
1692 let result = evaluator.eval("10 == 10", 0);
1694 assert!(result.is_ok());
1695 if let Ok(DynSolValue::Bool(b)) = result {
1696 assert_eq!(b, true);
1697 }
1698
1699 let result = evaluator.eval("10 == 20", 0);
1700 assert!(result.is_ok());
1701 if let Ok(DynSolValue::Bool(b)) = result {
1702 assert_eq!(b, false);
1703 }
1704
1705 let result = evaluator.eval("10 != 20", 0);
1707 assert!(result.is_ok());
1708 if let Ok(DynSolValue::Bool(b)) = result {
1709 assert_eq!(b, true);
1710 }
1711
1712 let result = evaluator.eval("10 < 20", 0);
1714 assert!(result.is_ok());
1715 if let Ok(DynSolValue::Bool(b)) = result {
1716 assert_eq!(b, true);
1717 }
1718
1719 let result = evaluator.eval("30 > 20", 0);
1721 assert!(result.is_ok());
1722 if let Ok(DynSolValue::Bool(b)) = result {
1723 assert_eq!(b, true);
1724 }
1725
1726 let result = evaluator.eval("10 <= 10", 0);
1728 assert!(result.is_ok());
1729 if let Ok(DynSolValue::Bool(b)) = result {
1730 assert_eq!(b, true);
1731 }
1732
1733 let result = evaluator.eval("20 >= 10", 0);
1735 assert!(result.is_ok());
1736 if let Ok(DynSolValue::Bool(b)) = result {
1737 assert_eq!(b, true);
1738 }
1739 }
1740
1741 #[test]
1742 fn test_eval_logical_operations() {
1743 let evaluator = ExpressionEvaluator::new_default();
1744
1745 let result = evaluator.eval("true && true", 0);
1747 assert!(result.is_ok());
1748 if let Ok(DynSolValue::Bool(b)) = result {
1749 assert_eq!(b, true);
1750 }
1751
1752 let result = evaluator.eval("true && false", 0);
1753 assert!(result.is_ok());
1754 if let Ok(DynSolValue::Bool(b)) = result {
1755 assert_eq!(b, false);
1756 }
1757
1758 let result = evaluator.eval("true || false", 0);
1760 assert!(result.is_ok());
1761 if let Ok(DynSolValue::Bool(b)) = result {
1762 assert_eq!(b, true);
1763 }
1764
1765 let result = evaluator.eval("false || false", 0);
1766 assert!(result.is_ok());
1767 if let Ok(DynSolValue::Bool(b)) = result {
1768 assert_eq!(b, false);
1769 }
1770
1771 let result = evaluator.eval("0 && 42", 0);
1773 assert!(result.is_ok());
1774 if let Ok(DynSolValue::Bool(b)) = result {
1775 assert_eq!(b, false);
1776 }
1777
1778 let result = evaluator.eval("1 || 0", 0);
1779 assert!(result.is_ok());
1780 if let Ok(DynSolValue::Bool(b)) = result {
1781 assert_eq!(b, true);
1782 }
1783 }
1784
1785 #[test]
1786 fn test_eval_ternary_operator() {
1787 let evaluator = ExpressionEvaluator::new_default();
1788
1789 let result = evaluator.eval("true ? 42 : 99", 0);
1791 assert!(result.is_ok());
1792 if let Ok(DynSolValue::Uint(val, _)) = result {
1793 assert_eq!(val, U256::from(42));
1794 }
1795
1796 let result = evaluator.eval("false ? 42 : 99", 0);
1798 assert!(result.is_ok());
1799 if let Ok(DynSolValue::Uint(val, _)) = result {
1800 assert_eq!(val, U256::from(99));
1801 }
1802
1803 let result = evaluator.eval("(10 > 5) ? \"yes\" : \"no\"", 0);
1805 assert!(result.is_ok());
1806 if let Ok(DynSolValue::String(s)) = result {
1807 assert_eq!(s, "yes");
1808 }
1809
1810 let result = evaluator.eval("true ? (false ? 1 : 2) : 3", 0);
1812 assert!(result.is_ok());
1813 if let Ok(DynSolValue::Uint(val, _)) = result {
1814 assert_eq!(val, U256::from(2));
1815 }
1816 }
1817
1818 #[test]
1819 fn test_eval_error_cases() {
1820 let evaluator = ExpressionEvaluator::new_default();
1821
1822 let result = evaluator.eval("10 / 0", 0);
1824 assert!(result.is_err());
1825 assert!(result.unwrap_err().to_string().contains("Division by zero"));
1826
1827 let result = evaluator.eval("10 % 0", 0);
1829 assert!(result.is_err());
1830 assert!(result.unwrap_err().to_string().contains("Modulo by zero"));
1831
1832 let result = evaluator.eval("10 +", 0);
1834 assert!(result.is_err());
1835
1836 let result = evaluator.eval("someVariable", 0);
1838 assert!(result.is_err());
1839 assert!(result.unwrap_err().to_string().contains("No variable handler configured"));
1840
1841 let result = evaluator.eval("msg.sender", 0);
1843 assert!(result.is_err());
1844 assert!(result.unwrap_err().to_string().contains("No msg handler configured"));
1845 }
1846
1847 #[test]
1848 fn test_eval_complex_expressions() {
1849 let evaluator = ExpressionEvaluator::new_default();
1850
1851 let result = evaluator.eval("(2 + 3) * 4 - 1", 0);
1853 assert!(result.is_ok());
1854 if let Ok(DynSolValue::Uint(val, _)) = result {
1855 assert_eq!(val, U256::from(19)); }
1857
1858 let result = evaluator.eval("(5 > 3) && (2 == 2) || false", 0);
1860 assert!(result.is_ok());
1861 if let Ok(DynSolValue::Bool(b)) = result {
1862 assert_eq!(b, true);
1863 }
1864
1865 let result = evaluator.eval("5 > 3 ? (2 + 2) : (3 * 3)", 0);
1867 assert!(result.is_ok());
1868 if let Ok(DynSolValue::Uint(val, _)) = result {
1869 assert_eq!(val, U256::from(4));
1870 }
1871 }
1872
1873 #[test]
1874 fn test_eval_with_debug_handlers() {
1875 let handlers = create_debug_handlers();
1876 let evaluator = ExpressionEvaluator::new(handlers);
1877
1878 let result = evaluator.eval("someVariable", 0);
1880 assert!(result.is_err());
1881 let error = result.unwrap_err().to_string();
1882 assert!(error.contains("DebugHandler::get_variable_value"));
1883 assert!(error.contains("name='someVariable'"));
1884 assert!(error.contains("snapshot_id=0"));
1885
1886 let result = evaluator.eval("someFunction(1, 2)", 0);
1888 assert!(result.is_err());
1889 let error = result.unwrap_err().to_string();
1890 assert!(error.contains("DebugHandler::call_function"));
1891 assert!(error.contains("name='someFunction'"));
1892 }
1893
1894 #[test]
1895 fn test_eval_type_casting_comprehensive() {
1896 let evaluator = ExpressionEvaluator::new_default();
1897
1898 let result = evaluator.eval("address(0)", 0);
1902 assert!(result.is_ok());
1903 if let Ok(DynSolValue::Address(addr)) = result {
1904 assert_eq!(addr, Address::ZERO);
1905 }
1906
1907 let result = evaluator.eval("address(0x1234567890123456789012345678901234567890)", 0);
1909 assert!(result.is_ok());
1910
1911 let result = evaluator.eval("uint256(true)", 0);
1918 assert!(result.is_ok());
1919 if let Ok(DynSolValue::Uint(val, bits)) = result {
1920 assert_eq!(val, U256::from(1));
1921 assert_eq!(bits, 256);
1922 }
1923
1924 let result = evaluator.eval("uint256(false)", 0);
1926 assert!(result.is_ok());
1927 if let Ok(DynSolValue::Uint(val, bits)) = result {
1928 assert_eq!(val, U256::ZERO);
1929 assert_eq!(bits, 256);
1930 }
1931
1932 let result = evaluator.eval("uint8(257)", 0);
1934 assert!(result.is_ok());
1935 if let Ok(DynSolValue::Uint(val, bits)) = result {
1936 assert_eq!(val, U256::from(1)); assert_eq!(bits, 8);
1938 }
1939
1940 let result = evaluator.eval("uint16(65537)", 0);
1942 assert!(result.is_ok());
1943 if let Ok(DynSolValue::Uint(val, bits)) = result {
1944 assert_eq!(val, U256::from(1)); assert_eq!(bits, 16);
1946 }
1947
1948 let result = evaluator.eval("uint32(0xFFFFFFFF)", 0);
1950 assert!(result.is_ok());
1951 if let Ok(DynSolValue::Uint(val, bits)) = result {
1952 assert_eq!(val, U256::from(0xFFFFFFFF_u32));
1953 assert_eq!(bits, 32);
1954 }
1955
1956 let result = evaluator.eval("int256(true)", 0);
1960 assert!(result.is_ok());
1961 if let Ok(DynSolValue::Int(val, bits)) = result {
1962 assert_eq!(val, I256::from_raw(U256::from(1)));
1963 assert_eq!(bits, 256);
1964 }
1965
1966 let result = evaluator.eval("int8(127)", 0);
1968 assert!(result.is_ok());
1969 if let Ok(DynSolValue::Int(val, bits)) = result {
1970 assert_eq!(val, I256::from_raw(U256::from(127)));
1971 assert_eq!(bits, 8);
1972 }
1973
1974 let result = evaluator.eval("int8(128)", 0);
1976 assert!(result.is_ok());
1977 if let Ok(DynSolValue::Int(_val, bits)) = result {
1978 assert_eq!(bits, 8);
1980 }
1982
1983 let result = evaluator.eval("bool(1)", 0);
1987 assert!(result.is_ok());
1988 if let Ok(DynSolValue::Bool(b)) = result {
1989 assert_eq!(b, true);
1990 }
1991
1992 let result = evaluator.eval("bool(0)", 0);
1994 assert!(result.is_ok());
1995 if let Ok(DynSolValue::Bool(b)) = result {
1996 assert_eq!(b, false);
1997 }
1998
1999 let result = evaluator.eval("bool(0xFFFFFFFFFFFFFFFF)", 0);
2001 assert!(result.is_ok());
2002 if let Ok(DynSolValue::Bool(b)) = result {
2003 assert_eq!(b, true);
2004 }
2005
2006 let result = evaluator.eval("bool(int256(1))", 0);
2008 assert!(result.is_ok());
2009 if let Ok(DynSolValue::Bool(b)) = result {
2010 assert_eq!(b, true);
2011 }
2012
2013 let result = evaluator.eval("bool(uint8(257))", 0);
2023 assert!(result.is_ok());
2024 if let Ok(DynSolValue::Bool(b)) = result {
2025 assert_eq!(b, true);
2027 }
2028
2029 let result = evaluator.eval("uint256(true) + uint256(false)", 0);
2031 assert!(result.is_ok());
2032 if let Ok(DynSolValue::Uint(val, _)) = result {
2033 assert_eq!(val, U256::from(1)); }
2035
2036 let result = evaluator.eval("uint8(300) == uint8(44)", 0);
2038 assert!(result.is_ok());
2039 if let Ok(DynSolValue::Bool(b)) = result {
2040 assert_eq!(b, true);
2042 }
2043
2044 let result = evaluator.eval("true ? uint256(1) : uint256(0)", 0);
2053 assert!(result.is_ok());
2054 if let Ok(DynSolValue::Uint(val, _)) = result {
2055 assert_eq!(val, U256::from(1));
2056 }
2057
2058 let result = evaluator.eval("uint256(uint8(uint16(65793)))", 0);
2060 assert!(result.is_ok());
2061 if let Ok(DynSolValue::Uint(val, bits)) = result {
2062 assert_eq!(val, U256::from(1));
2064 assert_eq!(bits, 256);
2065 }
2066
2067 let result = evaluator.eval("uint256(address(0x1234)) + 1", 0);
2069 assert!(result.is_ok());
2070
2071 let result = evaluator.eval("bool(1) && bool(0)", 0);
2073 assert!(result.is_ok());
2074 if let Ok(DynSolValue::Bool(b)) = result {
2075 assert_eq!(b, false); }
2077
2078 let result = evaluator.eval("uint8(255) + 1", 0);
2080 assert!(result.is_ok());
2081 }
2083
2084 #[test]
2085 fn test_eval_error_propagation() {
2086 let evaluator = ExpressionEvaluator::new_default();
2087
2088 let result = evaluator.eval("5 / 0", 0);
2090 eprintln!("Error: {:?}", result);
2091 assert!(result.unwrap_err().to_string().to_lowercase().contains("division by zero"));
2092
2093 let result = evaluator.eval("5 + true", 0);
2095 assert!(result.is_err());
2096
2097 let result = evaluator.eval("unknownVar", 0);
2099 assert!(result.is_err());
2100 assert!(result
2101 .unwrap_err()
2102 .to_string()
2103 .to_lowercase()
2104 .contains("no variable handler configured"));
2105 }
2106
2107 #[test]
2108 fn test_eval_edge_cases() {
2109 let evaluator = ExpressionEvaluator::new_default();
2110
2111 let result = evaluator.eval(
2113 "115792089237316195423570985008687907853269984665640564039457584007913129639935",
2114 0,
2115 );
2116 assert!(result.is_ok());
2117 if let Ok(DynSolValue::Uint(val, _)) = result {
2118 assert_eq!(val, U256::MAX);
2119 }
2120
2121 let result = evaluator.eval("-42", 0);
2123 assert!(result.is_ok());
2124 if let Ok(DynSolValue::Int(val, _)) = result {
2125 assert!(val < I256::ZERO);
2126 }
2127
2128 let result = evaluator.eval("\"hello world\"", 0);
2130 assert!(result.is_ok());
2131 if let Ok(DynSolValue::String(s)) = result {
2132 assert_eq!(s, "hello world");
2133 }
2134
2135 let result = evaluator.eval("0x1234567890123456789012345678901234567890", 0);
2137 assert!(result.is_ok());
2138 }
2139
2140 #[test]
2141 fn test_eval_array_literals() {
2142 let (handlers, debug_handler) = create_simulation_debug_handlers();
2147 let evaluator_with_handlers = ExpressionEvaluator::new(handlers);
2148
2149 let result = evaluator_with_handlers.eval("arrayVar.length", 0);
2151 assert!(result.is_ok());
2152 if let Ok(DynSolValue::Uint(val, _)) = result {
2153 assert_eq!(val, U256::from(10)); }
2155
2156 let result = evaluator_with_handlers.eval("someAddress.balance", 0);
2158 assert!(result.is_ok());
2159 if let Ok(DynSolValue::Uint(val, _)) = result {
2160 assert_eq!(val, U256::from(1000000)); }
2162
2163 let result = evaluator_with_handlers.eval("contractAddr.code", 0);
2165 assert!(result.is_ok());
2166 if let Ok(DynSolValue::Bytes(_)) = result {
2167 }
2169
2170 let log = debug_handler.get_log();
2172 assert!(!log.is_empty());
2173 assert!(log.iter().any(|entry| entry.contains("access_member")));
2174
2175 let member_accesses = log.iter().filter(|entry| entry.contains("access_member")).count();
2177 assert!(member_accesses >= 3, "Should have logged at least 3 member accesses");
2178 }
2179
2180 #[test]
2181 fn test_eval_hex_literals() {
2182 let evaluator = ExpressionEvaluator::new_default();
2183
2184 let result = evaluator.eval("0x42", 0);
2186 assert!(result.is_ok());
2187 if let Ok(DynSolValue::Uint(val, _)) = result {
2188 assert_eq!(val, U256::from(0x42));
2189 }
2190
2191 let result = evaluator.eval("0x1234ABCD", 0);
2193 assert!(result.is_ok());
2194 if let Ok(DynSolValue::Uint(val, _)) = result {
2195 assert_eq!(val, U256::from(0x1234ABCD));
2196 }
2197
2198 let result = evaluator.eval("0xFF", 0);
2200 assert!(result.is_ok());
2201 if let Ok(DynSolValue::Uint(val, _)) = result {
2202 assert_eq!(val, U256::from(255));
2203 }
2204
2205 let result = evaluator.eval("0xDEADBEEF", 0);
2207 assert!(result.is_ok());
2208 if let Ok(DynSolValue::Uint(val, _)) = result {
2209 assert_eq!(val, U256::from(0xDEADBEEFu32));
2210 }
2211
2212 let result = evaluator.eval("0x10 + 0x20", 0);
2214 assert!(result.is_ok());
2215 if let Ok(DynSolValue::Uint(val, _)) = result {
2216 assert_eq!(val, U256::from(0x30)); }
2218
2219 let result = evaluator.eval("address(0x0)", 0);
2221 assert!(result.is_ok());
2222 if let Ok(DynSolValue::Address(addr)) = result {
2223 assert_eq!(addr, Address::ZERO);
2224 }
2225
2226 let result = evaluator.eval("address(0x1234567890123456789012345678901234567890)", 0);
2228 assert!(result.is_ok());
2229 if let Ok(DynSolValue::Address(_)) = result {
2230 } else {
2232 panic!("Failed to cast hex literal to address");
2233 }
2234 }
2235
2236 #[test]
2237 fn test_eval_list_tuples() {
2238 let (handlers, debug_handler) = create_simulation_debug_handlers();
2242 let evaluator = ExpressionEvaluator::new(handlers);
2243
2244 let result = evaluator.eval("multiReturnFunc()", 0);
2246 assert!(result.is_ok());
2247 if let Ok(DynSolValue::Tuple(values)) = result {
2248 assert!(!values.is_empty());
2249 }
2250
2251 let result = evaluator.eval("tupleVar", 0);
2253 assert!(result.is_ok());
2254 let result = evaluator.eval("structVar.field1", 0);
2258 assert!(result.is_ok());
2259 if let Ok(DynSolValue::Uint(val, _)) = result {
2260 assert_eq!(val, U256::from(42)); }
2262
2263 let result = evaluator.eval("nestedStruct.inner.value", 0);
2265 assert!(result.is_ok());
2266
2267 let result = evaluator.eval("pairData.first", 0);
2270 assert!(result.is_ok());
2271
2272 let result = evaluator.eval("pairData.second", 0);
2273 assert!(result.is_ok());
2274
2275 let log = debug_handler.get_log();
2277 assert!(!log.is_empty());
2278
2279 let function_calls = log.iter().filter(|entry| entry.contains("call_function")).count();
2281 let member_accesses = log.iter().filter(|entry| entry.contains("access_member")).count();
2282
2283 assert!(function_calls >= 1, "Should have logged at least 1 function call");
2284 assert!(member_accesses >= 4, "Should have logged at least 4 member accesses");
2285 }
2286
2287 #[test]
2288 fn test_simulation_debug_handler_basic() {
2289 let (handlers, debug_handler) = create_simulation_debug_handlers();
2290 let evaluator = ExpressionEvaluator::new(handlers);
2291
2292 let result = evaluator.eval("balance", 0);
2294 assert!(result.is_ok());
2295 if let Ok(DynSolValue::Uint(val, _)) = result {
2296 assert_eq!(val, U256::from(1000000)); }
2298
2299 let result = evaluator.eval("msg.sender", 0);
2301 assert!(result.is_ok());
2302 if let Ok(DynSolValue::Address(addr)) = result {
2303 assert_eq!(addr, Address::from([0x42; 20])); }
2305
2306 let log = debug_handler.get_log();
2308 assert!(!log.is_empty());
2309 assert!(log.iter().any(|entry| entry.contains("get_variable_value")));
2310 assert!(log.iter().any(|entry| entry.contains("get_msg_sender")));
2311 }
2312
2313 #[test]
2314 fn test_simulation_debug_handler_custom_values() {
2315 let (handlers, debug_handler) = create_simulation_debug_handlers();
2316 let evaluator = ExpressionEvaluator::new(handlers);
2317
2318 debug_handler.set_variable("myBalance", DynSolValue::Uint(U256::from(5000), 256));
2320 debug_handler.set_variable("myAddress", DynSolValue::Address(Address::from([0x99; 20])));
2321
2322 let result = evaluator.eval("myBalance", 0);
2324 assert!(result.is_ok());
2325 if let Ok(DynSolValue::Uint(val, _)) = result {
2326 assert_eq!(val, U256::from(5000));
2327 }
2328
2329 let result = evaluator.eval("myAddress", 0);
2330 assert!(result.is_ok());
2331 if let Ok(DynSolValue::Address(addr)) = result {
2332 assert_eq!(addr, Address::from([0x99; 20]));
2333 }
2334
2335 let log = debug_handler.get_log();
2337 assert!(log.iter().any(|entry| entry.contains("returning stored value")));
2338 }
2339
2340 #[test]
2341 fn test_simulation_debug_handler_complex_expressions() {
2342 let (handlers, debug_handler) = create_simulation_debug_handlers();
2343 let evaluator = ExpressionEvaluator::new(handlers);
2344
2345 debug_handler.set_variable("userBalance", DynSolValue::Uint(U256::from(2000), 256));
2347 debug_handler.set_function("balanceOf", DynSolValue::Uint(U256::from(1500), 256));
2348
2349 debug_handler.clear_log(); let result = evaluator.eval("userBalance + balanceOf(msg.sender)", 0);
2353 assert!(result.is_ok());
2354 if let Ok(DynSolValue::Uint(val, _)) = result {
2355 assert_eq!(val, U256::from(3500)); }
2357
2358 let log = debug_handler.get_log();
2360 println!("Execution log:");
2361 for entry in &log {
2362 println!(" {}", entry);
2363 }
2364
2365 assert!(log.iter().any(|entry| entry.contains("get_variable_value: name='userBalance'")));
2367 assert!(log.iter().any(|entry| entry.contains("call_function: name='balanceOf'")));
2368 assert!(log.iter().any(|entry| entry.contains("get_msg_sender")));
2369 }
2370
2371 #[test]
2372 fn test_simulation_debug_handler_mapping_access() {
2373 let (handlers, debug_handler) = create_simulation_debug_handlers();
2374 let _evaluator = ExpressionEvaluator::new(handlers);
2375
2376 debug_handler.clear_log();
2377
2378 let mock_mapping = DynSolValue::Uint(U256::from(0), 256); let indices = vec![DynSolValue::Address(Address::from([0x11; 20]))]; let result = debug_handler.get_mapping_or_array_value(mock_mapping, indices, 0);
2384 assert!(result.is_ok());
2385 if let Ok(DynSolValue::Uint(val, _)) = result {
2386 assert_eq!(val, U256::from(1000000)); }
2388
2389 let log = debug_handler.get_log();
2391 assert!(log.iter().any(|entry| entry.contains("get_mapping_or_array_value")));
2392 }
2393
2394 #[test]
2395 fn test_simulation_debug_handler_member_access() {
2396 let (handlers, debug_handler) = create_simulation_debug_handlers();
2397 let _evaluator = ExpressionEvaluator::new(handlers);
2398
2399 let mock_object = DynSolValue::Address(Address::from([0x42; 20]));
2402
2403 let result = debug_handler.access_member(mock_object, "balance", 0);
2404 assert!(result.is_ok());
2405 if let Ok(DynSolValue::Uint(val, _)) = result {
2406 assert_eq!(val, U256::from(1000000)); }
2408
2409 let result = debug_handler.access_member(DynSolValue::Uint(U256::ZERO, 256), "length", 0);
2410 assert!(result.is_ok());
2411 if let Ok(DynSolValue::Uint(val, _)) = result {
2412 assert_eq!(val, U256::from(10)); }
2414 }
2415
2416 #[test]
2417 fn test_debug_handler_comparison() {
2418 let error_handlers = create_debug_handlers();
2422 let error_evaluator = ExpressionEvaluator::new(error_handlers);
2423
2424 let result = error_evaluator.eval("someVar", 0);
2425 assert!(result.is_err());
2426 assert!(result.unwrap_err().to_string().contains("DebugHandler::get_variable_value"));
2427
2428 let (sim_handlers, _sim_debug) = create_simulation_debug_handlers();
2430 let sim_evaluator = ExpressionEvaluator::new(sim_handlers);
2431
2432 let result = sim_evaluator.eval("someVar", 0);
2433 assert!(result.is_ok()); if let Ok(DynSolValue::Uint(val, _)) = result {
2435 assert_eq!(val, U256::from(42)); }
2437 }
2438
2439 #[test]
2440 fn test_eval_mixed_type_operations() {
2441 let evaluator = ExpressionEvaluator::new_default();
2442
2443 let result = evaluator.eval("(10 + 5) == 15", 0);
2445 assert!(result.is_ok());
2446 if let Ok(DynSolValue::Bool(b)) = result {
2447 assert_eq!(b, true);
2448 }
2449
2450 let result = evaluator.eval("!(10 == 5)", 0);
2452 assert!(result.is_ok());
2453 if let Ok(DynSolValue::Bool(b)) = result {
2454 assert_eq!(b, true);
2455 }
2456
2457 let result = evaluator.eval("(2 * 3 > 5) && (10 / 2 == 5)", 0);
2459 assert!(result.is_ok());
2460 if let Ok(DynSolValue::Bool(b)) = result {
2461 assert_eq!(b, true);
2462 }
2463 }
2464
2465 #[test]
2466 fn test_eval_type_casting() {
2467 let evaluator = ExpressionEvaluator::new_default();
2468
2469 let result = evaluator.eval("address(0x0)", 0);
2471 assert!(result.is_ok());
2472 if let Ok(DynSolValue::Address(addr)) = result {
2473 assert_eq!(addr, address!("0x0000000000000000000000000000000000000000"));
2474 }
2475 }
2476
2477 #[test]
2478 fn test_eval_parentheses_precedence() {
2479 let evaluator = ExpressionEvaluator::new_default();
2480
2481 let result = evaluator.eval("((2 + 3) * (4 - 1))", 0);
2483 assert!(result.is_ok());
2484 if let Ok(DynSolValue::Uint(val, _)) = result {
2485 assert_eq!(val, U256::from(15)); }
2487
2488 let result = evaluator.eval("(((10)))", 0);
2490 assert!(result.is_ok());
2491 if let Ok(DynSolValue::Uint(val, _)) = result {
2492 assert_eq!(val, U256::from(10));
2493 }
2494
2495 let result = evaluator.eval("-(2 + 3)", 0);
2497 assert!(result.is_ok());
2498 if let Ok(DynSolValue::Int(val, _)) = result {
2499 assert_eq!(val, I256::from_raw(U256::from(5)).wrapping_neg());
2500 }
2501 }
2502
2503 #[test]
2504 fn test_advanced_simulation_scenarios() {
2505 let (handlers, debug_handler) = create_simulation_debug_handlers();
2506 let evaluator = ExpressionEvaluator::new(handlers);
2507
2508 debug_handler.set_variable("token", DynSolValue::Address(Address::from([0xAB; 20])));
2510 debug_handler.set_function("balanceOf", DynSolValue::Uint(U256::from(50000), 256));
2511 debug_handler.set_function("totalSupply", DynSolValue::Uint(U256::from(1000000), 256));
2512
2513 let result = evaluator.eval("balanceOf()", 0);
2515 assert!(result.is_ok());
2516 if let Ok(DynSolValue::Uint(val, _)) = result {
2517 assert_eq!(val, U256::from(50000));
2518 }
2519
2520 let result = evaluator.eval("(balanceOf() * 100) / totalSupply()", 0);
2522 assert!(result.is_ok());
2523 if let Ok(DynSolValue::Uint(val, _)) = result {
2524 assert_eq!(val, U256::from(5)); }
2526
2527 let log = debug_handler.get_log();
2529 assert!(log.iter().any(|entry| entry.contains("balanceOf")));
2530 assert!(log.iter().any(|entry| entry.contains("totalSupply")));
2531 }
2532
2533 #[test]
2534 fn test_blockchain_context_simulation() {
2535 let (handlers, _debug_handler) = create_simulation_debug_handlers();
2536 let evaluator = ExpressionEvaluator::new(handlers);
2537
2538 let result = evaluator.eval("msg.sender", 0);
2540 assert!(result.is_ok());
2541 if let Ok(DynSolValue::Address(addr)) = result {
2542 assert_eq!(addr, Address::from([0x42; 20]));
2543 }
2544
2545 let result = evaluator.eval("msg.value", 0);
2546 assert!(result.is_ok());
2547 if let Ok(DynSolValue::Uint(val, _)) = result {
2548 assert_eq!(val, U256::from(1000000000000000000u64)); }
2550
2551 let result = evaluator.eval("block.number", 0);
2552 assert!(result.is_ok());
2553 if let Ok(DynSolValue::Uint(val, _)) = result {
2554 assert_eq!(val, U256::from(18500000));
2555 }
2556
2557 let result = evaluator.eval("block.timestamp", 0);
2558 assert!(result.is_ok());
2559 if let Ok(DynSolValue::Uint(val, _)) = result {
2560 assert_eq!(val, U256::from(1700000000));
2561 }
2562
2563 let result = evaluator.eval("tx.origin", 0);
2564 assert!(result.is_ok());
2565 if let Ok(DynSolValue::Address(addr)) = result {
2566 assert_eq!(addr, Address::from([0x11; 20]));
2567 }
2568
2569 let result = evaluator.eval("block.timestamp + 3600", 0); assert!(result.is_ok());
2572 if let Ok(DynSolValue::Uint(val, _)) = result {
2573 assert_eq!(val, U256::from(1700003600));
2574 }
2575 }
2576
2577 #[test]
2578 fn test_complex_mapping_and_array_operations() {
2579 let (handlers, debug_handler) = create_simulation_debug_handlers();
2580 let evaluator = ExpressionEvaluator::new(handlers);
2581
2582 debug_handler.set_variable("userIndex", DynSolValue::Uint(U256::from(5), 256));
2584
2585 let result = evaluator.eval("users[userIndex].balance", 0);
2587 assert!(result.is_ok());
2588
2589 let result = evaluator.eval("balances[msg.sender]", 0);
2591 assert!(result.is_ok());
2592 if let Ok(DynSolValue::Uint(val, _)) = result {
2593 assert_eq!(val, U256::from(1000000)); }
2595
2596 let result = evaluator.eval("tokenData[token].holders[owner].amount", 0);
2598 assert!(result.is_ok());
2599
2600 let log = debug_handler.get_log();
2602 assert!(log.iter().any(|entry| entry.contains("get_mapping_or_array_value")));
2603 assert!(log.iter().any(|entry| entry.contains("access_member")));
2604 }
2605
2606 #[test]
2607 fn test_advanced_function_call_scenarios() {
2608 let (handlers, debug_handler) = create_simulation_debug_handlers();
2609 let evaluator = ExpressionEvaluator::new(handlers);
2610
2611 debug_handler.set_function(
2613 "getReserves",
2614 DynSolValue::Tuple(vec![
2615 DynSolValue::Uint(U256::from(1000000), 256),
2616 DynSolValue::Uint(U256::from(500000), 256),
2617 DynSolValue::Uint(U256::from(1700000000), 256),
2618 ]),
2619 );
2620
2621 let result = evaluator.eval("getReserves()", 0);
2623 assert!(result.is_ok());
2624 if let Ok(DynSolValue::Tuple(values)) = result {
2625 assert_eq!(values.len(), 3);
2626 }
2627
2628 let result = evaluator.eval("name()", 0);
2630 assert!(result.is_ok());
2631 if let Ok(DynSolValue::String(name)) = result {
2632 assert_eq!(name, "MockToken");
2633 }
2634
2635 let result = evaluator.eval("symbol()", 0);
2636 assert!(result.is_ok());
2637 if let Ok(DynSolValue::String(symbol)) = result {
2638 assert_eq!(symbol, "MTK");
2639 }
2640
2641 let result = evaluator.eval("decimals()", 0);
2642 assert!(result.is_ok());
2643 if let Ok(DynSolValue::Uint(decimals, _)) = result {
2644 assert_eq!(decimals, U256::from(18));
2645 }
2646
2647 let result = evaluator.eval("approve()", 0);
2649 assert!(result.is_ok());
2650 if let Ok(DynSolValue::Bool(success)) = result {
2651 assert!(success);
2652 }
2653 }
2654
2655 #[test]
2656 fn test_cross_handler_interactions() {
2657 let (handlers, debug_handler) = create_simulation_debug_handlers();
2658 let evaluator = ExpressionEvaluator::new(handlers);
2659
2660 let result = evaluator.eval("(msg.value * balanceOf()) / totalSupply()", 0);
2662 assert!(result.is_ok());
2663
2664 let result = evaluator.eval("msg.value > 0 && balanceOf() > 1000", 0);
2666 assert!(result.is_ok());
2667 if let Ok(DynSolValue::Bool(is_valid)) = result {
2668 assert!(is_valid);
2669 }
2670
2671 let result = evaluator.eval("msg.sender == tx.origin", 0);
2673 assert!(result.is_ok());
2674 if let Ok(DynSolValue::Bool(is_same)) = result {
2675 assert!(!is_same); }
2677
2678 let result = evaluator.eval("block.number % 100", 0);
2680 assert!(result.is_ok());
2681
2682 let log = debug_handler.get_log();
2684 assert!(log.iter().any(|entry| entry.contains("get_msg_")));
2685 assert!(log.iter().any(|entry| entry.contains("get_tx_")));
2686 assert!(log.iter().any(|entry| entry.contains("get_block_")));
2687 assert!(log.iter().any(|entry| entry.contains("call_function")));
2688 }
2689
2690 #[test]
2691 fn test_error_handling_and_recovery() {
2692 let (handlers, debug_handler) = create_simulation_debug_handlers();
2693 let evaluator = ExpressionEvaluator::new(handlers);
2694
2695 let result = evaluator.eval("1 / 0", 0);
2697 assert!(result.is_err());
2698 let error_msg = result.unwrap_err().to_string().to_lowercase();
2699 assert!(error_msg.contains("division") && error_msg.contains("zero"));
2700
2701 let result = evaluator.eval("true + 5", 0);
2703 assert!(result.is_err());
2704
2705 let result = evaluator.eval("msg.sender", 0);
2707 assert!(result.is_ok());
2708
2709 let log = debug_handler.get_log();
2711 assert!(log.iter().any(|entry| entry.contains("get_msg_sender")));
2712 }
2713
2714 #[test]
2715 fn test_performance_and_logging_metrics() {
2716 let (handlers, debug_handler) = create_simulation_debug_handlers();
2717 let evaluator = ExpressionEvaluator::new(handlers);
2718
2719 debug_handler.clear_log();
2721
2722 let result = evaluator
2724 .eval("((balanceOf() * msg.value) / totalSupply()) > (block.timestamp % 1000)", 0);
2725 assert!(result.is_ok());
2726
2727 let log = debug_handler.get_log();
2729 assert!(!log.is_empty());
2730
2731 let function_calls = log.iter().filter(|entry| entry.contains("call_function")).count();
2733 let msg_accesses = log.iter().filter(|entry| entry.contains("get_msg_")).count();
2734 let block_accesses = log.iter().filter(|entry| entry.contains("get_block_")).count();
2735
2736 assert!(function_calls >= 2); assert!(msg_accesses >= 1); assert!(block_accesses >= 1); debug_handler.clear_log();
2742 let cleared_log = debug_handler.get_log();
2743 assert!(cleared_log.is_empty());
2744 }
2745
2746 #[test]
2747 fn test_dynamic_value_simulation() {
2748 let (handlers, _debug_handler) = create_simulation_debug_handlers();
2749 let evaluator = ExpressionEvaluator::new(handlers);
2750
2751 let balance_result = evaluator.eval("balance", 0);
2756 if let Ok(DynSolValue::Uint(val, _)) = balance_result {
2757 assert_eq!(val, U256::from(1000000)); } else {
2759 panic!("Expected balance to return Uint(1000000, 256)");
2760 }
2761
2762 let amount_result = evaluator.eval("amount", 0);
2763 if let Ok(DynSolValue::Uint(val, _)) = amount_result {
2764 assert_eq!(val, U256::from(1000000)); } else {
2766 panic!("Expected amount to return Uint(1000000, 256)");
2767 }
2768
2769 let value_result = evaluator.eval("value", 0);
2770 if let Ok(DynSolValue::Uint(val, _)) = value_result {
2771 assert_eq!(val, U256::from(1000000)); } else {
2773 panic!("Expected value to return Uint(1000000, 256)");
2774 }
2775
2776 let address_result = evaluator.eval("myaddress", 0);
2778 assert!(matches!(address_result.unwrap(), DynSolValue::Address(_)));
2779
2780 let owner_result = evaluator.eval("owner", 0);
2781 assert!(matches!(owner_result.unwrap(), DynSolValue::Address(_)));
2782
2783 let sender_result = evaluator.eval("sender", 0);
2784 assert!(matches!(sender_result.unwrap(), DynSolValue::Address(_)));
2785
2786 let count_result = evaluator.eval("count", 0);
2788 if let Ok(DynSolValue::Uint(val, _)) = count_result {
2789 assert_eq!(val, U256::from(5)); } else {
2791 panic!("Expected count to return Uint(5, 256)");
2792 }
2793
2794 let length_result = evaluator.eval("length", 0);
2795 if let Ok(DynSolValue::Uint(val, _)) = length_result {
2796 assert_eq!(val, U256::from(5)); } else {
2798 panic!("Expected length to return Uint(5, 256)");
2799 }
2800
2801 let index_result = evaluator.eval("index", 0);
2802 if let Ok(DynSolValue::Uint(val, _)) = index_result {
2803 assert_eq!(val, U256::from(5)); } else {
2805 panic!("Expected index to return Uint(5, 256)");
2806 }
2807
2808 let enabled_result = evaluator.eval("enabled", 0);
2810 if let Ok(DynSolValue::Bool(val)) = enabled_result {
2811 assert!(val); } else {
2813 panic!("Expected enabled to return Bool(true)");
2814 }
2815
2816 let active_result = evaluator.eval("active", 0);
2817 if let Ok(DynSolValue::Bool(val)) = active_result {
2818 assert!(val); } else {
2820 panic!("Expected active to return Bool(true)");
2821 }
2822
2823 let flag_result = evaluator.eval("flag", 0);
2824 if let Ok(DynSolValue::Bool(val)) = flag_result {
2825 assert!(val); } else {
2827 panic!("Expected flag to return Bool(true)");
2828 }
2829
2830 let name_result = evaluator.eval("name", 0);
2832 if let Ok(DynSolValue::String(val)) = name_result {
2833 assert_eq!(val, "Mock_name"); } else {
2835 panic!("Expected name to return String");
2836 }
2837
2838 let symbol_result = evaluator.eval("symbol", 0);
2839 if let Ok(DynSolValue::String(val)) = symbol_result {
2840 assert_eq!(val, "Mock_symbol"); } else {
2842 panic!("Expected symbol to return String");
2843 }
2844
2845 let uri_result = evaluator.eval("uri", 0);
2846 if let Ok(DynSolValue::String(val)) = uri_result {
2847 assert_eq!(val, "Mock_uri"); } else {
2849 panic!("Expected uri to return String");
2850 }
2851
2852 let fallback_result = evaluator.eval("randomVariable", 0);
2854 if let Ok(DynSolValue::Uint(val, _)) = fallback_result {
2855 assert_eq!(val, U256::from(42));
2856 } else {
2857 panic!("Expected fallback to return Uint(42, 256)");
2858 }
2859 }
2860
2861 #[test]
2862 fn test_enhanced_builtin_properties() {
2863 let (handlers, debug_handler) = create_simulation_debug_handlers();
2864 let evaluator = ExpressionEvaluator::new(handlers);
2865
2866 debug_handler.set_variable("testString", DynSolValue::String("Hello".to_string()));
2868 debug_handler.set_variable("testBytes", DynSolValue::Bytes(vec![1, 2, 3]));
2869 debug_handler.set_variable("testAddress", DynSolValue::Address(Address::ZERO));
2870 debug_handler.set_variable(
2871 "testInt",
2872 DynSolValue::Int(I256::from_raw(U256::from(42).wrapping_neg()), 256),
2873 );
2874 debug_handler.set_variable("zeroInt", DynSolValue::Int(I256::ZERO, 256));
2875 debug_handler.set_variable("zeroUint", DynSolValue::Uint(U256::ZERO, 256));
2876 debug_handler.set_variable("nonZeroUint", DynSolValue::Uint(U256::from(123), 256));
2877
2878 let result = evaluator.eval("testString.length", 0);
2882 assert!(result.is_ok());
2883 if let Ok(DynSolValue::Uint(len, _)) = result {
2884 assert_eq!(len, U256::from(5)); }
2886
2887 let result = evaluator.eval("testBytes.length", 0);
2889 assert!(result.is_ok());
2890 if let Ok(DynSolValue::Uint(len, _)) = result {
2891 assert_eq!(len, U256::from(3));
2892 }
2893
2894 let result = evaluator.eval("testInt.abs", 0);
2898 assert!(result.is_ok());
2899 if let Ok(DynSolValue::Uint(val, _)) = result {
2900 assert_eq!(val, U256::from(42));
2901 }
2902
2903 let result = evaluator.eval("zeroInt.isZero", 0);
2907 assert!(result.is_ok());
2908 if let Ok(DynSolValue::Bool(is_zero)) = result {
2909 assert!(is_zero);
2910 }
2911
2912 let result = evaluator.eval("zeroUint.isZero", 0);
2913 assert!(result.is_ok());
2914 if let Ok(DynSolValue::Bool(is_zero)) = result {
2915 assert!(is_zero);
2916 }
2917
2918 let result = evaluator.eval("testAddress.isZero", 0);
2919 assert!(result.is_ok());
2920 if let Ok(DynSolValue::Bool(is_zero)) = result {
2921 assert!(is_zero); }
2923
2924 let result = evaluator.eval("nonZeroUint.isZero", 0);
2926 assert!(result.is_ok());
2927 if let Ok(DynSolValue::Bool(is_zero)) = result {
2928 assert!(!is_zero);
2929 }
2930 }
2931
2932 #[test]
2933 fn test_builtin_member_functions() {
2934 let (handlers, debug_handler) = create_simulation_debug_handlers();
2935 let evaluator = ExpressionEvaluator::new(handlers);
2936
2937 debug_handler.set_variable("testString", DynSolValue::String("Hello World".to_string()));
2939 debug_handler.set_variable("emptyString", DynSolValue::String("".to_string()));
2940 debug_handler.set_variable("myBytes", DynSolValue::Bytes(vec![1, 2, 3, 4, 5]));
2941 debug_handler.set_variable("emptyBytes", DynSolValue::Bytes(vec![]));
2942 debug_handler.set_variable(
2943 "myArray",
2944 DynSolValue::Tuple(vec![
2945 DynSolValue::Uint(U256::from(10), 256),
2946 DynSolValue::Uint(U256::from(20), 256),
2947 DynSolValue::Uint(U256::from(30), 256),
2948 ]),
2949 );
2950 debug_handler.set_variable("emptyArray", DynSolValue::Tuple(vec![]));
2951 debug_handler.set_variable("testAddress", DynSolValue::Address(Address::from([0x42; 20])));
2952 debug_handler.set_variable("numberA", DynSolValue::Uint(U256::from(100), 256));
2953 debug_handler.set_variable("numberB", DynSolValue::Uint(U256::from(200), 256));
2954
2955 let result = evaluator.eval("testString.length", 0);
2959 assert!(result.is_ok());
2960 if let Ok(DynSolValue::Uint(len, _)) = result {
2961 assert_eq!(len, U256::from(11)); }
2963
2964 let result = evaluator.eval("myBytes.length", 0);
2966 assert!(result.is_ok());
2967 if let Ok(DynSolValue::Uint(len, _)) = result {
2968 assert_eq!(len, U256::from(5));
2969 }
2970
2971 let result = evaluator.eval("myArray.length", 0);
2973 assert!(result.is_ok());
2974 if let Ok(DynSolValue::Uint(len, _)) = result {
2975 assert_eq!(len, U256::from(3));
2976 }
2977
2978 let result = evaluator.eval("myArray.push()", 0);
2982 assert!(result.is_ok());
2983 if let Ok(DynSolValue::Uint(new_len, _)) = result {
2984 assert_eq!(new_len, U256::from(4)); }
2986
2987 debug_handler.set_variable("newElement", DynSolValue::Uint(U256::from(40), 256));
2989 let result = evaluator.eval("myArray.push(newElement)", 0);
2990 assert!(result.is_ok());
2991 if let Ok(DynSolValue::Uint(new_len, _)) = result {
2992 assert_eq!(new_len, U256::from(4)); }
2994
2995 let result = evaluator.eval("myArray.pop()", 0);
2997 assert!(result.is_ok());
2998 if let Ok(DynSolValue::Uint(popped_val, _)) = result {
2999 assert_eq!(popped_val, U256::from(30)); }
3001
3002 let result = evaluator.eval("emptyArray.pop()", 0);
3004 assert!(result.is_err());
3005 assert!(result.unwrap_err().to_string().contains("Cannot pop from empty array"));
3006
3007 debug_handler.set_variable("suffix", DynSolValue::String(" Test".to_string()));
3011 let result = evaluator.eval("testString.concat(suffix)", 0);
3012 assert!(result.is_ok());
3013 if let Ok(DynSolValue::String(concatenated)) = result {
3014 assert_eq!(concatenated, "Hello World Test");
3015 }
3016
3017 debug_handler.set_variable("startIndex", DynSolValue::Uint(U256::from(6), 256));
3019 let result = evaluator.eval("testString.slice(startIndex)", 0);
3020 assert!(result.is_ok());
3021 if let Ok(DynSolValue::String(sliced)) = result {
3022 assert_eq!(sliced, "World");
3023 }
3024
3025 debug_handler.set_variable("endIndex", DynSolValue::Uint(U256::from(5), 256));
3027 let result = evaluator.eval("testString.slice(0, endIndex)", 0);
3028 assert!(result.is_ok());
3029 if let Ok(DynSolValue::String(sliced)) = result {
3030 assert_eq!(sliced, "Hello");
3031 }
3032
3033 debug_handler.set_variable("moreBytes", DynSolValue::Bytes(vec![6, 7, 8]));
3037 let result = evaluator.eval("myBytes.concat(moreBytes)", 0);
3038 assert!(result.is_ok());
3039 if let Ok(DynSolValue::Bytes(concatenated)) = result {
3040 assert_eq!(concatenated, vec![1, 2, 3, 4, 5, 6, 7, 8]);
3041 }
3042
3043 let result = evaluator.eval("myBytes.slice(2)", 0);
3045 assert!(result.is_ok());
3046 if let Ok(DynSolValue::Bytes(sliced)) = result {
3047 assert_eq!(sliced, vec![3, 4, 5]);
3048 }
3049
3050 let result = evaluator.eval("myBytes.slice(1, 4)", 0);
3052 assert!(result.is_ok());
3053 if let Ok(DynSolValue::Bytes(sliced)) = result {
3054 assert_eq!(sliced, vec![2, 3, 4]);
3055 }
3056
3057 let result = evaluator.eval("numberA.min(numberB)", 0);
3065 assert!(result.is_ok());
3066 if let Ok(DynSolValue::Uint(min_val, _)) = result {
3067 assert_eq!(min_val, U256::from(100));
3068 }
3069
3070 let result = evaluator.eval("numberA.max(numberB)", 0);
3072 assert!(result.is_ok());
3073 if let Ok(DynSolValue::Uint(max_val, _)) = result {
3074 assert_eq!(max_val, U256::from(200));
3075 }
3076
3077 let result = evaluator.eval("testString.isEmpty()", 0);
3081 assert!(result.is_ok());
3082 if let Ok(DynSolValue::Bool(is_empty)) = result {
3083 assert!(!is_empty);
3084 }
3085
3086 let result = evaluator.eval("emptyString.isEmpty()", 0);
3087 assert!(result.is_ok());
3088 if let Ok(DynSolValue::Bool(is_empty)) = result {
3089 assert!(is_empty);
3090 }
3091
3092 let result = evaluator.eval("myBytes.isEmpty()", 0);
3094 assert!(result.is_ok());
3095 if let Ok(DynSolValue::Bool(is_empty)) = result {
3096 assert!(!is_empty);
3097 }
3098
3099 let result = evaluator.eval("emptyBytes.isEmpty()", 0);
3100 assert!(result.is_ok());
3101 if let Ok(DynSolValue::Bool(is_empty)) = result {
3102 assert!(is_empty);
3103 }
3104
3105 let result = evaluator.eval("myArray.isEmpty()", 0);
3107 assert!(result.is_ok());
3108 if let Ok(DynSolValue::Bool(is_empty)) = result {
3109 assert!(!is_empty);
3110 }
3111
3112 let result = evaluator.eval("emptyArray.isEmpty()", 0);
3113 assert!(result.is_ok());
3114 if let Ok(DynSolValue::Bool(is_empty)) = result {
3115 assert!(is_empty);
3116 }
3117 }
3118
3119 #[test]
3120 fn test_extremely_complex_expressions() {
3121 let (handlers, debug_handler) = create_simulation_debug_handlers();
3122 let evaluator = ExpressionEvaluator::new(handlers);
3123
3124 debug_handler.set_function(
3126 "getPoolData",
3127 DynSolValue::Tuple(vec![
3128 DynSolValue::Uint(U256::from(1000000), 256), DynSolValue::Uint(U256::from(2000000), 256), DynSolValue::Uint(U256::from(1700000000), 256), ]),
3132 );
3133
3134 debug_handler.set_function("calculateFee", DynSolValue::Uint(U256::from(3000), 256)); debug_handler.set_function("getPrice", DynSolValue::Uint(U256::from(2000), 256)); debug_handler.set_function("getUserBalance", DynSolValue::Uint(U256::from(50000), 256));
3137 debug_handler.set_function("getSlippageTolerance", DynSolValue::Uint(U256::from(100), 256)); let complex_expr1 = "((getUserBalance() * getPrice()) / 1000000) > ((calculateFee() * msg.value * getSlippageTolerance()) / (10000 * 100)) && (block.timestamp - 1700000000) < 3600 && msg.sender != tx.origin";
3141
3142 let result = evaluator.eval(complex_expr1, 0);
3143 assert!(result.is_ok());
3144 if let Ok(DynSolValue::Bool(is_valid)) = result {
3145 println!("Complex DeFi condition result: {}", is_valid);
3147 }
3148
3149 let complex_expr2 = "(((balanceOf() + getUserBalance()) * (getPrice() - calculateFee())) / totalSupply()) > (msg.value * ((block.number % 100) + 1)) ? ((getSlippageTolerance() * 2) + (block.timestamp % 1000)) : ((calculateFee() * 3) - (msg.value / 1000))";
3151
3152 let result = evaluator.eval(complex_expr2, 0);
3153 assert!(result.is_ok());
3154 println!("Complex ternary expression result: {:?}", result);
3155
3156 let complex_expr3 = "((balanceOf() * (block.number - 18500000)) + (getUserBalance() * getSlippageTolerance())) >= ((totalSupply() / 100) * ((msg.value > 1000000000000000000) ? (calculateFee() + 500) : (calculateFee() - 200))) && (block.timestamp > 1700000000) && ((tx.origin == msg.sender) || (getPrice() > 1800))";
3158
3159 let result = evaluator.eval(complex_expr3, 0);
3160 assert!(result.is_ok());
3161 if let Ok(DynSolValue::Bool(governance_valid)) = result {
3162 println!("Complex governance voting condition: {}", governance_valid);
3163 }
3164
3165 let log = debug_handler.get_log();
3167 assert!(!log.is_empty());
3168
3169 let function_calls = log.iter().filter(|entry| entry.contains("call_function")).count();
3171 assert!(function_calls >= 10, "Should have many function calls in complex expressions");
3172 }
3173
3174 #[test]
3175 fn test_ultra_complex_nested_expressions() {
3176 let (handlers, debug_handler) = create_simulation_debug_handlers();
3177 let evaluator = ExpressionEvaluator::new(handlers);
3178
3179 debug_handler.set_function(
3181 "getLiquidityData",
3182 DynSolValue::Tuple(vec![
3183 DynSolValue::Uint(U256::from(5000000), 256),
3184 DynSolValue::Uint(U256::from(3000000), 256),
3185 DynSolValue::Uint(U256::from(8000000), 256),
3186 ]),
3187 );
3188
3189 debug_handler.set_function("calculateRewards", DynSolValue::Uint(U256::from(12500), 256));
3190 debug_handler.set_function("getMultiplier", DynSolValue::Uint(U256::from(150), 256)); debug_handler.set_function("getRiskFactor", DynSolValue::Uint(U256::from(80), 256)); debug_handler.set_function("getTimeDecay", DynSolValue::Uint(U256::from(95), 256)); let ultra_complex = r#"
3196 (
3197 (
3198 (
3199 (balanceOf() * getMultiplier() * getRiskFactor()) / (100 * 100)
3200 ) +
3201 (
3202 (calculateRewards() * getTimeDecay() * ((block.timestamp - 1700000000) / 86400)) / (100 * 365)
3203 )
3204 ) *
3205 (
3206 (msg.value > (totalSupply() / 1000)) ?
3207 (
3208 ((getPrice() + calculateFee()) * (block.number % 1000)) / 500
3209 ) :
3210 (
3211 ((getPrice() - calculateFee()) * (block.timestamp % 10000)) / 2000
3212 )
3213 )
3214 ) >=
3215 (
3216 (
3217 (getUserBalance() * (100 + getSlippageTolerance())) / 100
3218 ) +
3219 (
3220 ((msg.sender == tx.origin) ? (calculateRewards() * 2) : (calculateRewards() / 2)) *
3221 ((block.number > 18500000) ? getMultiplier() : (getMultiplier() / 2))
3222 ) / 100
3223 )
3224 "#.replace('\n', "").replace(' ', "");
3225
3226 let result = evaluator.eval(&ultra_complex, 0);
3227 assert!(result.is_ok());
3228 if let Ok(DynSolValue::Bool(result_bool)) = result {
3229 println!("Ultra complex yield farming condition: {}", result_bool);
3230 }
3231
3232 let log = debug_handler.get_log();
3234 let total_operations = log.len();
3235 assert!(
3236 total_operations >= 20,
3237 "Ultra complex expression should generate many log entries, got: {}",
3238 total_operations
3239 );
3240
3241 println!("Total operations logged: {}", total_operations);
3242 println!("Sample log entries: {:?}", log.iter().take(5).collect::<Vec<_>>());
3243 }
3244}