Skip to content

Conversation

@timbrinded
Copy link
Collaborator

@timbrinded timbrinded commented Oct 24, 2025

Changes

  • Add Base network support: Added BASE_ASSETS constants and vault deployment configuration for Base mainnet
  • Refactor network terminology: Renamed 'l1' references to 'vault' to clarify that it represents the network where the vault is deployed (not necessarily Ethereum L1)
  • Fix wstETH pricing for L2 deployments: wstETH adapter now always queries Ethereum mainnet for pricing, regardless of vault deployment network
    • Added eth_mainnet_rpc configuration option for L2 deployments
    • Falls back to public RPC if not configured (with warning)
    • Added disclaimer about stETH/ETH depeg risk assumptions
  • Fix private key handling: Resolved issues with private key configuration parsing
  • Update tests: Fixed and updated test suite to handle Base network and new pricing logic

Technical Details

The wstETH adapter now distinguishes between:

  • Vault network (where assets are deployed)
  • Mainnet (where wstETH contract is queried for pricing)

This enables accurate wstETH pricing for vaults deployed on L2s like Base while maintaining the canonical wstETH exchange rate from mainnet.

timbrinded and others added 29 commits October 21, 2025 16:03
* refactor: ♻️ big refactor

* refactor: ♻️ Tidy

* docs: 📝 update readme

* refactor: ♻️ pr comments
* feat: add validation for asset prices in total_assets calculation (#35)

* feat: add validation for asset prices in total_assets calculation

- Implemented checks for invalid prices (<= 0) in the calculate_total_assets function.
- Added error handling to raise ValueError with details of invalid prices.
- Introduced a new test to ensure that invalid prices trigger the appropriate exception.

* refactor: turn invalid prices computation into list comprehension

* feat: add price validation for price adapter (#36)

* fix: update WstETHAdapter and tests to set ETH base asset price to 1

- Changed the base asset price for ETH in WstETHAdapter from 0 to 1 to ensure accurate pricing.
- Updated related tests to verify that the ETH price is now correctly set to 1 instead of 0.
- Adjusted documentation to clarify the base asset pricing behavior.

* feat: add price validation to BasePriceAdapter

* refactor: change validate_prices method to synchronous in price adapters

- Updated the validate_prices method in BasePriceAdapter to be synchronous instead of asynchronous.
- Adjusted calls to validate_prices in ChainlinkAdapter, CowSwapAdapter, and WstETHAdapter accordingly.

* feat: add TypedDict for network addresses in constants.py

* feat: add NetworkAddresses instances

* refactor: rename NetworkAddresses to NetworkTokens and update address constants

* feat: add network configuration and asset retrieval to OracleCLIConfig

* refactor: update WstETHAdapter to use dynamic asset addresses from config

* refactor: enhance WstETHAdapter to enforce required ETH address and simplify checks

* refactor: update CowSwapAdapter to use dynamic asset addresses and improve network configuration

* refactor: update ChainlinkAdapter to use dynamic asset addresses from config and enforce required ETH address

* refactor: update IdleBalancesAdapter to use dynamic asset addresses from config and enforce required ETH and USDC addresses

* refactor: remove optional asset address attributes from Chainlink, CowSwap, and WstETH adapters

* refactor: enforce required USDC address in HyperliquidAdapter and update asset address retrieval from config

* refactor: update Chainlink test suite to use dynamic asset addresses from config

* refactor: update WstETHAdapter tests to utilize dynamic asset addresses from config

* refactor: enhance HyperliquidAdapter tests to utilize dynamic USDC addresses from config

* refactor: update tests to utilize dynamic asset addresses from config for improved consistency

* refactor: update Chainlink and CowSwap tests to utilize dynamic asset addresses from config for improved consistency

* refactor: update Chainlink tests to include dynamic ETH address in price fetching for USDT and USDS on testnet

* refactor: update import paths from config to settings in CowSwap and Hyperliquid test files
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Copilot AI review requested due to automatic review settings October 24, 2025 11:18
@timbrinded timbrinded changed the title Fix/base support fix: 🛠️ Add Base Support Oct 24, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements comprehensive configuration management, Base network support, and modular asset adapter infrastructure for the TQ Oracle system.

Key Changes:

  • Migrated from dataclass-based config to Pydantic Settings with multi-source configuration precedence (CLI > ENV > TOML)
  • Added Base network support with network-specific asset mappings
  • Restructured asset adapters to support per-subvault configuration and multi-chain operation
  • Refactored orchestration into modular pipeline stages (preflight, assets, pricing, report)

Reviewed Changes

Copilot reviewed 49 out of 51 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/tq_oracle/settings.py New Pydantic-based settings with TOML/ENV/CLI precedence and network-specific derivations
src/tq_oracle/state.py Application state container replacing global config
src/tq_oracle/constants.py Network-specific asset mappings for mainnet/sepolia/base
src/tq_oracle/main.py Restructured CLI with callback-based initialization and settings injection
src/tq_oracle/pipeline/ Modular pipeline stages replacing monolithic orchestrator
src/tq_oracle/adapters/asset_adapters/ Chain-aware adapters with registry and per-subvault configuration
tests/ Updated tests to use OracleSettings instead of OracleCLIConfig
tq-oracle-example.toml Example configuration file demonstrating new TOML-based config

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 91 to 92
# Always sets the base asset to price 0
if prices.base_asset in prices.prices:
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 89 is misleading as it refers to setting the base asset price but appears above the sorting logic. Move this comment directly above line 90-91 where the base asset price is actually set, and keep the sorting comment on line 92 where it belongs.

Suggested change
# Always sets the base asset to price 0
if prices.base_asset in prices.prices:
if prices.base_asset in prices.prices:
# Always sets the base asset to price 0

Copilot uses AI. Check for mistakes.
Comment on lines 56 to 58
(SEPOLIA_ASSETS.get("USDC"), 6),
(ETH_MAINNET_ASSETS.get("USDT"), 6),
(ETH_MAINNET_ASSETS.get("USDS"), 18),
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TOKEN_DECIMALS dictionary construction filters out None addresses but doesn't include Base network assets. This creates an inconsistency where Base network USDC/USDT/USDS addresses won't be found in TOKEN_DECIMALS, potentially causing runtime errors. Add Base network assets to the list comprehension for completeness.

Suggested change
(SEPOLIA_ASSETS.get("USDC"), 6),
(ETH_MAINNET_ASSETS.get("USDT"), 6),
(ETH_MAINNET_ASSETS.get("USDS"), 18),
(SEPOLIA_ASSETS.get("USDC"), 6),
(BASE_ASSETS.get("USDC"), 6),
(ETH_MAINNET_ASSETS.get("USDT"), 6),
(BASE_ASSETS.get("USDT"), 6),
(ETH_MAINNET_ASSETS.get("USDS"), 18),
(BASE_ASSETS.get("USDS"), 18),

Copilot uses AI. Check for mistakes.
Comment on lines +96 to +99
addr
for addr in asset_addresses
if addr.lower() == self.wsteth_address.lower()
)
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next() call will raise StopIteration if no matching address is found in asset_addresses. Since this code is only reached when has_wsteth is True (which checks if wsteth_address is in asset_addresses_lower), this should theoretically be safe. However, add a default value or explicit check to prevent potential edge cases where case sensitivity mismatches could cause runtime errors.

Suggested change
addr
for addr in asset_addresses
if addr.lower() == self.wsteth_address.lower()
)
(addr for addr in asset_addresses if addr.lower() == self.wsteth_address.lower()),
None
)
if wsteth_addr_actual is None:
raise ValueError(
f"wstETH address {self.wsteth_address} found in asset_addresses_lower but not in asset_addresses. "
"This may be due to a case sensitivity mismatch."
)

Copilot uses AI. Check for mistakes.
if key in body:
raise ValueError(
f"Security violation: '{key}' found in TOML config file. "
f"Secrets must only be provided via environment variables or CLI flags."
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The security check prevents secrets in TOML files, which is good practice. However, the error message could be more actionable by specifying the exact environment variable name format (e.g., 'Use TQ_ORACLE_PRIVATE_KEY environment variable instead').

Suggested change
f"Secrets must only be provided via environment variables or CLI flags."
f"Use the '{OracleSettings.model_config['env_prefix']}{key.upper()}' environment variable instead."

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings October 24, 2025 12:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 30 out of 30 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copilot AI review requested due to automatic review settings October 24, 2025 13:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copilot AI review requested due to automatic review settings October 24, 2025 14:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@timbrinded timbrinded marked this pull request as ready for review October 24, 2025 14:38
@timbrinded timbrinded merged commit 76df7a7 into master Oct 25, 2025
6 checks passed
@timbrinded timbrinded deleted the fix/base-support branch October 25, 2025 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants