Skip to content

Commit 63caafe

Browse files
Merge branch 'main' of github.com:rainlanguage/rain.pyth into 2025-10-29-iau
2 parents 8e0404b + 33f006a commit 63caafe

File tree

6 files changed

+124
-14
lines changed

6 files changed

+124
-14
lines changed

.gas-snapshot

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
LibOpPythPriceTest:testIntegrity(uint256,uint256,uint256) (runs: 257, μ: 3725, ~: 3725)
2-
LibOpPythPriceTest:testRunForkCurrentPriceHappy() (gas: 17435)
3-
LibPythConstantsTest:testChainIdConstants() (gas: 3477)
4-
LibPythConstantsTest:testIntorastringConstants() (gas: 6410)
5-
LibPythGetPriceFeedContractTest:testGetPriceFeedContractArbitrum() (gas: 3156)
6-
LibPythGetPriceFeedContractTest:testGetPriceFeedContractBase() (gas: 3202)
7-
LibPythGetPriceFeedContractTest:testGetPriceFeedContractUnsupportedChainId(uint256) (runs: 257, μ: 4285, ~: 4285)
8-
LibPythGetPriceFeedIdTest:testPriceFeedIdKnownMappings() (gas: 7405)
9-
LibPythGetPriceFeedIdTest:testPriceFeedIdUnknownMappings(uint256) (runs: 257, μ: 5539, ~: 5539)
10-
LibPythGetPriceNoOlderThanTest:testPriceNoOlderThanArbitrum() (gas: 105463)
11-
PythWordsPythPriceTest:testPythWordsPythPriceHappy() (gas: 1554392)
1+
LibOpPythPriceTest:testIntegrity(bytes32,uint256,uint256) (runs: 256, μ: 507, ~: 507)
2+
LibOpPythPriceTest:testRunForkCurrentPriceHappy() (gas: 18098)
3+
LibPythConstantsTest:testChainIdConstants() (gas: 303)
4+
LibPythConstantsTest:testIntorastringConstants() (gas: 3294)
5+
LibPythGetPriceFeedContractTest:testGetPriceFeedContractArbitrum() (gas: 343)
6+
LibPythGetPriceFeedContractTest:testGetPriceFeedContractBase() (gas: 389)
7+
LibPythGetPriceFeedContractTest:testGetPriceFeedContractUnsupportedChainId(uint256) (runs: 256, μ: 4309, ~: 4309)
8+
LibPythGetPriceFeedIdTest:testPriceFeedIdKnownMappings() (gas: 6410)
9+
LibPythGetPriceFeedIdTest:testPriceFeedIdUnknownMappings(uint256) (runs: 253, μ: 6672, ~: 6672)
10+
LibPythGetPriceNoOlderThanTest:testPriceNoOlderThanArbitrum() (gas: 108388)
11+
LibPythGetPriceNoOlderThanTest:testPriceNoOlderThanBase() (gas: 109289)
12+
PythWordsPythPriceTest:testPythWordsPythPriceHappy() (gas: 1730836)

src/generated/PythWords.pointers.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pragma solidity ^0.8.25;
1010
// file needs the contract to exist so that it can be compiled.
1111

1212
/// @dev Hash of the known bytecode.
13-
bytes32 constant BYTECODE_HASH = bytes32(0x61b6a9bc93d4d671ec1edf90e01875a8f2ca1b9b9963cfd7f2afc0b80b677edc);
13+
bytes32 constant BYTECODE_HASH = bytes32(0xa9fe1909ca00897783bf99e68750a319e8294464f653fd428a391d9f68862f8e);
1414

1515
/// @dev The hash of the meta that describes the contract.
1616
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xe7bb5842b2cf1d25681a9885109fbf8943495bcebb9ec049bc3790e5db57fa80);

src/lib/pyth/LibPyth.sol

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,33 @@ library LibPyth {
2020
IPyth constant PRICE_FEED_CONTRACT_ARBITRUM = IPyth(0xff1a0f4744e8582DF1aE09D5611b887B6a12925C);
2121
IPyth constant PRICE_FEED_CONTRACT_BASE = IPyth(0x8250f4aF4B972684F7b336503E2D6dFeDeB1487a);
2222

23+
/// Crypto feeds.
24+
/// BTC/USD
25+
bytes32 constant PRICE_FEED_ID_CRYPTO_BTC_USD = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43;
26+
// slither-disable-next-line too-many-digits
27+
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_BTC_USD =
28+
uint256(0x8e43727970746f2e4254432f5553440000000000000000000000000000000000);
29+
/// WBTC/USD
30+
bytes32 constant PRICE_FEED_ID_CRYPTO_WBTC_USD = 0xc9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33;
31+
// slither-disable-next-line too-many-digits
32+
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WBTC_USD =
33+
uint256(0x8F43727970746F2E574254432F55534400000000000000000000000000000000);
34+
/// ETH/USD
35+
bytes32 constant PRICE_FEED_ID_CRYPTO_ETH_USD = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace;
36+
// slither-disable-next-line too-many-digits
37+
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_ETH_USD =
38+
uint256(0x8e43727970746f2e4554482f5553440000000000000000000000000000000000);
39+
/// WETH/USD
40+
bytes32 constant PRICE_FEED_ID_CRYPTO_WETH_USD = 0x9d4294bbcd1174d6f2003ec365831e64cc31d9f6f15a2b85399db8d5000960f6;
41+
// slither-disable-next-line too-many-digits
42+
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WETH_USD =
43+
uint256(0x8F43727970746F2E574554482F55534400000000000000000000000000000000);
44+
/// XRP/USD
45+
bytes32 constant PRICE_FEED_ID_CRYPTO_XRP_USD = 0xec5d399846a9209f3fe5881d70aae9268c94339ff9817e8d18ff19fa05eea1c8;
46+
// slither-disable-next-line too-many-digits
47+
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_XRP_USD =
48+
uint256(0x8e43727970746f2e5852502f5553440000000000000000000000000000000000);
49+
2350
/// Magnificent 7 share price feed IDs.
2451
/// Google.
2552
bytes32 constant PRICE_FEED_ID_EQUITY_US_GOOG_USD =
@@ -108,7 +135,17 @@ library LibPyth {
108135
/// TODO replace with O(1) lookup table.
109136
function getPriceFeedId(IntOrAString feedSymbolIntOrAString) internal pure returns (bytes32) {
110137
uint256 feedSymbol = IntOrAString.unwrap(feedSymbolIntOrAString);
111-
if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_GOOG_USD) {
138+
if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_BTC_USD) {
139+
return PRICE_FEED_ID_CRYPTO_BTC_USD;
140+
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WBTC_USD) {
141+
return PRICE_FEED_ID_CRYPTO_WBTC_USD;
142+
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_ETH_USD) {
143+
return PRICE_FEED_ID_CRYPTO_ETH_USD;
144+
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WETH_USD) {
145+
return PRICE_FEED_ID_CRYPTO_WETH_USD;
146+
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_XRP_USD) {
147+
return PRICE_FEED_ID_CRYPTO_XRP_USD;
148+
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_GOOG_USD) {
112149
return PRICE_FEED_ID_EQUITY_US_GOOG_USD;
113150
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_AMZN_USD) {
114151
return PRICE_FEED_ID_EQUITY_US_AMZN_USD;

test/src/lib/pyth/LibPyth.constants.t.sol

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@ contract LibPythConstantsTest is Test {
1313
}
1414

1515
function testIntorastringConstants() external pure {
16+
assertEq(
17+
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_BTC_USD,
18+
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.BTC/USD"))
19+
);
20+
assertEq(
21+
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WBTC_USD,
22+
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WBTC/USD"))
23+
);
24+
assertEq(
25+
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_ETH_USD,
26+
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.ETH/USD"))
27+
);
28+
assertEq(
29+
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WETH_USD,
30+
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WETH/USD"))
31+
);
32+
assertEq(
33+
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_XRP_USD,
34+
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.XRP/USD"))
35+
);
1636
assertEq(
1737
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_GOOG_USD,
1838
IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))

test/src/lib/pyth/LibPyth.getPriceFeedId.t.sol

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@ contract LibPythGetPriceFeedIdTest is Test {
1313

1414
function testPriceFeedIdKnownMappings() external pure {
1515
// Test known price feed IDs.
16+
assertEq(
17+
LibPyth.PRICE_FEED_ID_CRYPTO_BTC_USD, LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.BTC/USD"))
18+
);
19+
assertEq(
20+
LibPyth.PRICE_FEED_ID_CRYPTO_WBTC_USD,
21+
LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.WBTC/USD"))
22+
);
23+
assertEq(
24+
LibPyth.PRICE_FEED_ID_CRYPTO_ETH_USD, LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.ETH/USD"))
25+
);
26+
assertEq(
27+
LibPyth.PRICE_FEED_ID_CRYPTO_WETH_USD,
28+
LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.WETH/USD"))
29+
);
30+
assertEq(
31+
LibPyth.PRICE_FEED_ID_CRYPTO_XRP_USD, LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.XRP/USD"))
32+
);
1633
assertEq(
1734
LibPyth.PRICE_FEED_ID_EQUITY_US_GOOG_USD,
1835
LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))
@@ -65,7 +82,12 @@ contract LibPythGetPriceFeedIdTest is Test {
6582

6683
function testPriceFeedIdUnknownMappings(IntOrAString symbol) external {
6784
vm.assume(
68-
IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))
85+
IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.BTC/USD"))
86+
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WBTC/USD"))
87+
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.ETH/USD"))
88+
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WETH/USD"))
89+
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.XRP/USD"))
90+
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))
6991
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.AMZN/USD"))
7092
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.AAPL/USD"))
7193
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.MSFT/USD"))

test/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.sol

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,36 @@ contract LibPythGetPriceNoOlderThanTest is Test {
3232

3333
function testPriceNoOlderThanArbitrum() external {
3434
vm.createSelectFork(FORK_RPC_URL_ARBITRUM, FORK_BLOCK_ARBITRUM);
35+
checkPriceNoOlderThan(
36+
LibIntOrAString.fromString2("Crypto.BTC/USD"),
37+
LibDecimalFloat.packLossless(30 minutes, 0),
38+
LibDecimalFloat.packLossless(106345.97372127e8, -8),
39+
LibDecimalFloat.packLossless(42.72120769e8, -8)
40+
);
41+
checkPriceNoOlderThan(
42+
LibIntOrAString.fromString2("Crypto.WBTC/USD"),
43+
LibDecimalFloat.packLossless(30 minutes, 0),
44+
LibDecimalFloat.packLossless(106193.79417862e8, -8),
45+
LibDecimalFloat.packLossless(110.04339091e8, -8)
46+
);
47+
checkPriceNoOlderThan(
48+
LibIntOrAString.fromString2("Crypto.ETH/USD"),
49+
LibDecimalFloat.packLossless(30 minutes, 0),
50+
LibDecimalFloat.packLossless(2526.40213905e8, -8),
51+
LibDecimalFloat.packLossless(1.33646932e8, -8)
52+
);
53+
checkPriceNoOlderThan(
54+
LibIntOrAString.fromString2("Crypto.WETH/USD"),
55+
LibDecimalFloat.packLossless(60 days, 0),
56+
LibDecimalFloat.packLossless(1760.95597004e8, -8),
57+
LibDecimalFloat.packLossless(7.6662261e8, -8)
58+
);
59+
checkPriceNoOlderThan(
60+
LibIntOrAString.fromString2("Crypto.XRP/USD"),
61+
LibDecimalFloat.packLossless(2 hours, 0),
62+
LibDecimalFloat.packLossless(2.28242476e8, -8),
63+
LibDecimalFloat.packLossless(0.0012824e8, -8)
64+
);
3565
checkPriceNoOlderThan(
3666
LibIntOrAString.fromString2("Equity.US.GOOG/USD"),
3767
LibDecimalFloat.packLossless(72 hours, 0),

0 commit comments

Comments
 (0)