Skip to content

Commit 1cb7116

Browse files
feat: impl min bal and refactor subscription mgmt
Co-Authored-By: Tejas Badadare <[email protected]>
1 parent 0237566 commit 1cb7116

File tree

6 files changed

+284
-126
lines changed

6 files changed

+284
-126
lines changed

target_chains/ethereum/contracts/contracts/pulse/scheduler/IScheduler.sol

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ interface IScheduler is SchedulerEvents {
1414
* @notice Adds a new subscription
1515
* @param subscriptionParams The parameters for the subscription
1616
* @return subscriptionId The ID of the newly created subscription
17+
* @dev Requires msg.value to be at least the minimum balance for the subscription
1718
*/
1819
function addSubscription(
1920
SchedulerState.SubscriptionParams calldata subscriptionParams
20-
) external returns (uint256 subscriptionId);
21+
) external payable returns (uint256 subscriptionId);
2122

2223
/**
2324
* @notice Gets a subscription's parameters and status
@@ -43,13 +44,9 @@ interface IScheduler is SchedulerEvents {
4344
function updateSubscription(
4445
uint256 subscriptionId,
4546
SchedulerState.SubscriptionParams calldata newSubscriptionParams
46-
) external;
47+
) external payable;
4748

48-
/**
49-
* @notice Deactivates a subscription
50-
* @param subscriptionId The ID of the subscription to deactivate
51-
*/
52-
function deactivateSubscription(uint256 subscriptionId) external;
49+
// Deactivation is now handled through updateSubscription by setting isActive to false
5350

5451
/**
5552
* @notice Updates price feeds for a subscription.
@@ -116,7 +113,7 @@ interface IScheduler is SchedulerEvents {
116113
*/
117114
function getMinimumBalance(
118115
uint8 numPriceFeeds
119-
) external returns (uint256 minimumBalance);
116+
) external view returns (uint256 minimumBalance);
120117

121118
/**
122119
* @notice Gets all active subscriptions with their parameters

target_chains/ethereum/contracts/contracts/pulse/scheduler/Scheduler.sol

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ abstract contract Scheduler is IScheduler, SchedulerState {
2222

2323
function addSubscription(
2424
SubscriptionParams memory subscriptionParams
25-
) external override returns (uint256 subscriptionId) {
25+
) external payable override returns (uint256 subscriptionId) {
2626
if (subscriptionParams.priceIds.length > MAX_PRICE_IDS) {
2727
revert TooManyPriceIds(
2828
subscriptionParams.priceIds.length,
@@ -51,6 +51,17 @@ abstract contract Scheduler is IScheduler, SchedulerState {
5151
.maxGasMultiplierCapPct = DEFAULT_MAX_GAS_MULTIPLIER_CAP_PCT;
5252
}
5353

54+
// Calculate minimum balance required for this subscription
55+
uint256 minimumBalance = this.getMinimumBalance(uint8(subscriptionParams.priceIds.length));
56+
57+
// Ensure enough funds were provided
58+
if (msg.value < minimumBalance) {
59+
revert InsufficientBalance();
60+
}
61+
62+
// Set subscription to active
63+
subscriptionParams.isActive = true;
64+
5465
subscriptionId = _state.subscriptionNumber++;
5566

5667
// Store the subscription parameters
@@ -61,7 +72,7 @@ abstract contract Scheduler is IScheduler, SchedulerState {
6172
subscriptionId
6273
];
6374
status.priceLastUpdatedAt = 0;
64-
status.balanceInWei = 0;
75+
status.balanceInWei = msg.value;
6576
status.totalUpdates = 0;
6677
status.totalSpent = 0;
6778
status.isActive = true;
@@ -93,11 +104,20 @@ abstract contract Scheduler is IScheduler, SchedulerState {
93104
function updateSubscription(
94105
uint256 subscriptionId,
95106
SubscriptionParams memory newSubscriptionParams
96-
) external override onlyManager(subscriptionId) {
97-
if (!_state.subscriptionStatuses[subscriptionId].isActive) {
98-
revert InactiveSubscription();
107+
) external payable override onlyManager(subscriptionId) {
108+
SubscriptionStatus storage status = _state.subscriptionStatuses[subscriptionId];
109+
bool wasActive = status.isActive;
110+
bool willBeActive = newSubscriptionParams.isActive;
111+
112+
// If subscription is inactive and will remain inactive, no need to validate parameters
113+
if (!wasActive && !willBeActive) {
114+
// Update subscription parameters
115+
_state.subscriptionParams[subscriptionId] = newSubscriptionParams;
116+
emit SubscriptionUpdated(subscriptionId);
117+
return;
99118
}
100-
119+
120+
// Validate parameters for active or to-be-activated subscriptions
101121
if (newSubscriptionParams.priceIds.length > MAX_PRICE_IDS) {
102122
revert TooManyPriceIds(
103123
newSubscriptionParams.priceIds.length,
@@ -125,24 +145,35 @@ abstract contract Scheduler is IScheduler, SchedulerState {
125145
.gasConfig
126146
.maxGasMultiplierCapPct = DEFAULT_MAX_GAS_MULTIPLIER_CAP_PCT;
127147
}
148+
149+
// Handle activation/deactivation
150+
if (!wasActive && willBeActive) {
151+
// Reactivating a subscription - ensure minimum balance
152+
uint256 minimumBalance = this.getMinimumBalance(uint8(newSubscriptionParams.priceIds.length));
153+
154+
// Add any funds sent with this transaction
155+
status.balanceInWei += msg.value;
156+
157+
// Check if balance meets minimum requirement
158+
if (status.balanceInWei < minimumBalance) {
159+
revert InsufficientBalance();
160+
}
161+
162+
status.isActive = true;
163+
emit SubscriptionActivated(subscriptionId);
164+
} else if (wasActive && !willBeActive) {
165+
// Deactivating a subscription
166+
status.isActive = false;
167+
emit SubscriptionDeactivated(subscriptionId);
168+
}
128169

129170
// Update subscription parameters
130171
_state.subscriptionParams[subscriptionId] = newSubscriptionParams;
131172

132173
emit SubscriptionUpdated(subscriptionId);
133174
}
134175

135-
function deactivateSubscription(
136-
uint256 subscriptionId
137-
) external override onlyManager(subscriptionId) {
138-
if (!_state.subscriptionStatuses[subscriptionId].isActive) {
139-
revert InactiveSubscription();
140-
}
141-
142-
_state.subscriptionStatuses[subscriptionId].isActive = false;
143-
144-
emit SubscriptionDeactivated(subscriptionId);
145-
}
176+
// Removed standalone deactivateSubscription function as it's now handled in updateSubscription
146177

147178
function updatePriceFeeds(
148179
uint256 subscriptionId,
@@ -439,11 +470,22 @@ abstract contract Scheduler is IScheduler, SchedulerState {
439470
SubscriptionStatus storage status = _state.subscriptionStatuses[
440471
subscriptionId
441472
];
473+
SubscriptionParams storage params = _state.subscriptionParams[
474+
subscriptionId
475+
];
442476

443477
if (status.balanceInWei < amount) {
444478
revert InsufficientBalance();
445479
}
446480

481+
// If subscription is active, ensure minimum balance is maintained
482+
if (status.isActive) {
483+
uint256 minimumBalance = this.getMinimumBalance(uint8(params.priceIds.length));
484+
if (status.balanceInWei - amount < minimumBalance) {
485+
revert InsufficientBalance();
486+
}
487+
}
488+
447489
status.balanceInWei -= amount;
448490

449491
(bool sent, ) = msg.sender.call{value: amount}("");

target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerEvents.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ interface SchedulerEvents {
1010
);
1111
event SubscriptionUpdated(uint256 indexed subscriptionId);
1212
event SubscriptionDeactivated(uint256 indexed subscriptionId);
13+
event SubscriptionActivated(uint256 indexed subscriptionId);
1314
event PricesUpdated(uint256 indexed subscriptionId, uint256 timestamp);
1415
}

target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerState.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ contract SchedulerState {
3232
bytes32[] priceIds;
3333
address[] readerWhitelist;
3434
bool whitelistEnabled;
35+
bool isActive;
3536
UpdateCriteria updateCriteria;
3637
GasConfig gasConfig;
3738
}

target_chains/ethereum/contracts/contracts/pulse/scheduler/SchedulerUpgradeable.sol

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,16 @@ contract SchedulerUpgradeable is
6161
function version() public pure returns (string memory) {
6262
return "1.0.0";
6363
}
64+
65+
// Implementation of deactivateSubscription that forwards to updateSubscription
66+
function deactivateSubscription(uint256 subscriptionId) external onlyManager(subscriptionId) {
67+
// Get current subscription parameters
68+
SchedulerState.SubscriptionParams memory params = _state.subscriptionParams[subscriptionId];
69+
70+
// Set isActive to false
71+
params.isActive = false;
72+
73+
// Call updateSubscription to handle the deactivation
74+
this.updateSubscription(subscriptionId, params);
75+
}
6476
}

0 commit comments

Comments
 (0)