Skip to content

Commit 9cef775

Browse files
fix static
1 parent 05f9194 commit 9cef775

File tree

6 files changed

+73
-39
lines changed

6 files changed

+73
-39
lines changed

src/generated/PythWords.pointers.sol

Lines changed: 3 additions & 3 deletions
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(0x53dbbb78e3f6cc40e9fa84c2fd4fa657649d34c2dcb253e0730315131a589d71);
13+
bytes32 constant BYTECODE_HASH = bytes32(0x61b6a9bc93d4d671ec1edf90e01875a8f2ca1b9b9963cfd7f2afc0b80b677edc);
1414

1515
/// @dev The hash of the meta that describes the contract.
1616
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xe7bb5842b2cf1d25681a9885109fbf8943495bcebb9ec049bc3790e5db57fa80);
@@ -47,10 +47,10 @@ bytes constant SUB_PARSER_WORD_PARSERS = hex"0700";
4747
/// @dev Every two bytes is a function pointer for an operand handler.
4848
/// These positional indexes all map to the same indexes looked up in the parse
4949
/// meta.
50-
bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex"0ac6";
50+
bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex"0aca";
5151

5252
/// @dev The function pointers for the integrity check fns.
53-
bytes constant INTEGRITY_FUNCTION_POINTERS = hex"0aba";
53+
bytes constant INTEGRITY_FUNCTION_POINTERS = hex"0abf";
5454

5555
/// @dev The function pointers known to the interpreter for dynamic dispatch.
5656
/// By setting these as a constant they can be inlined into the interpreter

src/lib/op/LibOpPythPrice.sol

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ pragma solidity ^0.8.25;
55
import {OperandV2, StackItem} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol";
66
import {LibIntOrAString, IntOrAString} from "rain.intorastring/lib/LibIntOrAString.sol";
77
import {LibPyth} from "../pyth/LibPyth.sol";
8-
import {Float, LibDecimalFloat} from "rain.math.float/lib/LibDecimalFloat.sol";
8+
import {Float} from "rain.math.float/lib/LibDecimalFloat.sol";
99

1010
library LibOpPythPrice {
1111
using LibIntOrAString for IntOrAString;
1212

1313
/// Extern integrity for the Pyth price operation.
14-
/// Always requires 2 inputs and produces 1 output.
14+
/// Always requires 2 inputs and produces 2 outputs.
1515
function integrity(OperandV2, uint256, uint256) internal pure returns (uint256, uint256) {
16-
return (2, 1);
16+
return (2, 2);
1717
}
1818

1919
/// Runs the Pyth price operation.
@@ -26,14 +26,15 @@ library LibOpPythPrice {
2626
staleAfter := mload(add(inputs, 0x40))
2727
}
2828

29-
Float price = LibPyth.getPriceNoOlderThan(symbol, staleAfter);
29+
(Float price, Float conf) = LibPyth.getPriceNoOlderThan(symbol, staleAfter);
3030

3131
StackItem[] memory outputs;
3232
assembly ("memory-safe") {
3333
outputs := mload(0x40)
34-
mstore(0x40, add(outputs, 0x40))
35-
mstore(outputs, 1)
34+
mstore(0x40, add(outputs, 0x60))
35+
mstore(outputs, 2)
3636
mstore(add(outputs, 0x20), price)
37+
mstore(add(outputs, 0x40), conf)
3738
}
3839
return outputs;
3940
}

src/lib/pyth/LibPyth.sol

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,16 @@ library LibPyth {
129129
}
130130
}
131131

132-
function getPriceNoOlderThan(IntOrAString feedSymbol, Float staleAfter) internal view returns (Float) {
132+
function getPriceNoOlderThan(IntOrAString feedSymbol, Float staleAfter) internal view returns (Float, Float) {
133133
uint256 staleAfterUint = LibDecimalFloat.toFixedDecimalLossless(staleAfter, 0);
134134
bytes32 feedId = getPriceFeedId(feedSymbol);
135135
IPyth priceFeedContract = getPriceFeedContract(block.chainid);
136136

137137
PythStructs.Price memory priceData = priceFeedContract.getPriceNoOlderThan(feedId, staleAfterUint);
138138

139-
return LibDecimalFloat.packLossless(priceData.price, priceData.expo);
139+
return (
140+
LibDecimalFloat.packLossless(priceData.price, priceData.expo),
141+
LibDecimalFloat.packLossless(int256(uint256(priceData.conf)), priceData.expo)
142+
);
140143
}
141144
}

test/src/concrete/PythWords.pythPrice.t.sol

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,18 @@ contract PythWordsPythPriceTest is OpTest {
2121

2222
PythWords pythWords = new PythWords();
2323

24-
StackItem[] memory expectedStack = new StackItem[](1);
25-
expectedStack[0] = StackItem.wrap(Float.unwrap(LibDecimalFloat.packLossless(172.3176e5, -5)));
24+
StackItem[] memory expectedStack = new StackItem[](2);
25+
expectedStack[0] = StackItem.wrap(Float.unwrap(LibDecimalFloat.packLossless(2.00302e5, -5)));
26+
expectedStack[1] = StackItem.wrap(Float.unwrap(LibDecimalFloat.packLossless(172.3176e5, -5)));
2627

2728
checkHappy(
2829
bytes(
2930
string.concat(
3031
"using-words-from ",
3132
address(pythWords).toHexString(),
32-
" _: pyth-price(\"Equity.US.GOOG/USD\" 1080000);"
33+
"price confidence: pyth-price(\"Equity.US.GOOG/USD\" 1080000),",
34+
":ensure(equal-to(price 172.3176) \"bad price\"),",
35+
":ensure(equal-to(confidence 2.00302) \"bad confidence\");"
3336
)
3437
),
3538
expectedStack,

test/src/lib/op/LibOpPythPrice.t.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ contract LibOpPythPriceTest is Test {
1212
function testIntegrity(OperandV2 operand, uint256 inputs, uint256 outputs) external pure {
1313
(uint256 calculatedInputs, uint256 calculatedOutputs) = LibOpPythPrice.integrity(operand, inputs, outputs);
1414
assertEq(calculatedInputs, 2);
15-
assertEq(calculatedOutputs, 1);
15+
assertEq(calculatedOutputs, 2);
1616
}
1717

1818
function testRunForkCurrentPriceHappy() external {
@@ -23,7 +23,8 @@ contract LibOpPythPriceTest is Test {
2323
inputs[1] = StackItem.wrap(Float.unwrap(LibDecimalFloat.packLossless(72 hours, 0)));
2424

2525
StackItem[] memory outputs = LibOpPythPrice.run(OperandV2.wrap(0), inputs);
26-
assertEq(outputs.length, 1);
26+
assertEq(outputs.length, 2);
2727
assertEq(StackItem.unwrap(outputs[0]), Float.unwrap(LibDecimalFloat.packLossless(172.3176e5, -5)));
28+
assertEq(StackItem.unwrap(outputs[1]), Float.unwrap(LibDecimalFloat.packLossless(2.00302e5, -5)));
2829
}
2930
}

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

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,59 +11,74 @@ import {Float, LibDecimalFloat} from "rain.math.float/lib/LibDecimalFloat.sol";
1111
contract LibPythGetPriceNoOlderThanTest is Test {
1212
using LibIntOrAString for string;
1313

14-
function getPriceNoOlderThanExternal(IntOrAString symbol, Float maxAge) external view returns (Float) {
14+
function getPriceNoOlderThanExternal(IntOrAString symbol, Float maxAge) external view returns (Float, Float) {
1515
return LibPyth.getPriceNoOlderThan(symbol, maxAge);
1616
}
1717

18-
function checkPriceNoOlderThan(IntOrAString symbol, Float maxAge, Float expectedPrice) internal view {
19-
Float actualPrice = this.getPriceNoOlderThanExternal(symbol, maxAge);
18+
function checkPriceNoOlderThan(IntOrAString symbol, Float maxAge, Float expectedPrice, Float expectedConf)
19+
internal
20+
view
21+
{
22+
(Float actualPrice, Float actualConf) = LibPyth.getPriceNoOlderThan(symbol, maxAge);
2023
(int256 actualSignedCoefficient, int256 actualExponent) = LibDecimalFloat.unpack(actualPrice);
2124
console2.logInt(actualSignedCoefficient);
2225
console2.logInt(actualExponent);
23-
assertEq(Float.unwrap(LibPyth.getPriceNoOlderThan(symbol, maxAge)), Float.unwrap(expectedPrice));
26+
(actualSignedCoefficient, actualExponent) = LibDecimalFloat.unpack(actualConf);
27+
console2.logInt(actualSignedCoefficient);
28+
console2.logInt(actualExponent);
29+
assertEq(Float.unwrap(actualPrice), Float.unwrap(expectedPrice));
30+
assertEq(Float.unwrap(actualConf), Float.unwrap(expectedConf));
2431
}
2532

2633
function testPriceNoOlderThanArbitrum() external {
2734
vm.createSelectFork(FORK_RPC_URL_ARBITRUM, FORK_BLOCK_ARBITRUM);
2835
checkPriceNoOlderThan(
2936
LibIntOrAString.fromString2("Equity.US.GOOG/USD"),
3037
LibDecimalFloat.packLossless(72 hours, 0),
31-
LibDecimalFloat.packLossless(172.3176e5, -5)
38+
LibDecimalFloat.packLossless(172.3176e5, -5),
39+
LibDecimalFloat.packLossless(2.00302e5, -5)
3240
);
3341
checkPriceNoOlderThan(
3442
LibIntOrAString.fromString2("Equity.US.AMZN/USD"),
3543
LibDecimalFloat.packLossless(500 hours, 0),
36-
LibDecimalFloat.packLossless(205.06198e5, -5)
44+
LibDecimalFloat.packLossless(205.06198e5, -5),
45+
LibDecimalFloat.packLossless(0.27188e5, -5)
3746
);
3847
checkPriceNoOlderThan(
3948
LibIntOrAString.fromString2("Equity.US.AAPL/USD"),
4049
LibDecimalFloat.packLossless(72 hours, 0),
41-
LibDecimalFloat.packLossless(202.86002e5, -5)
50+
LibDecimalFloat.packLossless(202.86002e5, -5),
51+
LibDecimalFloat.packLossless(1.91401e5, -5)
4252
);
4353
checkPriceNoOlderThan(
4454
LibIntOrAString.fromString2("Equity.US.MSFT/USD"),
4555
LibDecimalFloat.packLossless(72 hours, 0),
46-
LibDecimalFloat.packLossless(469.8035e5, -5)
56+
LibDecimalFloat.packLossless(469.8035e5, -5),
57+
LibDecimalFloat.packLossless(2.02763e5, -5)
4758
);
4859
checkPriceNoOlderThan(
4960
LibIntOrAString.fromString2("Equity.US.TSLA/USD"),
5061
LibDecimalFloat.packLossless(300 hours, 0),
51-
LibDecimalFloat.packLossless(360.02978e5, -5)
62+
LibDecimalFloat.packLossless(360.02978e5, -5),
63+
LibDecimalFloat.packLossless(0.35259e5, -5)
5264
);
5365
checkPriceNoOlderThan(
5466
LibIntOrAString.fromString2("Equity.US.NVDA/USD"),
5567
LibDecimalFloat.packLossless(1000 hours, 0),
56-
LibDecimalFloat.packLossless(104.5623e5, -5)
68+
LibDecimalFloat.packLossless(104.5623e5, -5),
69+
LibDecimalFloat.packLossless(0.1513e5, -5)
5770
);
5871
checkPriceNoOlderThan(
5972
LibIntOrAString.fromString2("Equity.US.META/USD"),
6073
LibDecimalFloat.packLossless(8000 hours, 0),
61-
LibDecimalFloat.packLossless(448.73e5, -5)
74+
LibDecimalFloat.packLossless(448.73e5, -5),
75+
LibDecimalFloat.packLossless(0.72984e5, -5)
6276
);
6377
checkPriceNoOlderThan(
6478
LibIntOrAString.fromString2("Equity.US.GME/USD"),
6579
LibDecimalFloat.packLossless(8000 hours, 0),
66-
LibDecimalFloat.packLossless(29.3177e5, -5)
80+
LibDecimalFloat.packLossless(29.3177e5, -5),
81+
LibDecimalFloat.packLossless(0.26199e5, -5)
6782
);
6883
}
6984

@@ -72,57 +87,68 @@ contract LibPythGetPriceNoOlderThanTest is Test {
7287
checkPriceNoOlderThan(
7388
LibIntOrAString.fromString2("Equity.US.GOOG/USD"),
7489
LibDecimalFloat.packLossless(24 hours, 0),
75-
LibDecimalFloat.packLossless(246.29352e5, -5)
90+
LibDecimalFloat.packLossless(246.29352e5, -5),
91+
LibDecimalFloat.packLossless(0.40327e5, -5)
7692
);
7793
checkPriceNoOlderThan(
7894
LibIntOrAString.fromString2("Equity.US.AMZN/USD"),
7995
LibDecimalFloat.packLossless(24 hours, 0),
80-
LibDecimalFloat.packLossless(222.43512e5, -5)
96+
LibDecimalFloat.packLossless(222.43512e5, -5),
97+
LibDecimalFloat.packLossless(0.10153e5, -5)
8198
);
8299
checkPriceNoOlderThan(
83100
LibIntOrAString.fromString2("Equity.US.AAPL/USD"),
84101
LibDecimalFloat.packLossless(24 hours, 0),
85-
LibDecimalFloat.packLossless(257.33026e5, -5)
102+
LibDecimalFloat.packLossless(257.33026e5, -5),
103+
LibDecimalFloat.packLossless(0.13478e5, -5)
86104
);
87105
checkPriceNoOlderThan(
88106
LibIntOrAString.fromString2("Equity.US.MSFT/USD"),
89107
LibDecimalFloat.packLossless(24 hours, 0),
90-
LibDecimalFloat.packLossless(515.64431e5, -5)
108+
LibDecimalFloat.packLossless(515.64431e5, -5),
109+
LibDecimalFloat.packLossless(0.21746e5, -5)
91110
);
92111
checkPriceNoOlderThan(
93112
LibIntOrAString.fromString2("Equity.US.TSLA/USD"),
94113
LibDecimalFloat.packLossless(24 hours, 0),
95-
LibDecimalFloat.packLossless(436.03414e5, -5)
114+
LibDecimalFloat.packLossless(436.03414e5, -5),
115+
LibDecimalFloat.packLossless(0.28529e5, -5)
96116
);
97117
checkPriceNoOlderThan(
98118
LibIntOrAString.fromString2("Equity.US.NVDA/USD"),
99119
LibDecimalFloat.packLossless(24 hours, 0),
100-
LibDecimalFloat.packLossless(188.92e5, -5)
120+
LibDecimalFloat.packLossless(188.92e5, -5),
121+
LibDecimalFloat.packLossless(0.13648e5, -5)
101122
);
102123
checkPriceNoOlderThan(
103124
LibIntOrAString.fromString2("Equity.US.META/USD"),
104125
LibDecimalFloat.packLossless(24 hours, 0),
105-
LibDecimalFloat.packLossless(727.0145e5, -5)
126+
LibDecimalFloat.packLossless(727.0145e5, -5),
127+
LibDecimalFloat.packLossless(0.40439e5, -5)
106128
);
107129
checkPriceNoOlderThan(
108130
LibIntOrAString.fromString2("Equity.US.GME/USD"),
109131
LibDecimalFloat.packLossless(24 hours, 0),
110-
LibDecimalFloat.packLossless(27.24202e5, -5)
132+
LibDecimalFloat.packLossless(27.24202e5, -5),
133+
LibDecimalFloat.packLossless(0.05212e5, -5)
111134
);
112135
checkPriceNoOlderThan(
113136
LibIntOrAString.fromString2("Equity.US.MSTR/USD"),
114137
LibDecimalFloat.packLossless(24 hours, 0),
115-
LibDecimalFloat.packLossless(352.34642e5, -5)
138+
LibDecimalFloat.packLossless(352.34642e5, -5),
139+
LibDecimalFloat.packLossless(0.32048e5, -5)
116140
);
117141
checkPriceNoOlderThan(
118142
LibIntOrAString.fromString2("Equity.US.BRK-B/USD"),
119143
LibDecimalFloat.packLossless(24 hours, 0),
120-
LibDecimalFloat.packLossless(496.12003e5, -5)
144+
LibDecimalFloat.packLossless(496.12003e5, -5),
145+
LibDecimalFloat.packLossless(0.1009e5, -5)
121146
);
122147
checkPriceNoOlderThan(
123148
LibIntOrAString.fromString2("Equity.US.SPLG/USD"),
124149
LibDecimalFloat.packLossless(24 hours, 0),
125-
LibDecimalFloat.packLossless(78.71367e5, -5)
150+
LibDecimalFloat.packLossless(78.71367e5, -5),
151+
LibDecimalFloat.packLossless(0.03281e5, -5)
126152
);
127153
}
128154
}

0 commit comments

Comments
 (0)