FABRKNT
Reth Fundamentals — Your First Steps with Alloy
Inside the EVM
Lesson 7 of 11·QUIZ15 min30 XP

Treat this page as a workbench, not a blog post. The goal is to extract a reusable mental model from the source and carry it into the rest of the Fabrknt stack.

Course
Reth Fundamentals — Your First Steps with Alloy
Lesson role
QUIZ
Sequence
7 / 11

Quiz — A Mini EVM Stack

Question

Reproduce EVM stack operations in a Rust Vec. pop + push + wrapping arithmetic + the unwrap_unchecked safety pattern — the same mechanics power Revm's hot path.

Principle (minimum model)

  • Vec::pop returns Option<T>. Empty → None, Some(v) → value. The null check is enforced by the type system.
  • EVM stack limit = 1024. Revm has pub const STACK_LIMIT: usize = 1024;. Exceeding → StackOverflow.
  • EVM ADD uses wrapping_add. mod 2²⁵⁶. saturating_add or checked_add are off-consensus. + diverges between debug and release.
  • unwrap_unchecked() + unsafe. When the length was just checked, the panic path becomes dead code → unwrap_unchecked removes it from the hot path. Hand-check + encode the invariant in unsafe.
  • Stack machine vs register machine, redux. Smaller instruction set + simpler operand encoding → easier to ZK-circuit / formally verify; runtime speed trades for verifiability.

Worked example + steps

Quiz: a mini EVM stack

Build a tiny Rust EVM-style stack with three operations:

  • push(n) — push a number
  • add() — pop two, push their sum
  • peek() — read the top without removing it

You're building the same shape as the real Revm Stack you read in the previous lesson — just with i64 instead of U256 to keep things simple.

What you'll need

  • A struct that wraps a Vec<i64>
  • An impl block with new(), push(&mut self, n), add(&mut self), peek(&self)
  • Knowledge of Vec::pop and Vec::last return types — what does Rust hand you when the vector is empty?
  • Underflow handling: what should add() do when there are fewer than 2 items?

For the EVM-faithful version, addition wraps modulo (it doesn't saturate or panic on overflow). Look up the right method on integers.

Try it yourself

In Rust Playground, start with this scaffold:

struct MiniEvmStack {
    data: Vec<i64>,
}

impl MiniEvmStack {
    fn new() -> Self {
        Self { data: Vec::new() }
    }

    // TODO: push, add, peek
}

fn main() {
    let mut s = MiniEvmStack::new();
    s.push(100);
    s.push(200);
    s.add().unwrap();
    println!("{:?}", s.peek()); // Should print: Some(300)
}

Hints:

  • Vec::pop returns Option<T> — empty case is encoded in the return type
  • Vec::last returns Option<&T> — borrowed, not copied (cheap)
  • add should return a Result<(), &'static str> so you can do .ok_or("stack underflow")? on the pop calls
  • For EVM-correct addition, the integer method whose name says "wrap" is what you want

Once it works, mentally compare your design to the real Revm Stack from the previous lesson — they have the same shape.

Quiz

Summary (3 lines)

  • Vec::pop -> Option<T> enforces the empty check at the type level. EVM stack limit 1024 (Revm STACK_LIMIT). ADD is wrapping_add.
  • unwrap_unchecked + unsafe = post-guard hot-path optimisation. Encode the invariant in unsafe.
  • Stack-machine choice trades raw runtime speed for verifiability. Next: async + traits + generics.