Skip to content

Commit bb06fdb

Browse files
authored
[eth] Gas improvement: Optimize getPrice and getEmaPrice (#389)
* Optimize getPrice and getEmaPrice
1 parent b1afaac commit bb06fdb

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

ethereum/contracts/pyth/Pyth.sol

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,38 @@ abstract contract Pyth is PythGetters, PythSetters, AbstractPyth {
235235
);
236236
}
237237

238+
// This is an overwrite of the same method in AbstractPyth.sol
239+
// to be more gas efficient. It cannot move to PythGetters as it
240+
// is overwriting the interface. Even indirect calling of a similar
241+
// method from PythGetter has some gas overhead.
242+
function getPriceUnsafe(
243+
bytes32 id
244+
) public view override returns (PythStructs.Price memory price) {
245+
PythInternalStructs.PriceInfo storage info = _state.latestPriceInfo[id];
246+
price.publishTime = info.publishTime;
247+
price.expo = info.expo;
248+
price.price = info.price;
249+
price.conf = info.conf;
250+
251+
require(price.publishTime != 0, "price feed for the given id is not pushed or does not exist");
252+
}
253+
254+
// This is an overwrite of the same method in AbstractPyth.sol
255+
// to be more gas efficient. It cannot move to PythGetters as it
256+
// is overwriting the interface. Even indirect calling of a similar
257+
// method from PythGetter has some gas overhead.
258+
function getEmaPriceUnsafe(
259+
bytes32 id
260+
) public view override returns (PythStructs.Price memory price) {
261+
PythInternalStructs.PriceInfo storage info = _state.latestPriceInfo[id];
262+
price.publishTime = info.publishTime;
263+
price.expo = info.expo;
264+
price.price = info.emaPrice;
265+
price.conf = info.emaConf;
266+
267+
require(price.publishTime != 0, "price feed for the given id is not pushed or does not exist");
268+
}
269+
238270
function parsePriceFeedUpdates(
239271
bytes[] calldata updateData,
240272
bytes32[] calldata priceIds,

ethereum/forge-test/GasBenchmark.t.sol

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ contract GasBenchmark is Test, WormholeTestUtils, PythTestUtils {
130130
pyth.getPrice(priceIds[0]);
131131
}
132132

133+
134+
function testBenchmarkGetEmaPrice() public {
135+
// Set the block timestamp to 0. As prices have < 10 timestamp and staleness
136+
// is set to 60 seconds, the getPrice should work as expected.
137+
vm.warp(0);
138+
139+
pyth.getEmaPrice(priceIds[0]);
140+
}
141+
133142
function testBenchmarkGetUpdateFee() public view {
134143
pyth.getUpdateFee(freshPricesUpdateData);
135144
}

0 commit comments

Comments
 (0)