@@ -1246,9 +1246,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils {
12461246 scheduler.updatePriceFeeds (subscriptionId, updateData);
12471247 }
12481248
1249- function testUpdateSubscriptionEnforcesMinimumBalanceOnAddingFeeds ()
1250- public
1251- {
1249+ function testUpdateSubscriptionEnforcesMinimumBalance () public {
12521250 // Setup: Create subscription with 2 feeds, funded exactly to minimum
12531251 uint8 initialNumFeeds = 2 ;
12541252 uint256 subscriptionId = addTestSubscriptionWithFeeds (
@@ -1317,7 +1315,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils {
13171315 newParams_deact.priceIds = createPriceIds (newNumFeeds_deact);
13181316 newParams_deact.isActive = false ; // Deactivate
13191317
1320- // Action 3: Update (should succeed even with insufficient funds for 4 feeds)
1318+ // Action 3: Update (should succeed even with insufficient min balance for 4 feeds)
13211319 scheduler.updateSubscription (subId_deact, newParams_deact);
13221320
13231321 // Verification 3: Subscription should be inactive and have 4 feeds
@@ -1334,6 +1332,80 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils {
13341332 newNumFeeds_deact,
13351333 "Number of price feeds should be updated even when deactivating "
13361334 );
1335+
1336+ // Scenario 4: Reducing number of feeds still checks minimum balance
1337+ // Create a subscription with 2 feeds funded to minimum
1338+ uint8 initialNumFeeds_reduce = 2 ;
1339+ uint256 subId_reduce = addTestSubscriptionWithFeeds (
1340+ scheduler,
1341+ initialNumFeeds_reduce,
1342+ address (reader)
1343+ );
1344+
1345+ // Deplete the balance by updating price feeds multiple times
1346+ uint64 publishTime = SafeCast.toUint64 (block .timestamp );
1347+ for (uint i = 0 ; i < 50 ; i++ ) {
1348+ // Advance publish time by 60s for each update to satisfy update criteria
1349+ (
1350+ PythStructs.PriceFeed[] memory priceFeeds_reduce ,
1351+ uint64 [] memory slots_reduce
1352+ ) = createMockPriceFeedsWithSlots (publishTime + (i * 60 ), 2 );
1353+ mockParsePriceFeedUpdatesWithSlots (
1354+ pyth,
1355+ priceFeeds_reduce,
1356+ slots_reduce
1357+ );
1358+ bytes [] memory updateData_reduce = createMockUpdateData (
1359+ priceFeeds_reduce
1360+ );
1361+ vm.prank (pusher);
1362+ scheduler.updatePriceFeeds (subId_reduce, updateData_reduce);
1363+ }
1364+
1365+ // Check that balance is now below minimum for 1 feed
1366+ (, SchedulerState.SubscriptionStatus memory status_reduce ) = scheduler
1367+ .getSubscription (subId_reduce);
1368+ uint256 minBalanceForOneFeed = scheduler.getMinimumBalance (1 );
1369+ assertTrue (
1370+ status_reduce.balanceInWei < minBalanceForOneFeed,
1371+ "Balance should be below minimum for 1 feed "
1372+ );
1373+
1374+ // Prepare params to reduce feeds from 2 to 1
1375+ (
1376+ SchedulerState.SubscriptionParams memory currentParams_reduce ,
1377+
1378+ ) = scheduler.getSubscription (subId_reduce);
1379+ SchedulerState.SubscriptionParams
1380+ memory newParams_reduce = currentParams_reduce;
1381+ newParams_reduce.priceIds = new bytes32 [](1 );
1382+ newParams_reduce.priceIds[0 ] = currentParams_reduce.priceIds[0 ];
1383+
1384+ // Action 4: Update should fail due to insufficient balance
1385+ vm.expectRevert (abi.encodeWithSelector (InsufficientBalance.selector ));
1386+ scheduler.updateSubscription (subId_reduce, newParams_reduce);
1387+
1388+ // Add funds to cover minimum balance for 1 feed
1389+ uint256 additionalFunds = minBalanceForOneFeed -
1390+ status_reduce.balanceInWei +
1391+ 0.01 ether ;
1392+
1393+ // Now the update should succeed
1394+ scheduler.updateSubscription {value: additionalFunds}(
1395+ subId_reduce,
1396+ newParams_reduce
1397+ );
1398+
1399+ // Verify the subscription now has 1 feed
1400+ (
1401+ SchedulerState.SubscriptionParams memory updatedParams_reduce ,
1402+
1403+ ) = scheduler.getSubscription (subId_reduce);
1404+ assertEq (
1405+ updatedParams_reduce.priceIds.length ,
1406+ 1 ,
1407+ "Number of price feeds should be reduced to 1 "
1408+ );
13371409 }
13381410
13391411 function testGetPricesUnsafeAllFeeds () public {
0 commit comments