Skip to content

Commit ca81965

Browse files
Add subscription limit to the Aggregation Mode Payment Service contract
1 parent b185ee3 commit ca81965

File tree

5 files changed

+77
-9
lines changed

5 files changed

+77
-9
lines changed

contracts/script/deploy/AggregationModePaymentServiceDeployer.s.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@ contract AggregationModePaymentServiceDeployer is Script {
1414
address recipient = stdJson.readAddress(configData, ".permissions.recipient");
1515
uint256 amountToPay = stdJson.readUint(configData, ".amounts.amountToPayInWei");
1616
uint256 paymentExpirationTimeSeconds = stdJson.readUint(configData, ".amounts.paymentExpirationTimeSeconds");
17+
uint256 subscriptionLimit = stdJson.readUint(configData, ".amounts.subscriptionLimit");
1718

1819
vm.startBroadcast();
1920

2021
AggregationModePaymentService implementation = new AggregationModePaymentService();
2122
ERC1967Proxy proxy = new ERC1967Proxy(
2223
address(implementation),
2324
abi.encodeWithSignature(
24-
"initialize(address,address,uint256,uint256)",
25+
"initialize(address,address,uint256,uint256,uint256)",
2526
owner,
2627
recipient,
2728
amountToPay,
28-
paymentExpirationTimeSeconds
29+
paymentExpirationTimeSeconds,
30+
subscriptionLimit
2931
)
3032
);
3133

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
@@ -11,7 +11,8 @@
1111
},
1212
"amounts": {
1313
"amountToPayInWei": 1000000000000000000,
14-
"paymentExpirationTimeSeconds": 86400
14+
"paymentExpirationTimeSeconds": 86400,
15+
"subscriptionLimit": 5
1516
},
1617
"permissions": {
1718
"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: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
2020
/// @notice The address where the payment funds will be sent.
2121
address public paymentFundsRecipient;
2222

23+
/// @notice The limit of subscriptions for different addresses per month
24+
uint256 public subscriptionLimit;
25+
26+
/// @notice The amount of subscriptions for the current month
27+
uint256 public monthlySubscriptionsAmount;
28+
29+
/// @notice The amount of addresses currently subscribed. expirationTime is UTC seconds, to be
30+
/// compared against block timestamps
31+
mapping(address subscriber => uint256 expirationTime) public subscribedAddresses;
32+
2333
/**
2434
* @notice Emitted when a user deposits funds to purchase service time.
2535
* @param user Address that sent the payment.
@@ -37,6 +47,10 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
3747
/// @param newAmountToPay the new amount to pay for a subscription in wei.
3848
event AmountToPayUpdated(uint256 indexed newAmountToPay);
3949

50+
/// @notice Event emitted when the subscription limit is updated
51+
/// @param newSubscriptionLimit the new monthly subscription limit.
52+
event SubscriptionLimitUpdated(uint256 indexed newSubscriptionLimit);
53+
4054
/// @notice Event emitted when the funds recipient is updated
4155
/// @param newFundsRecipient the new address for receiving the funds on withdrawal.
4256
event FundsRecipientUpdated(address indexed newFundsRecipient);
@@ -48,6 +62,10 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
4862

4963
error InvalidDepositAmount(uint256 amountReceived, uint256 amountRequired);
5064

65+
error SubscriptionLimitReached(uint256 subscriptionLimit);
66+
67+
error SubscriptionNotExpired(uint256 expiration, uint256 currentTime);
68+
5169
/**
5270
* @notice Disables initializers for the implementation contract.
5371
*/
@@ -58,15 +76,27 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
5876
/**
5977
* @notice Initializes the contract and transfers ownership to the provided address.
6078
* @param _owner Address that becomes the contract owner.
79+
* @param _paymentFundsRecipient Address that will receive the withdrawal funds.
80+
* @param _amountToPayInWei Amount to pay in wei for the subscription.
81+
* @param _paymentExpirationTimeSeconds The time in seconds that the subscription takes to expire.
82+
* @param _subscriptionLimit The maximum subscribers that can be subscribed at the same time.
83+
*
6184
*/
62-
function initialize(address _owner, address _paymentFundsRecipient, uint256 _amountToPayInWei, uint256 _paymentExpirationTimeSeconds) public initializer {
85+
function initialize(
86+
address _owner,
87+
address _paymentFundsRecipient,
88+
uint256 _amountToPayInWei,
89+
uint256 _paymentExpirationTimeSeconds,
90+
uint256 _subscriptionLimit
91+
) public initializer {
6392
__Ownable_init();
6493
__UUPSUpgradeable_init();
6594
_transferOwnership(_owner);
6695

6796
paymentExpirationTimeSeconds = _paymentExpirationTimeSeconds;
6897
amountToPayInWei = _amountToPayInWei;
6998
paymentFundsRecipient = _paymentFundsRecipient;
99+
subscriptionLimit = _subscriptionLimit;
70100
}
71101

72102
/**
@@ -109,6 +139,23 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
109139
emit AmountToPayUpdated(newAmountToPay);
110140
}
111141

142+
/**
143+
* @notice Sets the new subscription limit. Only callable by the owner
144+
* @param newSubscriptionLimit The new monthly subscription limit.
145+
*/
146+
function setSubscriptionLimit(uint256 newSubscriptionLimit) public onlyOwner() {
147+
subscriptionLimit = newSubscriptionLimit;
148+
149+
emit SubscriptionLimitUpdated(newSubscriptionLimit);
150+
}
151+
152+
/**
153+
* @notice Resets the monthly subscriptions mapping counter to zero.
154+
*/
155+
function resetSubscriptions() public onlyOwner() {
156+
monthlySubscriptionsAmount = 0;
157+
}
158+
112159
/**
113160
* @notice Accepts payments and validates they meet the minimum requirement.
114161
*/
@@ -119,6 +166,23 @@ contract AggregationModePaymentService is Initializable, OwnableUpgradeable, UUP
119166
revert InvalidDepositAmount(amount, amountToPayInWei);
120167
}
121168

169+
if (monthlySubscriptionsAmount == subscriptionLimit) {
170+
revert SubscriptionLimitReached(subscriptionLimit);
171+
}
172+
173+
// Check if the user has already payed a subscription for this month
174+
uint256 insertedExpiration = subscribedAddresses[msg.sender];
175+
if (insertedExpiration == 0) {
176+
// this means the sender has not payed for a subscription before
177+
subscribedAddresses[msg.sender] = block.timestamp + paymentExpirationTimeSeconds;
178+
} else if (insertedExpiration > block.timestamp) {
179+
// this means the sender has an expired subscription
180+
subscribedAddresses[msg.sender] = block.timestamp + paymentExpirationTimeSeconds;
181+
} else {
182+
// this means the sender has a subscription that has not expired yet
183+
revert SubscriptionNotExpired(insertedExpiration, block.timestamp);
184+
}
185+
122186
emit UserPayment(msg.sender, amount, block.timestamp, block.timestamp + paymentExpirationTimeSeconds);
123187
}
124188

0 commit comments

Comments
 (0)