# JackpotRandomTicketBuyer

Lightweight helper contract for purchasing randomly-generated tickets. Simplifies the process of buying tickets with random number selections.

## State Variables

| Variable  | Type       | Description                              |
| --------- | ---------- | ---------------------------------------- |
| `jackpot` | `IJackpot` | Immutable reference to Jackpot contract  |
| `usdc`    | `IERC20`   | Immutable USDC token reference           |
| `nonce`   | `uint256`  | Per-call nonce for randomness uniqueness |

## Events

### RandomTicketsBought

```solidity
event RandomTicketsBought(
    address indexed recipient,
    uint256 indexed drawingId,
    uint256 count,
    uint256 cost,
    uint256[] ticketIds
);
```

## Functions

### buyTickets

Purchase a specified number of randomly-generated tickets.

```solidity
function buyTickets(
    uint256 _count,
    address _recipient,
    address[] memory _referrers,
    uint256[] memory _referralSplitBps,
    bytes32 _source
) external returns (uint256[] memory ticketIds)
```

**Parameters:**

| Name                | Type        | Description                                |
| ------------------- | ----------- | ------------------------------------------ |
| `_count`            | `uint256`   | Number of random tickets to purchase       |
| `_recipient`        | `address`   | Address to receive the ticket NFTs         |
| `_referrers`        | `address[]` | Referrer addresses for fee sharing         |
| `_referralSplitBps` | `uint256[]` | PRECISE\_UNIT-scaled weights (sum to 1e18) |
| `_source`           | `bytes32`   | Source identifier for tracking             |

**Returns:**

| Type        | Description                |
| ----------- | -------------------------- |
| `uint256[]` | Array of minted ticket IDs |

**Requirements:**

* `_count` must be > 0
* `_recipient` must not be zero address
* Caller must have approved sufficient USDC

**Example:**

```solidity
// Buy 10 random tickets
uint256 count = 10;
uint256 ticketPrice = jackpot.getDrawingState(jackpot.currentDrawingId()).ticketPrice;
uint256 totalCost = count * ticketPrice;

usdc.approve(address(randomBuyer), totalCost);

uint256[] memory ticketIds = randomBuyer.buyTickets(
    count,
    msg.sender,
    new address[](0),
    new uint256[](0),
    bytes32("my-app")
);
```

### With Referrers

```solidity
// Buy 5 random tickets with referrer
uint256 count = 5;
uint256 totalCost = count * jackpot.ticketPrice();

usdc.approve(address(randomBuyer), totalCost);

address[] memory referrers = new address[](1);
referrers[0] = referrerAddress;

uint256[] memory splits = new uint256[](1);
splits[0] = 1e18; // 100% to single referrer

uint256[] memory ticketIds = randomBuyer.buyTickets(
    count,
    msg.sender,
    referrers,
    splits,
    bytes32("referral-app")
);
```

## How Randomness Works

The contract uses on-chain entropy sources to generate random ticket numbers:

1. **Entropy Sources**: Combines `prevrandao`, previous block hash, and a per-call nonce
2. **Unique Generation**: Nonce increments each call to prevent same-block collisions
3. **Valid Tickets**: All generated tickets have valid, unique normal numbers and valid bonusballs

### Security Note

The randomness is suitable for ticket generation but not cryptographically secure. The final drawing uses Pyth Network entropy for provably fair winner selection.

## Comparison with Other Purchase Methods

| Method                     | Use Case              | Ticket Selection       |
| -------------------------- | --------------------- | ---------------------- |
| `Jackpot.buyTickets`       | Direct purchase       | User chooses numbers   |
| `JackpotRandomTicketBuyer` | Quick random purchase | Auto-generated         |
| `BatchPurchaseFacilitator` | Large orders          | Mix of static + random |
| `JackpotAutoSubscription`  | Recurring purchases   | Mix of static + random |

## Integration Example

```solidity
contract MyLotteryApp {
    IJackpotRandomTicketBuyer public randomBuyer;
    IERC20 public usdc;

    function quickPlay(uint256 ticketCount) external {
        uint256 cost = ticketCount * getTicketPrice();

        // Transfer USDC from user
        usdc.transferFrom(msg.sender, address(this), cost);
        usdc.approve(address(randomBuyer), cost);

        // Buy random tickets
        randomBuyer.buyTickets(
            ticketCount,
            msg.sender,
            new address[](0),
            new uint256[](0),
            bytes32("my-lottery-app")
        );
    }

    function getTicketPrice() public view returns (uint256) {
        uint256 drawingId = IJackpot(randomBuyer.jackpot()).currentDrawingId();
        return IJackpot(randomBuyer.jackpot()).getDrawingState(drawingId).ticketPrice;
    }
}
```
