← Projects

Smart Contract Invariant Monitor & Guardian

A Rust tool that replays historical DeFi exploits block by block and checks protocol invariants at each step. On the Euler Finance exploit it flags the violation 4 blocks, about 7 minutes, before the drain.

security
Problem
DeFi protocols face constant security threats. Even with audits and formal verification, hacks happen. Traditional monitoring is reactive, by the time you see an alert, funds are often already in Tornado Cash. We need runtime verification that can detect violations in seconds, not minutes.
Solution
Built a Rust-based system that monitors protocol invariants every block, detects violations in real-time, and can automatically pause protocols via Flashbots when critical issues are found. The Guardian simulates every action before execution, ensuring safety while providing sub-15-second response times.

Overview

What it is: A Rust-based system designed to bridge the gap between “code looks good” and “protocol is safe.” It replays historical DeFi exploits block by block, checks protocol invariants at each step, and includes a Guardian that can simulate and submit a pause transaction when a violation is found.

Why it matters: DeFi protocols manage billions of dollars, yet exploits continue to occur despite rigorous security practices. The challenge isn’t just writing secure code, it’s ensuring code remains secure when interacting with unpredictable blockchain state. Traditional reactive monitoring fails because by the time alerts arrive, funds are often already gone.

Who it’s for: DeFi protocol teams, security engineers, and infrastructure operators who need real-time protection for their protocols. It ships with Docker and Kubernetes manifests, but it has only been run in replay and testnet settings.

Impact: Replayed against the Euler Finance exploit (a $197M hack), the tool flags the invariant violation at block 16817996, 4 blocks (about 7 minutes) before the drain. That is what it demonstrates: detection lead time on one historical exploit, not a prevented loss. The architecture shows how runtime verification could provide the “eyes and hands” needed to watch a protocol block by block.

The Problem

The Challenge

In the high-stakes world of DeFi, security is a constant battle. We audit code, verify formal proofs, and run bug bounties. Yet, hacks still happen. The complexity of composability means that even perfectly audited code can break when interacting with an unforeseen external state.

Specific issues:

Who was affected:

Consequences of not solving it:

Why It Matters

When a hack happens, speed is everything. Seconds can mean the difference between a “close call” and a total protocol drain. The Euler Finance replay shows this: the tool flags the invariant violation 4 blocks before the drain.

The broader impact:

Existing Solutions

Current monitoring approaches:

Why they’re insufficient:

Gap identified:

Constraints & Requirements

Technical constraints:

Time constraints:

Resource constraints:

User constraints:

The Solution

Approach & Methodology

The solution combines two main components working together:

  1. The Monitor (The Observer): A read-only daemon that connects to Ethereum and replays every block, evaluating defined invariants and alerting on violations
  2. The Guardian (The Protector): An active participant that can automatically respond to critical violations by pausing protocols, but only after simulation and verification

Methodology:

Technology Stack

Core Language:

Blockchain Infrastructure:

Architecture Components:

Tools & Services:

Why this stack:

Architecture & Design Decisions

Architecture pattern: Modular Rust workspace with clear separation of concerns

Key design decisions:

  1. Provider Pooling: Multiple RPC providers with automatic failover and health monitoring
  2. Canonical Chain Tracking: Handles blockchain reorgs by maintaining chain state and rolling back on forks
  3. Simulation-First Pipeline: Every Guardian action simulated on local fork before execution
  4. Finality Depth: Only alert on blocks with high probability of being final
  5. JSON Configuration: Simple, universal format over custom DSL

Trade-offs:

Scalability considerations:

Key Features

  1. Real-Time Invariant Monitoring: Evaluates protocol invariants every block (12-second intervals)
  2. Automatic Violation Detection: Flags violations with severity levels (LOW, MEDIUM, HIGH, CRITICAL)
  3. Guardian Auto-Response: Can automatically pause protocols when critical violations are detected
  4. Simulation Safety: Every Guardian action tested on local fork before execution
  5. Reorg Handling: Tracks canonical chain and handles blockchain forks gracefully
  6. Provider Resilience: Automatic failover across multiple RPC providers
  7. Flashbots Integration: Protects rescue transactions from front-running
  8. JSON Configuration: Simple invariant definitions without custom code

Technical Highlights

Guardian Pipeline Architecture

// Simplified pipeline flow
async fn guardian_pipeline(violation: Violation) -> Result<()> {
    // 1. Severity check
    if violation.severity != Severity::Critical {
        return Ok(()); // Only act on critical violations
    }
    
    // 2. Simulation (safety net)
    let fork = anvil_fork_at_block(violation.block).await?;
    let simulation_result = fork.simulate(pause_transaction()).await?;
    
    if !simulation_result.success {
        return Err(SimulationFailed);
    }
    
    // 3. Execution via Flashbots
    let tx = construct_pause_transaction();
    flashbots.send_private(tx).await?;
    
    Ok(())
}

Key Technical Decisions:

  1. Rust workspace structure: Modular crates for clear separation of concerns
  2. Provider pooling: Round-robin with health-based ranking
  3. Canonical chain tracking: Parent hash validation for reorg detection
  4. Anvil simulation: Local fork ensures transaction will succeed
  5. Flashbots integration: Private mempool prevents front-running

Reorg Handling Implementation

struct BlockIndexer {
    canonical_chain: Vec<BlockHash>,
    processed_blocks: HashSet<BlockHash>,
}

impl BlockIndexer {
    fn process_block(&mut self, block: Block) -> Result<()> {
        // Detect reorg by checking parent hash
        if block.parent_hash != self.canonical_chain.last() {
            self.handle_reorg(block.parent_hash)?;
        }
        self.canonical_chain.push(block.hash);
        Ok(())
    }
}

Process & Timeline

Phase 1: Research & Planning

Phase 2: Design & Development

Phase 3: Testing & Refinement

Major Milestones

Challenges & Solutions

Challenge 1: Handling Blockchain Reorgs

The Problem: Blockchains fork and reorg. A naive monitor might alert on a violation in Block A, only for Block A to be “uncled” and replaced by Block B where everything is fine, causing false alarms.

Why it was difficult: Reorgs are rare but critical. Need to track canonical chain, detect forks, roll back state, and re-process blocks, all while maintaining performance.

The Solution:

What I learned: Blockchain state is non-linear. Production systems must handle the chaos of forks and reorgs, not just the happy path.

Challenge 2: RPC Provider Reliability

The Problem: Single RPC provider is a single point of failure. Nodes go down, rate limits are hit, data can lag, all causing monitor downtime.

Why it was difficult: Need to balance multiple providers, handle failures gracefully, and maintain performance while switching providers.

The Solution:

What I learned: Infrastructure reliability requires redundancy at every layer. Provider pooling is essential for production blockchain systems.

Challenge 3: Guardian Safety Guarantees

The Problem: Guardian can pause billion-dollar protocols. We cannot afford false positives or failed executions. Every action must be guaranteed to succeed.

Why it was difficult: Balancing safety (simulation) with speed (real-time response) while ensuring transactions will actually help.

The Solution:

What I learned: Safety-critical systems require multiple layers of verification. Simulation is non-negotiable for autonomous protocol control.

Visual Elements

Diagrams:

Case Study Visualizations:

Results & Metrics

Quantifiable Outcomes

Performance metrics:

Case study results (Euler Finance):

Technical metrics:

Impact & Value Delivered

What value did this project create?

How did it improve the situation?

What changed as a result?

What opportunities did it unlock?

Learnings

What Worked Well

What Didn’t Work

What I’d Do Differently

Key Insights:

Next Steps

Future Improvements

Potential Iterations

Ongoing Work

The project is open source and actively developed. Current focus areas:


Completed: December 1, 2024