From 486b3dc9c213cbf2ae375bc9a0d71f4315ad7f34 Mon Sep 17 00:00:00 2001 From: brock elmore Date: Sat, 9 Dec 2023 11:26:28 -0800 Subject: [PATCH] fix issue 69 Cleans up wrapping subtraction and when an assign occurs, the assignee inherits tmp_of from assignor --- crates/graph/src/nodes/context/solving.rs | 2 +- crates/graph/src/nodes/context/var/typing.rs | 21 +- crates/graph/src/range/elem/reference.rs | 6 +- crates/graph/src/range/exec/exec_op.rs | 100 +- crates/pyrometer/src/graph_backend.rs | 44 +- crates/pyrometer/tests/test_data/math.sol | 1232 +++++++++-------- .../tests/test_data/repros/issue69.sol | 15 + .../src/context_builder/mod.rs | 2 +- 8 files changed, 765 insertions(+), 657 deletions(-) create mode 100644 crates/pyrometer/tests/test_data/repros/issue69.sol diff --git a/crates/graph/src/nodes/context/solving.rs b/crates/graph/src/nodes/context/solving.rs index 273d97c0..390a2efb 100644 --- a/crates/graph/src/nodes/context/solving.rs +++ b/crates/graph/src/nodes/context/solving.rs @@ -79,7 +79,7 @@ impl ContextNode { dep: ContextVarNode, analyzer: &mut (impl GraphBackend + AnalyzerBackend), ) -> Result<(), GraphError> { - tracing::trace!("Adding ctx dependency: {}", dep.display_name(analyzer)?); + tracing::trace!("Adding ctx dependency: {}, is_controllable: {}", dep.display_name(analyzer)?, dep.is_controllable(analyzer)?); if dep.is_controllable(analyzer)? { let range = dep.ref_range(analyzer)?.unwrap(); let r = range.into_flattened_range(analyzer)?; diff --git a/crates/graph/src/nodes/context/var/typing.rs b/crates/graph/src/nodes/context/var/typing.rs index 44fc49b6..ce9d4340 100644 --- a/crates/graph/src/nodes/context/var/typing.rs +++ b/crates/graph/src/nodes/context/var/typing.rs @@ -57,7 +57,7 @@ impl ContextVarNode { Ok(global_first.is_storage(analyzer)? || global_first.is_calldata_input(analyzer)) } - pub fn is_independent_and_storage_or_calldata( + pub fn is_fundamental( &self, analyzer: &impl GraphBackend, ) -> Result { @@ -86,22 +86,13 @@ impl ContextVarNode { } pub fn is_controllable(&self, analyzer: &impl GraphBackend) -> Result { - if self.is_storage_or_calldata_input(analyzer)? - || self.is_msg(analyzer)? - || self.is_block(analyzer)? - { - Ok(true) - } else if let Some(tmp) = self.tmp_of(analyzer)? { - let rhs_controllable = if let Some(rhs) = tmp.rhs { - rhs.is_controllable(analyzer)? + Ok(self.dependent_on(analyzer, true)?.iter().any(|dependent_on| { + if let Ok(t) = dependent_on.is_fundamental(analyzer) { + t } else { false - }; - let lhs_controllable = tmp.lhs.is_controllable(analyzer)?; - Ok(lhs_controllable || rhs_controllable) - } else { - Ok(false) - } + } + })) } pub fn is_calldata_input(&self, analyzer: &impl GraphBackend) -> bool { diff --git a/crates/graph/src/range/elem/reference.rs b/crates/graph/src/range/elem/reference.rs index 57065f78..5b65d34f 100644 --- a/crates/graph/src/range/elem/reference.rs +++ b/crates/graph/src/range/elem/reference.rs @@ -65,7 +65,7 @@ impl RangeElem for Reference { analyzer: &impl GraphBackend, ) -> Result, GraphError> { let cvar = ContextVarNode::from(self.idx); - if cvar.is_independent_and_storage_or_calldata(analyzer)? { + if cvar.is_fundamental(analyzer)? { return Ok(Elem::Reference(Reference::new( cvar.global_first_version(analyzer).into(), ))); @@ -142,7 +142,7 @@ impl RangeElem for Reference { ) -> Result, GraphError> { let cvar = ContextVarNode::from(self.idx); - let independent = cvar.is_independent_and_storage_or_calldata(analyzer)?; + let independent = cvar.is_fundamental(analyzer)?; if independent { Ok(Elem::Reference(Reference::new( cvar.global_first_version(analyzer).into(), @@ -159,7 +159,7 @@ impl RangeElem for Reference { analyzer: &impl GraphBackend, ) -> Result, GraphError> { let cvar = ContextVarNode::from(self.idx); - if cvar.is_independent_and_storage_or_calldata(analyzer)? { + if cvar.is_fundamental(analyzer)? { Ok(Elem::Reference(Reference::new( cvar.global_first_version(analyzer).into(), ))) diff --git a/crates/graph/src/range/exec/exec_op.rs b/crates/graph/src/range/exec/exec_op.rs index e255aeb2..e68d9b47 100644 --- a/crates/graph/src/range/exec/exec_op.rs +++ b/crates/graph/src/range/exec/exec_op.rs @@ -204,12 +204,108 @@ impl ExecOp for RangeExpr { } RangeOp::Sub(unchecked) => { if unchecked { - let candidates = vec![ + let mut candidates = vec![]; + // check if rhs contains zero, if so add lhs_min and max as candidates + let zero = Elem::from(Concrete::from(U256::from(0))); + let one = Elem::from(Concrete::from(U256::from(1))); + let rhs_min_contains_zero = matches!( + rhs_min.range_ord(&zero), + Some(std::cmp::Ordering::Less) | Some(std::cmp::Ordering::Equal) + ); + + let rhs_max_contains_zero = matches!( + rhs_max.range_ord(&zero), + Some(std::cmp::Ordering::Greater) | Some(std::cmp::Ordering::Equal) + ); + + if rhs_min_contains_zero && rhs_max_contains_zero { + candidates.push(Some(lhs_min.clone())); + candidates.push(Some(lhs_max.clone())); + } + + // If we have the below case, where the lhs + // contains the rhs, we can add zero. Futher more, if + // the lhs contains rhs - 1, we can add max as it + // would overflow to uint256.max + // zero min max uint256.max + // lhs: | - - |----------------------------| - - | + // rhs: | - - |--| - - - - - - - - - - - - - - - | + match lhs_max.range_ord(&rhs_min) { + Some(std::cmp::Ordering::Less) => { + // We are going to overflow, zero not possible + } + Some(std::cmp::Ordering::Equal) => { + // We are going to at least be zero, + // we may overflow. check if rhs is const, otherwise + // add uint256.max as a candidate + candidates.push(Some(zero.clone())); + if !consts.1 { + candidates.push(zero.range_wrapping_sub(&one)); + } + } + Some(std::cmp::Ordering::Greater) => { + // No guarantees on overflow, check lhs_min + match lhs_min.range_ord(&rhs_min) { + Some(std::cmp::Ordering::Less) => { + // fully contained, add zero and max + candidates.push(Some(zero.clone())); + candidates.push(zero.range_wrapping_sub(&one)); + } + Some(std::cmp::Ordering::Equal) => { + // We are going to at least be zero, + // we may overflow. check if rhs is const, otherwise + // add uint256.max as a candidate + candidates.push(Some(zero.clone())); + if !consts.1 { + candidates.push(zero.range_wrapping_sub(&one)); + } + } + Some(std::cmp::Ordering::Greater) => { + // current info: + // zero min max uint256.max + // lhs: | - - |----------------------------| - - | + // rhs: | - |----? - - - - - - - - - - - - - - - | + // figure out where rhs max is + match lhs_min.range_ord(&rhs_max) { + Some(std::cmp::Ordering::Less) => { + // zero min + // lhs: | - - |---? + // rhs: | - |----| + // min max + // Add both + candidates.push(Some(zero.clone())); + candidates.push(zero.range_wrapping_sub(&one)); + } + Some(std::cmp::Ordering::Equal) => { + // zero min + // lhs: | - - |---? + // rhs: | |---| + // min max + // Add zero + candidates.push(Some(zero.clone())); + } + Some(std::cmp::Ordering::Greater) => { + // zero min + // lhs: | - - |---? + // rhs: |-----| + // min max + // Add nothing + } + _ => {} + } + } + _ => {} + } + } + _ => {} + } + + candidates.extend(vec![ lhs_min.range_wrapping_sub(&rhs_min), lhs_min.range_wrapping_sub(&rhs_max), lhs_max.range_wrapping_sub(&rhs_min), lhs_max.range_wrapping_sub(&rhs_max), - ]; + ]); let mut candidates = candidates.into_iter().flatten().collect::>(); candidates.sort_by(|a, b| match a.range_ord(b) { Some(r) => r, diff --git a/crates/pyrometer/src/graph_backend.rs b/crates/pyrometer/src/graph_backend.rs index 8ac14cd5..e842d82b 100644 --- a/crates/pyrometer/src/graph_backend.rs +++ b/crates/pyrometer/src/graph_backend.rs @@ -519,14 +519,14 @@ flowchart BT )?) } Node::ContextVar(_) => None, - _n => { + n => { handled_nodes.lock().unwrap().insert(*node); Some(format!( - " {}(\"{}\")", //\n style {} stroke:{}", + " {}(\"{}\")\n style {} stroke:{}", petgraph::graph::GraphIndex::index(node), as_dot_str(*node, self).replace('\"', "\'"), - // petgraph::graph::GraphIndex::index(node), - // n.dot_str_color() + petgraph::graph::GraphIndex::index(node), + n.dot_str_color() )) } } @@ -546,9 +546,9 @@ flowchart BT } let from = from.index(); let to = to.index(); - let _edge_idx = edge.index(); + let edge_idx = edge.index(); Some(format!( - " {from:} -->|\"{:?}\"| {to:}", // class {to} linkSource{edge_idx}\n class {from} linkTarget{edge_idx}", + " {from:} -->|\"{:?}\"| {to:}\n class {to} linkSource{edge_idx}\n class {from} linkTarget{edge_idx}", self.graph().edge_weight(edge).unwrap() )) } else { @@ -585,29 +585,29 @@ pub fn mermaid_node( g: &impl GraphBackend, indent: &str, node: NodeIdx, - _style: bool, - _class: Option<&str>, + style: bool, + class: Option<&str>, ) -> String { - let node_str = format!( + let mut node_str = format!( "{indent}{}(\"{}\")", petgraph::graph::GraphIndex::index(&node), as_dot_str(node, g).replace('\"', "\'"), ); - // if style { - // node_str.push_str(&format!( - // "\n{indent}style {} stroke:{}", - // petgraph::graph::GraphIndex::index(&node), - // g.node(node).dot_str_color() - // )); - // } + if style { + node_str.push_str(&format!( + "\n{indent}style {} stroke:{}", + petgraph::graph::GraphIndex::index(&node), + g.node(node).dot_str_color() + )); + } - // if let Some(class) = class { - // node_str.push_str(&format!( - // "\n{indent}class {} {class}", - // petgraph::graph::GraphIndex::index(&node), - // )); - // } + if let Some(class) = class { + node_str.push_str(&format!( + "\n{indent}class {} {class}", + petgraph::graph::GraphIndex::index(&node), + )); + } node_str } diff --git a/crates/pyrometer/tests/test_data/math.sol b/crates/pyrometer/tests/test_data/math.sol index d4d4786f..2acbf8d6 100644 --- a/crates/pyrometer/tests/test_data/math.sol +++ b/crates/pyrometer/tests/test_data/math.sol @@ -1,620 +1,626 @@ -contract Div { - function div(uint256 x, uint256 y) public returns (uint256) { - return x / y; - } - - function int_div(int256 x, int256 y) public returns (int256) { - return x / y; - } - - function div_conc() public returns (uint256) { - uint256 a1 = div(100, 1); - require(a1 == 100); - uint256 a2 = div(100, 2); - require(a2 == 50); - uint256 a3 = div(100, 4); - require(a3 == 25); - uint256 a4 = div(100, 8); - require(a4 == 12); - uint256 a5 = div(1000000000, 8); - require(a5 == 125000000); - uint256 a6 = div(1000000000, 16); - require(a6 == 62500000); - uint256 a7 = div(10000000000, 32); - require(a7 == 312500000); - uint256 a8 = div(100000000000000000000, 64); - require(a8 == 1562500000000000000); - uint256 a9 = div(100000000000000000000000000000000000, 128); - require(a9 == 781250000000000000000000000000000); - uint256 a10 = div(1, 255); - require(a10 == 0); - } - - function int_div_conc() public { - int256 a1 = int_div(100, 1); - require(a1 == 100); - int256 a2 = int_div(100, 2); - require(a2 == 50); - int256 a3 = int_div(100, 4); - require(a3 == 25); - int256 a4 = int_div(100, 8); - require(a4 == 12); - int256 a5 = int_div(1000000000, 8); - require(a5 == 125000000); - int256 a6 = int_div(1000000000, 16); - require(a6 == 62500000); - int256 a7 = int_div(10000000000, 32); - require(a7 == 312500000); - int256 a8 = int_div(100000000000000000000, 64); - require(a8 == 1562500000000000000); - int256 a9 = int_div(100000000000000000000000000000000000, 128); - require(a9 == 781250000000000000000000000000000); - int256 a10 = int_div(1, 255); - require(a10 == 0); - - int256 a11 = int_div(-100, 1); - require(a11 == -100); - int256 a12 = int_div(-100, 2); - require(a12 == -50); - int256 a13 = int_div(-100, 4); - require(a13 == -25); - int256 a14 = int_div(-100, 8); - require(a14 == -12); - int256 a15 = int_div(-1000000000, 8); - require(a15 == -125000000); - int256 a16 = int_div(-1000000000, 16); - require(a16 == -62500000); - int256 a17 = int_div(-10000000000, 32); - require(a17 == -312500000); - int256 a18 = int_div(-100000000000000000000, 64); - require(a18 == -1562500000000000000); - int256 a19 = int_div(-100000000000000000000000000000000000, 128); - require(a19 == -781250000000000000000000000000000); - int256 a20 = int_div(-1, 255); - require(a20 == 0); - - int256 a21 = int_div(-100, -1); - require(a21 == 100); - int256 a22 = int_div(-100, -2); - require(a22 == 50); - int256 a23 = int_div(-100, -4); - require(a23 == 25); - int256 a24 = int_div(-100, -8); - require(a24 == 12); - int256 a25 = int_div(-1000000000, -8); - require(a25 == 125000000); - int256 a26 = int_div(-1000000000, -16); - require(a26 == 62500000); - int256 a27 = int_div(-10000000000, -32); - require(a27 == 312500000); - int256 a28 = int_div(-100000000000000000000, -64); - require(a28 == 1562500000000000000); - int256 a29 = int_div(-100000000000000000000000000000000000, -128); - require(a29 == 781250000000000000000000000000000); - int256 a30 = int_div(-1, -255); - require(a30 == 0); - - int256 a31 = int_div(100, -1); - require(a31 == -100); - int256 a32 = int_div(100, -2); - require(a32 == -50); - int256 a33 = int_div(100, -4); - require(a33 == -25); - int256 a34 = int_div(100, -8); - require(a34 == -12); - int256 a35 = int_div(1000000000, -8); - require(a35 == -125000000); - int256 a36 = int_div(1000000000, -16); - require(a36 == -62500000); - int256 a37 = int_div(10000000000, -32); - require(a37 == -312500000); - int256 a38 = int_div(100000000000000000000, -64); - require(a38 == -1562500000000000000); - int256 a39 = int_div(100000000000000000000000000000000000, -128); - require(a39 == -781250000000000000000000000000000); - int256 a40 = int_div(1, -255); - require(a40 == 0); - } -} - -contract Mul { - function mul(uint256 x, uint256 y) public returns (uint256) { - return x * y; - } - - function int_mul(int256 x, int256 y) public returns (int256) { - return x * y; - } - - function mul_conc() public returns (uint256) { - uint256 a1 = mul(100, 1); - require(a1 == 100); - uint256 a2 = mul(100, 2); - require(a2 == 200); - uint256 a3 = mul(100, 4); - require(a3 == 400); - uint256 a4 = mul(100, 8); - require(a4 == 800); - uint256 a5 = mul(1000000000, 8); - require(a5 == 8000000000); - uint256 a6 = mul(1000000000, 16); - require(a6 == 16000000000); - uint256 a7 = mul(10000000000, 32); - require(a7 == 320000000000); - uint256 a8 = mul(100000000000000000000, 64); - require(a8 == 6400000000000000000000); - uint256 a9 = mul(100000000000000000000000000000000000, 128); - require(a9 == 12800000000000000000000000000000000000); - uint256 a10 = mul(1, 255); - require(a10 == 255); - } - - function int_mul_conc() public { - int256 a1 = int_mul(100, 1); - require(a1 == 100); - int256 a2 = int_mul(100, 2); - require(a2 == 200); - int256 a3 = int_mul(100, 4); - require(a3 == 400); - int256 a4 = int_mul(100, 8); - require(a4 == 800); - int256 a5 = int_mul(1000000000, 8); - require(a5 == 8000000000); - int256 a6 = int_mul(1000000000, 16); - require(a6 == 16000000000); - int256 a7 = int_mul(10000000000, 32); - require(a7 == 320000000000); - int256 a8 = int_mul(100000000000000000000, 64); - require(a8 == 6400000000000000000000); - int256 a9 = int_mul(100000000000000000000000000000000000, 128); - require(a9 == 12800000000000000000000000000000000000); - int256 a10 = int_mul(1, 255); - require(a10 == 255); - - int256 a11 = int_mul(-100, 1); - require(a11 == -100); - int256 a12 = int_mul(-100, 2); - require(a12 == -200); - int256 a13 = int_mul(-100, 4); - require(a13 == -400); - int256 a14 = int_mul(-100, 8); - require(a14 == -800); - int256 a15 = int_mul(-1000000000, 8); - require(a15 == -8000000000); - int256 a16 = int_mul(-1000000000, 16); - require(a16 == -16000000000); - int256 a17 = int_mul(-10000000000, 32); - require(a17 == -320000000000); - int256 a18 = int_mul(-100000000000000000000, 64); - require(a18 == -6400000000000000000000); - int256 a19 = int_mul(-100000000000000000000000000000000000, 128); - require(a19 == -12800000000000000000000000000000000000); - int256 a20 = int_mul(-1, 255); - require(a20 == -255); - - int256 a21 = int_mul(-100, -1); - require(a21 == 100); - int256 a22 = int_mul(-100, -2); - require(a22 == 200); - int256 a23 = int_mul(-100, -4); - require(a23 == 400); - int256 a24 = int_mul(-100, -8); - require(a24 == 800); - int256 a25 = int_mul(-1000000000, -8); - require(a25 == 8000000000); - int256 a26 = int_mul(-1000000000, -16); - require(a26 == 16000000000); - int256 a27 = int_mul(-10000000000, -32); - require(a27 == 320000000000); - int256 a28 = int_mul(-100000000000000000000, -64); - require(a28 == 6400000000000000000000); - int256 a29 = int_mul(-100000000000000000000000000000000000, -128); - require(a29 == 12800000000000000000000000000000000000); - int256 a30 = int_mul(-1, -255); - require(a30 == 255); - - int256 a31 = int_mul(100, -1); - require(a31 == -100); - int256 a32 = int_mul(100, -2); - require(a32 == -200); - int256 a33 = int_mul(100, -4); - require(a33 == -400); - int256 a34 = int_mul(100, -8); - require(a34 == -800); - int256 a35 = int_mul(1000000000, -8); - require(a35 == -8000000000); - int256 a36 = int_mul(1000000000, -16); - require(a36 == -16000000000); - int256 a37 = int_mul(10000000000, -32); - require(a37 == -320000000000); - int256 a38 = int_mul(100000000000000000000, -64); - require(a38 == -6400000000000000000000); - int256 a39 = int_mul(100000000000000000000000000000000000, -128); - require(a39 == -12800000000000000000000000000000000000); - int256 a40 = int_mul(1, -255); - require(a40 == -255); - } -} - -contract Add { - function add(uint256 x, uint256 y) public returns (uint256) { - return x + y; - } - - function int_add(int256 x, int256 y) public returns (int256) { - return x + y; - } - - function add_conc() public returns (uint256) { - uint256 a1 = add(100, 1); - require(a1 == 101); - uint256 a2 = add(100, 2); - require(a2 == 102); - uint256 a3 = add(100, 4); - require(a3 == 104); - uint256 a4 = add(100, 8); - require(a4 == 108); - uint256 a5 = add(1000000000, 8); - require(a5 == 1000000008); - uint256 a6 = add(1000000000, 16); - require(a6 == 1000000016); - uint256 a7 = add(10000000000, 32); - require(a7 == 10000000032); - uint256 a8 = add(100000000000000000000, 64); - require(a8 == 100000000000000000064); - uint256 a9 = add(100000000000000000000000000000000000, 128); - require(a9 == 100000000000000000000000000000000128); - uint256 a10 = add(1, 255); - require(a10 == 256); - } - - function int_add_conc() public { - int256 a1 = int_add(100, 1); - require(a1 == 101); - int256 a2 = int_add(100, 2); - require(a2 == 102); - int256 a3 = int_add(100, 4); - require(a3 == 104); - int256 a4 = int_add(100, 8); - require(a4 == 108); - int256 a5 = int_add(1000000000, 8); - require(a5 == 1000000008); - int256 a6 = int_add(1000000000, 16); - require(a6 == 1000000016); - int256 a7 = int_add(10000000000, 32); - require(a7 == 10000000032); - int256 a8 = int_add(100000000000000000000, 64); - require(a8 == 100000000000000000064); - int256 a9 = int_add(100000000000000000000000000000000000, 128); - require(a9 == 100000000000000000000000000000000128); - int256 a10 = int_add(1, 255); - require(a10 == 256); - - int256 a11 = int_add(-100, 1); - require(a11 == -99); - int256 a12 = int_add(-100, 2); - require(a12 == -98); - int256 a13 = int_add(-100, 4); - require(a13 == -96); - int256 a14 = int_add(-100, 8); - require(a14 == -92); - int256 a15 = int_add(-1000000000, 8); - require(a15 == -999999992); - int256 a16 = int_add(-1000000000, 16); - require(a16 == -999999984); - int256 a17 = int_add(-10000000000, 32); - require(a17 == -9999999968); - int256 a18 = int_add(-100000000000000000000, 64); - require(a18 == -99999999999999999936); - int256 a19 = int_add(-100000000000000000000000000000000000, 128); - require(a19 == -99999999999999999999999999999999872); - int256 a20 = int_add(-1, 255); - require(a20 == 254); - - int256 a21 = int_add(-100, -1); - require(a21 == -101); - int256 a22 = int_add(-100, -2); - require(a22 == -102); - int256 a23 = int_add(-100, -4); - require(a23 == -104); - int256 a24 = int_add(-100, -8); - require(a24 == -108); - int256 a25 = int_add(-1000000000, -8); - require(a25 == -1000000008); - int256 a26 = int_add(-1000000000, -16); - require(a26 == -1000000016); - int256 a27 = int_add(-10000000000, -32); - require(a27 == -10000000032); - int256 a28 = int_add(-100000000000000000000, -64); - require(a28 == -100000000000000000064); - int256 a29 = int_add(-100000000000000000000000000000000000, -128); - require(a29 == -100000000000000000000000000000000128); - int256 a30 = int_add(-1, -255); - require(a30 == -256); - - int256 a31 = int_add(100, -1); - require(a31 == 99); - int256 a32 = int_add(100, -2); - require(a32 == 98); - int256 a33 = int_add(100, -4); - require(a33 == 96); - int256 a34 = int_add(100, -8); - require(a34 == 92); - int256 a35 = int_add(1000000000, -8); - require(a35 == 999999992); - int256 a36 = int_add(1000000000, -16); - require(a36 == 999999984); - int256 a37 = int_add(10000000000, -32); - require(a37 == 9999999968); - int256 a38 = int_add(100000000000000000000, -64); - require(a38 == 99999999999999999936); - int256 a39 = int_add(100000000000000000000000000000000000, -128); - require(a39 == 99999999999999999999999999999999872); - int256 a40 = int_add(1, -255); - require(a40 == -254); - } -} - -contract Sub { - function sub(uint256 x, uint256 y) public returns (uint256) { - return x - y; - } - - function int_sub(int256 x, int256 y) public returns (int256) { - return x - y; - } - - function sub_conc() public returns (uint256) { - uint256 a1 = sub(100, 1); - require(a1 == 99); - uint256 a2 = sub(100, 2); - require(a2 == 98); - uint256 a3 = sub(100, 4); - require(a3 == 96); - uint256 a4 = sub(100, 8); - require(a4 == 92); - uint256 a5 = sub(1000000000, 8); - require(a5 == 999999992); - uint256 a6 = sub(1000000000, 16); - require(a6 == 999999984); - uint256 a7 = sub(10000000000, 32); - require(a7 == 9999999968); - uint256 a8 = sub(100000000000000000000, 64); - require(a8 == 99999999999999999936); - uint256 a9 = sub(100000000000000000000000000000000000, 128); - require(a9 == 99999999999999999999999999999999872); - } - - function int_sub_conc() public { - int256 a1 = int_sub(100, 1); - require(a1 == 99); - int256 a2 = int_sub(100, 2); - require(a2 == 98); - int256 a3 = int_sub(100, 4); - require(a3 == 96); - int256 a4 = int_sub(100, 8); - require(a4 == 92); - int256 a5 = int_sub(1000000000, 8); - require(a5 == 999999992); - int256 a6 = int_sub(1000000000, 16); - require(a6 == 999999984); - int256 a7 = int_sub(10000000000, 32); - require(a7 == 9999999968); - int256 a8 = int_sub(100000000000000000000, 64); - require(a8 == 99999999999999999936); - int256 a9 = int_sub(100000000000000000000000000000000000, 128); - require(a9 == 99999999999999999999999999999999872); - int256 a10 = int_sub(1, 255); - require(a10 == -254); - - int256 a11 = int_sub(-100, 1); - require(a11 == -101); - int256 a12 = int_sub(-100, 2); - require(a12 == -102); - int256 a13 = int_sub(-100, 4); - require(a13 == -104); - int256 a14 = int_sub(-100, 8); - require(a14 == -108); - int256 a15 = int_sub(-1000000000, 8); - require(a15 == -1000000008); - int256 a16 = int_sub(-1000000000, 16); - require(a16 == -1000000016); - int256 a17 = int_sub(-10000000000, 32); - require(a17 == -10000000032); - int256 a18 = int_sub(-100000000000000000000, 64); - require(a18 == -100000000000000000064); - int256 a19 = int_sub(-100000000000000000000000000000000000, 128); - require(a19 == -100000000000000000000000000000000128); - int256 a20 = int_sub(-1, 255); - require(a20 == -256); - - int256 a21 = int_sub(-100, -1); - require(a21 == -99); - int256 a22 = int_sub(-100, -2); - require(a22 == -98); - int256 a23 = int_sub(-100, -4); - require(a23 == -96); - int256 a24 = int_sub(-100, -8); - require(a24 == -92); - int256 a25 = int_sub(-1000000000, -8); - require(a25 == -999999992); - int256 a26 = int_sub(-1000000000, -16); - require(a26 == -999999984); - int256 a27 = int_sub(-10000000000, -32); - require(a27 == -9999999968); - int256 a28 = int_sub(-100000000000000000000, -64); - require(a28 == -99999999999999999936); - int256 a29 = int_sub(-100000000000000000000000000000000000, -128); - require(a29 == -99999999999999999999999999999999872); - int256 a30 = int_sub(-1, -255); - require(a30 == 254); - - int256 a31 = int_sub(100, -1); - require(a31 == 101); - int256 a32 = int_sub(100, -2); - require(a32 == 102); - int256 a33 = int_sub(100, -4); - require(a33 == 104); - int256 a34 = int_sub(100, -8); - require(a34 == 108); - int256 a35 = int_sub(1000000000, -8); - require(a35 == 1000000008); - int256 a36 = int_sub(1000000000, -16); - require(a36 == 1000000016); - int256 a37 = int_sub(10000000000, -32); - require(a37 == 10000000032); - int256 a38 = int_sub(100000000000000000000, -64); - require(a38 == 100000000000000000064); - int256 a39 = int_sub(100000000000000000000000000000000000, -128); - require(a39 == 100000000000000000000000000000000128); - int256 a40 = int_sub(1, -255); - require(a40 == 256); - } -} - -contract AssignMath { - function assignAdd(uint256 x) public { - x += 10; - } - - function assignSub(uint256 x) public { - x -= 10; - } - - function assignDiv(uint256 x) public { - x /= 10; - } - - function assignMul(uint256 x) public { - x *= 10; - } - - function preincrement(uint256 x) public returns (uint256, uint256) { - uint256 y = ++x; - return (y, x); - } - - function postincrement(uint256 x) public returns (uint256, uint256) { - uint256 y = x++; - return (y, x); - } - - function predecrement(uint256 x) public returns (uint256, uint256) { - uint256 y = --x; - return (y, x); - } - - function postdecrement(uint256 x) public returns (uint256, uint256) { - uint256 y = x--; - return (y, x); - } - - function pre_conc() public { - (uint256 y, uint256 x) = preincrement(100); - require(y == 101); - require(x == 101); - } - - function post_conc() public { - (uint256 y, uint256 x) = postincrement(100); - require(y == 100); - require(x == 101); - } - - function pre_deconc() public { - (uint256 y, uint256 x) = predecrement(100); - require(y == 99); - require(x == 99); - } - - function post_deconc() public { - (uint256 y, uint256 x) = postdecrement(100); - require(y == 100); - require(x == 99); - } -} - -contract Math { - function rmod(uint256 x, uint256 y) public returns (uint256) { - return x % y; - } - - function rexp(uint256 x, uint256 y) public returns (uint256) { - return x ** y; - } - - function int_rmod(int256 x, int256 y) public returns (int256) { - return x % y; - } - - function int_rexp(int256 x, uint256 y) public returns (int256) { - return x ** y; - } -} +// contract Div { +// function div(uint256 x, uint256 y) public returns (uint256) { +// return x / y; +// } + +// function int_div(int256 x, int256 y) public returns (int256) { +// return x / y; +// } + +// function div_conc() public returns (uint256) { +// uint256 a1 = div(100, 1); +// require(a1 == 100); +// uint256 a2 = div(100, 2); +// require(a2 == 50); +// uint256 a3 = div(100, 4); +// require(a3 == 25); +// uint256 a4 = div(100, 8); +// require(a4 == 12); +// uint256 a5 = div(1000000000, 8); +// require(a5 == 125000000); +// uint256 a6 = div(1000000000, 16); +// require(a6 == 62500000); +// uint256 a7 = div(10000000000, 32); +// require(a7 == 312500000); +// uint256 a8 = div(100000000000000000000, 64); +// require(a8 == 1562500000000000000); +// uint256 a9 = div(100000000000000000000000000000000000, 128); +// require(a9 == 781250000000000000000000000000000); +// uint256 a10 = div(1, 255); +// require(a10 == 0); +// } + +// function int_div_conc() public { +// int256 a1 = int_div(100, 1); +// require(a1 == 100); +// int256 a2 = int_div(100, 2); +// require(a2 == 50); +// int256 a3 = int_div(100, 4); +// require(a3 == 25); +// int256 a4 = int_div(100, 8); +// require(a4 == 12); +// int256 a5 = int_div(1000000000, 8); +// require(a5 == 125000000); +// int256 a6 = int_div(1000000000, 16); +// require(a6 == 62500000); +// int256 a7 = int_div(10000000000, 32); +// require(a7 == 312500000); +// int256 a8 = int_div(100000000000000000000, 64); +// require(a8 == 1562500000000000000); +// int256 a9 = int_div(100000000000000000000000000000000000, 128); +// require(a9 == 781250000000000000000000000000000); +// int256 a10 = int_div(1, 255); +// require(a10 == 0); + +// int256 a11 = int_div(-100, 1); +// require(a11 == -100); +// int256 a12 = int_div(-100, 2); +// require(a12 == -50); +// int256 a13 = int_div(-100, 4); +// require(a13 == -25); +// int256 a14 = int_div(-100, 8); +// require(a14 == -12); +// int256 a15 = int_div(-1000000000, 8); +// require(a15 == -125000000); +// int256 a16 = int_div(-1000000000, 16); +// require(a16 == -62500000); +// int256 a17 = int_div(-10000000000, 32); +// require(a17 == -312500000); +// int256 a18 = int_div(-100000000000000000000, 64); +// require(a18 == -1562500000000000000); +// int256 a19 = int_div(-100000000000000000000000000000000000, 128); +// require(a19 == -781250000000000000000000000000000); +// int256 a20 = int_div(-1, 255); +// require(a20 == 0); + +// int256 a21 = int_div(-100, -1); +// require(a21 == 100); +// int256 a22 = int_div(-100, -2); +// require(a22 == 50); +// int256 a23 = int_div(-100, -4); +// require(a23 == 25); +// int256 a24 = int_div(-100, -8); +// require(a24 == 12); +// int256 a25 = int_div(-1000000000, -8); +// require(a25 == 125000000); +// int256 a26 = int_div(-1000000000, -16); +// require(a26 == 62500000); +// int256 a27 = int_div(-10000000000, -32); +// require(a27 == 312500000); +// int256 a28 = int_div(-100000000000000000000, -64); +// require(a28 == 1562500000000000000); +// int256 a29 = int_div(-100000000000000000000000000000000000, -128); +// require(a29 == 781250000000000000000000000000000); +// int256 a30 = int_div(-1, -255); +// require(a30 == 0); + +// int256 a31 = int_div(100, -1); +// require(a31 == -100); +// int256 a32 = int_div(100, -2); +// require(a32 == -50); +// int256 a33 = int_div(100, -4); +// require(a33 == -25); +// int256 a34 = int_div(100, -8); +// require(a34 == -12); +// int256 a35 = int_div(1000000000, -8); +// require(a35 == -125000000); +// int256 a36 = int_div(1000000000, -16); +// require(a36 == -62500000); +// int256 a37 = int_div(10000000000, -32); +// require(a37 == -312500000); +// int256 a38 = int_div(100000000000000000000, -64); +// require(a38 == -1562500000000000000); +// int256 a39 = int_div(100000000000000000000000000000000000, -128); +// require(a39 == -781250000000000000000000000000000); +// int256 a40 = int_div(1, -255); +// require(a40 == 0); +// } +// } + +// contract Mul { +// function mul(uint256 x, uint256 y) public returns (uint256) { +// return x * y; +// } + +// function int_mul(int256 x, int256 y) public returns (int256) { +// return x * y; +// } + +// function mul_conc() public returns (uint256) { +// uint256 a1 = mul(100, 1); +// require(a1 == 100); +// uint256 a2 = mul(100, 2); +// require(a2 == 200); +// uint256 a3 = mul(100, 4); +// require(a3 == 400); +// uint256 a4 = mul(100, 8); +// require(a4 == 800); +// uint256 a5 = mul(1000000000, 8); +// require(a5 == 8000000000); +// uint256 a6 = mul(1000000000, 16); +// require(a6 == 16000000000); +// uint256 a7 = mul(10000000000, 32); +// require(a7 == 320000000000); +// uint256 a8 = mul(100000000000000000000, 64); +// require(a8 == 6400000000000000000000); +// uint256 a9 = mul(100000000000000000000000000000000000, 128); +// require(a9 == 12800000000000000000000000000000000000); +// uint256 a10 = mul(1, 255); +// require(a10 == 255); +// } + +// function int_mul_conc() public { +// int256 a1 = int_mul(100, 1); +// require(a1 == 100); +// int256 a2 = int_mul(100, 2); +// require(a2 == 200); +// int256 a3 = int_mul(100, 4); +// require(a3 == 400); +// int256 a4 = int_mul(100, 8); +// require(a4 == 800); +// int256 a5 = int_mul(1000000000, 8); +// require(a5 == 8000000000); +// int256 a6 = int_mul(1000000000, 16); +// require(a6 == 16000000000); +// int256 a7 = int_mul(10000000000, 32); +// require(a7 == 320000000000); +// int256 a8 = int_mul(100000000000000000000, 64); +// require(a8 == 6400000000000000000000); +// int256 a9 = int_mul(100000000000000000000000000000000000, 128); +// require(a9 == 12800000000000000000000000000000000000); +// int256 a10 = int_mul(1, 255); +// require(a10 == 255); + +// int256 a11 = int_mul(-100, 1); +// require(a11 == -100); +// int256 a12 = int_mul(-100, 2); +// require(a12 == -200); +// int256 a13 = int_mul(-100, 4); +// require(a13 == -400); +// int256 a14 = int_mul(-100, 8); +// require(a14 == -800); +// int256 a15 = int_mul(-1000000000, 8); +// require(a15 == -8000000000); +// int256 a16 = int_mul(-1000000000, 16); +// require(a16 == -16000000000); +// int256 a17 = int_mul(-10000000000, 32); +// require(a17 == -320000000000); +// int256 a18 = int_mul(-100000000000000000000, 64); +// require(a18 == -6400000000000000000000); +// int256 a19 = int_mul(-100000000000000000000000000000000000, 128); +// require(a19 == -12800000000000000000000000000000000000); +// int256 a20 = int_mul(-1, 255); +// require(a20 == -255); + +// int256 a21 = int_mul(-100, -1); +// require(a21 == 100); +// int256 a22 = int_mul(-100, -2); +// require(a22 == 200); +// int256 a23 = int_mul(-100, -4); +// require(a23 == 400); +// int256 a24 = int_mul(-100, -8); +// require(a24 == 800); +// int256 a25 = int_mul(-1000000000, -8); +// require(a25 == 8000000000); +// int256 a26 = int_mul(-1000000000, -16); +// require(a26 == 16000000000); +// int256 a27 = int_mul(-10000000000, -32); +// require(a27 == 320000000000); +// int256 a28 = int_mul(-100000000000000000000, -64); +// require(a28 == 6400000000000000000000); +// int256 a29 = int_mul(-100000000000000000000000000000000000, -128); +// require(a29 == 12800000000000000000000000000000000000); +// int256 a30 = int_mul(-1, -255); +// require(a30 == 255); + +// int256 a31 = int_mul(100, -1); +// require(a31 == -100); +// int256 a32 = int_mul(100, -2); +// require(a32 == -200); +// int256 a33 = int_mul(100, -4); +// require(a33 == -400); +// int256 a34 = int_mul(100, -8); +// require(a34 == -800); +// int256 a35 = int_mul(1000000000, -8); +// require(a35 == -8000000000); +// int256 a36 = int_mul(1000000000, -16); +// require(a36 == -16000000000); +// int256 a37 = int_mul(10000000000, -32); +// require(a37 == -320000000000); +// int256 a38 = int_mul(100000000000000000000, -64); +// require(a38 == -6400000000000000000000); +// int256 a39 = int_mul(100000000000000000000000000000000000, -128); +// require(a39 == -12800000000000000000000000000000000000); +// int256 a40 = int_mul(1, -255); +// require(a40 == -255); +// } +// } + +// contract Add { +// function add(uint256 x, uint256 y) public returns (uint256) { +// return x + y; +// } + +// function int_add(int256 x, int256 y) public returns (int256) { +// return x + y; +// } + +// function add_conc() public returns (uint256) { +// uint256 a1 = add(100, 1); +// require(a1 == 101); +// uint256 a2 = add(100, 2); +// require(a2 == 102); +// uint256 a3 = add(100, 4); +// require(a3 == 104); +// uint256 a4 = add(100, 8); +// require(a4 == 108); +// uint256 a5 = add(1000000000, 8); +// require(a5 == 1000000008); +// uint256 a6 = add(1000000000, 16); +// require(a6 == 1000000016); +// uint256 a7 = add(10000000000, 32); +// require(a7 == 10000000032); +// uint256 a8 = add(100000000000000000000, 64); +// require(a8 == 100000000000000000064); +// uint256 a9 = add(100000000000000000000000000000000000, 128); +// require(a9 == 100000000000000000000000000000000128); +// uint256 a10 = add(1, 255); +// require(a10 == 256); +// } + +// function int_add_conc() public { +// int256 a1 = int_add(100, 1); +// require(a1 == 101); +// int256 a2 = int_add(100, 2); +// require(a2 == 102); +// int256 a3 = int_add(100, 4); +// require(a3 == 104); +// int256 a4 = int_add(100, 8); +// require(a4 == 108); +// int256 a5 = int_add(1000000000, 8); +// require(a5 == 1000000008); +// int256 a6 = int_add(1000000000, 16); +// require(a6 == 1000000016); +// int256 a7 = int_add(10000000000, 32); +// require(a7 == 10000000032); +// int256 a8 = int_add(100000000000000000000, 64); +// require(a8 == 100000000000000000064); +// int256 a9 = int_add(100000000000000000000000000000000000, 128); +// require(a9 == 100000000000000000000000000000000128); +// int256 a10 = int_add(1, 255); +// require(a10 == 256); + +// int256 a11 = int_add(-100, 1); +// require(a11 == -99); +// int256 a12 = int_add(-100, 2); +// require(a12 == -98); +// int256 a13 = int_add(-100, 4); +// require(a13 == -96); +// int256 a14 = int_add(-100, 8); +// require(a14 == -92); +// int256 a15 = int_add(-1000000000, 8); +// require(a15 == -999999992); +// int256 a16 = int_add(-1000000000, 16); +// require(a16 == -999999984); +// int256 a17 = int_add(-10000000000, 32); +// require(a17 == -9999999968); +// int256 a18 = int_add(-100000000000000000000, 64); +// require(a18 == -99999999999999999936); +// int256 a19 = int_add(-100000000000000000000000000000000000, 128); +// require(a19 == -99999999999999999999999999999999872); +// int256 a20 = int_add(-1, 255); +// require(a20 == 254); + +// int256 a21 = int_add(-100, -1); +// require(a21 == -101); +// int256 a22 = int_add(-100, -2); +// require(a22 == -102); +// int256 a23 = int_add(-100, -4); +// require(a23 == -104); +// int256 a24 = int_add(-100, -8); +// require(a24 == -108); +// int256 a25 = int_add(-1000000000, -8); +// require(a25 == -1000000008); +// int256 a26 = int_add(-1000000000, -16); +// require(a26 == -1000000016); +// int256 a27 = int_add(-10000000000, -32); +// require(a27 == -10000000032); +// int256 a28 = int_add(-100000000000000000000, -64); +// require(a28 == -100000000000000000064); +// int256 a29 = int_add(-100000000000000000000000000000000000, -128); +// require(a29 == -100000000000000000000000000000000128); +// int256 a30 = int_add(-1, -255); +// require(a30 == -256); + +// int256 a31 = int_add(100, -1); +// require(a31 == 99); +// int256 a32 = int_add(100, -2); +// require(a32 == 98); +// int256 a33 = int_add(100, -4); +// require(a33 == 96); +// int256 a34 = int_add(100, -8); +// require(a34 == 92); +// int256 a35 = int_add(1000000000, -8); +// require(a35 == 999999992); +// int256 a36 = int_add(1000000000, -16); +// require(a36 == 999999984); +// int256 a37 = int_add(10000000000, -32); +// require(a37 == 9999999968); +// int256 a38 = int_add(100000000000000000000, -64); +// require(a38 == 99999999999999999936); +// int256 a39 = int_add(100000000000000000000000000000000000, -128); +// require(a39 == 99999999999999999999999999999999872); +// int256 a40 = int_add(1, -255); +// require(a40 == -254); +// } +// } + +// contract Sub { +// function sub(uint256 x, uint256 y) public returns (uint256) { +// return x - y; +// } + +// function int_sub(int256 x, int256 y) public returns (int256) { +// return x - y; +// } + +// function sub_conc() public returns (uint256) { +// uint256 a1 = sub(100, 1); +// require(a1 == 99); +// uint256 a2 = sub(100, 2); +// require(a2 == 98); +// uint256 a3 = sub(100, 4); +// require(a3 == 96); +// uint256 a4 = sub(100, 8); +// require(a4 == 92); +// uint256 a5 = sub(1000000000, 8); +// require(a5 == 999999992); +// uint256 a6 = sub(1000000000, 16); +// require(a6 == 999999984); +// uint256 a7 = sub(10000000000, 32); +// require(a7 == 9999999968); +// uint256 a8 = sub(100000000000000000000, 64); +// require(a8 == 99999999999999999936); +// uint256 a9 = sub(100000000000000000000000000000000000, 128); +// require(a9 == 99999999999999999999999999999999872); +// } + +// function int_sub_conc() public { +// int256 a1 = int_sub(100, 1); +// require(a1 == 99); +// int256 a2 = int_sub(100, 2); +// require(a2 == 98); +// int256 a3 = int_sub(100, 4); +// require(a3 == 96); +// int256 a4 = int_sub(100, 8); +// require(a4 == 92); +// int256 a5 = int_sub(1000000000, 8); +// require(a5 == 999999992); +// int256 a6 = int_sub(1000000000, 16); +// require(a6 == 999999984); +// int256 a7 = int_sub(10000000000, 32); +// require(a7 == 9999999968); +// int256 a8 = int_sub(100000000000000000000, 64); +// require(a8 == 99999999999999999936); +// int256 a9 = int_sub(100000000000000000000000000000000000, 128); +// require(a9 == 99999999999999999999999999999999872); +// int256 a10 = int_sub(1, 255); +// require(a10 == -254); + +// int256 a11 = int_sub(-100, 1); +// require(a11 == -101); +// int256 a12 = int_sub(-100, 2); +// require(a12 == -102); +// int256 a13 = int_sub(-100, 4); +// require(a13 == -104); +// int256 a14 = int_sub(-100, 8); +// require(a14 == -108); +// int256 a15 = int_sub(-1000000000, 8); +// require(a15 == -1000000008); +// int256 a16 = int_sub(-1000000000, 16); +// require(a16 == -1000000016); +// int256 a17 = int_sub(-10000000000, 32); +// require(a17 == -10000000032); +// int256 a18 = int_sub(-100000000000000000000, 64); +// require(a18 == -100000000000000000064); +// int256 a19 = int_sub(-100000000000000000000000000000000000, 128); +// require(a19 == -100000000000000000000000000000000128); +// int256 a20 = int_sub(-1, 255); +// require(a20 == -256); + +// int256 a21 = int_sub(-100, -1); +// require(a21 == -99); +// int256 a22 = int_sub(-100, -2); +// require(a22 == -98); +// int256 a23 = int_sub(-100, -4); +// require(a23 == -96); +// int256 a24 = int_sub(-100, -8); +// require(a24 == -92); +// int256 a25 = int_sub(-1000000000, -8); +// require(a25 == -999999992); +// int256 a26 = int_sub(-1000000000, -16); +// require(a26 == -999999984); +// int256 a27 = int_sub(-10000000000, -32); +// require(a27 == -9999999968); +// int256 a28 = int_sub(-100000000000000000000, -64); +// require(a28 == -99999999999999999936); +// int256 a29 = int_sub(-100000000000000000000000000000000000, -128); +// require(a29 == -99999999999999999999999999999999872); +// int256 a30 = int_sub(-1, -255); +// require(a30 == 254); + +// int256 a31 = int_sub(100, -1); +// require(a31 == 101); +// int256 a32 = int_sub(100, -2); +// require(a32 == 102); +// int256 a33 = int_sub(100, -4); +// require(a33 == 104); +// int256 a34 = int_sub(100, -8); +// require(a34 == 108); +// int256 a35 = int_sub(1000000000, -8); +// require(a35 == 1000000008); +// int256 a36 = int_sub(1000000000, -16); +// require(a36 == 1000000016); +// int256 a37 = int_sub(10000000000, -32); +// require(a37 == 10000000032); +// int256 a38 = int_sub(100000000000000000000, -64); +// require(a38 == 100000000000000000064); +// int256 a39 = int_sub(100000000000000000000000000000000000, -128); +// require(a39 == 100000000000000000000000000000000128); +// int256 a40 = int_sub(1, -255); +// require(a40 == 256); +// } +// } + +// contract AssignMath { +// function assignAdd(uint256 x) public { +// x += 10; +// } + +// function assignSub(uint256 x) public { +// x -= 10; +// } + +// function assignDiv(uint256 x) public { +// x /= 10; +// } + +// function assignMul(uint256 x) public { +// x *= 10; +// } + +// function preincrement(uint256 x) public returns (uint256, uint256) { +// uint256 y = ++x; +// return (y, x); +// } + +// function postincrement(uint256 x) public returns (uint256, uint256) { +// uint256 y = x++; +// return (y, x); +// } + +// function predecrement(uint256 x) public returns (uint256, uint256) { +// uint256 y = --x; +// return (y, x); +// } + +// function postdecrement(uint256 x) public returns (uint256, uint256) { +// uint256 y = x--; +// return (y, x); +// } + +// function pre_conc() public { +// (uint256 y, uint256 x) = preincrement(100); +// require(y == 101); +// require(x == 101); +// } + +// function post_conc() public { +// (uint256 y, uint256 x) = postincrement(100); +// require(y == 100); +// require(x == 101); +// } + +// function pre_deconc() public { +// (uint256 y, uint256 x) = predecrement(100); +// require(y == 99); +// require(x == 99); +// } + +// function post_deconc() public { +// (uint256 y, uint256 x) = postdecrement(100); +// require(y == 100); +// require(x == 99); +// } +// } + +// contract Math { +// function rmod(uint256 x, uint256 y) public returns (uint256) { +// return x % y; +// } + +// function rexp(uint256 x, uint256 y) public returns (uint256) { +// return x ** y; +// } + +// function int_rmod(int256 x, int256 y) public returns (int256) { +// return x % y; +// } + +// function int_rexp(int256 x, uint256 y) public returns (int256) { +// return x ** y; +// } +// } contract Unchecked { - function assemblyWrappingSub(uint256 a) public { - assembly { - a := sub(0, 100) - } - require(a == 115792089237316195423570985008687907853269984665640564039457584007913129639836); - - int256 y = type(int256).min; - assembly { - a := sub(y, 100) - } - require(a == 57896044618658097711785492504343953926634992332820282019728792003956564819868); - } - - function uncheckedSub(uint256 a) public { + // function assemblyWrappingSub(uint256 a) public { + // assembly { + // a := sub(0, 100) + // } + // require(a == 115792089237316195423570985008687907853269984665640564039457584007913129639836); + + // int256 y = type(int256).min; + // assembly { + // a := sub(y, 100) + // } + // require(a == 57896044618658097711785492504343953926634992332820282019728792003956564819868); + // } + + // function uncheckedSub(uint256 a) public { + // unchecked { + // a = 0 - 100; + // } + // require(a == 115792089237316195423570985008687907853269984665640564039457584007913129639836); + + // int256 y = type(int256).min; + // unchecked { + // a = y - 100; + // } + // require(a == 57896044618658097711785492504343953926634992332820282019728792003956564819868); + // } + + function uncheckedSymbolicSub(uint256 a, uint256 b) public { unchecked { - a = 0 - 100; - } - require(a == 115792089237316195423570985008687907853269984665640564039457584007913129639836); - - int256 y = type(int256).min; - unchecked { - a = y - 100; - } - require(a == 57896044618658097711785492504343953926634992332820282019728792003956564819868); - } - - function assemblyWrappingAdd(uint256 a) public { - uint256 m = type(uint256).max; - assembly { - a := add(m, 100) + a -= 100; } - require(a == 99); - a += (type(uint256).max - 99); - require(a == type(uint256).max); } - function uncheckedAdd(uint256 a) public { - unchecked { - a = type(uint256).max + 100; - } - require(a == 99); - a += (type(uint256).max - 99); - require(a == type(uint256).max); - } - - function assemblyWrappingMul(uint256 a) public { - uint256 m = type(uint128).max; - assembly { - a := mul(m, m) - } - require(a == 115792089237316195423570985008687907852589419931798687112530834793049593217025); - a /= 3; - a *= 3; - // require(a == 115792089237316195423570985008687907852589419931798687112530834793049593217025); - } - - function uncheckedMul(uint256 a) public { - unchecked { - a = type(uint256).max + 100; - } - require(a == 99); - a += (type(uint256).max - 99); - require(a == type(uint256).max); - } + // function assemblyWrappingAdd(uint256 a) public { + // uint256 m = type(uint256).max; + // assembly { + // a := add(m, 100) + // } + // require(a == 99); + // a += (type(uint256).max - 99); + // require(a == type(uint256).max); + // } + + // function uncheckedAdd(uint256 a) public { + // unchecked { + // a = type(uint256).max + 100; + // } + // require(a == 99); + // a += (type(uint256).max - 99); + // require(a == type(uint256).max); + // } + + // function assemblyWrappingMul(uint256 a) public { + // uint256 m = type(uint128).max; + // assembly { + // a := mul(m, m) + // } + // require(a == 115792089237316195423570985008687907852589419931798687112530834793049593217025); + // a /= 3; + // a *= 3; + // // require(a == 115792089237316195423570985008687907852589419931798687112530834793049593217025); + // } + + // function uncheckedMul(uint256 a) public { + // unchecked { + // a = type(uint256).max + 100; + // } + // require(a == 99); + // a += (type(uint256).max - 99); + // require(a == type(uint256).max); + // } } \ No newline at end of file diff --git a/crates/pyrometer/tests/test_data/repros/issue69.sol b/crates/pyrometer/tests/test_data/repros/issue69.sol new file mode 100644 index 00000000..232cf4a4 --- /dev/null +++ b/crates/pyrometer/tests/test_data/repros/issue69.sol @@ -0,0 +1,15 @@ +contract SymbolicTest { + // https://github.com/foundry-rs/foundry/issues/2851 + function backdoor(uint256 x) external pure { + uint256 number = 99; + unchecked { + uint256 z = x - 1; + if (z == 6912213124124531) { + number = 0; + } else { + number = 1; + } + } + assert(number != 0); + } +} \ No newline at end of file diff --git a/crates/solc-expressions/src/context_builder/mod.rs b/crates/solc-expressions/src/context_builder/mod.rs index 9cb83558..5a0579b4 100644 --- a/crates/solc-expressions/src/context_builder/mod.rs +++ b/crates/solc-expressions/src/context_builder/mod.rs @@ -1332,7 +1332,7 @@ pub trait ContextBuilder: ); let new_lhs = self.advance_var_in_ctx(lhs_cvar.latest_version(self), loc, ctx)?; - + new_lhs.underlying_mut(self).into_expr_err(loc)?.tmp_of = rhs_cvar.tmp_of(self).into_expr_err(loc)?; if lhs_cvar.is_storage(self).into_expr_err(loc)? { self.add_edge(new_lhs, rhs_cvar, Edge::Context(ContextEdge::StorageWrite)); }