Add SGOV Feed#20
Conversation
WalkthroughAdded SGOV/USD Pyth price feed constants and resolution logic, updated tests and fork baseline for SGOV (and several additional equity feeds). Also applied small formatting tweaks to function-pointer declarations, updated CI workflow prelude steps, replaced an env-based deploy address with a constant, and edited .gitignore. ChangesSGOV Price Feed and Tests
Formatting, CI, and Deploy
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gitignore:
- Line 3: Remove the .pre-commit-config.yaml entry from .gitignore so the shared
pre-commit configuration is tracked by the repository; locate the .gitignore
line that lists ".pre-commit-config.yaml" and delete that line (or stop ignoring
that specific filename) so the repository can update and version the pre-commit
hooks without requiring forced adds.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 752a9c68-8075-4373-a43f-b52657239ad9
⛔ Files ignored due to path filters (2)
flake.lockis excluded by!**/*.locksrc/generated/PythWords.pointers.solis excluded by!**/generated/**
📒 Files selected for processing (8)
.gitignoresrc/abstract/PythExtern.solsrc/abstract/PythSubParser.solsrc/lib/pyth/LibPyth.soltest/lib/LibFork.soltest/src/lib/pyth/LibPyth.constants.t.soltest/src/lib/pyth/LibPyth.getPriceFeedId.t.soltest/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.sol
| out | ||
| cache No newline at end of file | ||
| cache | ||
| .pre-commit-config.yaml No newline at end of file |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Don’t ignore the shared pre-commit config.
.pre-commit-config.yaml is normally repository-owned; ignoring it makes hook updates easy to miss and forces git add -f if the project later adopts pre-commit.
♻️ Proposed cleanup
-.pre-commit-config.yaml📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .pre-commit-config.yaml |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.gitignore at line 3, Remove the .pre-commit-config.yaml entry from
.gitignore so the shared pre-commit configuration is tracked by the repository;
locate the .gitignore line that lists ".pre-commit-config.yaml" and delete that
line (or stop ignoring that specific filename) so the repository can update and
version the pre-commit hooks without requiring forced adds.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
script/Deploy.sol (1)
12-23:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd a bytecode existence guard for
METABOARD_ADDRESSbefore emitting metadata.On Line 18, the script trusts a fixed address without checking deployment presence. If that address is not deployed on a target network, metadata registration can fail or no-op unexpectedly. Add a hard fail before
emitForDescribedAddress.Suggested patch
- IMetaBoardV1_2 metaboard = IMetaBoardV1_2(METABOARD_ADDRESS); + if (METABOARD_ADDRESS.code.length == 0) { + revert("METABOARD_ADDRESS has no code"); + } + IMetaBoardV1_2 metaboard = IMetaBoardV1_2(METABOARD_ADDRESS);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@script/Deploy.sol` around lines 12 - 23, Add a bytecode-existence guard for METABOARD_ADDRESS in run(): after creating metaboard (IMetaBoardV1_2 metaboard = ...), check address(metaboard).code.length > 0 (or address(METABOARD_ADDRESS).code.length > 0) and revert/require with a clear message (e.g., "METABOARD not deployed on this network") if zero; only call LibDescribedByMeta.emitForDescribedAddress when the check passes so the script hard-fails instead of silently continuing when the address has no deployed bytecode.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.sol`:
- Around line 401-409: Add a clear NatSpec/doc comment above the
PRICE_FEED_ID_EQUITY_US_SGOV_USD constant in LibPyth.sol explaining that the
SGOV Pyth feed can be up to ~48 hours stale (versus the usual 24h for equities)
due to T-bill/ETF weekend and market-closure behavior, and recommend downstream
callers use staleAfter >= 48 hours (or handle weekend/holiday gaps) when calling
functions like getPriceNoOlderThan; include the rationale (iShares 0-3 Month
Treasury Bond updates/market closures) and the concrete recommended minimum
window so callers don’t choose a sub-48h staleAfter and trigger on-chain
reverts.
---
Outside diff comments:
In `@script/Deploy.sol`:
- Around line 12-23: Add a bytecode-existence guard for METABOARD_ADDRESS in
run(): after creating metaboard (IMetaBoardV1_2 metaboard = ...), check
address(metaboard).code.length > 0 (or address(METABOARD_ADDRESS).code.length >
0) and revert/require with a clear message (e.g., "METABOARD not deployed on
this network") if zero; only call LibDescribedByMeta.emitForDescribedAddress
when the check passes so the script hard-fails instead of silently continuing
when the address has no deployed bytecode.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f0522882-ab88-4c9a-b779-39777bc14eab
⛔ Files ignored due to path filters (1)
src/generated/PythWords.pointers.solis excluded by!**/generated/**
📒 Files selected for processing (7)
.github/workflows/manual-sol-artifacts.yamlscript/Deploy.solsrc/lib/pyth/LibPyth.soltest/lib/LibFork.soltest/src/lib/pyth/LibPyth.constants.t.soltest/src/lib/pyth/LibPyth.getPriceFeedId.t.soltest/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.sol
| function testPriceNoOlderThanBaseSgov() external { | ||
| vm.createSelectFork(FORK_RPC_URL_BASE, FORK_BLOCK_BASE_SGOV); | ||
| checkPriceNoOlderThan( | ||
| LibIntOrAString.fromString2("Equity.US.SGOV/USD"), | ||
| LibDecimalFloat.packLossless(48 hours, 0), | ||
| LibDecimalFloat.packLossless(100.56505e5, -5), | ||
| LibDecimalFloat.packLossless(0.10552e5, -5) | ||
| ); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
SGOV uses 48 hours staleAfter — document the wider staleness requirement for callers.
Every other equity feed test uses 24 hours, but SGOV requires 48 hours at FORK_BLOCK_BASE_SGOV. This is expected for a T-bill ETF (iShares 0-3 Month Treasury Bond) whose Pyth price feed doesn't update over weekends or market-closure periods. The fork block likely falls on a post-weekend open, making the most recent published price ~48h old.
This is not a bug in the test, but downstream callers setting a sub-48h staleAfter for SGOV will encounter on-chain reverts during weekend/holiday gaps. A doc comment on the PRICE_FEED_ID_EQUITY_US_SGOV_USD constant noting this staleness characteristic would help callers set an appropriate window.
📝 Suggested doc comment addition in `src/lib/pyth/LibPyth.sol`
- /// SGOV/USD
+ /// SGOV/USD (iShares 0-3 Month Treasury Bond ETF)
+ /// Note: this feed does not update during weekends or market closures; callers
+ /// should use a staleAfter window of at least 48 hours to avoid weekend reverts.
bytes32 constant PRICE_FEED_ID_EQUITY_US_SGOV_USD =🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.sol` around lines 401 - 409,
Add a clear NatSpec/doc comment above the PRICE_FEED_ID_EQUITY_US_SGOV_USD
constant in LibPyth.sol explaining that the SGOV Pyth feed can be up to ~48
hours stale (versus the usual 24h for equities) due to T-bill/ETF weekend and
market-closure behavior, and recommend downstream callers use staleAfter >= 48
hours (or handle weekend/holiday gaps) when calling functions like
getPriceNoOlderThan; include the rationale (iShares 0-3 Month Treasury Bond
updates/market closures) and the concrete recommended minimum window so callers
don’t choose a sub-48h staleAfter and trigger on-chain reverts.
Motivation
Extend
rain.pythequity feed coverage by adding SGOV and additional ETF mappings so downstream consumers can resolve and read these symbols through the existing Pyth integration.What Changed
src/lib/pyth/LibPyth.solfor:EQUITY.US.SGOV/USDEQUITY.US.QQQM/USDEQUITY.US.VMO/USDEQUITY.US.ARKK/USDgetPriceNoOlderThanbehavior for the new feeds.Validation
test/src/lib/pyth/LibPyth.constants.t.soltest/src/lib/pyth/LibPyth.getPriceFeedId.t.soltest/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.soltest/lib/LibFork.solfor deterministic feed checks.Checks
By submitting this for review, I'm confirming I've done the following: