Skip to content

Commit

Permalink
fix: call exec_swap_nth instead of dup
Browse files Browse the repository at this point in the history
  • Loading branch information
WilfredTA committed Aug 3, 2023
1 parent fd3a6e2 commit 8d84b39
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 47 deletions.
44 changes: 44 additions & 0 deletions examples/swaps.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#![allow(unused_imports)]
use ser::{
bvc, bvi, conversion::*, machine::*, memory::*, parser::*, stack::*, storage::*, traits::*,
};
use z3::ast::*;
/*
SHOULD REVERT:
PUSH1 0x42
PUSH1 0x00
PUSH2 0x5000
CALLDATASIZE
SWAP2
PUSH1 0x0e // 14
JUMPI
REVERT
JUMPDEST
PUSH1 0
RETURN
SHOULD NOT REVERT:
PUSH1 0x42
PUSH1 0x00
PUSH2 0x5000
PUSH1 0x40
SWAP3
PUSH1 0x0e // 14
JUMPI
REVERT
JUMPDEST
PUSH1 0x10
RETURN
*/
const SWAP2_JUMPI_REVERT: &str = r#"604260006150003691600d57fd5b6000f3"#;
const SWAP3_JUMPI_RETURN_16: &str = r#"60426000615000604091600e57fd5b6000f3"#;
fn main() {
let pgm = Parser::with_pgm(SWAP2_JUMPI_REVERT).parse();
let mut evm = Evm::new(pgm);
let execution = evm.exec();
eprintln!("Execution tree: {:#?}", execution.states);
}
3 changes: 2 additions & 1 deletion src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,9 @@ impl<'ctx> Execution<'ctx> {

let curr_inst = curr_state.curr_instruction();
let curr_pc = curr_state.pc();
eprintln!("CURR STATE IN STEP FROM MUT: {:#?}", curr_state);
//eprintln!("CURR STATE IN STEP FROM MUT: {:#?}", curr_state);
let change_rec = curr_inst.exec(&curr_state);
eprintln!("CHANGE REC IN STEP: {:#?}", change_rec);

let is_branch = change_rec.constraints.is_some();
curr_state.apply_change(change_rec.clone());
Expand Down
37 changes: 19 additions & 18 deletions src/instruction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ fn exec_dup_nth(mach: &EvmState, n: usize) -> MachineRecord<32> {

fn exec_swap_nth(mach: &EvmState, n: usize) -> MachineRecord<32> {


eprintln!("EXEC SWAP NTH CALLED. N: {}", n);
MachineRecord {
stack: Some(StackChange { pop_qty: 0, push_qty: 0, swap_depth: n as u8, ops: vec![] }),
stack: Some(StackChange { pop_qty: 0, push_qty: 0, swap_depth: n, ops: vec![] }),
pc: (mach.pc(), mach.pc() + 1),
mem: Default::default(),
halt: false,
Expand Down Expand Up @@ -993,6 +993,7 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
push_qty: 0,
ops: vec![StackOp::Pop, StackOp::Pop],
};
eprintln!("JUMPI REACHED");

MachineRecord {
stack: Some(stack_rec),
Expand Down Expand Up @@ -1509,22 +1510,22 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
Instruction::Dup14 => exec_dup_nth(mach, 14),
Instruction::Dup15 => exec_dup_nth(mach, 15),
Instruction::Dup16 => exec_dup_nth(mach, 16),
Instruction::Swap1 => exec_dup_nth(mach, 1),
Instruction::Swap2 => exec_dup_nth(mach, 2),
Instruction::Swap3 => exec_dup_nth(mach, 3),
Instruction::Swap4 => exec_dup_nth(mach, 4),
Instruction::Swap5 => exec_dup_nth(mach, 5),
Instruction::Swap6 => exec_dup_nth(mach, 6),
Instruction::Swap7 => exec_dup_nth(mach, 7),
Instruction::Swap8 => exec_dup_nth(mach, 8),
Instruction::Swap9 => exec_dup_nth(mach, 9),
Instruction::Swap10 => exec_dup_nth(mach, 10),
Instruction::Swap11 => exec_dup_nth(mach, 11),
Instruction::Swap12 => exec_dup_nth(mach, 12),
Instruction::Swap13 => exec_dup_nth(mach, 13),
Instruction::Swap14 => exec_dup_nth(mach, 14),
Instruction::Swap15 => exec_dup_nth(mach, 15),
Instruction::Swap16 => exec_dup_nth(mach, 16),
Instruction::Swap1 => exec_swap_nth(mach, 1),
Instruction::Swap2 => exec_swap_nth(mach, 2),
Instruction::Swap3 => exec_swap_nth(mach, 3),
Instruction::Swap4 => exec_swap_nth(mach, 4),
Instruction::Swap5 => exec_swap_nth(mach, 5),
Instruction::Swap6 => exec_swap_nth(mach, 6),
Instruction::Swap7 => exec_swap_nth(mach, 7),
Instruction::Swap8 => exec_swap_nth(mach, 8),
Instruction::Swap9 => exec_swap_nth(mach, 9),
Instruction::Swap10 => exec_swap_nth(mach, 10),
Instruction::Swap11 => exec_swap_nth(mach, 11),
Instruction::Swap12 => exec_swap_nth(mach, 12),
Instruction::Swap13 => exec_swap_nth(mach, 13),
Instruction::Swap14 => exec_swap_nth(mach, 14),
Instruction::Swap15 => exec_swap_nth(mach, 15),
Instruction::Swap16 => exec_swap_nth(mach, 16),
Instruction::Log0 => todo!(),
Instruction::Log1 => todo!(),
Instruction::Log2 => todo!(),
Expand Down
23 changes: 16 additions & 7 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,31 +170,40 @@ impl<'ctx> Machine<32> for Evm<'ctx> {
let mut exec = Execution::new(self.states.val.clone(), self.pgm.clone());
let first_step = exec.step_mut();
step_recs.push(first_step);
let mut ids = vec![];
loop {
if let Some(step) = step_recs.pop() {
eprintln!(
"HALTED LEFT: {}, HALTED RIGHT: {}",
step.halted_left(),
step.halted_right()
);
if !step.halted_right() {
let continue_from_right = step.right_id();
if let Some(right_id) = continue_from_right {
eprintln!("LEFT ID: {:#?} RIGHT ID: {:#?}", step.left_id(), step.right_id());
// if !step.halted_right() {
// let continue_from_right = step.right_id();
if let Some(right_id) = step.right_id() {
ids.push(right_id.id());
let nxt_right_step = exec.step_from_mut(right_id);
step_recs.push(nxt_right_step);
}
}
if !step.halted_left() {
let continue_from_left = step.left_id();
if let Some(left_id) = continue_from_left {
//}
// if !step.halted_left() {
// let continue_from_left = step.left_id();
if let Some(left_id) = step.left_id() {
ids.push(left_id.id());
let nxt_step = exec.step_from_mut(left_id);
step_recs.push(nxt_step);
}
// }

if step.halted_left() && step.halted_right() {
eprintln!("Both have halted... Here are the step recs left: {:#?}", step_recs);
}
} else {
break;
}
}
eprintln!("All ids that were executed during a step: {:#?}", ids);

exec
}
Expand Down
2 changes: 1 addition & 1 deletion src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ impl From<u8> for Instruction {
#[derive(Default, Debug, Clone)]
pub struct Program {
pub map: HashMap<usize, Instruction>,
pub pgm: Vec<Instruction>,
pgm: Vec<Instruction>,
pub size: usize
}

Expand Down
2 changes: 1 addition & 1 deletion src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub enum StackOp<const SZ: usize> {
pub struct StackChange<const SZ: usize> {
pub pop_qty: u64,
pub push_qty: u64,
pub swap_depth: u8,
pub swap_depth: usize,
pub ops: Vec<StackOp<SZ>>,
}

Expand Down
20 changes: 16 additions & 4 deletions src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ impl<const SZ: usize> Stack<SZ> {

// where n is stack modulo top element;
pub (crate) fn swap_nth(&mut self, swap_depth: usize) {
eprintln!("SWAP EXECUTING AT DEPTH: {}", swap_depth);
if swap_depth < self.size() {
let mut new_stack = self.stack.clone();
let top_idx = self.size - 1;
Expand All @@ -53,10 +54,21 @@ impl<const SZ: usize> Stack<SZ> {
let swapped = self.peek_nth(swap_depth).cloned().expect(
&format!("stack too deep to swap with depth {}. Stack size: {}", swap_depth, self.size())
);
new_stack.remove(swap_idx);
new_stack.insert(swap_idx, top);
new_stack.pop();
new_stack.push(swapped);
eprintln!("STACK BEFORE SWAP: {:#?}", new_stack);
new_stack = new_stack.into_iter().enumerate().map(move |(idx, val)| {
if idx == swap_idx {
return top.clone();
} else if idx == top_idx {
return swapped.clone();
} else {
val
}
}).collect::<SmallVec<_>>();
eprintln!("STACK AFTER SWAP: {:#?}", new_stack);
// new_stack.remove(swap_idx);
// new_stack.insert(swap_idx, top);
// new_stack.pop();
// new_stack.push(swapped);
self.stack = new_stack;

} else {
Expand Down
40 changes: 25 additions & 15 deletions src/state/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
use z3_ext::ast::Bool;


#[derive(Clone, Debug, Default)]
#[derive(Clone, Default)]
pub struct EvmState {
pub memory: Memory,
pub storage: AccountStorage,
Expand Down Expand Up @@ -61,7 +61,8 @@ impl<'ctx> EvmState {
}
pub fn set_pc(&mut self, new_pc: usize) {
self.pc = new_pc;
if self.pc >= self.pgm.pgm.len() {
if self.pc >= self.pgm.get_size() {
eprintln!("SET PC--- PC: {} -- PGM SIZE: {}", self.pc, self.pgm.get_size());
self.halt = true;
}
}
Expand All @@ -76,25 +77,34 @@ impl<'ctx> EvmState {
self.pc < self.pgm.get_size() && !self.halt
}
pub fn curr_instruction(&self) -> Instruction {
self.pgm.get(self.pc).expect(&format!("Expected instruction at pc: {}", self.pc))
}
pub fn curr_inst_debug(&self) -> Instruction {
if !self.can_continue() {
eprintln!(
"EVM STATE CANNOT CONTINUE; BUT CURR INST IS REQUESTED: {:#?}",
self
);
eprintln!(
"Getting curr inst.. curr pc: {} and curr pgm len: {}",
self.pc,
self.pgm.get_size()
);

eprintln!("Curr instruction debug requested but cannot continue");
}

self.pgm.get(self.pc).expect(&format!("Expected instruction at pc: {}", self.pc))
self.pgm.get(self.pc).unwrap()
}
}

impl std::fmt::Display for EvmState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Pc: {}\nHalted: {}\nStack: {:?}\n{}", self.pc(), self.halt, self.stack(), self.mem())

//write!(f, "Pc: {}\nHalted: {}\nStack: {:?}\n{}", self.pc(), self.halt, self.stack(), self.mem())
write!(f, "Pc: {}, Stack: {:#?} halt: {:#?}", self.pc(), self.stack(), self.halt)
}
}

impl std::fmt::Debug for EvmState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EvmState").field("stack", &self.stack)
.field("pc", &self.pc)
.field("address", &self.address)
.field("halt", &self.halt)
.field("instruction", &self.curr_inst_debug())
.field("pgm size", &self.pgm.size)
.finish()
}
}


2 changes: 2 additions & 0 deletions src/state/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub struct StateTree<'ctx> {
pub(crate) right: Option<Box<StateTree<'ctx>>>,
}



impl<'ctx> From<(EvmState, Bool<'ctx>)> for StateTree<'ctx> {
fn from(t: (EvmState, Bool<'ctx>)) -> Self {
Self {
Expand Down

0 comments on commit 8d84b39

Please sign in to comment.