Oracle contracts
The contracts for price feeds, strategy scoring, and Guardian and Validator selection.
Addresses (Base Sepolia)
| Contract | Address | Purpose |
|---|---|---|
| OracleRegistry | to be published | Oracle node registration |
| PriceOracle | to be published | Asset price feeds |
| StrategyOracle | to be published | Strategy performance data |
| GuardianWorkloadManagerV2 | to be published | Guardian selection lottery |
| ValidatorFulfillmentManager | 0x8b6f112178bAC1a8968B12C292B0B2A123eE42D2 | Validator selection |
Verified addresses are published on Basescan (Base Sepolia) as they are confirmed. The remaining entries will be filled in on publication.
OracleRegistry
Manages the registration and reputation of Oracle nodes.
Key functions
// Register as oracle node
function registerOracle(
bytes32 nodeId,
string calldata endpoint,
uint256 stake
) external returns (bool);
// Update oracle reputation
function updateReputation(
bytes32 nodeId,
int256 delta,
string calldata reason
) external onlyRole(ADMIN_ROLE);
// Get oracle info
function getOracle(bytes32 nodeId) external view returns (OracleInfo memory);
Events
event OracleRegistered(bytes32 indexed nodeId, address indexed operator, uint256 stake);
event OracleDeregistered(bytes32 indexed nodeId, address indexed operator);
event ReputationUpdated(bytes32 indexed nodeId, int256 delta, uint256 newScore);
PriceOracle
Provides price feeds for the assets the protocol uses.
Chainlink integration
Planned. Chainlink VRF, price feeds and Automation are not live on Base Sepolia yet.
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract PriceOracle {
mapping(address => AggregatorV3Interface) public priceFeeds;
function getPrice(address asset) external view returns (uint256) {
AggregatorV3Interface feed = priceFeeds[asset];
(, int256 price,,,) = feed.latestRoundData();
return uint256(price);
}
}
Supported assets
| Asset | Feed Address | Decimals |
|---|---|---|
| ETH/USD | to be published | 8 |
| NODR/USD | to be published | 8 |
| USDC/USD | to be published | 8 |
StrategyOracle
Records and validates strategy performance metrics.
Key functions
// Submit strategy score (Oracle nodes only)
function submitScore(
bytes32 strategyId,
uint256 score,
bytes calldata proof
) external onlyRole(ORACLE_ROLE);
// Get aggregated score
function getStrategyScore(bytes32 strategyId) external view returns (
uint256 score,
uint256 confidence,
uint256 lastUpdate
);
Commit-reveal scheme
Scores use commit-reveal to prevent front-running:
// Phase 1: Commit hash
function commitScore(bytes32 strategyId, bytes32 commitment) external;
// Phase 2: Reveal score
function revealScore(
bytes32 strategyId,
uint256 score,
bytes32 salt
) external;
GuardianWorkloadManagerV2
Selects Guardian nodes for strategy validation. Selection uses keccak(timestamp, prevrandao, nonce). It does not use Chainlink VRF. VRF selection is planned.
Selection process
- A strategy needs Guardian review
- The contract derives a random seed from
keccak(timestamp, prevrandao, nonce) - Guardians are selected from that seed
- Guardian nodes vote on the backtest results
Key functions
// Request Guardian selection
function requestGuardianSelection(
bytes32 strategyId,
uint256 validationLevel
) external returns (uint256 requestId);
// Get selected Guardians
function getSelectedGuardians(uint256 requestId) external view returns (
address[] memory guardians,
uint256[] memory weights
);
ValidatorFulfillmentManager
Selects Validator nodes for ERC-7540 fulfillment operations.
Key functions
// Register vault for fulfillment
function registerVault(
address vault,
uint256 fulfillmentDelay
) external onlyRole(ADMIN_ROLE);
// Request validator selection for fulfillment
function requestFulfillment(
address vault,
uint256 requestId,
FulfillmentType fulfillmentType
) external returns (uint256 selectionId);
// Execute fulfillment (selected validator only)
function executeFulfillment(
uint256 selectionId
) external onlySelectedValidator(selectionId);
Events
event ValidatorSelected(
uint256 indexed selectionId,
address indexed validator,
address indexed vault,
uint256 requestId
);
event FulfillmentExecuted(
uint256 indexed selectionId,
address indexed validator,
bool success
);
Oracle manipulation protection
- Multiple oracles: Scores aggregated from multiple sources
- Outlier detection: Extreme values filtered
- Time weighted average: Prevents flash manipulation
- Reputation slashing: Bad actors lose stake
Integration example
import { ethers } from'ethers';
import { PriceOracleABI } from'@noderr/sdk/abis';
const priceOracle = new ethers.Contract(
PRICE_ORACLE_ADDRESS,
PriceOracleABI,
provider
);
// Get ETH priceconst ethPrice = await priceOracle.getPrice(ETH_ADDRESS);
console.log(`ETH Price: $${ethPrice / 1e8}`);
Last updated: June 2026