Rust service that simulates and risk-scores EVM transactions before signing.
It takes a proposed transaction, runs deterministic evaluation with RPC simulation and trace analysis, and returns a decision with evidence:
ALLOW, WARN, or BLOCK.
- Domain: blockchain security, transaction safety, pre-sign protection.
- Language and runtime: Rust + Tokio + Axum.
- Production focus: rate limiting, simulation budgets, fail-closed behavior, audit logging, SLO signals, admin control plane.
- Architecture style: modular pipeline with deterministic IDs, structured evidence, and observability-first operations.
- Delivery quality: automated CI on push/PR (format, build, lint, tests on Linux and Windows).
Users sign transactions with incomplete visibility into internal effects. This service reduces blind signing risk by turning raw calldata and trace output into explicit security evidence and policy decisions.
- Validates and normalizes input transaction fields.
- Pins a deterministic block (
requested blockorlatest-1). - Decodes intent from calldata selectors.
- Simulates execution (
eth_call) and classifies failure modes. - Optionally traces execution (
debug_traceCall) and extracts log facts. - Detects permission changes and token transfers (ERC20, ERC721, ERC1155).
- Runs policy and confidence logic.
- Returns a structured receipt with fired rules, uncertainties, and recommendations.
- Deterministic evaluation IDs for stable deduplication and auditability.
- Safety budgets for simulation and tracing:
- timeout limits
- max trace depth
- max trace payload size
- Fail-closed behavior (
off|warn|block) when analysis is partial. - Rate limiting:
- per-client buckets
- per-tenant and per-key quotas
- Redis-backed distributed mode with in-memory fallback option
- Admin control plane:
- runtime key lifecycle (upsert, disable, delete)
- runtime quota lifecycle (upsert, delete)
- file-backed persistence and live application without restart
- Security controls:
- API-key auth with optional salt and key metadata windows
- admin-token protected management routes
- request body size limits
- Observability:
- structured logs with request/evaluation context
- Prometheus metrics (latency, rule hits, failures, request outcomes)
- rolling SLO evaluator with alert signals and ops endpoint
src/api/*: HTTP handlers and routes.src/pipeline/mod.rs: orchestration and rule wiring.src/chain/*: RPC client, block pinning, simulation and trace wrappers.src/decode/mod.rs: calldata intent decoding.src/effects.rs: fact extraction from logs.src/policy.rs: decision and confidence policy.src/reverts.rs: revert reason decoding.src/safety/*: rate limiters and safety controls.src/management/*: admin control plane and persisted runtime config.src/observability/*: metrics and SLO evaluation.
| Method | Path | Purpose |
|---|---|---|
GET |
/health |
Liveness check |
GET |
/metrics |
Prometheus metrics |
GET |
/v1/ops/slo |
Rolling SLO report (OK, INSUFFICIENT_DATA, ALERT) |
POST |
/v1/evaluate/tx |
Main transaction risk evaluation |
GET |
/v1/admin/config |
Control-plane snapshot |
POST |
/v1/admin/keys/upsert |
Add or update API key |
POST |
/v1/admin/keys/disable |
Enable or disable API key |
POST |
/v1/admin/keys/delete |
Delete API key |
POST |
/v1/admin/quotas/upsert |
Add or update quota |
POST |
/v1/admin/quotas/delete |
Delete quota |
Admin routes are active when ADMIN_API_TOKEN is set and require x-admin-token.
cargo runService binds to http://127.0.0.1:8000.
Use an RPC for full simulation:
$env:RPC_URL="https://your-evm-rpc"
cargo runIf RPC_URL is not set, the service still responds with placeholder chain evidence and uncertainty SIMULATION_NOT_IMPLEMENTED.
curl -s -X POST "http://127.0.0.1:8000/v1/evaluate/tx" \
-H "Content-Type: application/json" \
-d '{
"chain_id": 1,
"from": "0x1111111111111111111111111111111111111111",
"to": "0x2222222222222222222222222222222222222222",
"data": "0x095ea7b30000000000000000000000003333333333333333333333333333333333333333000000000000000000000000000000000000000000000000ffffffffffffffff",
"value": "0x0",
"block_number": null
}'Key exported metrics:
tx_firewall_evaluate_latency_ms(histogram)tx_firewall_stage_latency_ms{stage="..."}(histogram)tx_firewall_rule_hits_total{rule_id="..."}tx_firewall_simulation_failures_total{kind="..."}tx_firewall_requests_total{outcome="ok|error|rate_limited|unauthorized"}tx_firewall_slo_status(0=OK,0.5=INSUFFICIENT_DATA,1=ALERT)tx_firewall_slo_p95_latency_mstx_firewall_slo_error_ratetx_firewall_slo_simulation_failure_ratetx_firewall_slo_alert{kind="..."}
This supports post-incident questions such as:
- Which pipeline stage increased latency?
- Did simulation failures spike?
- Did a specific risk rule suddenly increase?
- Is the service inside SLO right now?
Authentication and admin:
AUTH_REQUIRED(defaultfalse)AUTH_KEY_SALTAPI_KEYSADMIN_API_TOKEN(enables admin routes)CONTROL_PLANE_PATH(defaultcontrol_plane.json)
Request and safety limits:
MAX_REQUEST_BODY_BYTES(default65536)FAIL_CLOSED_MODE(off|warn|block, defaultwarn)ETH_CALL_TIMEOUT_MS(default10000)TRACE_TIMEOUT_MS(default12000)MAX_TRACE_DEPTH(default48)MAX_TRACE_SIZE_BYTES(default2097152)
Rate limits:
RATE_LIMIT_REQUESTS_PER_WINDOW(default120)RATE_LIMIT_WINDOW_SECS(default60)RATE_LIMIT_MAX_CLIENTS(default10000)TENANT_RATE_LIMITS(tenant overrides)RATE_LIMIT_BACKEND(memory|redis, defaultmemory)RATE_LIMIT_REDIS_ADDRRATE_LIMIT_REDIS_KEY_PREFIX(defaulttxfw:rl:)RATE_LIMIT_REDIS_CONNECT_TIMEOUT_MS(default80)RATE_LIMIT_REDIS_COMMAND_TIMEOUT_MS(default80)RATE_LIMIT_REDIS_PASSWORDRATE_LIMIT_REDIS_DB(default0)RATE_LIMIT_REDIS_FALLBACK_TO_MEMORY(defaulttrue)
SLO:
SLO_WINDOW_SECS(default300)SLO_MIN_SAMPLES(default50)SLO_MAX_P95_LATENCY_MS(default1200)SLO_MAX_ERROR_RATE(default0.05)SLO_MAX_SIMULATION_FAILURE_RATE(default0.20)
Audit:
AUDIT_LOG_PATHAUDIT_QUEUE_PATHAUDIT_DEAD_LETTER_PATHAUDIT_RETRY_MAX_ATTEMPTS(default8)AUDIT_DRAIN_BATCH_SIZE(default128)
Run all tests:
cargo testCurrent suite covers:
- validation and deterministic IDs
- decode and selector handling
- chain pinning and call behavior
- trace extraction and effect confidence
- policy/rules and fail-closed behavior
- simulation budget enforcement
- auth, audit logging, and request limits
- in-memory and Redis rate-limiting paths
- admin control-plane lifecycle
- SLO endpoint and alert conditions
- Designed and implemented a safety-critical decision pipeline in Rust.
- Built abuse resistance and graceful degradation controls.
- Added distributed systems behavior (Redis-backed limiter) with fallback strategy.
- Implemented runtime operability (control plane, live config changes, persistent state).
- Implemented metrics and SLO-driven operational visibility suitable for on-call workflows.
- Backed features with automated tests across functional and operational scenarios.
- EVM-only architecture at present.
- Trace quality depends on provider support for
debug_traceCall. - Some effects remain best-effort when traces are unavailable.
- provider capability matrix and adaptive fallback policy
- additional decoder coverage (routers, bridges, permits, AA flows)
- policy profile presets and externalized policy config
- OpenAPI spec and response schemas
- benchmark and soak-test profiles
No license file is currently defined in this repository.