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

Commit 32c079a

Browse files
authored
Update the SDK for downstream optimizations (#32)
* Move events to PythEvents This is helpful for testing in solidity (using Foundry) * Remove unneccsary events and event fields * Make all methods virtual This will allow downstream further optimizations * Bump version from 2.0.0 to 2.1.0 Events changes are breaking only to downstream consumers and not for on-chain consumers. So it's minor for on-chain usage. * Update ABIs * rename PythEvents + IPythEvents * Add abi for IPythEvents * Add/update comments
1 parent 53c5d9f commit 32c079a

File tree

11 files changed

+88
-235
lines changed

11 files changed

+88
-235
lines changed

AbstractPyth.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,33 @@ abstract contract AbstractPyth is IPyth {
1616

1717
function getValidTimePeriod() public view virtual override returns (uint validTimePeriod);
1818

19-
function getPrice(bytes32 id) external view override returns (PythStructs.Price memory price) {
19+
function getPrice(bytes32 id) external virtual view override returns (PythStructs.Price memory price) {
2020
return getPriceNoOlderThan(id, getValidTimePeriod());
2121
}
2222

23-
function getEmaPrice(bytes32 id) external view override returns (PythStructs.Price memory price) {
23+
function getEmaPrice(bytes32 id) external virtual view override returns (PythStructs.Price memory price) {
2424
return getEmaPriceNoOlderThan(id, getValidTimePeriod());
2525
}
2626

27-
function getPriceUnsafe(bytes32 id) public view override returns (PythStructs.Price memory price) {
27+
function getPriceUnsafe(bytes32 id) public virtual view override returns (PythStructs.Price memory price) {
2828
PythStructs.PriceFeed memory priceFeed = queryPriceFeed(id);
2929
return priceFeed.price;
3030
}
3131

32-
function getPriceNoOlderThan(bytes32 id, uint age) public view override returns (PythStructs.Price memory price) {
32+
function getPriceNoOlderThan(bytes32 id, uint age) public virtual view override returns (PythStructs.Price memory price) {
3333
price = getPriceUnsafe(id);
3434

3535
require(diff(block.timestamp, price.publishTime) <= age, "no price available which is recent enough");
3636

3737
return price;
3838
}
3939

40-
function getEmaPriceUnsafe(bytes32 id) public view override returns (PythStructs.Price memory price) {
40+
function getEmaPriceUnsafe(bytes32 id) public virtual view override returns (PythStructs.Price memory price) {
4141
PythStructs.PriceFeed memory priceFeed = queryPriceFeed(id);
4242
return priceFeed.emaPrice;
4343
}
4444

45-
function getEmaPriceNoOlderThan(bytes32 id, uint age) public view override returns (PythStructs.Price memory price) {
45+
function getEmaPriceNoOlderThan(bytes32 id, uint age) public virtual view override returns (PythStructs.Price memory price) {
4646
price = getEmaPriceUnsafe(id);
4747

4848
require(diff(block.timestamp, price.publishTime) <= age, "no ema price available which is recent enough");
@@ -62,7 +62,7 @@ abstract contract AbstractPyth is IPyth {
6262
// Access modifier is overridden to public to be able to call it locally.
6363
function updatePriceFeeds(bytes[] calldata updateData) public virtual payable override;
6464

65-
function updatePriceFeedsIfNecessary(bytes[] calldata updateData, bytes32[] calldata priceIds, uint64[] calldata publishTimes) external payable override {
65+
function updatePriceFeedsIfNecessary(bytes[] calldata updateData, bytes32[] calldata priceIds, uint64[] calldata publishTimes) external virtual payable override {
6666
require(priceIds.length == publishTimes.length, "priceIds and publishTimes arrays should have same length");
6767

6868
bool updateNeeded = false;

IPyth.sol

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,12 @@
22
pragma solidity ^0.8.0;
33

44
import "./PythStructs.sol";
5+
import "./IPythEvents.sol";
56

67
/// @title Consume prices from the Pyth Network (https://pyth.network/).
78
/// @dev Please refer to the guidance at https://docs.pyth.network/consumers/best-practices for how to consume prices safely.
89
/// @author Pyth Data Association
9-
interface IPyth {
10-
/// @dev Emitted when an update for price feed with `id` is processed successfully.
11-
/// @param id The Pyth Price Feed ID.
12-
/// @param fresh True if the price update is more recent and stored.
13-
/// @param chainId ID of the source chain that the batch price update containing this price.
14-
/// This value comes from Wormhole, and you can find the corresponding chains at https://docs.wormholenetwork.com/wormhole/contracts.
15-
/// @param sequenceNumber Sequence number of the batch price update containing this price.
16-
/// @param lastPublishTime Publish time of the previously stored price.
17-
/// @param publishTime Publish time of the given price update.
18-
/// @param price Price of the given price update.
19-
/// @param conf Confidence interval of the given price update.
20-
event PriceFeedUpdate(bytes32 indexed id, bool indexed fresh, uint16 chainId, uint64 sequenceNumber, uint lastPublishTime, uint publishTime, int64 price, uint64 conf);
21-
22-
/// @dev Emitted when a batch price update is processed successfully.
23-
/// @param chainId ID of the source chain that the batch price update comes from.
24-
/// @param sequenceNumber Sequence number of the batch price update.
25-
/// @param batchSize Number of prices within the batch price update.
26-
/// @param freshPricesInBatch Number of prices that were more recent and were stored.
27-
event BatchPriceFeedUpdate(uint16 chainId, uint64 sequenceNumber, uint batchSize, uint freshPricesInBatch);
28-
29-
/// @dev Emitted when a call to `updatePriceFeeds` is processed successfully.
30-
/// @param sender Sender of the call (`msg.sender`).
31-
/// @param batchCount Number of batches that this function processed.
32-
/// @param fee Amount of paid fee for updating the prices.
33-
event UpdatePriceFeeds(address indexed sender, uint batchCount, uint fee);
34-
10+
interface IPyth is IPythEvents {
3511
/// @notice Returns the period (in seconds) that a price feed is considered valid since its publish time
3612
function getValidTimePeriod() external view returns (uint validTimePeriod);
3713

IPythEvents.sol

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity ^0.8.0;
3+
4+
/// @title IPythEvents contains the events that Pyth contract emits.
5+
/// @dev This interface can be used for listening to the updates for off-chain and testing purposes.
6+
interface IPythEvents {
7+
/// @dev Emitted when the price feed with `id` has received a fresh update.
8+
/// @param id The Pyth Price Feed ID.
9+
/// @param publishTime Publish time of the given price update.
10+
/// @param price Price of the given price update.
11+
/// @param conf Confidence interval of the given price update.
12+
event PriceFeedUpdate(bytes32 indexed id, uint64 publishTime, int64 price, uint64 conf);
13+
14+
/// @dev Emitted when a batch price update is processed successfully.
15+
/// @param chainId ID of the source chain that the batch price update comes from.
16+
/// @param sequenceNumber Sequence number of the batch price update.
17+
event BatchPriceFeedUpdate(uint16 chainId, uint64 sequenceNumber);
18+
}

MockPyth.sol

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,37 +41,27 @@ contract MockPyth is AbstractPyth {
4141
require(success, "failed to transfer update fee");
4242
}
4343

44-
uint freshPrices = 0;
45-
4644
// Chain ID is id of the source chain that the price update comes from. Since it is just a mock contract
4745
// We set it to 1.
4846
uint16 chainId = 1;
4947

5048
for(uint i = 0; i < updateData.length; i++) {
5149
PythStructs.PriceFeed memory priceFeed = abi.decode(updateData[i], (PythStructs.PriceFeed));
5250

53-
bool fresh = false;
5451
uint lastPublishTime = priceFeeds[priceFeed.id].price.publishTime;
5552

5653
if (lastPublishTime < priceFeed.price.publishTime) {
5754
// Price information is more recent than the existing price information.
58-
fresh = true;
5955
priceFeeds[priceFeed.id] = priceFeed;
60-
freshPrices += 1;
56+
emit PriceFeedUpdate(priceFeed.id, uint64(lastPublishTime), priceFeed.price.price, priceFeed.price.conf);
6157
}
62-
63-
emit PriceFeedUpdate(priceFeed.id, fresh, chainId, sequenceNumber, priceFeed.price.publishTime,
64-
lastPublishTime, priceFeed.price.price, priceFeed.price.conf);
6558
}
6659

6760
// In the real contract, the input of this function contains multiple batches that each contain multiple prices.
6861
// This event is emitted when a batch is processed. In this mock contract we consider there is only one batch of prices.
6962
// Each batch has (chainId, sequenceNumber) as it's unique identifier. Here chainId is set to 1 and an increasing sequence number is used.
70-
emit BatchPriceFeedUpdate(chainId, sequenceNumber, updateData.length, freshPrices);
63+
emit BatchPriceFeedUpdate(chainId, sequenceNumber);
7164
sequenceNumber += 1;
72-
73-
// There is only 1 batch of prices
74-
emit UpdatePriceFeeds(msg.sender, 1, requiredFee);
7565
}
7666

7767
function getUpdateFee(bytes[] calldata updateData) public override view returns (uint feeAmount) {

abis/AbstractPyth.json

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,6 @@
1313
"internalType": "uint64",
1414
"name": "sequenceNumber",
1515
"type": "uint64"
16-
},
17-
{
18-
"indexed": false,
19-
"internalType": "uint256",
20-
"name": "batchSize",
21-
"type": "uint256"
22-
},
23-
{
24-
"indexed": false,
25-
"internalType": "uint256",
26-
"name": "freshPricesInBatch",
27-
"type": "uint256"
2816
}
2917
],
3018
"name": "BatchPriceFeedUpdate",
@@ -39,35 +27,11 @@
3927
"name": "id",
4028
"type": "bytes32"
4129
},
42-
{
43-
"indexed": true,
44-
"internalType": "bool",
45-
"name": "fresh",
46-
"type": "bool"
47-
},
48-
{
49-
"indexed": false,
50-
"internalType": "uint16",
51-
"name": "chainId",
52-
"type": "uint16"
53-
},
5430
{
5531
"indexed": false,
5632
"internalType": "uint64",
57-
"name": "sequenceNumber",
58-
"type": "uint64"
59-
},
60-
{
61-
"indexed": false,
62-
"internalType": "uint256",
63-
"name": "lastPublishTime",
64-
"type": "uint256"
65-
},
66-
{
67-
"indexed": false,
68-
"internalType": "uint256",
6933
"name": "publishTime",
70-
"type": "uint256"
34+
"type": "uint64"
7135
},
7236
{
7337
"indexed": false,
@@ -85,31 +49,6 @@
8549
"name": "PriceFeedUpdate",
8650
"type": "event"
8751
},
88-
{
89-
"anonymous": false,
90-
"inputs": [
91-
{
92-
"indexed": true,
93-
"internalType": "address",
94-
"name": "sender",
95-
"type": "address"
96-
},
97-
{
98-
"indexed": false,
99-
"internalType": "uint256",
100-
"name": "batchCount",
101-
"type": "uint256"
102-
},
103-
{
104-
"indexed": false,
105-
"internalType": "uint256",
106-
"name": "fee",
107-
"type": "uint256"
108-
}
109-
],
110-
"name": "UpdatePriceFeeds",
111-
"type": "event"
112-
},
11352
{
11453
"inputs": [
11554
{

abis/IPyth.json

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,6 @@
1313
"internalType": "uint64",
1414
"name": "sequenceNumber",
1515
"type": "uint64"
16-
},
17-
{
18-
"indexed": false,
19-
"internalType": "uint256",
20-
"name": "batchSize",
21-
"type": "uint256"
22-
},
23-
{
24-
"indexed": false,
25-
"internalType": "uint256",
26-
"name": "freshPricesInBatch",
27-
"type": "uint256"
2816
}
2917
],
3018
"name": "BatchPriceFeedUpdate",
@@ -39,35 +27,11 @@
3927
"name": "id",
4028
"type": "bytes32"
4129
},
42-
{
43-
"indexed": true,
44-
"internalType": "bool",
45-
"name": "fresh",
46-
"type": "bool"
47-
},
48-
{
49-
"indexed": false,
50-
"internalType": "uint16",
51-
"name": "chainId",
52-
"type": "uint16"
53-
},
5430
{
5531
"indexed": false,
5632
"internalType": "uint64",
57-
"name": "sequenceNumber",
58-
"type": "uint64"
59-
},
60-
{
61-
"indexed": false,
62-
"internalType": "uint256",
63-
"name": "lastPublishTime",
64-
"type": "uint256"
65-
},
66-
{
67-
"indexed": false,
68-
"internalType": "uint256",
6933
"name": "publishTime",
70-
"type": "uint256"
34+
"type": "uint64"
7135
},
7236
{
7337
"indexed": false,
@@ -85,31 +49,6 @@
8549
"name": "PriceFeedUpdate",
8650
"type": "event"
8751
},
88-
{
89-
"anonymous": false,
90-
"inputs": [
91-
{
92-
"indexed": true,
93-
"internalType": "address",
94-
"name": "sender",
95-
"type": "address"
96-
},
97-
{
98-
"indexed": false,
99-
"internalType": "uint256",
100-
"name": "batchCount",
101-
"type": "uint256"
102-
},
103-
{
104-
"indexed": false,
105-
"internalType": "uint256",
106-
"name": "fee",
107-
"type": "uint256"
108-
}
109-
],
110-
"name": "UpdatePriceFeeds",
111-
"type": "event"
112-
},
11352
{
11453
"inputs": [
11554
{

abis/IPythEvents.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
[
2+
{
3+
"anonymous": false,
4+
"inputs": [
5+
{
6+
"indexed": false,
7+
"internalType": "uint16",
8+
"name": "chainId",
9+
"type": "uint16"
10+
},
11+
{
12+
"indexed": false,
13+
"internalType": "uint64",
14+
"name": "sequenceNumber",
15+
"type": "uint64"
16+
}
17+
],
18+
"name": "BatchPriceFeedUpdate",
19+
"type": "event"
20+
},
21+
{
22+
"anonymous": false,
23+
"inputs": [
24+
{
25+
"indexed": true,
26+
"internalType": "bytes32",
27+
"name": "id",
28+
"type": "bytes32"
29+
},
30+
{
31+
"indexed": false,
32+
"internalType": "uint64",
33+
"name": "publishTime",
34+
"type": "uint64"
35+
},
36+
{
37+
"indexed": false,
38+
"internalType": "int64",
39+
"name": "price",
40+
"type": "int64"
41+
},
42+
{
43+
"indexed": false,
44+
"internalType": "uint64",
45+
"name": "conf",
46+
"type": "uint64"
47+
}
48+
],
49+
"name": "PriceFeedUpdate",
50+
"type": "event"
51+
}
52+
]

0 commit comments

Comments
 (0)