Skip to main content

Usage Guide

Download the Solidity interface and save it as ICfbVerifier.sol alongside your consumer contract.

The example below shows the workflow of using a verified value to settle a financial contract. Your application should keep the verifier proxy address, required feed ID and freshness limit in application configuration. Do not take these settings from the caller submitting an observation.

pragma solidity ^0.8.24;

import {ICfbVerifier} from "./ICfbVerifier.sol";

abstract contract OracleConsumer {
ICfbVerifier private immutable cfbVerifier;
bytes32 private immutable expectedFeedIdHash;
uint64 private immutable maxAgeMillis;

error IncorrectFeedId(string actualFeedId);
error UnsupportedVerifierVersion(uint8 version);
error FailedValidation();

constructor(address verifierProxy, string memory requiredFeedId, uint64 maximumAgeMillis) {
cfbVerifier = ICfbVerifier(verifierProxy);
expectedFeedIdHash = keccak256(bytes(requiredFeedId));
maxAgeMillis = maximumAgeMillis;
}

function settleContract(
uint64 contractId,
ICfbVerifier.ExpectedValue calldata expectedValue,
bytes calldata payload,
bytes calldata signature
) internal {
if (keccak256(bytes(expectedValue.feedId)) != expectedFeedIdHash) {
revert IncorrectFeedId(expectedValue.feedId);
}
try cfbVerifier.verifyValue(expectedValue, payload, signature, maxAgeMillis)
returns (ICfbVerifier.VerifiedValue memory verifiedValue)
{
if (verifiedValue.version != 1) {
revert UnsupportedVerifierVersion(verifiedValue.version);
}
settleContractWithVerifiedValue(contractId, verifiedValue.negative, verifiedValue.magnitude);
} catch {
revert FailedValidation();
}
}

function settleContractWithVerifiedValue(uint64 contractId, bool negative, uint128 magnitude)
internal virtual;
}

Supply expectedValue, payload and signature from the same API response's verification.cfbDaV1Value object. See verifyValue for the argument definitions and freshness limits.