Skip to content

feat(target_chains/ethereum): don't store update in contract storage in parsePriceFeedUpdates #2574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 1 addition & 2 deletions target_chains/ethereum/contracts/contracts/pyth/Pyth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ abstract contract Pyth is
encoded,
offset
);
updateLatestPriceIfNecessary(priceId, priceInfo);
{
// check whether caller requested for this data
uint k = findIndexOfPriceId(priceIds, priceId);
Expand Down Expand Up @@ -397,6 +396,6 @@ abstract contract Pyth is
}

function version() public pure returns (string memory) {
return "1.4.4-alpha.1";
return "1.4.5-alpha.1";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -897,85 +897,6 @@ contract PythWormholeMerkleAccumulatorTest is
);
}

function testParsePriceFeedUniqueWithWormholeMerkleUpdatesLatestPriceIfNecessary(
uint seed
) public {
setRandSeed(seed);

uint64 numPriceFeeds = (getRandUint64() % 10) + 2;
PriceFeedMessage[]
memory priceFeedMessages = generateRandomPriceFeedMessage(
numPriceFeeds
);
uint64 publishTime = getRandUint64();
bytes32[] memory priceIds = new bytes32[](1);
priceIds[0] = priceFeedMessages[0].priceId;
for (uint64 i = 0; i < numPriceFeeds; i++) {
priceFeedMessages[i].priceId = priceFeedMessages[0].priceId;
priceFeedMessages[i].publishTime = publishTime;
priceFeedMessages[i].prevPublishTime = publishTime;
}

// firstUpdate is the one we expect to be returned and latestUpdate is the one we expect to be stored
uint latestUpdate = (getRandUint() % numPriceFeeds);
priceFeedMessages[latestUpdate].prevPublishTime = publishTime + 1000;
priceFeedMessages[latestUpdate].publishTime = publishTime + 1000;

uint firstUpdate = (getRandUint() % numPriceFeeds);
while (firstUpdate == latestUpdate) {
firstUpdate = (getRandUint() % numPriceFeeds);
}
priceFeedMessages[firstUpdate].prevPublishTime = publishTime - 1;
(
bytes[] memory updateData,
uint updateFee
) = createWormholeMerkleUpdateData(priceFeedMessages);

// firstUpdate is returned but latestUpdate is stored
PythStructs.PriceFeed[] memory priceFeeds = pyth
.parsePriceFeedUpdatesUnique{value: updateFee}(
updateData,
priceIds,
publishTime,
MAX_UINT64
);
assertEq(priceFeeds.length, 1);
assertParsedPriceFeedEqualsMessage(
priceFeeds[0],
priceFeedMessages[firstUpdate],
priceIds[0]
);
assertPriceFeedMessageStored(priceFeedMessages[latestUpdate]);

// increase the latestUpdate publish time and make a new updateData
priceFeedMessages[latestUpdate].publishTime = publishTime + 2000;
(updateData, updateFee) = createWormholeMerkleUpdateData(
priceFeedMessages
);

// since there is a revert, the latestUpdate is not stored
vm.expectRevert(PythErrors.PriceFeedNotFoundWithinRange.selector);
pyth.parsePriceFeedUpdatesUnique{value: updateFee}(
updateData,
priceIds,
publishTime - 1,
MAX_UINT64
);
assertEq(
pyth.getPriceUnsafe(priceIds[0]).publishTime,
publishTime + 1000
);

// there is no revert, the latestPrice is updated with the latestUpdate
pyth.parsePriceFeedUpdatesUnique{value: updateFee}(
updateData,
priceIds,
publishTime,
MAX_UINT64
);
assertPriceFeedMessageStored(priceFeedMessages[latestUpdate]);
}

function testParsePriceFeedWithWormholeMerkleWorksRandomDistinctUpdatesInput(
uint seed
) public {
Expand Down
Loading