Skip to content
Security
Skill

/oracle-redundancy

Detect oracle fallback and redundancy failure modes (distinct from price manipulation) — single point of failure, missing staleness/heartbeat/deviation checks, an "all oracles down" path that reverts or silently returns stale/zero, missing L2 sequencer-uptime feed, and absent

From plugin
rugproof
1152 skills23 agents45 commands4 hooks

Claude Code

$ npx -y skills add omermaksutii/RugProof --skill oracle-redundancy --agent claude-code

SKILL.md

oracle-redundancy.SKILL.md
name: oracle-redundancy
description: Detect oracle fallback and redundancy failure modes (distinct from price manipulation) — single point of failure, missing staleness/heartbeat/deviation checks, an "all oracles down" path that reverts or silently returns stale/zero, missing L2 sequencer-uptime feed, and absent circuit breakers. Activate whenever code reads a price/rate feed, especially Chainlink latestRoundData, with fallbacks or on an L2.

Oracle redundancy detection

When this applies

Trigger on any of:

  • `latestRoundData()` / `latestAnswer()` reads from Chainlink or any push feed
  • Custom oracle aggregators with primary + fallback sources
  • L2 deployments reading any price feed (Arbitrum, Optimism, Base, etc.)
  • Rate/price reads that gate borrowing, liquidation, minting, or redemption
  • Any "if primary fails, use secondary" branching

Detection patterns

Missing staleness / heartbeat check (HIGH)

(, int256 price,,,) = feed.latestRoundData();   // ignores updatedAt & answeredInRound
require(price > 0);
return uint256(price);

**Signal:** no `updatedAt` freshness gate. A frozen feed (feed deprecated, node outage, or a market-wide halt) returns the last value forever; protocol prices off stale data. Require `block.timestamp - updatedAt <= heartbeat` and `answeredInRound >= roundId`.

Single point of failure (HIGH)

One feed, no fallback, no degradation plan. If that feed is deprecated or returns garbage, the protocol is bricked or mispriced. **Signal:** a hard dependency on exactly one external address with no alternative path.

Fallback that silently returns 0 or last price (HIGH)

try feed.latestRoundData() returns (...) { ... }
catch { return lastGoodPrice; }   // ← stale, or worse:
catch { return 0; }               // ← 0 collateral value = mass liquidation, or free mint

**Signal:** the catch path masks failure. Returning `0` can make collateral worthless (mass liquidation) or debt free; returning a stale cached price keeps trading on bad data. Failures must surface, not be swallowed.

Missing L2 sequencer-uptime feed (HIGH on L2)

// Arbitrum/Optimism: no check of the sequencer uptime feed
(, int256 answer, uint256 startedAt,,) = sequencerUptime.latestRoundData();
require(answer == 0 && block.timestamp - startedAt > GRACE_PERIOD);

**Signal:** on an L2, if the sequencer was down, Chainlink prices are stale on resume. Without the uptime feed + grace period, the first post-downtime block liquidates everyone at stale prices. Chainlink documents this exact guard.

"All oracles down" path undefined (MEDIUM)

The aggregator handles primary-down but has no defined behavior when *every* source is stale/reverting — it either reverts (DoS) or falls through to an uninitialized default. Define an explicit safe-halt (pause) rather than trade on uncertainty.

No deviation / circuit breaker (MEDIUM)

Accepting any reported price without comparing primary vs secondary deviation, so a single compromised/erroneous feed is trusted outright.

Severity rubric

| Pattern | Severity | Notes | |---|---|---| | Fallback returns 0 on failure | **High** | Mass liquidation / free mint | | Missing staleness/heartbeat gate | **High** | Trades on frozen price | | Single feed, no fallback | **High** | Brick / misprice on outage | | Missing L2 sequencer-uptime check | **High** | Stale-price liquidation on resume | | "All down" path reverts (DoS) vs safe-halt | **Medium** | Availability vs safety tradeoff | | No primary/secondary deviation check | **Medium** | Single bad feed trusted |

Remediation patterns

1. **Validate every read:** `updatedAt` freshness vs a per-feed heartbeat, `answeredInRound >= roundId`, `price > 0`, and a sane min/max bound. 2. **L2 sequencer-uptime feed** + `GRACE_PERIOD` before trusting prices post-downtime (Chainlink reference pattern). 3. **Real redundancy:** primary + independent secondary (e.g. Chainlink + Uniswap V3 TWAP / Pyth) with a deviation threshold; disagreement → pause, not pick-one. 4. **Fail closed:** when all sources are stale/invalid, **pause** the affected operations rather than returning 0, last price, or reverting unboundedly. 5. **Circuit breaker** on max per-block deviation to absorb wicks.

False-positive notes

  • A feed read that already checks `updatedAt`, `answeredInRound`, and bounds is fine — don't re-flag for "no fallback" if it correctly pauses on staleness.
  • Mainnet-only contracts don't need the sequencer feed — don't flag its absence off-L2.
  • A deliberate revert-on-stale (fail-closed) is acceptable when paired with a pause path; distinguish from an unbounded DoS.

Related

  • [[oracle-manipulation]] — manipulation is the price-correctness sibling to redundancy
  • [[liquidation-cascade]] — stale/zero prices trigger mass liquidation
  • [[dos-vectors]] — revert-on-all-down can become a denial of service
Read more
@omermaksutii
Ships withrugproof

Rugproof your code before someone else does. 🌐 Live site: omermaksutii.github.io/RugProof 📦 Latest: v1.0.0 — 45 commands · 23 agents · 45 skills · 13 MCP servers · tested, offline-first, with rule packs, a benchmark, non-EVM coverage, and post-deploy

1152 skills23 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
11
Star history of omermaksutii/RugProof on GitHub, a chart by star-history.com

Other skills on rugproof.

More skills from other plugins.

api-security

api-security

Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…

@zhaoxuya520@zhaoxuya520Install Skill
nemoclaw-user-guide

nemoclaw-user-guide

Find official NemoClaw documentation for installation, configuration, operation, or troubleshooting. Also handles requested docs…

@nvidia@nvidiaInstall Skill

Questions about oracle-redundancy.

Which coding agents can use oracle-redundancy?
oracle-redundancy installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.