This document provides a high-level overview of the internal architecture of the LP Yield Optimizer Vault. It is intended for developers who want to understand the system's components, data flow, and design principles.
The AVM is built on several key principles:
- Modularity & Separation of Concerns: Each package has a distinct responsibility (e.g., fetching data, analyzing data, executing transactions). This makes the system easier to understand, test, and maintain.
- Safety First: The system is designed to be fault-tolerant and risk-averse. This is achieved through rigorous data validation, on-chain simulations before execution, and strict slippage controls.
- Observability: The AVM's actions must be transparent. Comprehensive logging, a real-time web dashboard, and detailed historical snapshots provide deep insight into its behavior.
- Adaptability: The core strategy is defined by a set of
ScoringParametersthat are loaded from the database, allowing the strategy to be tuned and evolved without code changes.
The LP Yield Optimizer Vault operates in a continuous cycle. The following diagram illustrates the flow of data between the core components during a single operational cycle.
graph TD
subgraph "AVM Core Logic"
A[Data Fetcher] --> B(Analyzer);
B --> C(Planner);
C --> D{Vault Manager};
end
subgraph "External Systems"
E[Elys Blockchain]
F[CryptoCompare API]
G[Elys Supply API]
end
subgraph "Persistent State"
H[PostgreSQL Database]
end
A -- Fetches On-Chain Data --> E;
A -- Fetches Historical Prices --> F;
A -- Fetches Volume --> G;
D -- Queries State --> E;
D -- Executes Transactions --> E;
B -- Uses Parameters --> H;
style H fill:#f9f,stroke:#333,stroke-width:2px
A -- Provides Raw Data --> B;
B -- Provides Target Allocations --> C;
C -- Provides Action Plan --> D;
D -- Records Cycle Data --> H;
The project is organized into several key packages within the internal/ directory.
The main entry point of the application. It is responsible for:
- Initializing all components (logger, database, gRPC client).
- Loading the active
ScoringParametersfrom the database. - Starting the main operational loop on a timer (
runAVMCycle). - Launching the web server.
The AVM's "senses." This package is responsible for gathering all raw data required for analysis from various sources.
PoolRetriever.go: Fetches and assembles a complete picture of each liquidity pool from theammandmasterchefmodules.Tokens.go: Fetches token metadata, current prices, and orchestrates the retrieval of historical data.HourlyPrice.go: Fetches 30 days of hourly price data from the CryptoCompare API, essential for volatility calculations.WeeklyVolumeByPool.go: Fetches 7-day trading volume from the Elys Supply Stats API.
The AVM's "brain." It takes the raw data from the datafetcher and applies the AVM's core strategy to it.
CalculateVolatility.go: Calculates annualized volatility for each token.CalculatePoolScore.go: Orchestrates the scoring of each pool based on the activeScoringParameters. It calculates reward, risk, liquidity, and bonus components to produce a final score.SelectTopPools.go: Sorts pools by score, selects the top candidates, and determines the finaltargetAllocationswhile enforcing min/max allocation constraints.
The AVM's "strategist." It translates the high-level goal from the analyzer into a concrete, executable plan.
planner.go: Takes the current vault positions and thetargetAllocationsand generates a sequence ofSubActionstructs. It intelligently creates a two-phase plan:- Phase 1: Withdraw from over-allocated pools and consolidate all resulting non-USDC assets into USDC via swaps.
- Phase 2: Use the now-liquid USDC to perform single-sided deposits into under-allocated target pools.
The AVM's "hands." This package provides a high-level interface (VaultManager) for interacting with the target vault.
live.go: The live implementation of theVaultManagerinterface. It handles querying the vault's current state (positions, liquid USDC) and executing theActionPlangenerated by the planner.interface.go: Defines theVaultManagerinterface, allowing for mock implementations for testing.
The AVM's "signature." This package handles the low-level, security-critical details of creating, signing, and broadcasting transactions.
client.go: A robust Cosmos SDK signing client that initializes the keyring and client context.transactions.go: Translates the planner'sSubActionstructs into specific SDK messages, embeds slippage protection, and manages the transaction lifecycle. A key feature is its use of gas simulation to ensure efficient and reliable transaction broadcasting.
The AVM's "memory." It manages all interactions with the PostgreSQL database.
db.go: Handles the database connection and defines the schema for all tables.snapshot_store.go: Saves the detailedCycleSnapshotat the end of each cycle.parameters_store.go: Manages saving and loading different versions of theScoringParameters.analytics.go: Provides functions to query historical data for the web dashboard.
Provides a real-time monitoring dashboard.
server.go: A self-contained web server usinggorilla/muxthat exposes a REST API for querying cycle history and performance metrics. It serves a single-page HTML dashboard that consumes this API.
This package defines all the shared data structures used across the entire application, ensuring consistency and type safety.
- Start: The
runAVMCyclefunction is triggered by a timer. - Fetch: The
datafetchergathers all necessary on-chain and off-chain data. - Assess: The
vaultmanager queries the current state of the vault (positions, value). - Analyze: The
analyzertakes the fetched data and current vault state, calculates volatility and IL risk, and produces afinalScorefor each pool. - Select & Allocate: The
analyzerthen selects the top-scoring pools and calculates the idealtargetAllocations. - Plan: The
plannercompares the current allocations to the target allocations and generates a two-phaseActionPlanofSubActions, complete with simulation data for slippage protection. - Execute: The
vaultmanager calls thewalletto execute theActionPlan. Thewalletbuilds the transactions, simulates for gas, signs, and broadcasts them. - Record: After execution, the final state of the vault is queried. A
CycleSnapshotis populated with the initial state, the plan, the final state, and calculated performance metrics (net return, slippage, gas costs). - Save: The
statemanager saves the completeCycleSnapshotto the database. - Repeat: The AVM waits for the next timer tick.
- Parameter Optimization Loop: Implement the logic to periodically analyze historical
CycleSnapshotdata and automatically tune theScoringParametersto improve performance over time.