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

Commit 8ca5b8f

Browse files
ali-behjatitompntn
andauthored
Add updatePriceIfNecessary method (#23)
* Add updatePriceIfNecessary method * Bump version to 0.5.1 (not breaking change) Co-authored-by: Tom Pointon <[email protected]>
1 parent a34132e commit 8ca5b8f

File tree

8 files changed

+111
-4
lines changed

8 files changed

+111
-4
lines changed

AbstractPyth.sol

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import "./PythStructs.sol";
55
import "./IPyth.sol";
66

77
abstract contract AbstractPyth is IPyth {
8-
8+
/// @notice Returns the price feed with given id.
9+
/// @dev Reverts if the price does not exist.
10+
/// @param id The Pyth Price Feed ID of which to fetch the current price and confidence interval.
911
function queryPriceFeed(bytes32 id) public view virtual returns (PythStructs.PriceFeed memory priceFeed);
1012

1113
function getCurrentPrice(bytes32 id) external view override returns (PythStructs.Price memory price) {
@@ -59,4 +61,22 @@ abstract contract AbstractPyth is IPyth {
5961
return y - x;
6062
}
6163
}
64+
65+
// Access modifier is overridden to public to be able to call it locally.
66+
function updatePriceFeeds(bytes[] memory updateData) public virtual payable override;
67+
68+
function updatePriceFeedsIfNecessary(bytes[] memory updateData, bytes32[] memory priceIds, uint64[] memory publishTimes) external payable override {
69+
require(priceIds.length == publishTimes.length, "priceIds and publishTimes arrays should have same length");
70+
71+
bool updateNeeded = false;
72+
for(uint i = 0; i < priceIds.length; i++) {
73+
if (queryPriceFeed(priceIds[i]).publishTime < publishTimes[i]) {
74+
updateNeeded = true;
75+
}
76+
}
77+
78+
require(updateNeeded, "no prices in the submitted batch have fresh prices, so this update will have no effect");
79+
80+
updatePriceFeeds(updateData);
81+
}
6282
}

IPyth.sol

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@ interface IPyth {
7474
/// @param updateData Array of price update data.
7575
function updatePriceFeeds(bytes[] memory updateData) external payable;
7676

77+
/// @notice Wrapper around updatePriceFeeds that rejects fast if a price update is not necessary. A price update is
78+
/// necessary if the current on-chain publishTime is older than the given publishTime. It relies solely on the
79+
/// given `publishTimes` for the price feeds and does not read the actual price update publish time within `updateData`.
80+
///
81+
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
82+
/// `getUpdateFee` with the length of the `updateData` array.
83+
///
84+
/// `priceIds` and `publishTimes` are two arrays with the same size that correspond to senders known publishTime
85+
/// of each priceId when calling this method. If all of price feeds within `priceIds` have updated and have
86+
/// a newer or equal publish time than the given publish time, it will reject the transaction to save gas.
87+
/// Otherwise, it calls updatePriceFeeds method to update the prices.
88+
///
89+
/// @dev Reverts if update is not needed or the transferred fee is not sufficient or the updateData is invalid.
90+
/// @param updateData Array of price update data.
91+
/// @param priceIds Array of price ids.
92+
/// @param publishTimes Array of publishTimes. `publishTimes[i]` corresponds to known `publishTime` of `priceIds[i]`
93+
function updatePriceFeedsIfNecessary(bytes[] memory updateData, bytes32[] memory priceIds, uint64[] memory publishTimes) external payable;
7794

7895
/// @notice Returns the required fee to update an array of price updates.
7996
/// @param updateDataSize Number of price updates.

MockPyth.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ contract MockPyth is AbstractPyth {
1515
}
1616

1717
function queryPriceFeed(bytes32 id) public override view returns (PythStructs.PriceFeed memory priceFeed) {
18+
require(priceFeeds[id].id != 0, "no price feed found for the given price id");
1819
return priceFeeds[id];
1920
}
2021

abis/AbstractPyth.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,5 +386,28 @@
386386
"outputs": [],
387387
"stateMutability": "payable",
388388
"type": "function"
389+
},
390+
{
391+
"inputs": [
392+
{
393+
"internalType": "bytes[]",
394+
"name": "updateData",
395+
"type": "bytes[]"
396+
},
397+
{
398+
"internalType": "bytes32[]",
399+
"name": "priceIds",
400+
"type": "bytes32[]"
401+
},
402+
{
403+
"internalType": "uint64[]",
404+
"name": "publishTimes",
405+
"type": "uint64[]"
406+
}
407+
],
408+
"name": "updatePriceFeedsIfNecessary",
409+
"outputs": [],
410+
"stateMutability": "payable",
411+
"type": "function"
389412
}
390413
]

abis/IPyth.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,5 +295,28 @@
295295
"outputs": [],
296296
"stateMutability": "payable",
297297
"type": "function"
298+
},
299+
{
300+
"inputs": [
301+
{
302+
"internalType": "bytes[]",
303+
"name": "updateData",
304+
"type": "bytes[]"
305+
},
306+
{
307+
"internalType": "bytes32[]",
308+
"name": "priceIds",
309+
"type": "bytes32[]"
310+
},
311+
{
312+
"internalType": "uint64[]",
313+
"name": "publishTimes",
314+
"type": "uint64[]"
315+
}
316+
],
317+
"name": "updatePriceFeedsIfNecessary",
318+
"outputs": [],
319+
"stateMutability": "payable",
320+
"type": "function"
298321
}
299322
]

abis/MockPyth.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,5 +466,28 @@
466466
"outputs": [],
467467
"stateMutability": "payable",
468468
"type": "function"
469+
},
470+
{
471+
"inputs": [
472+
{
473+
"internalType": "bytes[]",
474+
"name": "updateData",
475+
"type": "bytes[]"
476+
},
477+
{
478+
"internalType": "bytes32[]",
479+
"name": "priceIds",
480+
"type": "bytes32[]"
481+
},
482+
{
483+
"internalType": "uint64[]",
484+
"name": "publishTimes",
485+
"type": "uint64[]"
486+
}
487+
],
488+
"name": "updatePriceFeedsIfNecessary",
489+
"outputs": [],
490+
"stateMutability": "payable",
491+
"type": "function"
469492
}
470493
]

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pythnetwork/pyth-sdk-solidity",
3-
"version": "0.5.0",
3+
"version": "0.5.1",
44
"description": "Read prices from the Pyth oracle",
55
"repository": {
66
"type": "git",

0 commit comments

Comments
 (0)