7Block Labs
Blockchain Infrastructure

ByAUJay

Verifiable Data Feed Hardening: Multi-Source Aggregation and Failover Strategies

Why this matters now

In 2025, “verifiable data” is shifting gears from just push-only feeds to something way cooler: cryptographically provable, on-demand streams, zk/TLS attestations of Web2 data, and optimistic verification backups. This means your risk landscape has widened quite a bit. Now you’re not just relying on a single oracle vendor; you’re juggling cross-chain relays, L2 sequencers, and your own aggregation logic. The key to success lies in crafting the right architecture that seamlessly integrates these elements into a sturdy control plane, ensuring provable integrity and clear failure modes.

What “verifiable” should mean in your stack

Verifiable information needs to be testable on-chain or through formal attestations, rather than relying solely on “trusted vendors.”

  • Signed, consensus data: So, when it comes to push feeds like Chainlink Data Feeds, they take median node observations and slap on some quorum signatures in the reports. For pull-based reports, think Chainlink Data Streams, those get signed by a decentralized oracle network (DON) and then verified on-chain by a Verifier contract. Remember, it’s all about using those proofs--don’t just take a number at face value. (docs.chain.link)
  • First-party provenance: With API3 Airnode, data providers can directly sign and publish to dAPIs, cutting out the middlemen. This means you get a straightforward request-response setup with clear configurations for gas strategies and concurrency. It’s pretty neat! (airnode-docs.api3.org)
  • Confidence-aware aggregation: Pyth is doing something cool by publishing not just an aggregate price but also a confidence interval based on the prices and confidences submitted by publishers. Their aggregation algorithm is a median-of-votes approach with a touch of interquartile dispersion to help downweight those noisy sources out there. So, remember to use confidence in your controls and not just as a pretty number on the screen. (docs.pyth.network)
  • zk/TLS attestations: DECO (zkTLS) and TLSNotary are pretty slick when it comes to authenticating data from HTTPS sessions without needing any changes on the server side. While they might not completely “solve the oracle problem,” they do let you mix private Web2 data provenance with a decentralized oracle for those really important settlement actions. It’s a win-win! (blog.chain.link)

Push vs pull and where each belongs

  • Push (like Chainlink Data Feeds) gives you updates based on deviation or heartbeat, making it perfect for collateral valuation and widely used reference prices. Just remember to check updatedAt and your acceptable staleness. You can dive into more details here.
  • Pull (for instance, Pyth Pull Oracle or Chainlink Data Streams) grabs updates right when you need them, aiming for super low latency, sometimes even under a second. Pair it with on-chain verification and a commit-reveal or atomic execution approach to dodge any frontrunning issues. Get more info here.

Actionable Take

When it comes to trading and handling liquidations, stick with pull-based reads alongside on-chain verification. On the flip side, for your accounting or health checks, go for push-based feeds but make sure to set some strict staleness gates.

Multi-source aggregation: a concrete pattern that actually resists bad data

You’re looking for a way to shield yourself from both genuine noise and tricky outliers. Check out this tried-and-true approach:

  1. Normalize and validate each candidate source S:
  • Toss it out if it's outdated beyond the feed-specific Service Level Agreement (SLA):
    • For push feeds: make sure updatedAt is greater than or equal to now minus S.staleBudget.
    • For pull reports: confirm that the signed report is valid and its timestamp is within S.staleBudget.
  • If the source gives you a confidence interval (like Pyth), bump up the price you use for risk-sensitive branches by using the upper bound for long positions and the lower bound for shorts. Check out the Pyth documentation for more details!

2) Robust Combine:

  • Start by creating a vector V filled with your candidate prices.
  • Next up, let’s do some symmetric trimming: we’ll drop the highest and lowest k values, where k is roughly floor(n/5) for n ≥ 5. After that, we’ll grab the median. If a source gives you an estimated variance (or confidence), make sure to weight those by the inverse-variance when calculating a winsorized mean. If that info isn’t available, just stick with the median to keep any single feed from having too much influence. Pyth’s median-of-votes approach really backs up this lean towards using medians. You can check out more about it here.

3) Cross-check with market-structure aware fallbacks:

  • DEX TWAP guardrail: To keep things in check, you’ll want to query the Uniswap v3 TWAP over a minimum of 30 minutes. This helps you catch any alerts or clamp down on those wild price spikes. Remember, TWAP isn’t your go-to price, but it serves as a sanity check and is tough to manipulate over that stretch of time. Check it out here: (blog.uniswap.org)

4) Publish a “Decision Record”:

  • Make sure to save the participating sources, the trimmed set, the final statistics, and a staleness snapshot. This is super important for auditing and handling any incidents that come up. It’ll help you show that the decision came from your control logic and not some vendor.

Tip: If your protocol needs to operate in one transaction, go ahead and fetch a pull-based report (like Data Streams or a Pyth update), check it on-chain, and then apply your aggregation logic. If that's not the case, you can pre-stage your updates using Automation or Keepers and read the aggregated value synchronously. (docs.chain.link)

Vendor selection: mixing push, pull, first-party, and programmable oracles

  • Chainlink Data Feeds (push): These guys are pretty mature and cover a wide range of assets. Just keep an eye on deviation and heartbeat for each asset, and don’t forget to integrate those L2 Sequencer Uptime Feeds for your rollups (you can check out the failover details). (docs.chain.link)
  • Chainlink Data Streams (pull): With sub-second updates and commit-reveal capabilities, these streams are awesome. Make sure to verify reports on-chain using the Verifier contract. They're perfect for perpetuals, auctions, or running safety checks on AMMs when things get intense. (docs.chain.link)
  • Pyth (pull): If you need on-demand updates along with confidence intervals, Pyth has your back. They use Wormhole VAAs for cross-chain delivery, so you can update on-chain just-in-time and verify that the message signed by the guardian is all good. (docs.pyth.network)
  • API3 Airnode/dAPIs (first-party): Get direct signatures from data providers with these! They even support OEV auctions for liquidation-aligned updates, which can help recapture value for your protocol. (airnode-docs.api3.org)
  • Switchboard (programmable): Want to build custom aggregators? This is the place to do it! You can set parameters for min responses and staleness, plus incorporate other oracles. On Solana, using bundles/quotes can help you avoid write locks and verify Ed25519 signatures with around 485 compute units. They also support TEE-backed attestation paths. (docs.switchboard.xyz)

Practical rule: Make sure your top tier has at least one push, one pull, and one programmable/first-party path.

Failover: design for what breaks in the real world

1) L2 Sequencer Downtime

  • For Optimistic and ZK rollups, it’s a good idea to hook up Chainlink's L2 Sequencer Uptime Feeds. If the sequencer goes down, pause any risky actions like liquidations or minting. Then, kick off a grace timer (maybe around 30 to 60 minutes) to ensure everything's sorted out before any user-impacting transactions get replayed. This way, we can avoid “unfair” liquidations, where only those savvy with Layer 1 can make a move. Check out more details here.

2) Cross-chain relay delays

  • When you’re using Pyth through Wormhole, make sure your on-chain consumer checks the guardian-signed VAA and sets a max-age for the VAAs it’ll accept. If that age is exceeded, it’s a good idea to switch to another source or implement a TWAP safeguard until you get a fresh update. Hermes is great for streaming the latest Merkle-root-backed updates, so consider using it in your off-chain updaters and caching those VAAs. Check out the details here!
  1. Vendor Outage or Mispricing
  • The active-active aggregation we mentioned earlier is designed to handle any single-source failures without a hitch. Plus, here are a couple of extra tips:
    • Set up “last good price” rules: If all your sources go stale beyond a certain point, just freeze the price to the last good one and automatically bump up collateral factors and fees.
    • For those rare, tricky situations where a subjective dispute pops up (like wondering if an event actually happened), you can trigger UMA OOV3 assertions. Just make sure to set the bonds and liveness based on the potential payout; usually, liveness ranges from 2 hours to 2 days, while DVM sorts out disputes in about 2-4 days. Check out more details in the UMA docs.

4) Market Hours and Maintenance Windows

  • It's best not to read equity or FX feeds when the markets are closed. Luckily, both Chainlink and Pyth provide market-hours metadata, so you can set up schedules. This way, your protocol will know when a feed should be silent and can adjust risk buffers accordingly. Check out more details in the documentation.

Confidence intervals are a control input, not a UI garnish

If a feed puts out a price and confidence level (like Pyth does), think of that confidence as a sort of “volatility meter.”

  • When it comes to liquidations, think about using price −/+ confidence for a more cautious approach to valuation.
  • In fast-moving markets or fragmented platforms, confidence can vary widely: adjust collateral factors and slippage tolerances on the fly.
  • For mark-to-market, make sure to log both the price and the confidence level. This way, your audit trail matches up with real market fluctuations instead of giving the illusion of precision. (docs.pyth.network)

Concrete build: a reference aggregator

Here’s a quick outline we usually kick things off with, before we tailor it to fit each client’s needs:

  • Sources

    • S1: Chainlink Data Feed (push)
    • S2: Pyth (pull, confidence-aware)
    • S3: API3 dAPI (first-party)
    • S4: Switchboard custom aggregator that mixes exchange APIs with Pyth/Chainlink mirrors (just to keep things redundant)
    • S5: Uniswap v3 30m TWAP (just a guardrail) (docs.chain.link)
  • Validation per source

    • Make sure to verify signatures for pull reports.
    • Staleness budgets: for push = min(heartbeat, deviation cadence) + jitter; for pull = ≤ 3s; and for TWAP = observation window + 1 block. (docs.chain.link)
  • Aggregation

    • Start by creating a candidate set using S1 through S4; make sure to toss out any that don't pass the staleness or signature checks. Then, go ahead and apply k=1 trimming and median.
    • If you've got S2 (Pyth) in the mix, add some annotations with σ=confidence, and calculate the risk price using median ± max(confidence-padded deltas).
    • If you’re left with no solid candidates, take a look at the TWAP, adjust those action thresholds, and switch to “degraded mode.”
  • L2 Awareness

    • If you’re using OP, Arbitrum, or Base, make sure to keep an eye on the Sequencer Uptime Feed. If it’s down or just coming back up during the grace period, hold off on any price-triggered liquidations and big leverage moves. You can find more info on this here.
  • Dispute escalation

    • For unusual prints that might involve 7- or 8-figure amounts, make sure to assert to UMA OOV3 with a bond set at X bps of the at-risk TVL, and liveness should be between 2 hours and 48 hours. (docs.uma.xyz)

Pseudo-implementation sketch (Solidity-like):

contract Example {
    uint public value;

    constructor(uint initialValue) {
        value = initialValue;
    }

    function setValue(uint newValue) public {
        value = newValue;
    }

    function getValue() public view returns (uint) {
        return value;
    }
}

Key features:

  • State Variable: We've got a public variable value that keeps track of our number.
  • Constructor: The constructor takes an initial value to set the state variable when the contract is created.
  • Set Value Function: This function lets us update the value whenever we need to.
  • Get Value Function: This function allows us to retrieve the current value of value.

Usage:

  1. Deploy the contract with an initial value.
  2. Call setValue to update it.
  3. Use getValue to see what’s currently stored.

Feel free to play around with it!

function resilientPrice(bytes32 assetId) external returns (int256 px, uint256 ts) {
  // 1) Rollup safety
  require(sequencerIsUpAndGracePassed(), "L2 sequencer down");

  // 2) Gather candidates
  Candidate[] memory c = new Candidate[](4);
  c.push(readChainlink(assetId));    // validates updatedAt vs heartbeat/deviation
  c.push(verifyAndReadPyth(assetId)); // verifies VAA; returns price + confidence
  c.push(readAPI3(assetId));         // verifies dAPI beacons
  c.push(readSwitchboard(assetId));  // respects minResponses, maxStaleness

  // 3) Filter + trim
  Candidate[] memory ok = filterFreshAndSigned(c);
  require(ok.length >= 2, "insufficient fresh sources");
  int256 medianPx = trimmedMedian(ok, /*k=*/1);

  // 4) Confidence-aware risk guard
  int256 riskPx = applyConfidenceGuards(medianPx, ok); // widen by max sigma if relevant

  // 5) Degraded path
  if (needsDegrade(ok)) {
    int256 twap = readUniswapTWAP(assetId, 30 minutes); // guardrail
    return (min(riskPx, twap), block.timestamp);
  }

  return (riskPx, block.timestamp);
}

Notes:

  • The Switchboard aggregator is super handy for tweaking Min Responses, Sample Size, and Max Staleness--definitely make use of these settings! (docs.switchboard.xyz)
  • If you're on Solana, go for Switchboard’s bundles/quotes; they skip write locks and verify Ed25519 without breaking the bank. These are perfect for those compute-heavy programs. (docs.switchboard.xyz)
  • When it comes to Pyth, remember to update on read; make sure to verify the Wormhole VAA and check the price “schedule” so you’re in sync with market hours. (docs.pyth.network)

Bringing Web2 data on-chain without giving up provenance

When you're looking for account balances, NAVs, or audit flags from Web2, here’s what you need to keep in mind:

  • zkTLS proofs (like DECO and TLSNotary) help you get verified, low-key insights from HTTPS sessions. You can use them for things like KYC access, proof-of-funds, or compliance checks. Just pair them with an on-chain oracle to handle disputes and dish out rewards for good behavior. Check it out here: (blog.chain.link)
  • When it comes to NAVs and single-source RWAs where there's no market, make sure to maintain cryptographic continuity. This means every update needs to link back to the last one (using a sequence number plus the previous signature hash). Stick to a strict signer policy and set re-sign intervals to keep things fresh. Some recent projects have really nailed this down for tokenized assets. Learn more here: (blog.redstone.finance)

Operations: SLOs, monitoring, chaos drills

Sure! Here’s a casual take on that:

Bake these into your runbooks:

  • Automate wherever you can: Set up scripts to handle repetitive tasks. This saves you time and reduces the chance for errors.
  • Document everything: Keep detailed notes on your processes. This is super helpful for anyone who might pick up your work later.
  • Stay updated: Make sure to regularly check for updates on tools and technologies you use. Staying in the loop keeps everything running smoothly.
  • Create a troubleshooting guide: Anticipate common issues and document how to fix them. It'll save you a lot of headaches down the road.
  • Review and revise: Regularly go back to your runbooks and make sure everything’s still accurate and relevant. This keeps your team on the same page.
  • Encourage feedback: Ask your team for their input on the runbooks. They might have suggestions that can make things even better.

Keep these tips in mind to ensure your runbooks are always handy and effective!

  • SLOs per feed: We’re aiming for some specific targets here. For staleness, we want to keep pushes to less than or equal to heartbeat + 2 blocks and pulls to a max of 2 seconds. Also, let’s keep an eye on the max jitter and ensure we have a good number of concurrent sources up and running.
  • Alert matrix:

    • Immediate Alerts: We need to jump on things like signature verification failures, any crazy confidence spikes beyond Xσ, and if we’re diverging from the median by more than Y bps.
    • Within 1 Minute Alerts: We should also be on the lookout if the sequencer goes down, if we see the relay backlog growing, or if we’re missing heartbeats.
  • Chaos testing: Let’s spice things up a bit! Take down one vendor for 24 hours, block the L2 sequencer, throw in some outlier prints, delay those cross-chain VAAs, and make sure our protocol can handle these situations gracefully.
  • Postmortem-friendly logs: It’s crucial to keep a “decision record” and a history of our confidence levels. This will help us explain any liquidations or pauses to users and auditors when needed.

Emerging best practices we recommend adopting in 2025

  • Make sure to include sequencer-aware circuit breakers on all L2s you support; really, don’t ship without them. (docs.chain.link)
  • Use confidence-driven risk knobs: automatically bump up collateral and slippage buffers when confidence increases (thanks, Pyth!) or as market hours wrap up. (docs.pyth.network)
  • Implement OEV recapture for liquidation flows, so updates happen right when they’re needed, and the value goes back to the protocol, not just to the searchers. (blog.api3.org)
  • Mix it up with push, pull, and programmable options: relying on a single vendor isn’t a great strategy. Get creative with programmable oracles (like Switchboard) to blend together Chainlink, Pyth, API3, and your own exchange APIs with your personalized thresholds. (docs.switchboard.xyz)
  • Think of TWAP as a guardrail, not your main source; aim for a window of at least 30 minutes to make those attacks less appealing, and if you have to lean more on DEX data, consider using time-weighted medians or winsorization. (blog.uniswap.org)

Quick checklist

  • Make sure to have at least three independent sources--think push, pull, and programmable/first-party types.
  • Incorporate confidence- and schedule-aware controls.
  • Implement L2 Sequencer Uptime gating along with a grace period.
  • Set up a TWAP guardrail of at least 30 minutes; it should never be the sole source of price info.
  • Ensure UMA OOV3 is ready for those tricky subjective or disputed cases, complete with context-appropriate bonds and liveness.
  • Focus on observability: keep an eye out for staleness, divergence, confidence levels, and signature verification alerts.
  • Have a documented degraded-mode policy that includes last-good-price logic.

Where 7Block Labs can help

We create, set up, and rigorously test resilient data planes for exchanges, perpetual contracts, lenders, and real-world asset platforms--usually in less than eight weeks! If you’re looking for a multi-source aggregator that includes cryptographic verification, failover that’s aware of sequencers, risk controls driven by confidence, and thoroughly audited runbooks, we’ll handle the whole process from start to finish.

Sources and Further Reading:

  • Dive into the Chainlink Data Feeds and learn all about their architecture, verification, and some best practices. Check it out here.
  • Get the lowdown on the Pyth pull oracle model, including cross-chain transport, price aggregation, and how confidence is used. You can find more details here.
  • Explore the ins and outs of Uniswap v3 oracle mechanics, especially the economics behind TWAP manipulation. Everything you need is right here.
  • Check out the UMA Optimistic Oracle v3 to understand liveness, bonding, and DVM resolution timelines. You can learn more here.
  • Don’t miss the info on Chainlink L2 Sequencer Uptime Feeds and how they handle outages by visiting this link: here.
  • Get acquainted with API3 Airnode/dAPIs and the OEV recapture model. It’s all laid out for you here.
  • Lastly, dig into Switchboard aggregators, Solana bundles/quotes, and TEE-backed attestations. Find the details here.

If you're looking for a reference implementation that's perfectly tailored to your specific assets and chains, just give us a shout--we'll provide you with a robust aggregator and a failover strategy that you can actually verify, instead of just taking our word for it.

Like what you're reading? Let's build together.

Get a free 30-minute consultation with our engineering team.

7BlockLabs

Full-stack blockchain product studio: DeFi, dApps, audits, integrations.

7Block Labs is a trading name of JAYANTH TECHNOLOGIES LIMITED.

Registered in England and Wales (Company No. 16589283).

Registered Office address: Office 13536, 182-184 High Street North, East Ham, London, E6 2JA.

© 2026 7BlockLabs. All rights reserved.