# JackpotAutoSubscription

**Contract Address:** [`0x02A58B725116BA687D9356Eafe0fA771d58a37ac`](https://basescan.org/address/0x02A58B725116BA687D9356Eafe0fA771d58a37ac)

Enables recurring ticket purchases across multiple drawings. Users prepay for a subscription period and keepers execute daily ticket purchases automatically.

## State Variables

| Variable            | Type                               | Description                             |
| ------------------- | ---------------------------------- | --------------------------------------- |
| `jackpot`           | `IJackpot`                         | Immutable reference to Jackpot contract |
| `usdc`              | `IERC20`                           | Immutable USDC token reference          |
| `batchFacilitator`  | `IBatchPurchaseFacilitator`        | Batch facilitator for large orders      |
| `subscriptions`     | `mapping(address => Subscription)` | Active subscriptions per user           |
| `staticTickets`     | `mapping(address => Ticket[])`     | Static tickets per user                 |
| `ticketPickerNonce` | `uint256`                          | Nonce for dynamic ticket generation     |

## Structs

### Subscription

```solidity
struct Subscription {
    uint64 remainingUSDC;           // USDC balance for remaining days
    uint64 lastExecutedDrawing;     // Last drawing tickets were purchased
    uint64 subscribedTicketPrice;   // Price locked at subscription time
    uint64 dynamicTicketCount;      // Random tickets per day
    address[] referrers;            // Referrer addresses
    uint256[] referralSplit;        // PRECISE_UNIT-scaled weights
}
```

### SubscriptionInfo

```solidity
struct SubscriptionInfo {
    Subscription subscription;       // Subscription details
    IJackpot.Ticket[] staticTickets; // User's static tickets for each day
}
```

## Enums

### ExecutionAction

```solidity
enum ExecutionAction {
    EXECUTE,                       // Execute tickets, subscription continues
    EXECUTE_AND_CLOSE,             // Final execution, subscription completed
    SKIP_ALREADY_EXECUTED,         // Already executed this drawing
    SKIP_NO_ACTIVE_SUBSCRIPTION,   // No active subscription
    SKIP_ACTIVE_BATCH_ORDER,       // Has active batch order, skip
    CANCEL_PRICE_CHANGE,           // Ticket price changed, auto-cancelled
    CANCEL_TOO_MANY_REFERRERS,     // Too many referrers, auto-cancelled
    CANCEL_USER_REQUESTED          // User requested cancellation
}
```

## Events

### SubscriptionCreated

```solidity
event SubscriptionCreated(
    address indexed payer,
    address indexed recipient,
    uint256 totalCost,
    uint256 totalDays,
    uint256 drawingStart,
    uint256 dynamicTicketCount,
    uint256 staticTicketCount,
    uint256 ticketPrice
);
```

### SubscriptionCancelled

```solidity
event SubscriptionCancelled(
    address indexed recipient,
    ExecutionAction indexed executionAction,
    uint64 refundAmount
);
```

### SubscriptionExecuted

```solidity
event SubscriptionExecuted(
    address indexed recipient,
    uint256 indexed drawingId,
    uint256[] ticketIds,
    uint256 dynamicTicketsPurchased,
    uint256 staticTicketsPurchased
);
```

### SubscriptionSkipped

```solidity
event SubscriptionSkipped(
    address indexed recipient,
    uint256 indexed drawingId,
    ExecutionAction indexed executionAction
);
```

## Functions

### createSubscription

Create an auto-subscription for consecutive daily ticket purchases.

```solidity
function createSubscription(
    address _recipient,
    uint64 _totalDays,
    uint64 _dynamicTicketCount,
    IJackpot.Ticket[] calldata _userStaticTickets,
    address[] calldata _referrers,
    uint256[] calldata _referralSplit
) external
```

**Parameters:**

| Name                  | Type        | Description                                |
| --------------------- | ----------- | ------------------------------------------ |
| `_recipient`          | `address`   | Address to receive ticket NFTs each day    |
| `_totalDays`          | `uint64`    | Number of days to run subscription         |
| `_dynamicTicketCount` | `uint64`    | Random tickets to purchase per day         |
| `_userStaticTickets`  | `Ticket[]`  | User-defined static tickets per day        |
| `_referrers`          | `address[]` | Referrer addresses for all purchases       |
| `_referralSplit`      | `uint256[]` | PRECISE\_UNIT-scaled weights (sum to 1e18) |

**Requirements:**

* Recipient must not have an active subscription
* `_totalDays` must be > 0
* Per-day ticket count (dynamic + static) must be > 0
* Static tickets must have valid numbers
* Caller must have approved sufficient USDC for all days

**Example:**

```solidity
// Subscribe for 30 days with 5 random tickets + 2 lucky numbers per day
uint64 days = 30;
uint64 dynamicPerDay = 5;

// My lucky numbers for each day
IJackpot.Ticket[] memory myTickets = new IJackpot.Ticket[](2);
myTickets[0] = IJackpot.Ticket({
    normals: [1, 7, 14, 21, 28],
    bonusball: 7
});
myTickets[1] = IJackpot.Ticket({
    normals: [5, 10, 15, 20, 25],
    bonusball: 5
});

// Calculate total cost: 30 days × 7 tickets × price
uint256 ticketPrice = jackpot.ticketPrice();
uint256 totalCost = days * (dynamicPerDay + myTickets.length) * ticketPrice;

// Approve and subscribe
usdc.approve(address(autoSubscription), totalCost);
autoSubscription.createSubscription(
    msg.sender,
    days,
    dynamicPerDay,
    myTickets,
    new address[](0),   // no referrers
    new uint256[](0)    // no splits
);
```

***

### cancelSubscription

Cancel your active subscription and receive a refund.

```solidity
function cancelSubscription() external
```

**Requirements:**

* Caller must have an active subscription

**Example:**

```solidity
// Cancel and get remaining USDC back
autoSubscription.cancelSubscription();
```

***

### getSubscriptionInfo

Get subscription details for a user.

```solidity
function getSubscriptionInfo(address _recipient) external view returns (SubscriptionInfo memory)
```

**Parameters:**

| Name         | Type      | Description      |
| ------------ | --------- | ---------------- |
| `_recipient` | `address` | Address to query |

**Returns:**

| Type               | Description                             |
| ------------------ | --------------------------------------- |
| `SubscriptionInfo` | Subscription details and static tickets |

**Example:**

```solidity
IJackpotAutoSubscription.SubscriptionInfo memory info =
    autoSubscription.getSubscriptionInfo(msg.sender);

uint64 remainingUSDC = info.subscription.remainingUSDC;
uint64 lastExecuted = info.subscription.lastExecutedDrawing;
uint64 ticketsPerDay = info.subscription.dynamicTicketCount +
                       uint64(info.staticTickets.length);

// Calculate remaining days
uint256 ticketPrice = info.subscription.subscribedTicketPrice;
uint256 remainingDays = remainingUSDC / (ticketsPerDay * ticketPrice);
```

***

### getSubscriptionsAction

Get recommended actions for a batch of subscriptions (for keepers).

```solidity
function getSubscriptionsAction(
    address[] calldata _subscriptions
) external view returns (ExecutionAction[] memory)
```

**Parameters:**

| Name             | Type        | Description           |
| ---------------- | ----------- | --------------------- |
| `_subscriptions` | `address[]` | Addresses to evaluate |

**Returns:**

| Type                | Description                         |
| ------------------- | ----------------------------------- |
| `ExecutionAction[]` | Recommended action for each address |

## Subscription Flow

1. **Create**: User approves USDC and calls `createSubscription`
2. **Daily Execution**: Keepers call `executeSubscriptions` each day
3. **Ticket Purchase**: Subscription buys tickets for current drawing
4. **Completion**: Subscription ends when USDC runs out or user cancels

### Price Protection

Subscriptions lock in the ticket price at creation time:

* If ticket price increases, subscription is auto-cancelled with refund
* This protects users from unexpected cost increases

### Cancellation Scenarios

Subscriptions are automatically cancelled when:

* Ticket price changes from subscribed price
* Too many referrers (exceeds max allowed)

### Integration with Batch Facilitator

Large subscriptions (>= minimum batch size) are routed through the BatchPurchaseFacilitator for efficient execution.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.megapot.io/developers/contract-overview/auto-subscription.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
