feat(target_chains/ethereum/sdk/solidity): add convertToUint method to the sdk (#1390)
* Moving convertToUint to utils * pre-commit fix * reversing OracleSwap example * pre-commit] * added test * abi-gen * Added solc to sdk * resolved comments
This commit is contained in:
parent
9328b73284
commit
77db9ee53b
|
@ -59453,7 +59453,47 @@
|
|||
"devDependencies": {
|
||||
"abi_generator": "*",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-solidity": "^1.0.0-rc.1"
|
||||
"prettier-plugin-solidity": "^1.0.0-rc.1",
|
||||
"solc": "^0.8.25"
|
||||
}
|
||||
},
|
||||
"target_chains/ethereum/sdk/solidity/node_modules/commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"target_chains/ethereum/sdk/solidity/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"target_chains/ethereum/sdk/solidity/node_modules/solc": {
|
||||
"version": "0.8.25",
|
||||
"resolved": "https://registry.npmjs.org/solc/-/solc-0.8.25.tgz",
|
||||
"integrity": "sha512-7P0TF8gPeudl1Ko3RGkyY6XVCxe2SdD/qQhtns1vl3yAbK/PDifKDLHGtx1t7mX3LgR7ojV7Fg/Kc6Q9D2T8UQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"command-exists": "^1.2.8",
|
||||
"commander": "^8.1.0",
|
||||
"follow-redirects": "^1.12.1",
|
||||
"js-sha3": "0.8.0",
|
||||
"memorystream": "^0.3.1",
|
||||
"semver": "^5.5.0",
|
||||
"tmp": "0.0.33"
|
||||
},
|
||||
"bin": {
|
||||
"solcjs": "solc.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"target_chains/solana/sdk/js/pyth_solana_receiver": {
|
||||
|
@ -71066,7 +71106,37 @@
|
|||
"requires": {
|
||||
"abi_generator": "*",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-solidity": "^1.0.0-rc.1"
|
||||
"prettier-plugin-solidity": "^1.0.0-rc.1",
|
||||
"solc": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"dev": true
|
||||
},
|
||||
"solc": {
|
||||
"version": "0.8.25",
|
||||
"resolved": "https://registry.npmjs.org/solc/-/solc-0.8.25.tgz",
|
||||
"integrity": "sha512-7P0TF8gPeudl1Ko3RGkyY6XVCxe2SdD/qQhtns1vl3yAbK/PDifKDLHGtx1t7mX3LgR7ojV7Fg/Kc6Q9D2T8UQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"command-exists": "^1.2.8",
|
||||
"commander": "^8.1.0",
|
||||
"follow-redirects": "^1.12.1",
|
||||
"js-sha3": "0.8.0",
|
||||
"memorystream": "^0.3.1",
|
||||
"semver": "^5.5.0",
|
||||
"tmp": "0.0.33"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pythnetwork/pyth-solana-receiver": {
|
||||
|
|
|
@ -12,6 +12,7 @@ import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
|||
import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol";
|
||||
import "@pythnetwork/pyth-sdk-solidity/IPythEvents.sol";
|
||||
import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
|
||||
import "@pythnetwork/pyth-sdk-solidity/PythUtils.sol";
|
||||
|
||||
import "forge-std/Test.sol";
|
||||
import "./WormholeTestUtils.t.sol";
|
||||
|
@ -275,3 +276,35 @@ abstract contract PythTestUtils is Test, WormholeTestUtils, RandTestUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
contract PythUtilsTest is Test, WormholeTestUtils, PythTestUtils, IPythEvents {
|
||||
function testConvertToUnit() public {
|
||||
// Price can't be negative
|
||||
vm.expectRevert();
|
||||
PythUtils.convertToUint(-100, -5, 18);
|
||||
|
||||
// Exponent can't be positive
|
||||
vm.expectRevert();
|
||||
PythUtils.convertToUint(100, 5, 18);
|
||||
|
||||
// Price with 18 decimals and exponent -5
|
||||
assertEq(
|
||||
PythUtils.convertToUint(100, -5, 18),
|
||||
1000000000000000 // 100 * 10^13
|
||||
);
|
||||
|
||||
// Price with 9 decimals and exponent -2
|
||||
assertEq(
|
||||
PythUtils.convertToUint(100, -2, 9),
|
||||
1000000000 // 100 * 10^7
|
||||
);
|
||||
|
||||
// Price with 4 decimals and exponent -5
|
||||
assertEq(PythUtils.convertToUint(100, -5, 4), 10);
|
||||
|
||||
// Price with 5 decimals and exponent -2
|
||||
// @note: We will lose precision here as price is
|
||||
// 0.00001 and we are targetDecimals is 2.
|
||||
assertEq(PythUtils.convertToUint(100, -5, 2), 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
library PythUtils {
|
||||
/// @notice Converts a Pyth price to a uint256 with a target number of decimals
|
||||
/// @param price The Pyth price
|
||||
/// @param expo The Pyth price exponent
|
||||
/// @param targetDecimals The target number of decimals
|
||||
/// @return The price as a uint256
|
||||
/// @dev Function will lose precision if targetDecimals is less than the Pyth price decimals.
|
||||
/// This method will truncate any digits that cannot be represented by the targetDecimals.
|
||||
/// e.g. If the price is 0.000123 and the targetDecimals is 2, the result will be 0
|
||||
function convertToUint(
|
||||
int64 price,
|
||||
int32 expo,
|
||||
uint8 targetDecimals
|
||||
) public pure returns (uint256) {
|
||||
if (price < 0 || expo > 0 || expo < -255) {
|
||||
revert();
|
||||
}
|
||||
|
||||
uint8 priceDecimals = uint8(uint32(-1 * expo));
|
||||
|
||||
if (targetDecimals >= priceDecimals) {
|
||||
return
|
||||
uint(uint64(price)) *
|
||||
10 ** uint32(targetDecimals - priceDecimals);
|
||||
} else {
|
||||
return
|
||||
uint(uint64(price)) /
|
||||
10 ** uint32(priceDecimals - targetDecimals);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int64",
|
||||
"name": "price",
|
||||
"type": "int64"
|
||||
},
|
||||
{
|
||||
"internalType": "int32",
|
||||
"name": "expo",
|
||||
"type": "int32"
|
||||
},
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "targetDecimals",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "convertToUint",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
|
@ -9,7 +9,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"format": "npx prettier --write .",
|
||||
"generate-abi": "npx generate-abis IPyth IPythEvents AbstractPyth MockPyth PythErrors",
|
||||
"generate-abi": "npx generate-abis IPyth IPythEvents AbstractPyth MockPyth PythErrors PythUtils",
|
||||
"check-abi": "git diff --exit-code abis",
|
||||
"build": "solcjs --bin MockPyth.sol --base-path . -o build/"
|
||||
},
|
||||
|
@ -25,8 +25,9 @@
|
|||
},
|
||||
"homepage": "https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/ethereum/sdk/solidity",
|
||||
"devDependencies": {
|
||||
"abi_generator": "*",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-solidity": "^1.0.0-rc.1",
|
||||
"abi_generator": "*"
|
||||
"solc": "^0.8.25"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue