Skip to content

Commit 4cd48cf

Browse files
authored
Merge pull request #1 from pyth-network/chore-add-test
chore Add some more test
2 parents 89091d9 + 6b567b2 commit 4cd48cf

File tree

4 files changed

+76
-23
lines changed

4 files changed

+76
-23
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
"test": "test"
99
},
1010
"scripts": {
11-
"test": "echo \"Error: no test specified\" && exit 1"
11+
"test": "forge test",
12+
"test:verbose": "forge test -vvv",
13+
"test:gas": "forge test --gas-report",
14+
"coverage": "forge coverage"
1215
},
1316
"keywords": [],
1417
"author": "",

src/morpho-pyth/interfaces/IMorphoPythOracleFactory.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ interface IMorphoPythOracleFactory {
4343
/// @param quoteFeed2 Second quote feed. Pass bytes32(0) if the price = 1. We recommend using stablecoin feeds
4444
/// instead of passing 1.
4545
/// @param quoteTokenDecimals Quote token decimals.
46-
/// @param priceFeedMaxAge The maximum age in secondsfor the oracles prices to be considered valid.
46+
/// @param priceFeedMaxAge The maximum age in seconds for the oracles prices to be considered valid. We have only
47+
/// one price feed max age for all price feed.
4748
/// @param salt The salt to use for the CREATE2.
4849
/// @dev The base asset should be the collateral token and the quote asset the loan token.
4950
function createMorphoPythOracle(

test/MorphoPythOracleTest.sol

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)