@@ -546,20 +546,16 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils {
546546 );
547547 }
548548
549- // Old version of testAddFundsEnforcesMinimumBalance removed to avoid duplication
550-
551- function testAddFundsWithInactiveSubscription () public {
549+ function testAddFundsWithInactiveSubscriptionReverts () public {
552550 // Create a subscription with minimum balance
553551 uint256 subscriptionId = addTestSubscription (
554552 scheduler,
555553 address (reader)
556554 );
557555
558556 // Get subscription parameters and calculate minimum balance
559- (
560- SchedulerState.SubscriptionParams memory params ,
561- // Status not needed for this test
562- ) = scheduler.getSubscription (subscriptionId);
557+ (SchedulerState.SubscriptionParams memory params , ) = scheduler
558+ .getSubscription (subscriptionId);
563559 uint256 minimumBalance = scheduler.getMinimumBalance (
564560 uint8 (params.priceIds.length )
565561 );
@@ -578,7 +574,11 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils {
578574 SchedulerState.SubscriptionParams memory testUpdatedParams ,
579575 SchedulerState.SubscriptionStatus memory testUpdatedStatus
580576 ) = scheduler.getSubscription (subscriptionId);
581- assertEq (testUpdatedStatus.balanceInWei, 1 wei, "Balance should be 1 wei after withdrawal " );
577+ assertEq (
578+ testUpdatedStatus.balanceInWei,
579+ 1 wei,
580+ "Balance should be 1 wei after withdrawal "
581+ );
582582
583583 // Try to add funds to inactive subscription (should fail with InactiveSubscription)
584584 vm.expectRevert (abi.encodeWithSelector (InactiveSubscription.selector ));
@@ -590,149 +590,76 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils {
590590 scheduler.updateSubscription (subscriptionId, testUpdatedParams);
591591 }
592592
593- // Old version of testAddFundsEnforcesMinimumBalanceForPermanentSubscription removed to avoid duplication
594-
595593 function testAddFundsEnforcesMinimumBalance () public {
596- // Create a subscription with more than minimum balance
597- uint256 subscriptionId = scheduler.createSubscription {value: 0.03 ether }(
598- createDefaultSubscriptionParams (2 , address (reader))
594+ uint256 subscriptionId = addTestSubscriptionWithFeeds (
595+ scheduler,
596+ 2 ,
597+ address (reader)
599598 );
600-
601- // Get subscription parameters and calculate minimum balance
602- (
603- SchedulerState.SubscriptionParams memory params ,
604- SchedulerState.SubscriptionStatus memory status
605- ) = scheduler.getSubscription (subscriptionId);
599+ (SchedulerState.SubscriptionParams memory params , ) = scheduler
600+ .getSubscription (subscriptionId);
606601 uint256 minimumBalance = scheduler.getMinimumBalance (
607602 uint8 (params.priceIds.length )
608603 );
609604
610- // Verify subscription is active and has more than minimum balance
611- assertTrue (params.isActive, "Subscription should be active " );
612- assertTrue (status.balanceInWei > minimumBalance, "Initial balance should be greater than minimum balance " );
605+ // Send multiple price updates to drain the balance below minimum
606+ for (uint i = 0 ; i < 5 ; i++ ) {
607+ // Advance time to satisfy heartbeat criteria
608+ vm.warp (block .timestamp + 60 );
613609
614- // Deactivate the subscription so we can withdraw funds
615- SchedulerState.SubscriptionParams memory deactivatedParams = params;
616- deactivatedParams.isActive = false ;
617- scheduler.updateSubscription (subscriptionId, deactivatedParams);
610+ // Create price feeds with current timestamp
611+ uint64 publishTime = SafeCast.toUint64 (block .timestamp );
612+ PythStructs.PriceFeed[] memory priceFeeds;
613+ uint64 [] memory slots;
614+ (priceFeeds, slots) = createMockPriceFeedsWithSlots (
615+ publishTime,
616+ params.priceIds.length
617+ );
618618
619- // Withdraw funds to get below minimum balance
620- uint256 withdrawAmount = status.balanceInWei - minimumBalance + 1 wei ;
621- scheduler.withdrawFunds (subscriptionId, withdrawAmount);
619+ // Mock Pyth response
620+ mockParsePriceFeedUpdatesWithSlotsStrict (pyth, priceFeeds, slots);
621+ bytes [] memory updateData = createMockUpdateData (priceFeeds);
622+
623+ // Perform update
624+ vm.prank (pusher);
625+ scheduler.updatePriceFeeds (subscriptionId, updateData);
626+ }
622627
623628 // Verify balance is now below minimum
624629 (
625630 ,
626- SchedulerState.SubscriptionStatus memory statusAfterWithdraw
631+ SchedulerState.SubscriptionStatus memory statusAfterUpdates
627632 ) = scheduler.getSubscription (subscriptionId);
628633 assertTrue (
629- statusAfterWithdraw .balanceInWei < minimumBalance,
630- "Balance should be below minimum after withdrawal "
634+ statusAfterUpdates .balanceInWei < minimumBalance,
635+ "Balance should be below minimum after updates "
631636 );
632637
633- // Try to reactivate with insufficient balance (should revert with InsufficientBalance)
634- SchedulerState.SubscriptionParams memory reactivatedParams = deactivatedParams;
635- reactivatedParams.isActive = true ;
638+ // Try to add funds that would still leave balance below minimum
639+ // Expect a revert with InsufficientBalance
640+ uint256 insufficientFunds = minimumBalance -
641+ statusAfterUpdates.balanceInWei -
642+ 1 ;
636643 vm.expectRevert (abi.encodeWithSelector (InsufficientBalance.selector ));
637- scheduler.updateSubscription (subscriptionId, reactivatedParams);
638-
639- // Try to add funds to the inactive subscription (should revert with InactiveSubscription)
640- vm.expectRevert (abi.encodeWithSelector (InactiveSubscription.selector ));
641- scheduler.addFunds {value: 0.01 ether }(subscriptionId);
642-
643- // Create a new active subscription with exactly minimum balance
644- uint256 newSubscriptionId = scheduler.createSubscription {value: minimumBalance}(
645- createDefaultSubscriptionParams (2 , address (reader))
646- );
647-
648- // Get subscription parameters and verify balance
649- (
650- SchedulerState.SubscriptionParams memory newParams ,
651- SchedulerState.SubscriptionStatus memory newStatus
652- ) = scheduler.getSubscription (newSubscriptionId);
653- assertTrue (newParams.isActive, "New subscription should be active " );
654- assertEq (newStatus.balanceInWei, minimumBalance, "New subscription balance should equal minimum balance " );
655-
656- // Try to add 0 funds (should succeed since balance is already at minimum)
657- scheduler.addFunds {value: 0 }(newSubscriptionId);
658-
659- // Verify balance is still at minimum
660- (
661- ,
662- SchedulerState.SubscriptionStatus memory statusAfterAddingZero
663- ) = scheduler.getSubscription (newSubscriptionId);
664- assertEq (
665- statusAfterAddingZero.balanceInWei,
666- minimumBalance,
667- "Balance should still be at minimum after adding 0 funds "
668- );
669-
670- // Add more funds (should succeed)
671- scheduler.addFunds {value: 1 ether }(newSubscriptionId);
672-
673- // Verify balance is now increased
674- (
675- ,
676- SchedulerState.SubscriptionStatus memory statusAfterAddingMore
677- ) = scheduler.getSubscription (newSubscriptionId);
678- assertEq (
679- statusAfterAddingMore.balanceInWei,
680- minimumBalance + 1 ether,
681- "Balance should be increased after adding more funds "
682- );
683- }
684-
685- function testAddFundsEnforcesMinimumBalanceForPermanentSubscription () public {
686- // Create a permanent subscription with exactly minimum balance
687- SchedulerState.SubscriptionParams memory params = createDefaultSubscriptionParams (
688- 2 ,
689- address (reader)
690- );
691- params.isPermanent = true ;
692-
693- uint256 minimumBalance = scheduler.getMinimumBalance (uint8 (params.priceIds.length ));
694- uint256 subscriptionId = scheduler.createSubscription {value: minimumBalance}(params);
644+ scheduler.addFunds {value: insufficientFunds}(subscriptionId);
695645
696- // Verify subscription is active and has exactly minimum balance
697- (
698- SchedulerState.SubscriptionParams memory createdParams ,
699- SchedulerState.SubscriptionStatus memory status
700- ) = scheduler.getSubscription (subscriptionId);
701- assertTrue (createdParams.isActive, "Subscription should be active " );
702- assertTrue (createdParams.isPermanent, "Subscription should be permanent " );
703- assertEq (status.balanceInWei, minimumBalance, "Initial balance should equal minimum balance " );
646+ // Add sufficient funds to get back above minimum
647+ uint256 sufficientFunds = minimumBalance -
648+ statusAfterUpdates.balanceInWei +
649+ 1 ;
650+ scheduler.addFunds {value: sufficientFunds}(subscriptionId);
704651
705- // Try to add 0 funds (should succeed since balance is already at minimum)
706- scheduler.addFunds {value: 0 }(subscriptionId);
707-
708- // Verify balance is still at minimum
652+ // Verify balance is now above minimum
709653 (
710654 ,
711- SchedulerState.SubscriptionStatus memory statusAfterAddingZero
655+ SchedulerState.SubscriptionStatus memory statusAfterAddingFunds
712656 ) = scheduler.getSubscription (subscriptionId);
713- assertEq (
714- statusAfterAddingZero.balanceInWei,
715- minimumBalance,
716- "Balance should still be at minimum after adding 0 funds "
717- );
718-
719- // Add more funds (should succeed)
720- scheduler.addFunds {value: 1 wei }(subscriptionId);
721-
722- // Verify balance is now increased
723- (
724- ,
725- SchedulerState.SubscriptionStatus memory statusAfterAddingMore
726- ) = scheduler.getSubscription (subscriptionId);
727- assertEq (
728- statusAfterAddingMore.balanceInWei,
729- minimumBalance + 1 wei,
730- "Permanent subscription balance should be minimum + 1 wei after adding funds "
657+ assertTrue (
658+ statusAfterAddingFunds.balanceInWei >= minimumBalance,
659+ "Balance should be at or above minimum after adding sufficient funds "
731660 );
732661 }
733662
734-
735-
736663 function testWithdrawFunds () public {
737664 // Add a subscription and get the parameters
738665 uint256 subscriptionId = addTestSubscription (
0 commit comments