@@ -13,6 +13,29 @@ contract MorphoPythOracleTest is Test {
1313 function setUp () public {
1414 mockPyth = new MockPyth (60 , 1 );
1515
16+ // Update the price feed
17+ mockPyth.updatePriceFeeds {value: 2 }(getPriceUpdateData ());
18+
19+ assertEq (mockPyth.getPriceUnsafe (pythWbtcUsdFeed).price, 30000 * 1e8 );
20+ assertEq (mockPyth.getPriceUnsafe (pythUsdtUsdFeed).price, 1 * 1e8 );
21+
22+ oracle = new MorphoPythOracle (
23+ address (mockPyth),
24+ vaultZero,
25+ 1 ,
26+ pythWbtcUsdFeed,
27+ pythFeedZero,
28+ pythWbtcUsdTokenDecimals,
29+ vaultZero,
30+ 1 ,
31+ pythUsdtUsdFeed,
32+ pythFeedZero,
33+ pythUsdtUsdTokenDecimals,
34+ oneMinute
35+ );
36+ }
37+
38+ function getPriceUpdateData () internal view returns (bytes [] memory ) {
1639 // Create price feed update data for WBTC/USD
1740 bytes [] memory updateData = new bytes [](2 );
1841 updateData[0 ] = mockPyth.createPriceFeedUpdateData (
@@ -36,25 +59,7 @@ contract MorphoPythOracleTest is Test {
3659 uint64 (block .timestamp ),
3760 uint64 (block .timestamp )
3861 );
39- // Update the price feed
40- mockPyth.updatePriceFeeds {value: 2 }(updateData);
41- assertEq (mockPyth.getPriceUnsafe (pythWbtcUsdFeed).price, 30000 * 1e8 );
42- assertEq (mockPyth.getPriceUnsafe (pythUsdtUsdFeed).price, 1 * 1e8 );
43-
44- oracle = new MorphoPythOracle (
45- address (mockPyth),
46- vaultZero,
47- 1 ,
48- pythWbtcUsdFeed,
49- pythFeedZero,
50- pythWbtcUsdTokenDecimals,
51- vaultZero,
52- 1 ,
53- pythUsdtUsdFeed,
54- pythFeedZero,
55- pythUsdtUsdTokenDecimals,
56- oneHour
57- );
62+ return updateData;
5863 }
5964
6065 function testInitialSetup () public {
@@ -88,4 +93,48 @@ contract MorphoPythOracleTest is Test {
8893 ) / uint256 (int256 (mockPyth.getPriceUnsafe (pythUsdtUsdFeed).price))
8994 );
9095 }
96+
97+ function testPriceFeedAgeValidation () public {
98+ // This should work - price is current
99+ uint256 price = oracle.price ();
100+ assertTrue (price > 0 );
101+ }
102+
103+ function testPriceFeedStalePrice () public {
104+ vm.warp (block .timestamp + oneMinute + 1 );
105+ // This should revert due to stale price
106+ vm.expectRevert (bytes4 (0x19abf40e )); // StalePrice error
107+ oracle.price ();
108+ }
109+
110+ function testZeroPriceHandling () public {
111+ // Set up price feeds with zero price
112+ bytes [] memory updateData = new bytes [](2 );
113+ updateData[0 ] = mockPyth.createPriceFeedUpdateData (
114+ pythWbtcUsdFeed,
115+ 0 , // Zero price
116+ 1000000 , // Confidence interval
117+ - 6 , // Expo (-6 means price is multiplied by 10^-6)
118+ 0 , // EMA price
119+ 0 , // EMA Confidence interval
120+ uint64 (block .timestamp ) + 1 ,
121+ uint64 (block .timestamp ) + 1
122+ );
123+
124+ updateData[1 ] = mockPyth.createPriceFeedUpdateData (
125+ pythUsdtUsdFeed,
126+ 1 * 1e6 , // Price of 1 USD
127+ 0 , // Confidence interval
128+ - 6 , // Expo (-6 means price is multiplied by 10^-6)
129+ 1 * 1e6 , // EMA price
130+ 0 , // EMA Confidence interval
131+ uint64 (block .timestamp ) + 1 ,
132+ uint64 (block .timestamp ) + 1
133+ );
134+ mockPyth.updatePriceFeeds {value: 2 }(updateData);
135+
136+ // Zero price should be valid (price = 0 is allowed, only negative is rejected)
137+ uint256 price = oracle.price ();
138+ assertEq (price, 0 );
139+ }
91140}
0 commit comments