Skip to content

Commit 04a23bf

Browse files
committed
added some test
1 parent 991b7c5 commit 04a23bf

File tree

2 files changed

+58
-71
lines changed

2 files changed

+58
-71
lines changed

target_chains/ethereum/contracts/forge-test/utils/PythTestUtils.t.sol

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -401,64 +401,64 @@ contract PythUtilsTest is Test, WormholeTestUtils, PythTestUtils, IPythEvents {
401401
}
402402

403403
function testCombinePrices() public {
404-
// Test case 1: Basic price combination (ETH/USD / BTC/USD = ETH/BTC)
405-
PythStructs.Price memory ethUsd = PythStructs.Price({
404+
// Test case 1: Basic price combination (StEth/Eth / Eth/USD = ETH/BTC)
405+
PythStructs.Price memory stEthEth = PythStructs.Price({
406406
price: 206487956502,
407407
conf: 10,
408408
expo: -8,
409409
publishTime: block.timestamp
410410
});
411411

412-
PythStructs.Price memory btcUsd = PythStructs.Price({
412+
PythStructs.Price memory ethUsd = PythStructs.Price({
413413
price: 206741615681,
414414
conf: 100,
415415
expo: -8,
416416
publishTime: block.timestamp
417417
});
418418

419-
(int64 price, int32 expo) = PythUtils.combinePrices(ethUsd.price, ethUsd.expo, btcUsd.price, btcUsd.expo);
420-
assertApproxEqRel(price, 99875203, 9e17);
419+
(int64 price, int32 expo) = PythUtils.combinePrices(stEthEth.price, stEthEth.expo, ethUsd.price, ethUsd.expo);
420+
assertApproxEqRel(price, 100000000, 9e17); // $1
421421
assertEq(expo, -8);
422422

423-
// // Test case 2: Different exponents
424-
// PythStructs.Price memory smallPrice = PythStructs.Price({
425-
// price: 100, // $0.01
426-
// conf: 1,
427-
// expo: -4, // 4 decimals
428-
// publishTime: block.timestamp
429-
// });
430-
431-
// PythStructs.Price memory largePrice = PythStructs.Price({
432-
// price: 1000, // $10
433-
// conf: 10,
434-
// expo: -2, // 2 decimals
435-
// publishTime: block.timestamp
436-
// });
437-
438-
// (price, expo) = PythUtils.combinePrices(smallPrice, largePrice, -2);
439-
// assertEq(price, 1); // 0.01
440-
// assertEq(expo, -2);
441-
442-
// // Test case 3: Revert on negative prices
443-
// PythStructs.Price memory negativePrice = PythStructs.Price({
444-
// price: -100,
445-
// conf: 10,
446-
// expo: -2,
447-
// publishTime: block.timestamp
448-
// });
449-
450-
// vm.expectRevert();
451-
// PythUtils.combinePrices(negativePrice, btcUsd, -2);
452-
453-
// // Test case 4: Revert on positive exponents
454-
// PythStructs.Price memory invalidExpo = PythStructs.Price({
455-
// price: 100,
456-
// conf: 10,
457-
// expo: 2,
458-
// publishTime: block.timestamp
459-
// });
460-
461-
// vm.expectRevert();
462-
// PythUtils.combinePrices(ethUsd, invalidExpo, -2);
423+
// Test case 2: Different exponents
424+
PythStructs.Price memory smallPrice = PythStructs.Price({
425+
price: 100, // $0.01
426+
conf: 1,
427+
expo: -4, // 4 decimals
428+
publishTime: block.timestamp
429+
});
430+
431+
PythStructs.Price memory largePrice = PythStructs.Price({
432+
price: 1000, // $10
433+
conf: 10,
434+
expo: -2, // 2 decimals
435+
publishTime: block.timestamp
436+
});
437+
438+
(price, expo) = PythUtils.combinePrices(smallPrice.price, smallPrice.expo, largePrice.price, largePrice.expo);
439+
assertEq(price, 10); // 0.001
440+
assertEq(expo, -4);
441+
442+
// Test case 3: Revert on negative prices
443+
PythStructs.Price memory negativePrice = PythStructs.Price({
444+
price: -100,
445+
conf: 10,
446+
expo: -2,
447+
publishTime: block.timestamp
448+
});
449+
450+
vm.expectRevert();
451+
PythUtils.combinePrices(negativePrice.price, negativePrice.expo, ethUsd.price, ethUsd.expo);
452+
453+
// Test case 4: Revert on positive exponents
454+
PythStructs.Price memory invalidExpo = PythStructs.Price({
455+
price: 100,
456+
conf: 10,
457+
expo: 2,
458+
publishTime: block.timestamp
459+
});
460+
461+
vm.expectRevert();
462+
PythUtils.combinePrices(ethUsd.price, ethUsd.expo, invalidExpo.price, invalidExpo.expo);
463463
}
464464
}

target_chains/ethereum/sdk/solidity/PythUtils.sol

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,42 +41,29 @@ library PythUtils {
4141
/// @return expo The exponent of the combined price
4242
/// @dev This function will revert if either price is negative or if the exponents are invalid
4343
function combinePrices(
44-
PythStructs.Price memory price1,
45-
PythStructs.Price memory price2
44+
int64 price1,
45+
int32 expo1,
46+
int64 price2,
47+
int32 expo2
4648
) public pure returns (int64 combinedPrice, int32 expo) {
47-
if (price1.price < 0 || price2.price < 0 || price1.expo > 0 || price2.expo > 0 || price1.expo < -255 || price2.expo < -255) {
49+
if (price1 < 0 || price2 < 0 || expo1 > 0 || expo2 > 0 || expo1 < -255 || expo2 < -255) {
4850
revert();
4951
}
5052

51-
uint8 p1Decimals = uint8(uint32(-1 * price1.expo));
52-
uint8 p2Decimals = uint8(uint32(-1 * price2.expo));
53+
// Convert both prices to the same decimal places (using the larger of the two)
54+
uint8 maxDecimals = uint8(uint32(-1 * (expo1 < expo2 ? expo1 : expo2)));
55+
uint256 p1 = convertToUint(price1, expo1, maxDecimals);
56+
uint256 p2 = convertToUint(price2, expo2, maxDecimals);
5357

54-
uint256 p1;
55-
uint256 p2;
58+
// Calculate the combined price with precision
59+
uint256 combined = (p1 * 10**18) / p2;
60+
combined = combined / 10 ** (18 - maxDecimals);
5661

57-
if (p1Decimals >= p2Decimals) {
58-
p2 = convertToUint(price2.price, price2.expo, p1Decimals);
59-
p1 = uint256(uint64(price1.price));
60-
} else {
61-
p1 = convertToUint(price1.price, price1.expo, p2Decimals);
62-
p2 = uint256(uint64(price2.price));
63-
}
64-
65-
66-
console.log("p1", p1);
67-
console.log("p2", p2);
68-
69-
// Calculate the combined price
70-
uint256 combined = (p1 * 10**18) / p2; // Multiply by 10^18 to maintain precision
71-
console.log("combined", combined);
72-
// Calculate the new exponent
73-
combined = combined / 10 ** (18 - p1Decimals);
74-
console.log("newExpo", p1Decimals);
7562
// Check if the combined price fits in int64
7663
if (combined > uint256(uint64(type(int64).max))) {
7764
revert();
7865
}
7966

80-
return (int64(uint64(combined)), price1.expo);
67+
return (int64(uint64(combined)), expo1 < expo2 ? expo1 : expo2);
8168
}
8269
}

0 commit comments

Comments
 (0)