Subscription

Every subscription is stored on-chain as a Subscription struct. The purpose of a Subscription is primarily to store information about the subscription and keep track of when the subscription can be processed.

struct Subscription {
        address sender;
        address recipient;
        uint256 amount;
        address token;
        uint256 maxProcessingFee;
        address processingFeeToken;
        uint40 lastPayment;
        address sponsor;
        uint32 cooldown;
        uint32 auctionDuration;
        uint16 paymentCounter;
}

The sub2 contract stores a public array of subscriptions and the index in this acts as a unique id.

Subscription[] public subscriptions;

Because the subscriptions array is public, anyone can easily lookup any subscription. The only way a subscription can be added to the array is through the createSubscription and createSubscriptionWithSponsor functions.

The protocol uses the three fields lastPayment, cooldown and auctionDuration to keep track of when payments can be processed. The lastPayment field is the UNIX timestamp in seconds of the last payment of the subscription, however, there are a few important things to note.

  1. If the subscription was created with an initial delay, the lastPayment field will still be set even though no payment has been made initially. To check whether a payment has happened, the paymentCounter field can be used.

  2. When a payment is made as a result of the processPayment function, the lastPayment field will be set to the moment the payment is due (start of auction period) and not when the actual payment happens, i.e. when processPayment is called. The processPayment function emits an event Payment which can be used to get the exact timestamp of the transfer and contains additional information.

Subscriptions can be classified into X states depending on the current block.timestamp:

On initial delay: Subscription is waiting for the first payment.

On cooldown: Subscription is for payment to be due.

In auction: Subscription is in auction mode. Payment is open for processing.

Expired: Payment of subscription was not processed in the auction period so the subscription has expired.

Cancelled: Subscription was actively cancelled.

Subscriptions in the expired state can be cancelled by anyone. When a subscription is cancelled the index in Subscriptions is reset to all zero values. It is important to note that the sub2 protocol supports the reusing of indices. This means that another Subscription object can be created at the index of a previous one and is an effort to minimise the on-chain space consumed by the subscriptions array to be proportional to the number of active subscriptions instead of the number of subscriptions ever created. In practice, this means that it is important when querying subscriptions to check that the recipient and further details are correct.

Last updated