Skip to content

fix(oracle): restore Chainlink staleness check dropped by an unrelated commit - #343

Open
Morenikeoa wants to merge 1 commit into
dcccrypto:mainfrom
Morenikeoa:fix/oracle-chainlink-staleness-upstream
Open

fix(oracle): restore Chainlink staleness check dropped by an unrelated commit#343
Morenikeoa wants to merge 1 commit into
dcccrypto:mainfrom
Morenikeoa:fix/oracle-chainlink-staleness-upstream

Conversation

@Morenikeoa

Copy link
Copy Markdown

Summary

parseChainlinkPrice validated buffer size, decimals, and price positivity, but had no staleness protection — the public API's own module docstring claims "These utilities validate oracle data BEFORE parsing to prevent silent propagation of stale or malformed Chainlink data as price," which was no longer true.

This protection existed once: commit fb9083e ("fix(oracle): add staleness check to parseChainlinkPrice") added CHAINLINK_TIMESTAMP_OFFSET, OraclePrice.updatedAt, and an opt-in maxStalenessSeconds parameter that throws on stale data. It was silently dropped in a later, unrelated commit (af46df6, "v12.17 SDK update + SBF account parsing offset fix + V1M2 discovery") — a commit whose stated purpose is unrelated slab-layout work, indicating this was an incidental regression rather than an intentional removal.

Any caller using the public parseChainlinkPrice/isValidChainlinkOracle API to source a price for trading/liquidation decisions got zero protection against a frozen/stale oracle account, with no way to even opt into a staleness bound.

Fix

Restore fb9083e's implementation (CHAINLINK_TIMESTAMP_OFFSET, ParseChainlinkOptions.maxStalenessSeconds, OraclePrice.updatedAt, and the age-check throw), adapted into the current file. Backward compatible: omitting maxStalenessSeconds preserves prior behavior exactly, just with updatedAt additionally populated.

Test plan

  • Added regression tests in test/oracle.test.ts: a fresh oracle within the staleness bound doesn't throw, a 30-day-old oracle with a 60s bound throws, and updatedAt is populated even when maxStalenessSeconds is omitted.
  • Confirmed the new tests fail against the current regressed code (import error — CHAINLINK_TIMESTAMP_OFFSET doesn't exist) and pass against this fix.
  • Full suite green (pnpm test exit 0, including "All oracle tests passed!"); vitest portion unchanged at 851 passed / 31 skipped since oracle.test.ts runs via tsx outside the vitest-counted suite.

…d commit

parseChainlinkPrice validated buffer size, decimals, and price
positivity, but had no staleness protection — the public API's own
module docstring claims "These utilities validate oracle data BEFORE
parsing to prevent silent propagation of stale or malformed Chainlink
data as price," which was no longer true.

This protection existed once: commit fb9083e ("fix(oracle): add
staleness check to parseChainlinkPrice", 2026-04-04) added
CHAINLINK_TIMESTAMP_OFFSET, OraclePrice.updatedAt, and an opt-in
maxStalenessSeconds parameter that throws on stale data. It was
silently dropped in commit af46df6 (2026-04-16, "v12.17 SDK update +
SBF account parsing offset fix + V1M2 discovery") — a commit whose
stated purpose is unrelated slab-layout work, indicating this was an
incidental regression rather than an intentional removal.

Any caller using the public parseChainlinkPrice/isValidChainlinkOracle
API to source a price for trading/liquidation decisions got zero
protection against a frozen/stale oracle account, with no way to even
opt into a staleness bound.

Fix: restore fb9083e's implementation verbatim (CHAINLINK_TIMESTAMP_OFFSET,
ParseChainlinkOptions.maxStalenessSeconds, OraclePrice.updatedAt, and the
age-check throw), adapted into the current file. Backward compatible:
omitting maxStalenessSeconds preserves prior behavior exactly, just with
updatedAt additionally populated.

Added regression tests in test/oracle.test.ts: a fresh oracle within
the staleness bound doesn't throw, a 30-day-old oracle with a 60s bound
throws, and updatedAt is populated even when maxStalenessSeconds is
omitted. Confirmed the new tests fail against the current regressed
code (import error — CHAINLINK_TIMESTAMP_OFFSET doesn't exist) and pass
against this fix.

Full suite (pnpm test): exit 0, all green, including "All oracle tests
passed!". Vitest portion: 851 passed | 31 skipped (882 total, unchanged
— oracle.test.ts runs via tsx outside the vitest-counted suite).
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Morenikeoa, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 29 minutes and 6 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 98025b5a-1d0e-466a-8b1c-ecff6d72d1b9

📥 Commits

Reviewing files that changed from the base of the PR and between 673bc47 and 5108667.

📒 Files selected for processing (2)
  • src/solana/oracle.ts
  • test/oracle.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant