From 9ae285792f0f33ade5ee01c162e50c77899289a2 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Tue, 22 Apr 2025 13:51:32 -0700 Subject: [PATCH 1/3] feat: disallow any config change to permanent feeds, remove gasconfig --- .../contracts/pulse/scheduler/Scheduler.sol | 121 +----------------- .../pulse/scheduler/SchedulerErrors.sol | 3 +- .../pulse/scheduler/SchedulerState.sol | 18 --- .../contracts/forge-test/PulseScheduler.t.sol | 119 +++-------------- .../utils/PulseSchedulerTestUtils.t.sol | 18 +-- 5 files changed, 30 insertions(+), 249 deletions(-) diff --git a/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol b/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol index 80c3853f5b..3255bd038a 100644 --- a/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol +++ b/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol @@ -64,16 +64,19 @@ abstract contract Scheduler is IScheduler, SchedulerState { uint256 subscriptionId, SubscriptionParams memory newParams ) external override onlyManager(subscriptionId) { + // Re-add the definition for currentStatus SchedulerState.SubscriptionStatus storage currentStatus = _state .subscriptionStatuses[subscriptionId]; - SchedulerState.SubscriptionParams storage currentParams = _state - .subscriptionParams[subscriptionId]; + SubscriptionParams storage currentParams = _state.subscriptionParams[ + subscriptionId + ]; bool wasActive = currentParams.isActive; bool willBeActive = newParams.isActive; // Check for permanent subscription restrictions if (currentParams.isPermanent) { - _validatePermanentSubscriptionUpdate(currentParams, newParams); + // For permanent subscriptions, no updates are allowed at all. + revert CannotUpdatePermanentSubscription(); } // If subscription is inactive and will remain inactive, no need to validate parameters @@ -182,19 +185,6 @@ abstract contract Scheduler is IScheduler, SchedulerState { ) { revert InvalidUpdateCriteria(); } - - // If gas config is unset, set it to the default (100x multipliers) - if ( - params.gasConfig.maxBaseFeeMultiplierCapPct == 0 || - params.gasConfig.maxPriorityFeeMultiplierCapPct == 0 - ) { - params - .gasConfig - .maxPriorityFeeMultiplierCapPct = DEFAULT_MAX_PRIORITY_FEE_MULTIPLIER_CAP_PCT; - params - .gasConfig - .maxBaseFeeMultiplierCapPct = DEFAULT_MAX_BASE_FEE_MULTIPLIER_CAP_PCT; - } } /** @@ -415,103 +405,6 @@ abstract contract Scheduler is IScheduler, SchedulerState { revert UpdateConditionsNotMet(); } - /** - * @notice Internal helper to validate modifications to a permanent subscription. - * @param currentParams The current subscription parameters (storage). - * @param newParams The proposed new subscription parameters (memory). - */ - function _validatePermanentSubscriptionUpdate( - SubscriptionParams storage currentParams, - SubscriptionParams memory newParams - ) internal view { - // Cannot disable isPermanent flag once set - if (!newParams.isPermanent) { - revert IllegalPermanentSubscriptionModification(); - } - - // Cannot deactivate a permanent subscription - if (!newParams.isActive) { - revert IllegalPermanentSubscriptionModification(); - } - - // Cannot remove price feeds from a permanent subscription - if (newParams.priceIds.length < currentParams.priceIds.length) { - revert IllegalPermanentSubscriptionModification(); - } - - // Check that all existing price IDs are preserved (adding is allowed, not removing) - for (uint i = 0; i < currentParams.priceIds.length; i++) { - bool found = false; - for (uint j = 0; j < newParams.priceIds.length; j++) { - if (currentParams.priceIds[i] == newParams.priceIds[j]) { - found = true; - break; - } - } - if (!found) { - revert IllegalPermanentSubscriptionModification(); - } - } - - // Cannot change reader whitelist settings for permanent subscriptions - if (newParams.whitelistEnabled != currentParams.whitelistEnabled) { - revert IllegalPermanentSubscriptionModification(); - } - - // Check if the set of addresses in the whitelist is the same - if ( - newParams.readerWhitelist.length != - currentParams.readerWhitelist.length - ) { - revert IllegalPermanentSubscriptionModification(); - } - uint256 n = newParams.readerWhitelist.length; - bool[] memory currentVisited = new bool[](n); - uint256 matchesFound = 0; - for (uint256 i = 0; i < n; i++) { - bool foundInCurrent = false; - for (uint256 j = 0; j < n; j++) { - if ( - !currentVisited[j] && - newParams.readerWhitelist[i] == - currentParams.readerWhitelist[j] - ) { - currentVisited[j] = true; - foundInCurrent = true; - matchesFound++; - break; - } - } - if (!foundInCurrent) { - revert IllegalPermanentSubscriptionModification(); - } - } - - // Cannot change update criteria for permanent subscriptions - if ( - newParams.updateCriteria.updateOnHeartbeat != - currentParams.updateCriteria.updateOnHeartbeat || - newParams.updateCriteria.heartbeatSeconds != - currentParams.updateCriteria.heartbeatSeconds || - newParams.updateCriteria.updateOnDeviation != - currentParams.updateCriteria.updateOnDeviation || - newParams.updateCriteria.deviationThresholdBps != - currentParams.updateCriteria.deviationThresholdBps - ) { - revert IllegalPermanentSubscriptionModification(); - } - - // Cannot change gas config for permanent subscriptions - if ( - newParams.gasConfig.maxBaseFeeMultiplierCapPct != - currentParams.gasConfig.maxBaseFeeMultiplierCapPct || - newParams.gasConfig.maxPriorityFeeMultiplierCapPct != - currentParams.gasConfig.maxPriorityFeeMultiplierCapPct - ) { - revert IllegalPermanentSubscriptionModification(); - } - } - /// FETCH PRICES /** @@ -635,7 +528,7 @@ abstract contract Scheduler is IScheduler, SchedulerState { // Prevent withdrawals from permanent subscriptions if (params.isPermanent) { - revert IllegalPermanentSubscriptionModification(); + revert CannotUpdatePermanentSubscription(); } if (status.balanceInWei < amount) { diff --git a/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerErrors.sol b/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerErrors.sol index 1149a0e523..6a24a0e5ab 100644 --- a/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerErrors.sol +++ b/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerErrors.sol @@ -8,7 +8,7 @@ error Unauthorized(); // Subscription state errors error InactiveSubscription(); error InsufficientBalance(); -error IllegalPermanentSubscriptionModification(); +error CannotUpdatePermanentSubscription(); // Price feed errors error InvalidPriceId(bytes32 providedPriceId, bytes32 expectedPriceId); @@ -20,7 +20,6 @@ error PriceSlotMismatch(); // Update criteria errors error InvalidUpdateCriteria(); -error InvalidGasConfig(); error UpdateConditionsNotMet(); error TimestampOlderThanLastUpdate( uint256 providedUpdateTimestamp, diff --git a/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerState.sol b/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerState.sol index 1e1093e775..576a1faa15 100644 --- a/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerState.sol +++ b/target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerState.sol @@ -9,10 +9,6 @@ contract SchedulerState { uint8 public constant MAX_PRICE_IDS_PER_SUBSCRIPTION = 255; /// Maximum number of addresses in the reader whitelist uint8 public constant MAX_READER_WHITELIST_SIZE = 255; - /// Default max gas multiplier - uint32 public constant DEFAULT_MAX_BASE_FEE_MULTIPLIER_CAP_PCT = 10_000; - /// Default max fee multiplier - uint32 public constant DEFAULT_MAX_PRIORITY_FEE_MULTIPLIER_CAP_PCT = 10_000; // TODO: make these updateable via governance /// Maximum time in the past (relative to current block timestamp) @@ -45,7 +41,6 @@ contract SchedulerState { bool isActive; bool isPermanent; UpdateCriteria updateCriteria; - GasConfig gasConfig; } struct SubscriptionStatus { @@ -55,19 +50,6 @@ contract SchedulerState { uint256 totalSpent; } - /// @dev When pushing prices, providers will use a "fast gas" estimation as default. - /// If the gas is insufficient to land the transaction, the provider will linearly scale - /// base fee and priority fee multipliers until the transaction lands. - /// These parameters allow the subscriber to impose limits on these multipliers. - /// For example, with maxBaseFeeMultiplierCapPct = 10_000 (default), the provider can - /// use a max of 100x (10000%) of the estimated gas as reported by the RPC. - struct GasConfig { - /// Base gas fee price multiplier limit percent for update operations - uint32 maxBaseFeeMultiplierCapPct; - /// Priority fee multiplier limit for update operations - uint32 maxPriorityFeeMultiplierCapPct; - } - struct UpdateCriteria { bool updateOnHeartbeat; uint32 heartbeatSeconds; diff --git a/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol b/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol index 3eb3888b5b..c3cea97c59 100644 --- a/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol +++ b/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol @@ -144,11 +144,6 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { params.updateCriteria.deviationThresholdBps, "Deviation threshold mismatch" ); - assertEq( - storedParams.gasConfig.maxBaseFeeMultiplierCapPct, - params.gasConfig.maxBaseFeeMultiplierCapPct, - "Max gas multiplier mismatch" - ); assertEq( status.balanceInWei, @@ -178,12 +173,6 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { deviationThresholdBps: 200 // Changed from 100 }); - SchedulerState.GasConfig memory newGasConfig = SchedulerState - .GasConfig({ - maxBaseFeeMultiplierCapPct: 20_000, // Changed from 10_000 - maxPriorityFeeMultiplierCapPct: 20_000 // Changed from 10_000 - }); - SchedulerState.SubscriptionParams memory newParams = SchedulerState .SubscriptionParams({ priceIds: newPriceIds, @@ -191,8 +180,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { whitelistEnabled: false, // Changed from true isActive: true, isPermanent: false, - updateCriteria: newUpdateCriteria, - gasConfig: newGasConfig + updateCriteria: newUpdateCriteria }); // Update subscription @@ -230,11 +218,6 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { 200, "Deviation threshold mismatch" ); - assertEq( - storedParams.gasConfig.maxBaseFeeMultiplierCapPct, - 20_000, - "Max gas multiplier mismatch" - ); } function testUpdateSubscriptionClearsRemovedPriceFeeds() public { @@ -508,9 +491,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { updatedParams.isPermanent = false; vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.updateSubscription(subscriptionId, updatedParams); @@ -525,9 +506,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { updatedParams.priceIds = reducedPriceIds; vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.updateSubscription(subscriptionId, updatedParams); @@ -540,13 +519,11 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { scheduler.addFunds{value: extraFunds}(subscriptionId); vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.withdrawFunds(subscriptionId, 0.1 ether); - // Test 4: Can still add more price feeds + // Test 4: Cannot add more price feeds updatedParams = storedParams; bytes32[] memory expandedPriceIds = new bytes32[]( params.priceIds.length + 1 @@ -558,39 +535,28 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { uint256(keccak256(abi.encodePacked("additional-price-id"))) ); updatedParams.priceIds = expandedPriceIds; - updatedParams.isPermanent = true; // Ensure we keep isPermanent flag set to true + vm.expectRevert( + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) + ); scheduler.updateSubscription(subscriptionId, updatedParams); - // Verify price feeds were added + // Verify price feeds were not added (length should remain the same) (storedParams, ) = scheduler.getSubscription(subscriptionId); assertEq( storedParams.priceIds.length, - params.priceIds.length + 1, - "Should be able to add price feeds to permanent subscription" - ); - - // Test 5: Cannot change gasConfig - updatedParams = storedParams; - updatedParams.gasConfig.maxBaseFeeMultiplierCapPct = - storedParams.gasConfig.maxBaseFeeMultiplierCapPct + - 100; - vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + params.priceIds.length, // Verify length hasn't changed + "Should not be able to add price feeds to permanent subscription" ); - scheduler.updateSubscription(subscriptionId, updatedParams); + // Test 5: Cannot change gasConfig (This check is now implicit in the general update rejection) // Test 6: Cannot change updateCriteria updatedParams = storedParams; updatedParams.updateCriteria.heartbeatSeconds = storedParams.updateCriteria.heartbeatSeconds + 60; vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.updateSubscription(subscriptionId, updatedParams); @@ -598,9 +564,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { updatedParams = storedParams; updatedParams.whitelistEnabled = !storedParams.whitelistEnabled; vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.updateSubscription(subscriptionId, updatedParams); @@ -615,9 +579,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { expandedWhitelist[storedParams.readerWhitelist.length] = address(0x456); updatedParams.readerWhitelist = expandedWhitelist; vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.updateSubscription(subscriptionId, updatedParams); @@ -634,7 +596,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { updatedParams.readerWhitelist = reducedWhitelist; vm.expectRevert( abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector + CannotUpdatePermanentSubscription.selector ) ); scheduler.updateSubscription(subscriptionId, updatedParams); @@ -644,9 +606,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { updatedParams = storedParams; updatedParams.isActive = false; vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.updateSubscription(subscriptionId, updatedParams); } @@ -678,9 +638,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { // Verify we can't make it non-permanent again params.isPermanent = false; vm.expectRevert( - abi.encodeWithSelector( - IllegalPermanentSubscriptionModification.selector - ) + abi.encodeWithSelector(CannotUpdatePermanentSubscription.selector) ); scheduler.updateSubscription(subscriptionId, params); } @@ -1292,11 +1250,6 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { deviationThresholdBps: 100 }); - SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig({ - maxBaseFeeMultiplierCapPct: 10_000, - maxPriorityFeeMultiplierCapPct: 10_000 - }); - SchedulerState.SubscriptionParams memory pusherParams = SchedulerState .SubscriptionParams({ priceIds: priceIds, @@ -1304,8 +1257,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { whitelistEnabled: false, isActive: true, isPermanent: false, - updateCriteria: updateCriteria, - gasConfig: gasConfig + updateCriteria: updateCriteria }); uint256 minimumBalance = scheduler.getMinimumBalance( @@ -1520,39 +1472,6 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { scheduler.updateSubscription(initialSubId, invalidDeviationParams); } - // Helper function to create default subscription parameters - function _createDefaultSubscriptionParams( - uint256 numFeeds - ) internal view returns (SchedulerState.SubscriptionParams memory) { - bytes32[] memory priceIds = createPriceIds(numFeeds); - address[] memory readerWhitelist = new address[](1); - readerWhitelist[0] = address(reader); - - SchedulerState.UpdateCriteria memory updateCriteria = SchedulerState - .UpdateCriteria({ - updateOnHeartbeat: true, - heartbeatSeconds: 60, - updateOnDeviation: true, - deviationThresholdBps: 100 - }); - - SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig({ - maxBaseFeeMultiplierCapPct: 10_000, - maxPriorityFeeMultiplierCapPct: 10_000 - }); - - return - SchedulerState.SubscriptionParams({ - priceIds: priceIds, - readerWhitelist: readerWhitelist, - whitelistEnabled: true, - isActive: true, - isPermanent: false, - updateCriteria: updateCriteria, - gasConfig: gasConfig - }); - } - // Required to receive ETH when withdrawing funds receive() external payable {} } diff --git a/target_chains/ethereum/contracts/forge-test/utils/PulseSchedulerTestUtils.t.sol b/target_chains/ethereum/contracts/forge-test/utils/PulseSchedulerTestUtils.t.sol index b1806535d8..5a13d4454f 100644 --- a/target_chains/ethereum/contracts/forge-test/utils/PulseSchedulerTestUtils.t.sol +++ b/target_chains/ethereum/contracts/forge-test/utils/PulseSchedulerTestUtils.t.sol @@ -54,11 +54,6 @@ abstract contract PulseSchedulerTestUtils is Test, PulseTestUtils { address[] memory readerWhitelist = new address[](1); readerWhitelist[0] = whitelistedReader; - SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig({ - maxBaseFeeMultiplierCapPct: 10_000, - maxPriorityFeeMultiplierCapPct: 10_000 - }); - SchedulerState.SubscriptionParams memory params = SchedulerState .SubscriptionParams({ priceIds: priceIds, @@ -66,12 +61,11 @@ abstract contract PulseSchedulerTestUtils is Test, PulseTestUtils { whitelistEnabled: true, isActive: true, isPermanent: false, - updateCriteria: updateCriteria, - gasConfig: gasConfig + updateCriteria: updateCriteria }); uint256 minimumBalance = scheduler.getMinimumBalance( - uint8(priceIds.length) + uint8(params.priceIds.length) ); return scheduler.createSubscription{value: minimumBalance}(params); } @@ -93,11 +87,6 @@ abstract contract PulseSchedulerTestUtils is Test, PulseTestUtils { deviationThresholdBps: 100 }); - SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig({ - maxBaseFeeMultiplierCapPct: 10_000, - maxPriorityFeeMultiplierCapPct: 10_000 - }); - return SchedulerState.SubscriptionParams({ priceIds: priceIds, @@ -105,8 +94,7 @@ abstract contract PulseSchedulerTestUtils is Test, PulseTestUtils { whitelistEnabled: true, isActive: true, isPermanent: false, - updateCriteria: updateCriteria, - gasConfig: gasConfig + updateCriteria: updateCriteria }); } } From db103ef5189c457e0fc40afbdf3f6d8577ac2743 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Tue, 22 Apr 2025 13:55:20 -0700 Subject: [PATCH 2/3] doc: remove unnecessary comments --- .../contracts/contracts/pulse/scheduler/Scheduler.sol | 4 +--- .../ethereum/contracts/forge-test/PulseScheduler.t.sol | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol b/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol index 3255bd038a..2694794403 100644 --- a/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol +++ b/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol @@ -64,7 +64,6 @@ abstract contract Scheduler is IScheduler, SchedulerState { uint256 subscriptionId, SubscriptionParams memory newParams ) external override onlyManager(subscriptionId) { - // Re-add the definition for currentStatus SchedulerState.SubscriptionStatus storage currentStatus = _state .subscriptionStatuses[subscriptionId]; SubscriptionParams storage currentParams = _state.subscriptionParams[ @@ -73,9 +72,8 @@ abstract contract Scheduler is IScheduler, SchedulerState { bool wasActive = currentParams.isActive; bool willBeActive = newParams.isActive; - // Check for permanent subscription restrictions + // Updates to permanent subscriptions are not allowed if (currentParams.isPermanent) { - // For permanent subscriptions, no updates are allowed at all. revert CannotUpdatePermanentSubscription(); } diff --git a/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol b/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol index c3cea97c59..26ce056da5 100644 --- a/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol +++ b/target_chains/ethereum/contracts/forge-test/PulseScheduler.t.sol @@ -549,7 +549,6 @@ contract SchedulerTest is Test, SchedulerEvents, PulseSchedulerTestUtils { "Should not be able to add price feeds to permanent subscription" ); - // Test 5: Cannot change gasConfig (This check is now implicit in the general update rejection) // Test 6: Cannot change updateCriteria updatedParams = storedParams; updatedParams.updateCriteria.heartbeatSeconds = From 4c943074c3debe1d020933de0f1a8d6a8eeab3e8 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Tue, 22 Apr 2025 14:02:28 -0700 Subject: [PATCH 3/3] fix: consistency --- .../contracts/contracts/pulse/scheduler/Scheduler.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol b/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol index 2694794403..094b7ab5ae 100644 --- a/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol +++ b/target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol @@ -64,13 +64,12 @@ abstract contract Scheduler is IScheduler, SchedulerState { uint256 subscriptionId, SubscriptionParams memory newParams ) external override onlyManager(subscriptionId) { - SchedulerState.SubscriptionStatus storage currentStatus = _state - .subscriptionStatuses[subscriptionId]; + SubscriptionStatus storage currentStatus = _state.subscriptionStatuses[ + subscriptionId + ]; SubscriptionParams storage currentParams = _state.subscriptionParams[ subscriptionId ]; - bool wasActive = currentParams.isActive; - bool willBeActive = newParams.isActive; // Updates to permanent subscriptions are not allowed if (currentParams.isPermanent) { @@ -78,6 +77,8 @@ abstract contract Scheduler is IScheduler, SchedulerState { } // If subscription is inactive and will remain inactive, no need to validate parameters + bool wasActive = currentParams.isActive; + bool willBeActive = newParams.isActive; if (!wasActive && !willBeActive) { // Update subscription parameters _state.subscriptionParams[subscriptionId] = newParams;