@@ -88,15 +88,15 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
8888
8989 reader = new MockReader (address (proxy));
9090
91- // Start tests at timestamp 100 to avoid underflow when we set
92- // `minPublishTime = timestamp - 10 seconds ` in updatePriceFeeds
93- vm.warp (100 );
91+ // Start tests at a high timestamp to avoid underflow when we set
92+ // `minPublishTime = timestamp - 1 hour ` in updatePriceFeeds
93+ vm.warp (100000 );
9494
9595 // Give pusher 100 ETH for testing
9696 vm.deal (pusher, 100 ether);
9797 }
9898
99- function testcreateSubscription () public {
99+ function testCreateSubscription () public {
100100 // Create subscription parameters
101101 bytes32 [] memory priceIds = createPriceIds ();
102102 address [] memory readerWhitelist = new address [](1 );
@@ -269,11 +269,14 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
269269
270270 bytes32 [] memory initialPriceIds = createPriceIds (numInitialFeeds);
271271 uint64 publishTime = SafeCast.toUint64 (block .timestamp );
272- PythStructs.PriceFeed[] memory initialPriceFeeds = createMockPriceFeeds (
272+ PythStructs.PriceFeed[] memory initialPriceFeeds;
273+ uint64 [] memory slots;
274+ (initialPriceFeeds, slots) = createMockPriceFeedsWithSlots (
273275 publishTime,
274276 numInitialFeeds
275277 );
276- mockParsePriceFeedUpdates (pyth, initialPriceFeeds);
278+
279+ mockParsePriceFeedUpdatesWithSlots (pyth, initialPriceFeeds, slots);
277280 bytes [] memory updateData = createMockUpdateData (initialPriceFeeds);
278281
279282 vm.prank (pusher);
@@ -575,10 +578,14 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
575578 // Create price feeds and mock Pyth response for first update
576579 bytes32 [] memory priceIds = createPriceIds ();
577580 uint64 publishTime1 = SafeCast.toUint64 (block .timestamp );
578- PythStructs.PriceFeed[] memory priceFeeds1 = createMockPriceFeeds (
579- publishTime1
581+ PythStructs.PriceFeed[] memory priceFeeds1;
582+ uint64 [] memory slots;
583+ (priceFeeds1, slots) = createMockPriceFeedsWithSlots (
584+ publishTime1,
585+ priceIds.length
580586 );
581- mockParsePriceFeedUpdates (pyth, priceFeeds1);
587+
588+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds1, slots);
582589 bytes [] memory updateData1 = createMockUpdateData (priceFeeds1);
583590
584591 // Perform first update
@@ -630,7 +637,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
630637 priceFeeds2[i].emaPrice.publishTime = publishTime2;
631638 }
632639
633- mockParsePriceFeedUpdates (pyth, priceFeeds2); // Mock for the second call
640+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds2, slots ); // Mock for the second call
634641 bytes [] memory updateData2 = createMockUpdateData (priceFeeds2);
635642
636643 // Perform second update
@@ -686,25 +693,24 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
686693 );
687694 uint256 fundAmount = 1 ether ;
688695 scheduler.addFunds {value: fundAmount}(subscriptionId);
689-
690696 // First update to set initial timestamp
691697 bytes32 [] memory priceIds = createPriceIds ();
692698 uint64 publishTime1 = SafeCast.toUint64 (block .timestamp );
693- PythStructs.PriceFeed[] memory priceFeeds1 = createMockPriceFeeds (
694- publishTime1
695- );
696- mockParsePriceFeedUpdates (pyth, priceFeeds1);
699+ PythStructs.PriceFeed[] memory priceFeeds1;
700+ uint64 [] memory slots1;
701+ (priceFeeds1, slots1) = createMockPriceFeedsWithSlots (publishTime1, 2 );
702+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds1, slots1 );
697703 bytes [] memory updateData1 = createMockUpdateData (priceFeeds1);
698704 vm.prank (pusher);
699705 scheduler.updatePriceFeeds (subscriptionId, updateData1, priceIds);
700706
701707 // Prepare second update within heartbeat interval
702708 vm.warp (block .timestamp + 30 ); // Advance time by 30 seconds (less than 60)
703709 uint64 publishTime2 = SafeCast.toUint64 (block .timestamp );
704- PythStructs.PriceFeed[] memory priceFeeds2 = createMockPriceFeeds (
705- publishTime2 // Same prices, just new timestamp
706- );
707- mockParsePriceFeedUpdates (pyth, priceFeeds2); // Mock the response for the second update
710+ PythStructs.PriceFeed[] memory priceFeeds2;
711+ uint64 [] memory slots2;
712+ (priceFeeds2, slots2) = createMockPriceFeedsWithSlots (publishTime2, 2 );
713+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds2, slots2);
708714 bytes [] memory updateData2 = createMockUpdateData (priceFeeds2);
709715
710716 // Expect revert because heartbeat condition is not met
@@ -736,10 +742,10 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
736742 // First update to set initial price
737743 bytes32 [] memory priceIds = createPriceIds ();
738744 uint64 publishTime1 = SafeCast.toUint64 (block .timestamp );
739- PythStructs.PriceFeed[] memory priceFeeds1 = createMockPriceFeeds (
740- publishTime1
741- );
742- mockParsePriceFeedUpdates (pyth, priceFeeds1);
745+ PythStructs.PriceFeed[] memory priceFeeds1;
746+ uint64 [] memory slots;
747+ (priceFeeds1, slots) = createMockPriceFeedsWithSlots (publishTime1, 2 );
748+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds1, slots );
743749 bytes [] memory updateData1 = createMockUpdateData (priceFeeds1);
744750 vm.prank (pusher);
745751 scheduler.updatePriceFeeds (subscriptionId, updateData1, priceIds);
@@ -765,7 +771,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
765771 priceFeeds2[i].price.publishTime = publishTime2;
766772 }
767773
768- mockParsePriceFeedUpdates (pyth, priceFeeds2);
774+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds2, slots );
769775 bytes [] memory updateData2 = createMockUpdateData (priceFeeds2);
770776
771777 // Expect revert because deviation condition is not met
@@ -785,22 +791,22 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
785791 // First update to establish last updated timestamp
786792 bytes32 [] memory priceIds = createPriceIds ();
787793 uint64 publishTime1 = SafeCast.toUint64 (block .timestamp );
788- PythStructs.PriceFeed[] memory priceFeeds1 = createMockPriceFeeds (
789- publishTime1
790- );
791- mockParsePriceFeedUpdates (pyth, priceFeeds1);
794+ PythStructs.PriceFeed[] memory priceFeeds1;
795+ uint64 [] memory slots1;
796+ (priceFeeds1, slots1) = createMockPriceFeedsWithSlots (publishTime1, 2 );
797+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds1, slots1 );
792798 bytes [] memory updateData1 = createMockUpdateData (priceFeeds1);
793799
794800 vm.prank (pusher);
795801 scheduler.updatePriceFeeds (subscriptionId, updateData1, priceIds);
796802
797803 // Prepare second update with an older timestamp
798804 uint64 publishTime2 = publishTime1 - 10 ; // Timestamp older than the first update
799- PythStructs.PriceFeed[] memory priceFeeds2 = createMockPriceFeeds (
800- publishTime2
801- );
805+ PythStructs.PriceFeed[] memory priceFeeds2;
806+ uint64 [] memory slots2;
807+ (priceFeeds2, slots2) = createMockPriceFeedsWithSlots (publishTime2, 2 );
802808 // Mock Pyth response to return feeds with the older timestamp
803- mockParsePriceFeedUpdates (pyth, priceFeeds2);
809+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds2, slots2 );
804810 bytes [] memory updateData2 = createMockUpdateData (priceFeeds2);
805811
806812 // Expect revert with TimestampOlderThanLastUpdate (checked in _validateShouldUpdatePrices)
@@ -817,30 +823,32 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
817823 scheduler.updatePriceFeeds (subscriptionId, updateData2, priceIds);
818824 }
819825
820- function testUpdatePriceFeedsRevertsOnMismatchedTimestamps () public {
826+ function testUpdatePriceFeedsRevertsOnMismatchedSlots () public {
821827 // First add a subscription and funds
822828 uint256 subscriptionId = addTestSubscription ();
823829 uint256 fundAmount = 1 ether ;
824830 scheduler.addFunds {value: fundAmount}(subscriptionId);
825831
826- // Create two price feeds with mismatched timestamps
832+ // Create two price feeds with same timestamp but different slots
827833 bytes32 [] memory priceIds = createPriceIds (2 );
828- uint64 time1 = SafeCast.toUint64 (block .timestamp );
829- uint64 time2 = time1 + 10 ;
834+ uint64 publishTime = SafeCast.toUint64 (block .timestamp );
830835 PythStructs.PriceFeed[] memory priceFeeds = new PythStructs.PriceFeed [](
831836 2
832837 );
833- priceFeeds[0 ] = createSingleMockPriceFeed (time1 );
834- priceFeeds[1 ] = createSingleMockPriceFeed (time2 );
838+ priceFeeds[0 ] = createSingleMockPriceFeed (publishTime );
839+ priceFeeds[1 ] = createSingleMockPriceFeed (publishTime );
835840
836- // Mock Pyth response to return these feeds
837- mockParsePriceFeedUpdates (pyth, priceFeeds);
838- bytes [] memory updateData = createMockUpdateData (priceFeeds); // Data needs to match expected length
841+ // Create slots array with different slot values
842+ uint64 [] memory slots = new uint64 [](2 );
843+ slots[0 ] = 100 ;
844+ slots[1 ] = 200 ; // Different slot
839845
840- // Expect revert with PriceTimestampMismatch error
841- vm.expectRevert (
842- abi.encodeWithSelector (PriceTimestampMismatch.selector )
843- );
846+ // Mock Pyth response to return these feeds with mismatched slots
847+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds, slots);
848+ bytes [] memory updateData = createMockUpdateData (priceFeeds);
849+
850+ // Expect revert with PriceSlotMismatch error
851+ vm.expectRevert (abi.encodeWithSelector (PriceSlotMismatch.selector ));
844852
845853 // Attempt to update price feeds
846854 vm.prank (pusher);
@@ -855,10 +863,10 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
855863
856864 bytes32 [] memory priceIds = createPriceIds ();
857865 uint64 publishTime = SafeCast.toUint64 (block .timestamp );
858- PythStructs.PriceFeed[] memory priceFeeds = createMockPriceFeeds (
859- publishTime
860- );
861- mockParsePriceFeedUpdates (pyth, priceFeeds);
866+ PythStructs.PriceFeed[] memory priceFeeds;
867+ uint64 [] memory slots;
868+ (priceFeeds, slots) = createMockPriceFeedsWithSlots (publishTime, 2 );
869+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds, slots );
862870 bytes [] memory updateData = createMockUpdateData (priceFeeds);
863871
864872 vm.prank (pusher);
@@ -893,11 +901,10 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
893901
894902 bytes32 [] memory priceIds = createPriceIds (3 );
895903 uint64 publishTime = SafeCast.toUint64 (block .timestamp );
896- PythStructs.PriceFeed[] memory priceFeeds = createMockPriceFeeds (
897- publishTime,
898- 3
899- );
900- mockParsePriceFeedUpdates (pyth, priceFeeds);
904+ PythStructs.PriceFeed[] memory priceFeeds;
905+ uint64 [] memory slots;
906+ (priceFeeds, slots) = createMockPriceFeedsWithSlots (publishTime, 3 );
907+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds, slots);
901908 bytes [] memory updateData = createMockUpdateData (priceFeeds);
902909
903910 vm.prank (pusher);
@@ -964,10 +971,10 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
964971
965972 // Update price feeds for the subscription
966973 uint64 publishTime = SafeCast.toUint64 (block .timestamp );
967- PythStructs.PriceFeed[] memory priceFeeds = createMockPriceFeeds (
968- publishTime
969- );
970- mockParsePriceFeedUpdates (pyth, priceFeeds);
974+ PythStructs.PriceFeed[] memory priceFeeds;
975+ uint64 [] memory slots;
976+ (priceFeeds, slots) = createMockPriceFeedsWithSlots (publishTime, 2 );
977+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds, slots );
971978 bytes [] memory updateData = createMockUpdateData (priceFeeds);
972979
973980 vm.prank (pusher);
@@ -1025,20 +1032,20 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
10251032
10261033 // Update price feeds for the subscription
10271034 uint64 publishTime = SafeCast.toUint64 (block .timestamp + 10 ); // Slightly different time
1028- PythStructs.PriceFeed[] memory priceFeeds = createMockPriceFeeds (
1035+ PythStructs.PriceFeed[] memory priceFeeds;
1036+ uint64 [] memory slots;
1037+ (priceFeeds, slots) = createMockPriceFeedsWithSlots (
10291038 publishTime,
10301039 priceIds.length
10311040 );
1032- mockParsePriceFeedUpdates (pyth, priceFeeds);
1041+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds, slots );
10331042 bytes [] memory updateData = createMockUpdateData (priceFeeds);
10341043
10351044 vm.prank (pusher);
10361045 scheduler.updatePriceFeeds (subscriptionId, updateData, priceIds);
10371046
10381047 // Try to access from the non-whitelisted address (should fail)
1039- address randomUser = address (0xdead );
1040- address manager = address (this ); // Test contract is the manager
1041- vm.startPrank (randomUser);
1048+ vm.startPrank (address (0xdead ));
10421049 bytes32 [] memory emptyPriceIds = new bytes32 [](0 );
10431050 vm.expectRevert (abi.encodeWithSelector (Unauthorized.selector ));
10441051 scheduler.getPricesUnsafe (subscriptionId, emptyPriceIds);
@@ -1063,7 +1070,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
10631070 );
10641071
10651072 // Try to access from the manager address (should succeed)
1066- vm.startPrank (manager);
1073+ // Test contract is the manager
1074+ vm.startPrank (address (this ));
10671075 PythStructs.Price[] memory pricesFromManager = scheduler
10681076 .getPricesUnsafe (subscriptionId, emptyPriceIds);
10691077 assertEq (
@@ -1082,9 +1090,9 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
10821090
10831091 bytes32 [] memory priceIds = createPriceIds ();
10841092 uint64 publishTime = SafeCast.toUint64 (block .timestamp );
1085- PythStructs.PriceFeed[] memory priceFeeds = createMockPriceFeeds (
1086- publishTime
1087- );
1093+ PythStructs.PriceFeed[] memory priceFeeds;
1094+ uint64 [] memory slots;
1095+ (priceFeeds, slots) = createMockPriceFeedsWithSlots (publishTime, 2 );
10881096
10891097 // Ensure EMA prices are set in the mock price feeds
10901098 for (uint i = 0 ; i < priceFeeds.length ; i++ ) {
@@ -1094,7 +1102,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
10941102 priceFeeds[i].emaPrice.expo = priceFeeds[i].price.expo;
10951103 }
10961104
1097- mockParsePriceFeedUpdates (pyth, priceFeeds);
1105+ mockParsePriceFeedUpdatesWithSlots (pyth, priceFeeds, slots );
10981106 bytes [] memory updateData = createMockUpdateData (priceFeeds);
10991107
11001108 vm.prank (pusher);
0 commit comments