The Guardian of the Chain: In Practice & Future (Part 3/3)
TL;DR
- Euler Finance: March 2023, ~$197M exploit; replay with the exploit-analyzer shows invariant violation would have been detected 7 minutes (35 blocks) before the major drain.
- Walkthrough: Clone repo → build → seed → list → analyze (with exploit ID and Euler config) → inspect Markdown report and JSON artifacts.
- Secrets: Never put private keys in config files; use environment variables and keep keys out of version control.
- Roadmap: Multi-chain, ML anomaly detection, enterprise integrations, and more invariant types are on the horizon.
Table of Contents
- Introduction
- Background: Euler Finance Exploit
- Case Study: Replay and Results
- Step-by-Step: Run the Euler Analysis Yourself
- Getting Started With Your Own Config
- The Road Ahead: Future Improvements
- Common Pitfalls to Avoid
- Conclusion
- Related Posts
Introduction
Hook: On March 13, 2023, Euler Finance was exploited for nearly $197 million. The exploit-analyzer lets you replay that timeline with invariant checks and see exactly when a violation would have been detected.
Context: In Part 1 we introduced the CLI and invariant-based replay; in Part 2 we walked through the Rust architecture. Here we run the Euler Finance case study step-by-step, interpret the outputs, and outline the roadmap.
Preview: You’ll get a concrete walkthrough (clone, build, seed, list, analyze, view results), correct clone and config examples with no private keys in files, and a concise roadmap for where the project is headed.
Background: Euler Finance Exploit
Euler Finance was a lending protocol: users deposit assets and borrow against them. Solvency is the core invariant: reserves ≥ liabilities. In March 2023, an attacker exploited a flaw in the protocol’s internal accounting (a “donation” that skewed accounting), leading to a ~$197M drain.
Replaying blocks with a reserve_ratio_min invariant (e.g. reserves / liabilities ≥ 1.0) shows the first block where that invariant is violated and the detection lead time—how many blocks or minutes before the main exploit. That’s what the analyzer produces.
Case Study: Replay and Results
The Invariant
For the Euler case study, the config uses a solvency-style invariant:
- Type:
reserve_ratio_min - Condition: Reserves / Liabilities ≥ 1.0
- Severity: CRITICAL
When the ratio drops below 1.0, the analyzer records a violation and the block number.
What the Replay Shows
The analyzer replays a block range around the exploit (e.g. 100 blocks before, 10 after) and evaluates the invariant every block. From the Quick Start guide, a typical run reports something like:
- First violation block: When the invariant first fails (e.g. reserve ratio < 1.0).
- Detection lead time:
35 blocks before the main exploit (7 minutes at ~12s per block). - Total violations: Count over the replayed range.
- Outputs:
report.md,violations.json,run-metadata.json.
So the same invariant logic would have flagged the issue 7 minutes before the major drain—proof that invariant-based replay can answer “when could we have known?”
Interpreting the Artifacts
report.md: Human-readable summary, first violation block, timeline. Use this to quickly see “would we have caught it, and how early?”violations.json: Every violation event (block, values, severity) for scripts or dashboards.run-metadata.json: Run-level metrics (e.g. detection lead time, block range) for record-keeping or CI.
Step-by-Step: Run the Euler Analysis Yourself
1. Clone and build
git clone https://github.com/RahilBhavan/Smart-Contract-Invariant-Monitor-and-Guardian-.git
cd "Smart Contract Invariant Monitor and Guardian "
cd monitor
cargo build --release
2. Seed the exploit database
cargo run --bin exploit-analyzer -- seed
This populates known exploits, including Euler Finance.
3. List exploits and get the Euler ID
cargo run --bin exploit-analyzer -- list
Use the exploit ID shown for the Euler Finance entry (e.g. in the format suggested by the list output). You’ll pass it as --exploit-id in the next step.
4. Set RPC URL and run analysis
Use a mainnet RPC endpoint (e.g. Alchemy or Infura). Never commit API keys or secrets to the repo.
export RPC_URL="https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY"
# Replace <EXPLOIT_ID> with the ID from `list`
cargo run --bin exploit-analyzer -- analyze \
--exploit-id "<EXPLOIT_ID>" \
--config config/case-studies/euler.json \
--rpc-url "$RPC_URL" \
--blocks-before 100 \
--blocks-after 10 \
--output output/euler-analysis
5. View results
ls output/euler-analysis/
cat output/euler-analysis/Euler-Finance-*/report.md
cat output/euler-analysis/Euler-Finance-*/violations.json
cat output/euler-analysis/Euler-Finance-*/run-metadata.json
You should see the first violation block, detection lead time (~35 blocks / ~7 minutes), and full violation timeline.
Getting Started With Your Own Config
To replay a custom block range with your own invariants:
-
Define invariants in a JSON config (see Part 2 for structure). Use the same schema as
config/case-studies/euler.jsonorconfig/invariants.jsonin the repo. -
Use environment variables for secrets. Do not put RPC API keys or private keys in config files or in git.
export RPC_URL="https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY"If you later use Guardian or other features that need a signing key, keep it in an env var (e.g.
GUARDIAN_PRIVATE_KEY) and load it in code or tooling—never commit it. -
Run a replay:
cargo run --bin exploit-analyzer -- replay \ --config config/invariants.json \ --rpc-url "$RPC_URL" \ --start-block 18000000 \ --end-block 18000100 \ --output output/custom-replay
Warning: Never store private keys or API keys in config files or version control. Use environment variables or a secrets manager and restrict access.
The Road Ahead: Future Improvements
The project is open source and evolving. Possible directions (not commitments):
- Multi-chain: Support for L2s (Arbitrum, Optimism, Base) and different finality rules; cross-chain invariant analysis.
- Anomaly detection: ML or statistical methods beyond binary invariants (e.g. gas or volume anomalies).
- Enterprise integrations: Secret management (e.g. Azure Key Vault, GCP Secret Manager, AWS Secrets Manager), SSO.
- Alerting: Richer alert channels (e.g. SMTP, SMS, custom webhooks) and aggregation.
- Performance: Parallel block and invariant processing, horizontal scaling for large replays.
- Invariant types: Time-based, cross-protocol, or composite invariants; pluggable types.
Check the GitHub repo and docs for the latest roadmap and contribution guidelines.
Common Pitfalls to Avoid
Pitfall 1: Over-reliance on a single invariant type
What goes wrong: You only check one thing (e.g. reserve ratio) and miss other failure modes.
How to avoid it: Start with critical invariants (e.g. solvency), then add others (health factors, oracle deviation) and tune severity. Replay past incidents to validate.
Pitfall 2: Secrets in config or git
What goes wrong: RPC API keys or private keys end up in JSON files and get committed.
How to avoid it: Use environment variables (e.g. RPC_URL, GUARDIAN_PRIVATE_KEY) and never commit secrets. Add *.env and secret-containing configs to .gitignore.
Pitfall 3: Wrong block range or exploit ID
What goes wrong: Replay misses the exploit or analyzes the wrong event.
How to avoid it: Use list and show <id> to confirm exploit IDs and block numbers. For custom replays, choose start/end blocks so the range covers the event you care about.
Conclusion
Summary: Part 3 walked through the Euler Finance case study: what the exploit was, how the exploit-analyzer replays it with a reserve-ratio invariant, and how to run the same analysis yourself. The replay shows invariant violation would have been detected 7 minutes before the major drain. We also covered clone/build/seed/list/analyze, correct use of env vars for secrets (no private keys in config), and a concise roadmap.
Key takeaways:
- Replay is reproducible: Clone, build, seed, list, analyze—then inspect report and JSON.
- Detection lead time is measurable: The Euler run demonstrates ~35 blocks / ~7 minutes lead time.
- Secrets stay out of config and git: Use environment variables (and optional secrets managers) for keys and API tokens.
- Roadmap: Multi-chain, anomaly detection, enterprise features, and more invariant types are potential next steps.
Call to action:
- Read Part 1: Sleep Soundly and Part 2: Under the Hood if you haven’t yet.
- Run the Quick Start and try the Euler analysis.
- Contribute or open issues on GitHub.
Tip: Start with the built-in Euler case study and config; then duplicate and adapt the config for your own protocol and block ranges.
Related Posts
- The Guardian of the Chain: Sleep Soundly (Part 1) — Introduction and invariant-based replay
- The Guardian of the Chain: Under the Hood (Part 2) — Rust architecture and workflow
Additional Resources
- Smart Contract Invariant Monitor & Guardian — GitHub repository
- Quick Start Guide — 5-minute setup and Euler run
- Architecture — Components and data flow
Tags: case-study, defi, security, euler-finance, roadmap