feat: add Commodities.UKOILSPOT (Brent Crude Oil) price feed#19
feat: add Commodities.UKOILSPOT (Brent Crude Oil) price feed#19alastairong1 wants to merge 4 commits intomainfrom
Conversation
Add Brent Crude Oil CFD spot price feed (Commodities.UKOILSPOT) to the Pyth symbol-to-feed-ID mapping. This enables Rain strategies to use pyth-price with the UKOILSPOT symbol for oil-backed tokenized assets. Feed ID: 0x27f0d5e09a830083e5491795cac9ca521399c8f7fd56240d09484b14e614d57a Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use block 40538400 (16 seconds after price publish) instead of 40582366 (24.4 hours after) so the test can use 24 hours maxAge consistently with all other fork tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WalkthroughIntroduces a new commodity price feed (Commodities.UKOILSPOT): adds feed ID and symbol constants, updates Pyth library symbol-to-ID resolution, adds a fork constant, and extends tests to validate constants, mapping, and price retrieval for the new feed. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MetaBoard is deployed via Zoltu CREATE2 deployer at the same address on every chain, so there is no need for a DEPLOY_METABOARD_ADDRESS environment variable. This fixes the deployment CI failure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 `@script/Deploy.sol`:
- Around line 10-13: The code uses the constant METABOARD_ADDRESS to instantiate
and call MetaBoard without verifying that contract code exists there; add a
preflight check using extcodesize (or Address.code.length) on METABOARD_ADDRESS
and require it be > 0 with a clear error like "MetaBoard not deployed on this
chain" before creating the MetaBoard instance (the line that does
MetaBoard(METABOARD_ADDRESS)) or making any calls; if you prefer, import
OpenZeppelin's Address library and use Address.isContract(METABOARD_ADDRESS) for
the same guard.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4f5ffd67-5302-485c-86df-23c1a26d1bc2
📒 Files selected for processing (1)
script/Deploy.sol
| /// @dev MetaBoard is deterministically deployed via Zoltu CREATE2 deployer | ||
| /// at the same address on every chain. | ||
| address constant METABOARD_ADDRESS = address(0xfb8437AeFBB8031064E274527C5fc08e30Ac6928); | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether a hardcoded metaboard address is used without an on-chain code existence guard.
rg -n -C2 'METABOARD_ADDRESS|IMetaBoardV1_2\(METABOARD_ADDRESS\)|\.code\.length|MetaBoardNotDeployed' script/Deploy.solRepository: rainlanguage/rain.pyth
Length of output: 613
🏁 Script executed:
cat -n script/Deploy.solRepository: rainlanguage/rain.pyth
Length of output: 1387
Add a preflight contract-code check for the fixed MetaBoard address.
Using a constant address without verifying code exists on the active chain can make deployments brittle on chains where MetaBoard is not deployed yet. The instantiation at line 18 will succeed, but the call at line 22 will revert with a confusing error. Add a guard to fail fast.
🔧 Proposed fix
address constant METABOARD_ADDRESS = address(0xfb8437AeFBB8031064E274527C5fc08e30Ac6928);
+error MetaBoardNotDeployed(address metaboard, uint256 chainId);
contract Deploy is Script {
function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYMENT_KEY");
bytes memory subParserDescribedByMeta = vm.readFileBinary("meta/PythWords.rain.meta");
+ if (METABOARD_ADDRESS.code.length == 0) {
+ revert MetaBoardNotDeployed(METABOARD_ADDRESS, block.chainid);
+ }
IMetaBoardV1_2 metaboard = IMetaBoardV1_2(METABOARD_ADDRESS);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@script/Deploy.sol` around lines 10 - 13, The code uses the constant
METABOARD_ADDRESS to instantiate and call MetaBoard without verifying that
contract code exists there; add a preflight check using extcodesize (or
Address.code.length) on METABOARD_ADDRESS and require it be > 0 with a clear
error like "MetaBoard not deployed on this chain" before creating the MetaBoard
instance (the line that does MetaBoard(METABOARD_ADDRESS)) or making any calls;
if you prefer, import OpenZeppelin's Address library and use
Address.isContract(METABOARD_ADDRESS) for the same guard.
Summary
Commodities.UKOILSPOT(Brent Crude Oil CFD spot) to the Pyth symbol-to-feed-ID mapping0x27f0d5e09a830083e5491795cac9ca521399c8f7fd56240d09484b14e614d57apyth-price(pair timeout)with the UKOILSPOT symbolChanges
src/lib/pyth/LibPyth.sol— AddedPRICE_FEED_ID_COMMODITIES_UKOILSPOT+PRICE_FEED_SYMBOL_INTORASTRING_COMMODITIES_UKOILSPOTconstants andelse ifbranch ingetPriceFeedId()src/generated/PythWords.pointers.sol— RegeneratedBYTECODE_HASHtest/lib/LibFork.sol— AddedFORK_BLOCK_BASE_UKOILSPOT(block 40538400, 16s after price publish)test/src/lib/pyth/LibPyth.constants.t.sol— Added IntOrAString encoding assertiontest/src/lib/pyth/LibPyth.getPriceFeedId.t.sol— Added known mapping assertion + fuzz exclusiontest/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.sol— Added fork test with 24h maxAge (price: $60.30017, conf: $0.15811)Test plan
forge test— all 17 tests pass (constants, known mappings, fuzz, fork tests including new UKOILSPOT)forge script script/BuildPointers.sol— pointers regeneratedSummary by CodeRabbit
New Features
Tests
Chores