Skip to content
This repository was archived by the owner on May 6, 2025. It is now read-only.

Add parsePriceFeedUpdates #34

Merged
merged 2 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions AbstractPyth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,16 @@ abstract contract AbstractPyth is IPyth {

updatePriceFeeds(updateData);
}

function parsePriceFeedUpdates(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64 minPublishTime,
uint64 maxPublishTime
)
external
payable
virtual
override
returns (PythStructs.PriceFeed[] memory priceFeeds);
}
24 changes: 24 additions & 0 deletions IPyth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,28 @@ interface IPyth is IPythEvents {
function getUpdateFee(
bytes[] calldata updateData
) external view returns (uint feeAmount);

/// @notice Parse `updateData` and return price feeds of the given `priceIds` if they are all published
/// within `minPublishTime` and `maxPublishTime`.
///
/// You can use this method if you want to use a Pyth price at a fixed time and not the most recent price;
/// otherwise, please consider using `updatePriceFeeds`. This method does not store the price updates on-chain.
///
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
/// `getUpdateFee` with the length of the `updateData` array.
///
///
/// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is
/// no update for any of the given `priceIds` within the given time range.
/// @param updateData Array of price update data.
/// @param priceIds Array of price ids.
/// @param minPublishTime minimum acceptable publishTime for the given `priceIds`.
/// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`.
/// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order).
function parsePriceFeedUpdates(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64 minPublishTime,
uint64 maxPublishTime
) external payable returns (PythStructs.PriceFeed[] memory priceFeeds);
}
44 changes: 37 additions & 7 deletions MockPyth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@ contract MockPyth is AbstractPyth {
uint requiredFee = getUpdateFee(updateData);
require(msg.value >= requiredFee, "Insufficient paid fee amount");

if (msg.value > requiredFee) {
(bool success, ) = payable(msg.sender).call{
value: msg.value - requiredFee
}("");
require(success, "failed to transfer update fee");
}

// Chain ID is id of the source chain that the price update comes from. Since it is just a mock contract
// We set it to 1.
uint16 chainId = 1;
Expand Down Expand Up @@ -87,6 +80,43 @@ contract MockPyth is AbstractPyth {
return singleUpdateFeeInWei * updateData.length;
}

function parsePriceFeedUpdates(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64 minPublishTime,
uint64 maxPublishTime
) external payable override returns (PythStructs.PriceFeed[] memory feeds) {
uint requiredFee = getUpdateFee(updateData);
require(msg.value >= requiredFee, "Insufficient paid fee amount");

feeds = new PythStructs.PriceFeed[](priceIds.length);

for (uint i = 0; i < priceIds.length; i++) {
for (uint j = 0; j < updateData.length; j++) {
feeds[i] = abi.decode(updateData[j], (PythStructs.PriceFeed));

if (feeds[i].id == priceIds[i]) {
break;
}
}

require(
feeds[i].id == priceIds[i],
"price id does not exist in the updateData"
);

uint publishTime = feeds[i].price.publishTime;
require(
minPublishTime <= publishTime,
"price feed publish time out of range"
);
require(
publishTime <= maxPublishTime,
"price feed publish time out of range"
);
}
}

function createPriceFeedUpdateData(
bytes32 id,
int64 price,
Expand Down
95 changes: 95 additions & 0 deletions abis/AbstractPyth.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,101 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes[]",
"name": "updateData",
"type": "bytes[]"
},
{
"internalType": "bytes32[]",
"name": "priceIds",
"type": "bytes32[]"
},
{
"internalType": "uint64",
"name": "minPublishTime",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "maxPublishTime",
"type": "uint64"
}
],
"name": "parsePriceFeedUpdates",
"outputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"components": [
{
"internalType": "int64",
"name": "price",
"type": "int64"
},
{
"internalType": "uint64",
"name": "conf",
"type": "uint64"
},
{
"internalType": "int32",
"name": "expo",
"type": "int32"
},
{
"internalType": "uint256",
"name": "publishTime",
"type": "uint256"
}
],
"internalType": "struct PythStructs.Price",
"name": "price",
"type": "tuple"
},
{
"components": [
{
"internalType": "int64",
"name": "price",
"type": "int64"
},
{
"internalType": "uint64",
"name": "conf",
"type": "uint64"
},
{
"internalType": "int32",
"name": "expo",
"type": "int32"
},
{
"internalType": "uint256",
"name": "publishTime",
"type": "uint256"
}
],
"internalType": "struct PythStructs.Price",
"name": "emaPrice",
"type": "tuple"
}
],
"internalType": "struct PythStructs.PriceFeed[]",
"name": "priceFeeds",
"type": "tuple[]"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
Expand Down
95 changes: 95 additions & 0 deletions abis/IPyth.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,101 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes[]",
"name": "updateData",
"type": "bytes[]"
},
{
"internalType": "bytes32[]",
"name": "priceIds",
"type": "bytes32[]"
},
{
"internalType": "uint64",
"name": "minPublishTime",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "maxPublishTime",
"type": "uint64"
}
],
"name": "parsePriceFeedUpdates",
"outputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "id",
"type": "bytes32"
},
{
"components": [
{
"internalType": "int64",
"name": "price",
"type": "int64"
},
{
"internalType": "uint64",
"name": "conf",
"type": "uint64"
},
{
"internalType": "int32",
"name": "expo",
"type": "int32"
},
{
"internalType": "uint256",
"name": "publishTime",
"type": "uint256"
}
],
"internalType": "struct PythStructs.Price",
"name": "price",
"type": "tuple"
},
{
"components": [
{
"internalType": "int64",
"name": "price",
"type": "int64"
},
{
"internalType": "uint64",
"name": "conf",
"type": "uint64"
},
{
"internalType": "int32",
"name": "expo",
"type": "int32"
},
{
"internalType": "uint256",
"name": "publishTime",
"type": "uint256"
}
],
"internalType": "struct PythStructs.Price",
"name": "emaPrice",
"type": "tuple"
}
],
"internalType": "struct PythStructs.PriceFeed[]",
"name": "priceFeeds",
"type": "tuple[]"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
Expand Down
Loading