# echenim/yieldhunter architecture

> Architecture diagram of the GitHub repository echenim/yieldhunter, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-16). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/echenim/yieldhunter
- Repository: https://github.com/echenim/yieldhunter

## Overview

This is a Rust workspace for real-time DeFi monitoring and automated action. The system is split into small domain crates plus one server binary that wires them together, with shared infrastructure for config, persistence, and eventing.

1. **Overall shape**
   - The repository is organized around a pipeline:
     - on-chain data ingestion
     - borrower risk monitoring
     - liquidation opportunity evaluation
     - transaction execution
     - yield allocation evaluation
   - A separate backtesting engine reuses the same domain concepts against historical data.

2. **Shared foundation: `defily-common`**
   - This crate holds the cross-cutting primitives used by all services:
     - configuration loading
     - database access
     - cache abstraction
     - event definitions
     - NATS integration
     - shared domain types and error handling
   - Architecturally, this is the common boundary that keeps the services from duplicating infrastructure code.

3. **Protocol ingestion: `defily-indexer`**
   - The indexer is the on-chain data intake layer.
   - It contains protocol-specific adapters, with explicit support code for **Aave V3** and an adapter abstraction for additional protocols.
   - Its job is to translate blockchain/protocol state into normalized internal events or stored records that downstream services can consume.

4. **Risk monitoring: `defily-risk`**
   - This service watches indexed positions and computes borrower health/risk state.
   - It is the first decisioning layer after ingestion: it determines whether a borrower has crossed a liquidation threshold.
   - The `monitor` and `store` modules suggest a stateful service that reads persisted position data, derives health metrics, and emits risk updates.

5. **Liquidation analysis: `defily-liquidation`**
   - This crate takes risky positions and evaluates whether a liquidation is economically worthwhile.
   - The `profitability` module indicates it factors in liquidation bonus, gas, slippage, and likely protocol-specific constraints before declaring an opportunity actionable.
   - This is the business-rule boundary between “at risk” and “worth executing.”

6. **Execution: `defily-executor`**
   - Once an opportunity is approved, the executor is responsible for carrying out the action.
   - The presence of a `circuit_breaker` module shows an operational safety boundary: execution can be throttled or stopped under adverse conditions.
   - This service is the only layer that should interact with transaction submission / live execution mechanics.

7. **Yield optimization: `defily-yield`**
   - Separate from liquidation, this crate evaluates lending protocol yields and incentives.
   - It supports the allocation side of the system: deciding where capital should be deployed for best return.
   - In the architecture, it consumes market/protocol state but produces allocation recommendations rather than liquidation actions.

8. **Event-driven coupling**
   - The repository’s architecture is explicitly event-driven:
     - indexer publishes normalized updates
     - risk, liquidation, and yield services consume those updates
     - shared event types ensure the services stay loosely coupled
   - NATS is the likely message backbone for runtime coordination, while the database acts as the durable state layer.

9. **Durable state and schema**
   - `migrations/001_initial.sql` plus `defily-common/src/db.rs` indicate a relational database-backed state store.
   - This store likely holds indexed protocol state, borrower positions, computed risk snapshots, and historical observations used by both live services and backtests.
   - The architecture uses persistence as the source of truth, not just in-memory streaming.

10. **Backtesting: `defily-backtest`**
    - The backtesting crate replays stored historical data to evaluate strategies offline.
    - Its `engine` and `report` modules suggest a simulation core plus post-run analytics/output.
    - This is a separate execution mode that validates liquidation and yield strategies before they are used in production.

11. **Service orchestration: `defily-server`**
    - The only binary in the tree is `defily-server/src/main.rs`, which likely bootstraps the service graph.
    - In practice, this is the composition root that loads config, connects to infrastructure, and starts the relevant agents.

12. **Runtime and deployment boundaries**
    - The workspace is configured through `config/default.toml`.
    - `docker-compose.yml` implies local infrastructure dependencies are containerized for development/testing.
    - The presence of Cargo workspace files and multiple service crates shows a modular Rust runtime, not a monolith.

13. **Key data flow for an architecture diagram**
    - Blockchain nodes feed protocol indexers.
    - Indexers normalize and persist protocol state, and publish events.
    - Risk monitoring consumes the state/events to identify under-collateralized accounts.
    - Liquidation logic filters those accounts for profitability.
    - Executor submits transactions for approved opportunities.
    - Yield evaluator reads the same market/protocol state to recommend capital allocation.
    - Backtesting reads historical state from storage and reuses the same strategy logic offline.

14. **Main architectural boundaries**
    - **Protocol-specific vs protocol-agnostic**: adapters in the indexer isolate Aave/other protocol details from the shared risk/liquidation logic.
    - **Decisioning vs execution**: liquidation profitability and risk computation are separated from live transaction submission.
    - **Live system vs simulation**: backtesting is isolated so it can reuse logic without touching execution infrastructure.
    - **Shared infra vs domain services**: `defily-common` centralizes plumbing and contracts.

15. **What to draw as primary nodes**
    - External: blockchain nodes / lending protocols, database, message bus.
    - Core services: indexer, risk monitor, liquidation engine, executor, yield evaluator, backtest engine.
    - Shared layer: common config/db/event types/cache/NATS.
    - Orchestrator: server binary that assembles the live services.

Main entry points: [`crates/defily-indexer/src/service.rs`](https://github.com/echenim/yieldhunter/blob/main/crates/defily-indexer/src/service.rs) (Indexer), [`crates/defily-liquidation/src/service.rs`](https://github.com/echenim/yieldhunter/blob/main/crates/defily-liquidation/src/service.rs) (Liquidation), [`crates/defily-risk/src/service.rs`](https://github.com/echenim/yieldhunter/blob/main/crates/defily-risk/src/service.rs) (Risk monitor), [`crates/defily-server/src/main.rs`](https://github.com/echenim/yieldhunter/blob/main/crates/defily-server/src/main.rs) (Server)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_external["External systems"]
  node_blockchain(("Blockchain<br/>external source"))
  node_database[("Database<br/>persistent store<br/>[001_initial.sql]")]
  node_nats(("NATS<br/>message bus"))
end

subgraph group_shared["Shared foundation"]
  node_defily_common_config["Config<br/>[config.rs]"]
  node_defily_common_db["DB layer<br/>shared persistence<br/>[db.rs]"]
  node_defily_common_cache["Cache<br/>[cache.rs]"]
  node_defily_common_events["Events<br/>shared contracts<br/>[events.rs]"]
  node_defily_common_nats["NATS client<br/>shared messaging<br/>[nats.rs]"]
  node_defily_common_types["Domain types<br/>shared models<br/>[types.rs]"]
end

subgraph group_live["Live pipeline"]
  node_indexer["Indexer<br/>ingestion service<br/>[service.rs]"]
  node_aave_v3["Aave V3<br/>protocol adapter<br/>[aave_v3.rs]"]
  node_adapter["Adapters<br/>adapter trait<br/>[adapter.rs]"]
  node_risk["Risk monitor<br/>risk service<br/>[service.rs]"]
  node_risk_monitor["Monitor<br/>risk logic<br/>[monitor.rs]"]
  node_liquidation["Liquidation<br/>decision service<br/>[service.rs]"]
  node_profitability["Profitability<br/>business rules<br/>[profitability.rs]"]
  node_executor["Executor<br/>execution service<br/>[service.rs]"]
  node_circuit_breaker{{"Circuit breaker<br/>safety control<br/>[circuit_breaker.rs]"}}
  node_yield_eval["Yield eval<br/>allocation service<br/>[evaluator.rs]"]
  node_server["Server<br/>composition root<br/>[main.rs]"]
end

subgraph group_offline["Offline analysis"]
  node_backtest["Backtest<br/>simulation engine<br/>[engine.rs]"]
  node_report["Report<br/>analysis output<br/>[report.rs]"]
end

node_blockchain -->|"on-chain data"| node_indexer
node_indexer -->|"persist"| node_database
node_indexer -->|"publish"| node_nats
node_indexer -->|"positions"| node_risk
node_indexer -->|"market state"| node_liquidation
node_indexer -->|"protocol state"| node_yield_eval
node_defily_common_config -->|"loads"| node_server
node_defily_common_db -->|"reads/writes"| node_indexer
node_defily_common_db -->|"reads/writes"| node_risk
node_defily_common_db -->|"reads"| node_liquidation
node_defily_common_db -->|"reads"| node_yield_eval
node_defily_common_events -->|"contracts"| node_nats
node_defily_common_nats -->|"connects"| node_indexer
node_defily_common_nats -->|"connects"| node_risk
node_defily_common_nats -->|"connects"| node_liquidation
node_defily_common_nats -->|"connects"| node_yield_eval
node_defily_common_types -->|"models"| node_risk
node_defily_common_types -->|"models"| node_liquidation
node_defily_common_types -->|"models"| node_executor
node_aave_v3 -->|"implements"| node_adapter
node_adapter -->|"abstraction"| node_indexer
node_risk -->|"uses"| node_risk_monitor
node_risk -->|"risky positions"| node_liquidation
node_liquidation -->|"filters"| node_profitability
node_liquidation -->|"approved ops"| node_executor
node_executor -->|"guards"| node_circuit_breaker
node_server -->|"starts"| node_indexer
node_server -->|"starts"| node_risk
node_server -->|"starts"| node_liquidation
node_server -->|"starts"| node_executor
node_server -->|"starts"| node_yield_eval
node_database -->|"historical data"| node_backtest
node_backtest -->|"outputs"| node_report
node_backtest -->|"reuses logic"| node_liquidation
node_backtest -->|"reuses logic"| node_yield_eval

click node_database "https://github.com/echenim/yieldhunter/blob/main/migrations/001_initial.sql"
click node_defily_common_config "https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/config.rs"
click node_defily_common_db "https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/db.rs"
click node_defily_common_cache "https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/cache.rs"
click node_defily_common_events "https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/events.rs"
click node_defily_common_nats "https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/nats.rs"
click node_defily_common_types "https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/types.rs"
click node_indexer "https://github.com/echenim/yieldhunter/blob/main/crates/defily-indexer/src/service.rs"
click node_aave_v3 "https://github.com/echenim/yieldhunter/blob/main/crates/defily-indexer/src/aave_v3.rs"
click node_adapter "https://github.com/echenim/yieldhunter/blob/main/crates/defily-indexer/src/adapter.rs"
click node_risk "https://github.com/echenim/yieldhunter/blob/main/crates/defily-risk/src/service.rs"
click node_risk_monitor "https://github.com/echenim/yieldhunter/blob/main/crates/defily-risk/src/monitor.rs"
click node_liquidation "https://github.com/echenim/yieldhunter/blob/main/crates/defily-liquidation/src/service.rs"
click node_profitability "https://github.com/echenim/yieldhunter/blob/main/crates/defily-liquidation/src/profitability.rs"
click node_executor "https://github.com/echenim/yieldhunter/blob/main/crates/defily-executor/src/service.rs"
click node_circuit_breaker "https://github.com/echenim/yieldhunter/blob/main/crates/defily-executor/src/circuit_breaker.rs"
click node_yield_eval "https://github.com/echenim/yieldhunter/blob/main/crates/defily-yield/src/evaluator.rs"
click node_server "https://github.com/echenim/yieldhunter/blob/main/crates/defily-server/src/main.rs"
click node_backtest "https://github.com/echenim/yieldhunter/blob/main/crates/defily-backtest/src/engine.rs"
click node_report "https://github.com/echenim/yieldhunter/blob/main/crates/defily-backtest/src/report.rs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_blockchain,node_database,node_nats toneBlue
class node_defily_common_config,node_defily_common_db,node_defily_common_cache,node_defily_common_events,node_defily_common_nats,node_defily_common_types toneAmber
class node_indexer,node_aave_v3,node_adapter,node_risk,node_risk_monitor,node_liquidation,node_profitability,node_executor,node_circuit_breaker,node_yield_eval,node_server toneMint
class node_backtest,node_report toneRose
```

## Components

### External systems

Blockchain, storage, and messaging dependencies outside the Rust workspace.

- **Blockchain**: external source · On-chain protocols and nodes that produce the raw DeFi state.
- [Database](https://github.com/echenim/yieldhunter/blob/main/migrations/001_initial.sql): persistent store · Relational state store backed by the workspace migrations. · `migrations/001_initial.sql`
- **NATS**: message bus · Event backbone used for loose coupling between services.

### Shared foundation

Cross-cutting primitives reused by all services.

- [Config](https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/config.rs): shared config · Configuration loading and environment wiring. · `crates/defily-common/src/config.rs`
- [DB layer](https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/db.rs): shared persistence · Database access and repository primitives. · `crates/defily-common/src/db.rs`
- [Cache](https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/cache.rs): shared cache · Cache abstraction used across services. · `crates/defily-common/src/cache.rs`
- [Events](https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/events.rs): shared contracts · Normalized event definitions passed between services. · `crates/defily-common/src/events.rs`
- [NATS client](https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/nats.rs): shared messaging · Integration layer for publishing and consuming events. · `crates/defily-common/src/nats.rs`
- [Domain types](https://github.com/echenim/yieldhunter/blob/main/crates/defily-common/src/types.rs): shared models · Common domain data structures and error handling boundary. · `crates/defily-common/src/types.rs`

### Live pipeline

Runtime services that ingest, assess, decide, and execute actions.

- [Indexer](https://github.com/echenim/yieldhunter/blob/main/crates/defily-indexer/src/service.rs): ingestion service · Normalizes on-chain protocol state into internal records and events. · `crates/defily-indexer/src/service.rs`
- [Aave V3](https://github.com/echenim/yieldhunter/blob/main/crates/defily-indexer/src/aave_v3.rs): protocol adapter · Protocol-specific ingestion logic for Aave V3. · `crates/defily-indexer/src/aave_v3.rs`
- [Adapters](https://github.com/echenim/yieldhunter/blob/main/crates/defily-indexer/src/adapter.rs): adapter trait · Abstraction for supporting additional lending protocols. · `crates/defily-indexer/src/adapter.rs`
- [Risk monitor](https://github.com/echenim/yieldhunter/blob/main/crates/defily-risk/src/service.rs): risk service · Computes borrower health and detects liquidation thresholds. · `crates/defily-risk/src/service.rs`
- [Monitor](https://github.com/echenim/yieldhunter/blob/main/crates/defily-risk/src/monitor.rs): risk logic · Derives health metrics from stored positions and market state. · `crates/defily-risk/src/monitor.rs`
- [Liquidation](https://github.com/echenim/yieldhunter/blob/main/crates/defily-liquidation/src/service.rs): decision service · Evaluates whether a risky position is profitable to liquidate. · `crates/defily-liquidation/src/service.rs`
- [Profitability](https://github.com/echenim/yieldhunter/blob/main/crates/defily-liquidation/src/profitability.rs): business rules · Applies bonus, gas, slippage, and protocol constraints. · `crates/defily-liquidation/src/profitability.rs`
- [Executor](https://github.com/echenim/yieldhunter/blob/main/crates/defily-executor/src/service.rs): execution service · Submits approved actions to live transaction mechanics. · `crates/defily-executor/src/service.rs`
- [Circuit breaker](https://github.com/echenim/yieldhunter/blob/main/crates/defily-executor/src/circuit_breaker.rs): safety control · Operational guardrail that can throttle or stop execution. · `crates/defily-executor/src/circuit_breaker.rs`
- [Yield eval](https://github.com/echenim/yieldhunter/blob/main/crates/defily-yield/src/evaluator.rs): allocation service · Evaluates protocol yields and incentives for capital allocation. · `crates/defily-yield/src/evaluator.rs`
- [Server](https://github.com/echenim/yieldhunter/blob/main/crates/defily-server/src/main.rs): composition root · Binary that loads config and starts the live service graph. · `crates/defily-server/src/main.rs`

### Offline analysis

Backtesting and reporting components that reuse live domain logic.

- [Backtest](https://github.com/echenim/yieldhunter/blob/main/crates/defily-backtest/src/engine.rs): simulation engine · Replays historical state to test strategies offline. · `crates/defily-backtest/src/engine.rs`
- [Report](https://github.com/echenim/yieldhunter/blob/main/crates/defily-backtest/src/report.rs): analysis output · Produces post-run results and evaluation summaries. · `crates/defily-backtest/src/report.rs`

## Connections

- Blockchain → Indexer: on-chain data · Raw protocol state is ingested by the indexer.
- Indexer → Database: persist · Normalized state is written to durable storage.
- Indexer → NATS: publish · Index updates are emitted as events.
- Indexer → Risk monitor: positions · Risk monitoring consumes indexed position updates.
- Indexer → Liquidation: market state · Liquidation analysis reads the same normalized state.
- Indexer → Yield eval: protocol state · Yield evaluation consumes market and protocol data.
- Config → Server: loads · Shared configuration is used to bootstrap the runtime.
- DB layer → Indexer: reads/writes · The indexer uses the shared persistence layer.
- DB layer → Risk monitor: reads/writes · Risk monitoring persists and reads borrower state.
- DB layer → Liquidation: reads · Liquidation service consults stored state.
- DB layer → Yield eval: reads · Yield evaluation consults stored market state.
- Events → NATS: contracts · Shared events define the message payloads.
- NATS client → Indexer: connects · The indexer publishes and subscribes through NATS.
- NATS client → Risk monitor: connects · Risk service consumes updates through NATS.
- NATS client → Liquidation: connects · Liquidation service consumes updates through NATS.
- NATS client → Yield eval: connects · Yield service consumes updates through NATS.
- Domain types → Risk monitor: models · Risk logic relies on shared domain types.
- Domain types → Liquidation: models · Liquidation logic relies on shared domain types.
- Domain types → Executor: models · Execution uses shared domain types and errors.
- Aave V3 → Adapters: implements · Aave V3 is one protocol-specific adapter implementation.
- Adapters → Indexer: abstraction · Protocol adapters plug into the indexer boundary.
- Risk monitor → Monitor: uses · The service delegates health computation to monitoring logic.
- Risk monitor → Liquidation: risky positions · Detected risk states feed liquidation evaluation.
- Liquidation → Profitability: filters · Profitability rules decide whether liquidation is actionable.
- Liquidation → Executor: approved ops · Actionable opportunities are passed to execution.
- Executor → Circuit breaker: guards · Execution is constrained by safety controls.
- Server → Indexer: starts · The binary composes and starts the indexer.
- Server → Risk monitor: starts · The binary composes and starts risk monitoring.
- Server → Liquidation: starts · The binary composes and starts liquidation analysis.
- Server → Executor: starts · The binary composes and starts execution.
- Server → Yield eval: starts · The binary composes and starts yield evaluation.
- Database → Backtest: historical data · Backtesting replays stored historical state.
- Backtest → Report: outputs · Simulation results are summarized by reporting.
- Backtest → Liquidation: reuses logic · Offline simulation reuses liquidation strategy concepts.
- Backtest → Yield eval: reuses logic · Offline simulation reuses yield evaluation concepts.
