@@ -13,6 +13,29 @@ contract MorphoPythOracleTest is Test {
13
13
function setUp () public {
14
14
mockPyth = new MockPyth (60 , 1 );
15
15
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 ) {
16
39
// Create price feed update data for WBTC/USD
17
40
bytes [] memory updateData = new bytes [](2 );
18
41
updateData[0 ] = mockPyth.createPriceFeedUpdateData (
@@ -36,25 +59,7 @@ contract MorphoPythOracleTest is Test {
36
59
uint64 (block .timestamp ),
37
60
uint64 (block .timestamp )
38
61
);
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;
58
63
}
59
64
60
65
function testInitialSetup () public {
@@ -88,4 +93,48 @@ contract MorphoPythOracleTest is Test {
88
93
) / uint256 (int256 (mockPyth.getPriceUnsafe (pythUsdtUsdFeed).price))
89
94
);
90
95
}
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
+ }
91
140
}
0 commit comments