Skip to content

Commit 2440b38

Browse files
feat(pulse-scheduler): address initial comments, update sub management, enforce mininum balance (#2585)
* feat(scheduler): init scheduler state and core functions * ci: apply precommit * test(scheduler): add pulsescheduler tests * fix: better naming * test: add test for mismatched timestamps * fix: access control, add todos * feat(scheduler): enhance price update logic and validation - Updated price feed parsing to allow for a timestamp range of [-10s, now]. - Introduced validation for update conditions, including checks for heartbeat and price deviation. - Added new error handling for outdated timestamps and unmet update conditions. - Refactored subscription status to use a uint256 for last updated timestamp. - Expanded test coverage for update conditions and validation scenarios. * feat: address comments, update sub mgmt, enforce min balance * doc: update comments * refactor: add->createSubscription * fix: clear updates for removed feeds * test: add positive and negative tests for whitelist * refactor: gasconfig names
1 parent 59ea3c8 commit 2440b38

File tree

5 files changed

+897
-239
lines changed

5 files changed

+897
-239
lines changed

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

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ import "./SchedulerEvents.sol";
88
import "./SchedulerState.sol";
99

1010
interface IScheduler is SchedulerEvents {
11-
// CORE FUNCTIONS
12-
1311
/**
14-
* @notice Adds a new subscription
12+
* @notice Creates a new subscription
13+
* @dev Requires msg.value to be at least the minimum balance for the subscription (calculated by getMinimumBalance()).
1514
* @param subscriptionParams The parameters for the subscription
1615
* @return subscriptionId The ID of the newly created subscription
1716
*/
18-
function addSubscription(
17+
function createSubscription(
1918
SchedulerState.SubscriptionParams calldata subscriptionParams
20-
) external returns (uint256 subscriptionId);
19+
) external payable returns (uint256 subscriptionId);
2120

2221
/**
2322
* @notice Gets a subscription's parameters and status
@@ -37,6 +36,8 @@ interface IScheduler is SchedulerEvents {
3736

3837
/**
3938
* @notice Updates an existing subscription
39+
* @dev You can activate or deactivate a subscription by setting isActive to true or false.
40+
* @dev Reactivating a subscription requires the subscription to hold at least the minimum balance (calculated by getMinimumBalance()).
4041
* @param subscriptionId The ID of the subscription to update
4142
* @param newSubscriptionParams The new parameters for the subscription
4243
*/
@@ -45,12 +46,6 @@ interface IScheduler is SchedulerEvents {
4546
SchedulerState.SubscriptionParams calldata newSubscriptionParams
4647
) external;
4748

48-
/**
49-
* @notice Deactivates a subscription
50-
* @param subscriptionId The ID of the subscription to deactivate
51-
*/
52-
function deactivateSubscription(uint256 subscriptionId) external;
53-
5449
/**
5550
* @notice Updates price feeds for a subscription.
5651
* Verifies the updateData using the Pyth contract and validates that all feeds have the same timestamp.
@@ -64,16 +59,36 @@ interface IScheduler is SchedulerEvents {
6459
bytes32[] calldata priceIds
6560
) external;
6661

67-
/**
68-
* @notice Gets the latest prices for a subscription
69-
* @param subscriptionId The ID of the subscription
70-
* @param priceIds Optional array of price IDs to retrieve. If empty, returns all price feeds for the subscription.
71-
* @return The latest price feeds for the requested price IDs
62+
/** @notice Returns the price of a price feed without any sanity checks.
63+
* @dev This function returns the most recent price update in this contract without any recency checks.
64+
* This function is unsafe as the returned price update may be arbitrarily far in the past.
65+
*
66+
* Users of this function should check the `publishTime` in the price to ensure that the returned price is
67+
* sufficiently recent for their application. If you are considering using this function, it may be
68+
* safer / easier to use `getPriceNoOlderThan`.
69+
* @return prices - please read the documentation of PythStructs.Price to understand how to use this safely.
70+
*/
71+
function getPricesUnsafe(
72+
uint256 subscriptionId,
73+
bytes32[] calldata priceIds
74+
) external view returns (PythStructs.Price[] memory prices);
75+
76+
/** @notice Returns the exponentially-weighted moving average price of a price feed without any sanity checks.
77+
* @dev This function returns the same price as `getEmaPrice` in the case where the price is available.
78+
* However, if the price is not recent this function returns the latest available price.
79+
*
80+
* The returned price can be from arbitrarily far in the past; this function makes no guarantees that
81+
* the returned price is recent or useful for any particular application.
82+
*
83+
* Users of this function should check the `publishTime` in the price to ensure that the returned price is
84+
* sufficiently recent for their application. If you are considering using this function, it may be
85+
* safer / easier to use either `getEmaPrice` or `getEmaPriceNoOlderThan`.
86+
* @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
7287
*/
73-
function getLatestPrices(
88+
function getEmaPriceUnsafe(
7489
uint256 subscriptionId,
7590
bytes32[] calldata priceIds
76-
) external view returns (PythStructs.PriceFeed[] memory);
91+
) external view returns (PythStructs.Price[] memory price);
7792

7893
/**
7994
* @notice Adds funds to a subscription's balance
@@ -82,23 +97,40 @@ interface IScheduler is SchedulerEvents {
8297
function addFunds(uint256 subscriptionId) external payable;
8398

8499
/**
85-
* @notice Withdraws funds from a subscription's balance
100+
* @notice Withdraws funds from a subscription's balance.
101+
* @dev A minimum balance must be maintained for active subscriptions. To withdraw past
102+
* the minimum balance limit, deactivate the subscription first.
86103
* @param subscriptionId The ID of the subscription
87104
* @param amount The amount to withdraw
88105
*/
89106
function withdrawFunds(uint256 subscriptionId, uint256 amount) external;
90107

108+
/**
109+
* @notice Returns the minimum balance an active subscription of a given size needs to hold.
110+
* @param numPriceFeeds The number of price feeds in the subscription.
111+
*/
112+
function getMinimumBalance(
113+
uint8 numPriceFeeds
114+
) external view returns (uint256 minimumBalanceInWei);
115+
91116
/**
92117
* @notice Gets all active subscriptions with their parameters
93118
* @dev This function has no access control to allow keepers to discover active subscriptions
119+
* @param startIndex The starting index for pagination
120+
* @param maxResults The maximum number of results to return
94121
* @return subscriptionIds Array of active subscription IDs
95122
* @return subscriptionParams Array of subscription parameters for each active subscription
123+
* @return totalCount Total number of active subscriptions
96124
*/
97-
function getActiveSubscriptions()
125+
function getActiveSubscriptions(
126+
uint256 startIndex,
127+
uint256 maxResults
128+
)
98129
external
99130
view
100131
returns (
101132
uint256[] memory subscriptionIds,
102-
SchedulerState.SubscriptionParams[] memory subscriptionParams
133+
SchedulerState.SubscriptionParams[] memory subscriptionParams,
134+
uint256 totalCount
103135
);
104136
}

0 commit comments

Comments
 (0)