Skip to content

Commit d73600f

Browse files
Rework the subscription logic to avoid subscribing for more than N months ahead
1 parent 17c66a5 commit d73600f

File tree

5 files changed

+40
-21
lines changed

5 files changed

+40
-21
lines changed

contracts/script/deploy/AggregationModePaymentServiceDeployer.s.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,21 @@ contract AggregationModePaymentServiceDeployer is Script {
1515
uint256 amountToPay = stdJson.readUint(configData, ".amounts.amountToPayInWei");
1616
uint256 paymentExpirationTimeSeconds = stdJson.readUint(configData, ".amounts.paymentExpirationTimeSeconds");
1717
uint256 subscriptionLimit = stdJson.readUint(configData, ".amounts.subscriptionLimit");
18+
uint256 maxSubscriptionTimeAhead = stdJson.readUint(configData, ".amounts.maxSubscriptionTimeAhead");
1819

1920
vm.startBroadcast();
2021

2122
AggregationModePaymentService implementation = new AggregationModePaymentService();
2223
ERC1967Proxy proxy = new ERC1967Proxy(
2324
address(implementation),
2425
abi.encodeWithSignature(
25-
"initialize(address,address,uint256,uint256,uint256)",
26+
"initialize(address,address,uint256,uint256,uint256,uint256)",
2627
owner,
2728
recipient,
2829
amountToPay,
2930
paymentExpirationTimeSeconds,
30-
subscriptionLimit
31+
subscriptionLimit,
32+
maxSubscriptionTimeAhead
3133
)
3234
);
3335

contracts/script/deploy/config/devnet/proof-aggregator-service.devnet.config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"amounts": {
1313
"amountToPayInWei": 1000000000000000000,
1414
"paymentExpirationTimeSeconds": 86400,
15-
"subscriptionLimit": 5
15+
"subscriptionLimit": 5,
16+
"maxSubscriptionTimeAhead": 7776000
1617
},
1718
"permissions": {
1819
"owner": "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",

contracts/scripts/anvil/state/alignedlayer-deployed-anvil-state.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

contracts/src/core/AggregationModePaymentService.sol

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
2626
/// @notice The amount of subscriptions for the current month
2727
uint256 public monthlySubscriptionsAmount;
2828

29+
/// @notice Maximum amount of time (in seconds) an address can be subscribed ahead of the current block timestamp.
30+
/// Prevents stacking multiple short subscriptions and paying them over an extended period.
31+
uint256 public maxSubscriptionTimeAhead;
32+
2933
/// @notice The amount of addresses currently subscribed. expirationTime is UTC seconds, to be
3034
/// compared against block timestamps
3135
mapping(address subscriber => uint256 expirationTime) public subscribedAddresses;
@@ -55,6 +59,10 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
5559
/// @param newSubscriptionsAmount the new monthly subscription amount.
5660
event MonthlySubscriptionsAmountUpdated(uint256 indexed newSubscriptionsAmount);
5761

62+
/// @notice Event emitted when the max subscription time ahead is updated
63+
/// @param newMaxSubscriptionTimeAhead the max time allowed to subscribe ahead the current timestamp.
64+
event MaxSubscriptionTimeAheadUpdated(uint256 indexed newMaxSubscriptionTimeAhead);
65+
5866
/// @notice Event emitted when the funds recipient is updated
5967
/// @param newFundsRecipient the new address for receiving the funds on withdrawal.
6068
event FundsRecipientUpdated(address indexed newFundsRecipient);
@@ -68,7 +76,7 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
6876

6977
error SubscriptionLimitReached(uint256 subscriptionLimit);
7078

71-
error SubscriptionNotExpired(uint256 expiration, uint256 currentTime);
79+
error SubscriptionTimeExceedsLimit(uint256 newSubscriptionTime, uint256 timeLimit);
7280

7381
/**
7482
* @notice Disables initializers for the implementation contract.
@@ -91,7 +99,8 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
9199
address _paymentFundsRecipient,
92100
uint256 _amountToPayInWei,
93101
uint256 _paymentExpirationTimeSeconds,
94-
uint256 _subscriptionLimit
102+
uint256 _subscriptionLimit,
103+
uint256 _maxSubscriptionTimeAhead
95104
) public initializer {
96105
__Ownable_init();
97106
__UUPSUpgradeable_init();
@@ -101,6 +110,7 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
101110
amountToPayInWei = _amountToPayInWei;
102111
paymentFundsRecipient = _paymentFundsRecipient;
103112
subscriptionLimit = _subscriptionLimit;
113+
maxSubscriptionTimeAhead = _maxSubscriptionTimeAhead;
104114
}
105115

106116
/**
@@ -162,6 +172,16 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
162172

163173
emit MonthlySubscriptionsAmountUpdated(newSubscriptionsAmount);
164174
}
175+
176+
/**
177+
* @notice Sets the max subscription time ahead to the value received by parameter. Only callable by the owner
178+
* @param newMaxSubscriptionTimeAhead max time allowed to subscribe ahead the current timestamp.
179+
*/
180+
function setMaxSubscriptionTimeAhead(uint256 newMaxSubscriptionTimeAhead) public onlyOwner() {
181+
maxSubscriptionTimeAhead = newMaxSubscriptionTimeAhead;
182+
183+
emit MaxSubscriptionTimeAheadUpdated(newMaxSubscriptionTimeAhead);
184+
}
165185

166186
/**
167187
* @notice Adds an array of addresses to the payment map and emits the Payment event.
@@ -194,17 +214,12 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
194214
revert SubscriptionLimitReached(subscriptionLimit);
195215
}
196216

197-
// Check if the user has already payed a subscription for this month
198-
uint256 insertedExpiration = subscribedAddresses[msg.sender];
199-
if (insertedExpiration == 0) {
200-
// this means the sender has not payed for a subscription before
201-
subscribedAddresses[msg.sender] = block.timestamp + paymentExpirationTimeSeconds;
202-
} else if (insertedExpiration > block.timestamp) {
203-
// this means the sender has an expired subscription
204-
subscribedAddresses[msg.sender] = block.timestamp + paymentExpirationTimeSeconds;
205-
} else {
206-
// this means the sender has a subscription that has not expired yet
207-
revert SubscriptionNotExpired(insertedExpiration, block.timestamp);
217+
subscribedAddresses[msg.sender] = block.timestamp + paymentExpirationTimeSeconds;
218+
219+
uint256 newExpiration = subscribedAddresses[msg.sender];
220+
221+
if (newExpiration - block.timestamp > maxSubscriptionTimeAhead) {
222+
revert SubscriptionTimeExceedsLimit(newExpiration, maxSubscriptionTimeAhead);
208223
}
209224

210225
++monthlySubscriptionsAmount;

0 commit comments

Comments
 (0)