Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
LibOpPythPriceTest:testIntegrity(uint256,uint256,uint256) (runs: 257, μ: 3725, ~: 3725)
LibOpPythPriceTest:testRunForkCurrentPriceHappy() (gas: 17435)
LibPythConstantsTest:testChainIdConstants() (gas: 3477)
LibPythConstantsTest:testIntorastringConstants() (gas: 6410)
LibPythGetPriceFeedContractTest:testGetPriceFeedContractArbitrum() (gas: 3156)
LibPythGetPriceFeedContractTest:testGetPriceFeedContractBase() (gas: 3202)
LibPythGetPriceFeedContractTest:testGetPriceFeedContractUnsupportedChainId(uint256) (runs: 257, μ: 4285, ~: 4285)
LibPythGetPriceFeedIdTest:testPriceFeedIdKnownMappings() (gas: 7405)
LibPythGetPriceFeedIdTest:testPriceFeedIdUnknownMappings(uint256) (runs: 257, μ: 5539, ~: 5539)
LibPythGetPriceNoOlderThanTest:testPriceNoOlderThanArbitrum() (gas: 105463)
PythWordsPythPriceTest:testPythWordsPythPriceHappy() (gas: 1554392)
LibOpPythPriceTest:testIntegrity(bytes32,uint256,uint256) (runs: 256, μ: 507, ~: 507)
LibOpPythPriceTest:testRunForkCurrentPriceHappy() (gas: 18098)
LibPythConstantsTest:testChainIdConstants() (gas: 303)
LibPythConstantsTest:testIntorastringConstants() (gas: 3294)
LibPythGetPriceFeedContractTest:testGetPriceFeedContractArbitrum() (gas: 343)
LibPythGetPriceFeedContractTest:testGetPriceFeedContractBase() (gas: 389)
LibPythGetPriceFeedContractTest:testGetPriceFeedContractUnsupportedChainId(uint256) (runs: 256, μ: 4309, ~: 4309)
LibPythGetPriceFeedIdTest:testPriceFeedIdKnownMappings() (gas: 6410)
LibPythGetPriceFeedIdTest:testPriceFeedIdUnknownMappings(uint256) (runs: 253, μ: 6672, ~: 6672)
LibPythGetPriceNoOlderThanTest:testPriceNoOlderThanArbitrum() (gas: 108388)
LibPythGetPriceNoOlderThanTest:testPriceNoOlderThanBase() (gas: 109289)
PythWordsPythPriceTest:testPythWordsPythPriceHappy() (gas: 1730836)
2 changes: 1 addition & 1 deletion src/generated/PythWords.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pragma solidity ^0.8.25;
// file needs the contract to exist so that it can be compiled.

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0x61b6a9bc93d4d671ec1edf90e01875a8f2ca1b9b9963cfd7f2afc0b80b677edc);
bytes32 constant BYTECODE_HASH = bytes32(0xa9fe1909ca00897783bf99e68750a319e8294464f653fd428a391d9f68862f8e);

/// @dev The hash of the meta that describes the contract.
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xe7bb5842b2cf1d25681a9885109fbf8943495bcebb9ec049bc3790e5db57fa80);
Expand Down
39 changes: 38 additions & 1 deletion src/lib/pyth/LibPyth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,33 @@ library LibPyth {
IPyth constant PRICE_FEED_CONTRACT_ARBITRUM = IPyth(0xff1a0f4744e8582DF1aE09D5611b887B6a12925C);
IPyth constant PRICE_FEED_CONTRACT_BASE = IPyth(0x8250f4aF4B972684F7b336503E2D6dFeDeB1487a);

/// Crypto feeds.
/// BTC/USD
bytes32 constant PRICE_FEED_ID_CRYPTO_BTC_USD = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43;
// slither-disable-next-line too-many-digits
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_BTC_USD =
uint256(0x8e43727970746f2e4254432f5553440000000000000000000000000000000000);
/// WBTC/USD
bytes32 constant PRICE_FEED_ID_CRYPTO_WBTC_USD = 0xc9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33;
// slither-disable-next-line too-many-digits
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WBTC_USD =
uint256(0x8F43727970746F2E574254432F55534400000000000000000000000000000000);
/// ETH/USD
bytes32 constant PRICE_FEED_ID_CRYPTO_ETH_USD = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace;
// slither-disable-next-line too-many-digits
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_ETH_USD =
uint256(0x8e43727970746f2e4554482f5553440000000000000000000000000000000000);
/// WETH/USD
bytes32 constant PRICE_FEED_ID_CRYPTO_WETH_USD = 0x9d4294bbcd1174d6f2003ec365831e64cc31d9f6f15a2b85399db8d5000960f6;
// slither-disable-next-line too-many-digits
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WETH_USD =
uint256(0x8F43727970746F2E574554482F55534400000000000000000000000000000000);
/// XRP/USD
bytes32 constant PRICE_FEED_ID_CRYPTO_XRP_USD = 0xec5d399846a9209f3fe5881d70aae9268c94339ff9817e8d18ff19fa05eea1c8;
// slither-disable-next-line too-many-digits
uint256 constant PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_XRP_USD =
uint256(0x8e43727970746f2e5852502f5553440000000000000000000000000000000000);

/// Magnificent 7 share price feed IDs.
/// Google.
bytes32 constant PRICE_FEED_ID_EQUITY_US_GOOG_USD =
Expand Down Expand Up @@ -102,7 +129,17 @@ library LibPyth {
/// TODO replace with O(1) lookup table.
function getPriceFeedId(IntOrAString feedSymbolIntOrAString) internal pure returns (bytes32) {
uint256 feedSymbol = IntOrAString.unwrap(feedSymbolIntOrAString);
if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_GOOG_USD) {
if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_BTC_USD) {
return PRICE_FEED_ID_CRYPTO_BTC_USD;
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WBTC_USD) {
return PRICE_FEED_ID_CRYPTO_WBTC_USD;
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_ETH_USD) {
return PRICE_FEED_ID_CRYPTO_ETH_USD;
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WETH_USD) {
return PRICE_FEED_ID_CRYPTO_WETH_USD;
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_XRP_USD) {
return PRICE_FEED_ID_CRYPTO_XRP_USD;
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_GOOG_USD) {
return PRICE_FEED_ID_EQUITY_US_GOOG_USD;
} else if (feedSymbol == PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_AMZN_USD) {
return PRICE_FEED_ID_EQUITY_US_AMZN_USD;
Expand Down
20 changes: 20 additions & 0 deletions test/src/lib/pyth/LibPyth.constants.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ contract LibPythConstantsTest is Test {
}

function testIntorastringConstants() external pure {
assertEq(
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_BTC_USD,
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.BTC/USD"))
);
assertEq(
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WBTC_USD,
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WBTC/USD"))
);
assertEq(
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_ETH_USD,
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.ETH/USD"))
);
assertEq(
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_WETH_USD,
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WETH/USD"))
);
assertEq(
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_CRYPTO_XRP_USD,
IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.XRP/USD"))
);
assertEq(
LibPyth.PRICE_FEED_SYMBOL_INTORASTRING_EQUITY_US_GOOG_USD,
IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))
Expand Down
24 changes: 23 additions & 1 deletion test/src/lib/pyth/LibPyth.getPriceFeedId.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ contract LibPythGetPriceFeedIdTest is Test {

function testPriceFeedIdKnownMappings() external pure {
// Test known price feed IDs.
assertEq(
LibPyth.PRICE_FEED_ID_CRYPTO_BTC_USD, LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.BTC/USD"))
);
assertEq(
LibPyth.PRICE_FEED_ID_CRYPTO_WBTC_USD,
LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.WBTC/USD"))
);
assertEq(
LibPyth.PRICE_FEED_ID_CRYPTO_ETH_USD, LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.ETH/USD"))
);
assertEq(
LibPyth.PRICE_FEED_ID_CRYPTO_WETH_USD,
LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.WETH/USD"))
);
assertEq(
LibPyth.PRICE_FEED_ID_CRYPTO_XRP_USD, LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Crypto.XRP/USD"))
);
assertEq(
LibPyth.PRICE_FEED_ID_EQUITY_US_GOOG_USD,
LibPyth.getPriceFeedId(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))
Expand Down Expand Up @@ -61,7 +78,12 @@ contract LibPythGetPriceFeedIdTest is Test {

function testPriceFeedIdUnknownMappings(IntOrAString symbol) external {
vm.assume(
IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))
IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.BTC/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WBTC/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.ETH/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.WETH/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Crypto.XRP/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.GOOG/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.AMZN/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.AAPL/USD"))
&& IntOrAString.unwrap(symbol) != IntOrAString.unwrap(LibIntOrAString.fromString2("Equity.US.MSFT/USD"))
Expand Down
30 changes: 30 additions & 0 deletions test/src/lib/pyth/LibPyth.getPriceNoOlderThan.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,36 @@ contract LibPythGetPriceNoOlderThanTest is Test {

function testPriceNoOlderThanArbitrum() external {
vm.createSelectFork(FORK_RPC_URL_ARBITRUM, FORK_BLOCK_ARBITRUM);
checkPriceNoOlderThan(
LibIntOrAString.fromString2("Crypto.BTC/USD"),
LibDecimalFloat.packLossless(30 minutes, 0),
LibDecimalFloat.packLossless(106345.97372127e8, -8),
LibDecimalFloat.packLossless(42.72120769e8, -8)
);
checkPriceNoOlderThan(
LibIntOrAString.fromString2("Crypto.WBTC/USD"),
LibDecimalFloat.packLossless(30 minutes, 0),
LibDecimalFloat.packLossless(106193.79417862e8, -8),
LibDecimalFloat.packLossless(110.04339091e8, -8)
);
checkPriceNoOlderThan(
LibIntOrAString.fromString2("Crypto.ETH/USD"),
LibDecimalFloat.packLossless(30 minutes, 0),
LibDecimalFloat.packLossless(2526.40213905e8, -8),
LibDecimalFloat.packLossless(1.33646932e8, -8)
);
checkPriceNoOlderThan(
LibIntOrAString.fromString2("Crypto.WETH/USD"),
LibDecimalFloat.packLossless(60 days, 0),
LibDecimalFloat.packLossless(1760.95597004e8, -8),
LibDecimalFloat.packLossless(7.6662261e8, -8)
);
checkPriceNoOlderThan(
LibIntOrAString.fromString2("Crypto.XRP/USD"),
LibDecimalFloat.packLossless(2 hours, 0),
LibDecimalFloat.packLossless(2.28242476e8, -8),
LibDecimalFloat.packLossless(0.0012824e8, -8)
);
checkPriceNoOlderThan(
LibIntOrAString.fromString2("Equity.US.GOOG/USD"),
LibDecimalFloat.packLossless(72 hours, 0),
Expand Down