Skip to content

RAAC crvUSD to USD Oracle

Overview

The CrvUSDToUSDOracle is a robust, multi-tiered price oracle that provides the crvUSD/USD exchange rate for the RAAC protocol. It implements a sophisticated fallback mechanism to ensure price availability even during oracle failures, with built-in circuit breakers to protect against depeg events.

The oracle uses a three-tier fallback system:

  1. Primary: Direct Chainlink crvUSD/USD feed
  2. Secondary: ETH/USD + ETH/crvUSD (Curve TriCRV pool)
  3. Tertiary: Hard-coded fallback price

Non-Reverting Design

The oracle is designed to never revert on price queries. Instead, it gracefully falls back through multiple price sources to ensure continuous operation of the protocol.


Architecture

flowchart TD
    A[Price Query] --> B{crvUSD/USD Feed Available?}
    B -- Yes --> C{Price Fresh?<br/>< 1 day + 1 hour}
    C -- Yes --> D[Return crvUSD/USD Price<br/>Level 0]
    C -- No --> E{ETH/USD + Curve Available?}
    B -- No --> E

    E -- Yes --> F{ETH Price Fresh?<br/>< 1 hour + 10 min}
    F -- Yes --> G[Calculate: ETH/USD ÷ ETH/crvUSD<br/>Level 1]
    F -- No --> H[Return Fallback Price<br/>Level 2]
    E -- No --> H

    D --> I[Apply Circuit Breaker]
    G --> I
    H --> I
    I --> J[Return Final Price]

    style D fill:#d9f0d3
    style G fill:#fff2cc
    style H fill:#f4cccc

Fallback Levels

Level Source Description Staleness Check
0 Chainlink crvUSD/USD Direct price feed from Chainlink 1 day + 1 hour
1 ETH/USD + ETH/crvUSD Chainlink ETH/USD × Curve TriCRV ETH/crvUSD 1 hour + 10 minutes
2 Hard-coded fallback Protocol-set fallback price (default: $1.00) N/A

Purpose

  • Price Conversion: Convert crvUSD prices to USD for house price calculations
  • Reliability: Ensure price availability through multiple fallback mechanisms
  • Depeg Protection: Circuit breaker prevents extreme price deviations
  • Protocol Integration: Seamless integration with RAACHousePrices for price conversion

Key Features

Multi-Tier Fallback System

The oracle implements a sophisticated three-tier fallback mechanism:

  1. Primary Source: Chainlink crvUSD/USD feed on Arbitrum
  2. Secondary Source: Chainlink ETH/USD feed combined with Curve TriCRV pool ETH/crvUSD price
  3. Tertiary Source: Hard-coded fallback price (configurable by owner)

Circuit Breaker Protection

flowchart LR
    A[Raw Price] --> B{Circuit Breaker Enabled?}
    B -- No --> C[Return Raw Price]
    B -- Yes --> D{Price < Min Threshold?}
    D -- Yes --> E[Return Min Threshold<br/>0.9 USD]
    D -- No --> F{Price > Max Threshold?}
    F -- Yes --> G[Return Max Threshold<br/>1.1 USD]
    F -- No --> C

    style E fill:#f4cccc
    style G fill:#f4cccc
    style C fill:#d9f0d3
  • Default thresholds: 0.9 USD (min) to 1.1 USD (max)
  • Configurable: Owner can adjust thresholds or disable circuit breaker
  • Depeg protection: Prevents extreme price deviations during market stress

Price Sources

Secondary: ETH/USD + Curve TriCRV


Key Functions

Price Queries

Function Description Returns
getLatestPrice() Full price data with fallback level (price, timestamp, fallbackLevel)
getPrice() Simple price query uint256 price
decimals() Price decimals (always 18) uint8

Configuration (Owner Only)

Function Description Parameters
setCrvUSDDataFeed(address) Set Chainlink crvUSD/USD feed _crvUSDDataFeed
setEthDataFeed(address) Set Chainlink ETH/USD feed _ethDataFeed
setCurveOracle(address) Set Curve TriCRV oracle _curveOracle
setMaxStableStaleTime(uint256) Set crvUSD feed staleness limit _maxStableStaleTime
setMaxUnstableStaleTime(uint256) Set ETH feed staleness limit _maxUnstableStaleTime
setFallbackPriceInUSD(uint256) Set hard-coded fallback price _fallbackPriceInUSD
setCircuitBreakerConfig(bool, uint256, uint256) Configure circuit breaker enabled, minThreshold, maxThreshold
setK(uint256) Set Curve pool token index _K

Fallback Logic Details

// Check if crvUSD/USD feed is available and fresh
if (address(crvUSDDataFeed) != address(0)) {
    (, int256 answer, , uint256 updatedAt, ) = crvUSDDataFeed.latestRoundData();
    if (answer > 0 && block.timestamp - updatedAt <= maxStableStaleTime) {
        return normalizeTo18Decimals(uint256(answer), crvUSDDataFeed.decimals());
    }
}

Level 1: ETH/USD + Curve Calculation

// Calculate crvUSD/USD = ETH/USD ÷ ETH/crvUSD
uint256 ethPriceInUSD = normalizeTo18Decimals(ethAnswer, ethDataFeed.decimals());
uint256 ETHPriceInCrvUSD = curveOracle.price_oracle(K);
uint256 crvUSDPriceInUSD = (ethPriceInUSD * 10**18) / ETHPriceInCrvUSD;

Level 2: Hard-coded Fallback

// Return protocol-set fallback price
return fallbackPriceInUSD; // Default: 1e18 (1.00 USD)

Circuit Breaker Configuration

Default Settings

  • Enabled: true
  • Min Threshold: 0.9e18 (0.90 USD)
  • Max Threshold: 1.1e18 (1.10 USD)

Circuit Breaker Logic

function _clampCircuitBreaker(uint256 price) internal view returns (uint256) {
    if (!circuitBreakerEnabled) return price;

    if (price < minPriceThreshold) return minPriceThreshold;
    if (price > maxPriceThreshold) return maxPriceThreshold;
    return price;
}

Integration with RAACHousePrices

The oracle is integrated with RAACHousePrices for price conversion:

// In RAACHousePrices.getLatestPrice()
uint256 usdPrice = tokenToHousePrice[_tokenId];
uint256 crvUSDPrice = (usdPrice * 10**crvUSDToUSDOracle.decimals()) / crvUSDToUSDOracle.getPrice();

This ensures house prices stored in USD are properly converted to crvUSD for protocol calculations.


Operational Considerations

Monitoring

  • Monitor fallback level usage to detect oracle issues
  • Track circuit breaker activations during market stress
  • Ensure all price feeds remain healthy and updated

Emergency Procedures

  • Oracle Failure: System automatically falls back to secondary/tertiary sources
  • Depeg Event: Circuit breaker clamps prices within safe thresholds
  • Feed Staleness: Automatic fallback to fresher sources

Owner Responsibilities

The owner must ensure all oracle addresses are correctly configured and monitor the system for proper operation. Incorrect configuration could lead to stale or incorrect prices.