Skip to content

Commit 96f1bca

Browse files
committed
test: fix testAddFundsEnforcesMinimumBalance
1 parent 929bef1 commit 96f1bca

File tree

1 file changed

+53
-126
lines changed

1 file changed

+53
-126
lines changed

target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol

Lines changed: 53 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)