A command-line application for collecting Total Value Locked (TVL) data from vault protocols using modular protocol adapters.
TQ Oracle performs read smart contract READ calls through a registry of protocol adapters to aggregate TVL data for specified vaults. Each adapter is responsible for querying specific contracts and returning standardized asset price data.
For detailed system architecture and integration with Mellow Finance flexible-vaults, see ARCHITECTURE.md.
You can run this CLI without any git cloning, directly with uv
uvx --from git+https://github.com/Moonsong-Labs/tq-oracle.git tq-oracle --help This project uses uv for dependency management:
# Clone the repository
git clone <repo-url>
cd tq-oracle
# Install dependencies
uv sync
TQ Oracle supports three ways to configure the application, with the following precedence (highest to lowest):
- CLI Arguments - Explicit command-line flags
- Environment Variables - Set via shell or
.envfile - TOML Configuration File - Persistent configuration
Run the CLI with a vault address and dry-run flag to preview reports without submission.
- Create
tq-oracle.tomlin project directory or~/.config/tq-oracle/config.toml - Configure vault address, network, RPC endpoints, and operational settings
- Run with minimal CLI arguments - config file is auto-detected
- See
tq-oracle.toml.examplefor complete configuration template
- Create
.envfile for environment-specific settings - Set RPC endpoints, subvault addresses, and other non-secret configuration
- Important: Always use environment variables or CLI flags for secrets (private keys, API keys) - never store them in TOML files
- Run with vault address and any additional CLI options
All configuration options can be set via CLI arguments, environment variables, or TOML config file.
| CLI Option | Environment Variable | TOML Key | Default | Description |
|---|---|---|---|---|
vault_address (argument) |
TQ_ORACLE_VAULT_ADDRESS |
vault_address |
required | Vault contract address passed as positional argument |
--config -c |
- | - | Auto-detect | Path to TOML configuration file |
--network -n |
TQ_ORACLE_NETWORK |
network |
"mainnet" |
Network to report on (mainnet, sepolia, base) |
--block-number |
TQ_ORACLE_BLOCK_NUMBER |
block_number |
Latest block | Block number to snapshot vault state |
--vault-rpc |
TQ_ORACLE_VAULT_RPC |
vault_rpc |
Network default | RPC endpoint for the selected vault network |
--dry-run/--no-dry-run |
TQ_ORACLE_DRY_RUN |
dry_run |
true |
Preview report without submitting a Safe transaction |
--ignore-empty-vault/--require-nonempty-vault |
TQ_ORACLE_IGNORE_EMPTY_VAULT |
ignore_empty_vault |
false |
Skip failure when vault holds zero assets |
--ignore-timeout-check/--enforce-timeout-check |
TQ_ORACLE_IGNORE_TIMEOUT_CHECK |
ignore_timeout_check |
false |
Skip minimum interval guard between reports |
--ignore-active-proposal-check/--enforce-active-proposal-check |
TQ_ORACLE_IGNORE_ACTIVE_PROPOSAL_CHECK |
ignore_active_proposal_check |
false |
Skip duplicate active proposal guard |
--log-level |
TQ_ORACLE_LOG_LEVEL |
log_level |
"INFO" |
Override logging verbosity (TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL) |
--show-config |
- | - | false |
Dump effective configuration (with secrets redacted) and exit |
| TOML Key | Default | Description |
|---|---|---|
max_calls |
3 |
Maximum number of RPC retry attempts |
rpc_max_concurrent_calls |
5 |
Maximum concurrent RPC connections |
rpc_delay |
0.15 |
Delay between RPC calls (seconds) |
rpc_jitter |
0.10 |
Random jitter for RPC delays (seconds) |
price_warning_tolerance_percentage |
0.5 |
Price deviation warning threshold (%) |
price_failure_tolerance_percentage |
1.0 |
Price deviation failure threshold (%) |
TQ Oracle supports configuring multiple asset adapters per subvault address, allowing you to compose TVL from various sources.
Configuration via TOML:
- Specify target subvault address
- Define which chain the subvault operates on (typically
vault_chain) - List additional adapters to run for this subvault
- Option to skip default idle balances check
- Option to skip subvault existence validation
Available Asset Adapters:
idle_balances- Checks for idle USDC balances not yet deployed
See tq-oracle-example.toml for complete configuration examples.
Run with auto-detected config file:
# Loads from tq-oracle.toml or ~/.config/tq-oracle/config.toml
tq-oracleRun with explicit vault address:
# Override vault address from config
tq-oracle 0xYourVaultAddressRun with custom config file:
tq-oracle --config path/to/custom-config.tomlRun with network override:
tq-oracle --network sepolia 0xYourVaultAddressPreview configuration without running:
tq-oracle --show-configIncrease verbosity for debugging:
tq-oracle --log-level DEBUGCommon Usage Patterns:
- Dry-run on mainnet: Preview report generation without submitting to chain
- Testnet execution: Run against testnet with Safe multi-sig for testing
- Pre-deployment testing: Test with empty vaults using ignore flags
src/tq_oracle/
├── main.py # CLI entry point (Typer)
├── settings.py # Configuration management (pydantic-settings)
├── state.py # Application state container
├── pipeline/ # Orchestration pipeline
├── domain/ # Core domain models
├── adapters/ # Protocol adapters
├── processors/ # Data processing utilities
├── report/ # Report generation and publishing
├── safe/ # Safe transaction building
├── checks/ # Pre-flight validation orchestration
└── abis/ # Contract ABIs (JSON)Before processing TVL data, TQ Oracle runs automated pre-flight validation checks to ensure data integrity:
- Safe State Validation: Ensures no duplicate or pending reports exist
- Check Retry Logic: Automatically retries failed checks with exponential backoff when recommended
- CCTP Bridge Detection (disabled): Re-enable via the checklist when cross-chain monitoring is required
These checks prevent race conditions and ensure accurate TVL snapshots by detecting ongoing cross-chain transfers that could affect asset balances. You can bypass individual guards when needed via the CLI flags --ignore-empty-vault, --ignore-timeout-check/--enforce-timeout-check, and --ignore-active-proposal-check/--enforce-active-proposal-check.
A standalone test script is available in scripts/check_cctp_inflight.py and can be used once the CCTP integration is re-enabled.
Asset adapters fetch asset holdings from specific protocols (e.g., Aave, Lido).
Quick overview:
- Create adapter file in
src/tq_oracle/adapters/asset_adapters/implementingBaseAssetAdapter - Register adapter in
src/tq_oracle/adapters/asset_adapters/__init__.py'sADAPTER_REGISTRY - Write integration tests in
tests/adapters/asset_adapters/ - Add asset addresses to
src/tq_oracle/constants.pyif needed
The adapter name in the registry is used in the [[subvault_adapters]] configuration's additional_adapters field.
Price adapters fetch USD prices for assets from price oracles (e.g., Chainlink, Pyth).
- Create adapter file in
src/tq_oracle/adapters/price_adapters/implementingBasePriceAdapter - Register adapter in
src/tq_oracle/adapters/price_adapters/__init__.py'sPRICE_ADAPTERSlist - Implement async
fetch_prices()method to query oracle and return price data - Write unit tests in
tests/adapters/price_adapters/
Note:
ChainlinkAdapteris exported for use in price validators but not used directly in the main pricing pipeline.
Price validators cross-check prices from the main price adapters against reference sources to detect anomalies or manipulation. They run after price fetching and can issue warnings or halt execution if prices deviate beyond configured thresholds.
- Create validator file in
src/tq_oracle/adapters/price_validators/implementingBasePriceValidator - Register validator in
src/tq_oracle/adapters/price_validators/__init__.py'sPRICE_VALIDATORSlist - Implement async
validate_prices()method to cross-check prices and return validation results - Configure tolerance thresholds in settings for warning and failure levels
- Write unit tests in
tests/adapters/price_validators/
Validators respect tolerance thresholds configured in settings.py:
price_warning_tolerance_percentage(default: 0.5%) - Issues warningsprice_failure_tolerance_percentage(default: 1.0%) - Halts execution
- Install dependencies: Use
uv sync --all-extrasfor development dependencies - Run tests: Execute test suite with pytest
- Lint code: Check code quality with ruff
- Format code: Apply consistent formatting with ruff format