> For the complete documentation index, see [llms.txt](https://sub2.gitbook.io/sub2/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sub2.gitbook.io/sub2/concepts/subscription.md).

# 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.

```solidity
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.&#x20;

```solidity
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.&#x20;

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.
