Skip to content

Commit 8b6cf2d

Browse files
committed
wip-update
1 parent 2784001 commit 8b6cf2d

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,11 @@ contract PythUtilsTest is Test, WormholeTestUtils, PythTestUtils, IPythEvents {
438438

439439
// Price with 4 decimals and exponent 5
440440
assertEq(PythUtils.convertToUint(100, 1, 2), 100_000); // 100 with 3 zeros
441+
442+
443+
// Edge Cases
444+
assertEq(PythUtils.convertToUint(100, -255, 18), 0);
445+
// assertEq(PythUtils.convertToUint(100, 255, 18), 100_00_000_000_000_000_000_000_000);
441446
}
442447

443448
function testCombinePrices() public {

target_chains/ethereum/sdk/solidity/Math.sol

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,35 @@ library Math {
174174
}
175175
}
176176

177+
/**
178+
* @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).
179+
*/
180+
function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
181+
unchecked {
182+
uint256 c = a * b;
183+
/// @solidity memory-safe-assembly
184+
assembly {
185+
// Only true when the multiplication doesn't overflow
186+
// (c / a == b) || (a == 0)
187+
success := or(eq(div(c, a), b), iszero(a))
188+
}
189+
// equivalent to: success ? c : 0
190+
result = c * toUint(success);
191+
}
192+
}
193+
194+
/**
195+
* @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
196+
*/
197+
function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
198+
unchecked {
199+
success = b > 0;
200+
/// @solidity memory-safe-assembly
201+
assembly {
202+
// The `DIV` opcode returns zero when the denominator is 0.
203+
result := div(a, b)
204+
}
205+
}
206+
}
207+
177208
}

target_chains/ethereum/sdk/solidity/PythUtils.sol

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,24 @@ library PythUtils {
2929
revert PythErrors.InvalidInputExpo();
3030
}
3131

32-
int256 combinedExpo = int32(int8(targetDecimals)) + int32(int8(uint8(uint32(expo))));
32+
int256 combinedExpo = int32(int8(targetDecimals)) + expo;
33+
console.log("combinedExpo", combinedExpo);
3334

3435
if (combinedExpo > 0) {
35-
return uint(uint64(price)) * 10 ** uint32(int32(combinedExpo));
36+
(bool success, uint256 result) = Math.tryMul(uint64(price), 10 ** uint(uint32(int32(combinedExpo))));
37+
if (!success) {
38+
revert PythErrors.CombinedPriceOverflow();
39+
}
40+
return result;
3641
} else {
37-
return uint(uint64(price)) / 10 ** uint32(Math.abs(combinedExpo));
42+
console.log("combinedExpo < 0");
43+
console.log("price", price);
44+
console.log("Math.abs(combinedExpo)", Math.abs(combinedExpo));
45+
(bool success, uint256 result) = Math.tryDiv(uint64(price), 10 ** uint(Math.abs(combinedExpo)));
46+
if (!success) {
47+
revert PythErrors.CombinedPriceOverflow();
48+
}
49+
return result;
3850
}
3951
}
4052

0 commit comments

Comments
 (0)