Skip to content

Commit 46808d8

Browse files
committed
feat: refactor TwapPriceFeed function for improved readability and structure
1 parent d0ff3a3 commit 46808d8

File tree

2 files changed

+94
-109
lines changed

2 files changed

+94
-109
lines changed

target_chains/ethereum/contracts/contracts/pyth/Pyth.sol

Lines changed: 83 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -317,21 +317,16 @@ abstract contract Pyth is
317317
override
318318
returns (PythStructs.TwapPriceFeed[] memory twapPriceFeeds)
319319
{
320-
{
321-
if (updateData.length != 2) {
322-
revert PythErrors.InvalidUpdateData();
323-
}
324-
uint requiredFee = getUpdateFee(updateData[0]);
320+
if (updateData.length != 2) {
321+
revert PythErrors.InvalidUpdateData();
322+
}
323+
uint requiredFee = getUpdateFee(updateData[0]);
325324

326-
// Check if the two updateData contains the same number of priceUpdates
327-
// by comparing fees since getUpdateFee parses the update data to count price feeds
328-
if (requiredFee != getUpdateFee(updateData[1])) {
329-
revert PythErrors.InvalidUpdateData();
330-
}
331-
if (msg.value < requiredFee) revert PythErrors.InsufficientFee();
325+
if (requiredFee != getUpdateFee(updateData[1])) {
326+
revert PythErrors.InvalidUpdateData();
332327
}
328+
if (msg.value < requiredFee) revert PythErrors.InsufficientFee();
333329

334-
// Parse the updateData
335330
unchecked {
336331
twapPriceFeeds = new PythStructs.TwapPriceFeed[](priceIds.length);
337332
for (uint i = 0; i < updateData[0].length; i++) {
@@ -343,123 +338,102 @@ abstract contract Pyth is
343338
UnsafeCalldataBytesLib.toUint32(updateData[1][i], 0) ==
344339
ACCUMULATOR_MAGIC)
345340
) {
346-
uint offsetStart;
347-
uint offsetEnd;
348-
{
349-
UpdateType updateType;
350-
(
351-
offsetStart,
352-
updateType
353-
) = extractUpdateTypeFromAccumulatorHeader(
354-
updateData[0][i]
355-
);
356-
if (updateType != UpdateType.WormholeMerkle) {
357-
revert PythErrors.InvalidUpdateData();
358-
}
359-
(
360-
offsetEnd,
361-
updateType
362-
) = extractUpdateTypeFromAccumulatorHeader(
363-
updateData[1][i]
364-
);
365-
if (updateType != UpdateType.WormholeMerkle) {
366-
revert PythErrors.InvalidUpdateData();
367-
}
341+
PythInternalStructs.TwapUpdateData memory twapData;
342+
UpdateType updateType;
343+
(
344+
twapData.offsetStart,
345+
updateType
346+
) = extractUpdateTypeFromAccumulatorHeader(
347+
updateData[0][i]
348+
);
349+
if (updateType != UpdateType.WormholeMerkle) {
350+
revert PythErrors.InvalidUpdateData();
351+
}
352+
(
353+
twapData.offsetEnd,
354+
updateType
355+
) = extractUpdateTypeFromAccumulatorHeader(
356+
updateData[1][i]
357+
);
358+
if (updateType != UpdateType.WormholeMerkle) {
359+
revert PythErrors.InvalidUpdateData();
368360
}
369361

370-
bytes20 digestStart;
371-
bytes20 digestEnd;
372-
uint8 numUpdatesStart;
373-
uint8 numUpdatesEnd;
374-
bytes calldata encodedStart;
375-
bytes calldata encodedEnd;
376362
(
377-
offsetStart,
378-
digestStart,
379-
numUpdatesStart,
380-
encodedStart
363+
twapData.offsetStart,
364+
twapData.digestStart,
365+
twapData.numUpdatesStart,
366+
twapData.encodedStart
381367
) = extractWormholeMerkleHeaderDigestAndNumUpdatesAndEncodedFromAccumulatorUpdate(
382368
updateData[0][i],
383-
offsetStart
369+
twapData.offsetStart
384370
);
385371
(
386-
offsetEnd,
387-
digestEnd,
388-
numUpdatesEnd,
389-
encodedEnd
372+
twapData.offsetEnd,
373+
twapData.digestEnd,
374+
twapData.numUpdatesEnd,
375+
twapData.encodedEnd
390376
) = extractWormholeMerkleHeaderDigestAndNumUpdatesAndEncodedFromAccumulatorUpdate(
391377
updateData[1][i],
392-
offsetEnd
378+
twapData.offsetEnd
393379
);
394380

395-
// We have already validated the number of updates in the first and second updateData so we only use numUpdatesStart here
396-
for (uint j = 0; j < numUpdatesStart; j++) {
397-
PythInternalStructs.TwapPriceInfo
398-
memory twapPriceInfoStart;
399-
PythInternalStructs.TwapPriceInfo
400-
memory twapPriceInfoEnd;
401-
bytes32 priceIdStart;
402-
bytes32 priceIdEnd;
381+
PythInternalStructs.TwapPriceInfo memory twapPriceInfoStart;
382+
PythInternalStructs.TwapPriceInfo memory twapPriceInfoEnd;
383+
bytes32 priceIdStart;
384+
bytes32 priceIdEnd;
403385

404-
(
405-
offsetStart,
406-
twapPriceInfoStart,
407-
priceIdStart
408-
) = extractTwapPriceInfoFromMerkleProof(
409-
digestStart,
410-
encodedStart,
411-
offsetStart
412-
);
413-
(
414-
offsetEnd,
415-
twapPriceInfoEnd,
416-
priceIdEnd
417-
) = extractTwapPriceInfoFromMerkleProof(
418-
digestEnd,
419-
encodedEnd,
420-
offsetEnd
421-
);
422-
423-
if (priceIdStart != priceIdEnd)
424-
revert PythErrors.InvalidTwapUpdateDataSet();
386+
// Use original calldata directly in function calls
387+
(
388+
twapData.offsetStart,
389+
twapPriceInfoStart,
390+
priceIdStart
391+
) = extractTwapPriceInfoFromMerkleProof(
392+
twapData.digestStart,
393+
updateData[0][i],
394+
twapData.offsetStart
395+
);
396+
(
397+
twapData.offsetEnd,
398+
twapPriceInfoEnd,
399+
priceIdEnd
400+
) = extractTwapPriceInfoFromMerkleProof(
401+
twapData.digestEnd,
402+
updateData[1][i],
403+
twapData.offsetEnd
404+
);
425405

426-
// Unlike parsePriceFeedUpdatesInternal, we don't call updateLatestPriceIfNecessary here.
427-
// TWAP calculations are read-only operations that compute time-weighted averages
428-
// without updating the contract's state, returning calculated values directly to the caller.
429-
{
430-
uint k = findIndexOfPriceId(priceIds, priceIdStart);
406+
if (priceIdStart != priceIdEnd)
407+
revert PythErrors.InvalidTwapUpdateDataSet();
431408

432-
// If priceFeed[k].id != 0 then it means that there was a valid
433-
// update for priceIds[k] and we don't need to process this one.
434-
if (
435-
k == priceIds.length ||
436-
twapPriceFeeds[k].id != 0
437-
) {
438-
continue;
439-
}
409+
// Unlike parsePriceFeedUpdatesInternal, we don't call updateLatestPriceIfNecessary here.
410+
// TWAP calculations are read-only operations that compute time-weighted averages
411+
// without updating the contract's state, returning calculated values directly to the caller.
412+
uint k = findIndexOfPriceId(priceIds, priceIdStart);
440413

441-
// Perform additional validation checks on the TWAP price data
442-
// to ensure proper time ordering, consistent exponents, and timestamp integrity
443-
// before using the data for calculations
444-
validateTwapPriceInfo(
445-
twapPriceInfoStart,
446-
twapPriceInfoEnd
447-
);
448-
449-
twapPriceFeeds[k] = calculateTwap(
450-
priceIdStart,
451-
twapPriceInfoStart,
452-
twapPriceInfoEnd
453-
);
454-
}
414+
// If priceFeed[k].id != 0 then it means that there was a valid
415+
// update for priceIds[k] and we don't need to process this one.
416+
if (k == priceIds.length || twapPriceFeeds[k].id != 0) {
417+
continue;
455418
}
456-
if (offsetStart != encodedStart.length) {
419+
420+
// Perform additional validation checks on the TWAP price data
421+
// to ensure proper time ordering, consistent exponents, and timestamp integrity
422+
// before using the data for calculations
423+
validateTwapPriceInfo(twapPriceInfoStart, twapPriceInfoEnd);
424+
425+
twapPriceFeeds[k] = calculateTwap(
426+
priceIdStart,
427+
twapPriceInfoStart,
428+
twapPriceInfoEnd
429+
);
430+
if (twapData.offsetStart != twapData.encodedStart.length) {
457431
revert PythErrors.InvalidTwapUpdateData();
458432
}
459-
if (offsetEnd != encodedEnd.length) {
433+
if (twapData.offsetEnd != twapData.encodedEnd.length) {
460434
revert PythErrors.InvalidTwapUpdateData();
461435
}
462-
if (offsetStart != offsetEnd) {
436+
if (twapData.offsetStart != twapData.offsetEnd) {
463437
revert PythErrors.InvalidTwapUpdateData();
464438
}
465439
} else {

target_chains/ethereum/contracts/contracts/pyth/PythInternalStructs.sol

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,15 @@ contract PythInternalStructs {
4444
uint16 chainId;
4545
bytes32 emitterAddress;
4646
}
47+
48+
struct TwapUpdateData {
49+
uint offsetStart;
50+
uint offsetEnd;
51+
bytes20 digestStart;
52+
bytes20 digestEnd;
53+
uint8 numUpdatesStart;
54+
uint8 numUpdatesEnd;
55+
bytes encodedStart;
56+
bytes encodedEnd;
57+
}
4758
}

0 commit comments

Comments
 (0)