# ScaledEntropyProvider

Provides cryptographically secure random number generation using Pyth Network entropy. Used for provably fair drawing winner selection.

## State Variables

| Variable          | Type         | Description                   |
| ----------------- | ------------ | ----------------------------- |
| `entropy`         | `IEntropyV2` | Pyth Network entropy contract |
| `entropyProvider` | `address`    | Pyth entropy provider address |
| `pending`         | `mapping`    | Pending randomness requests   |

## Structs

### SetRequest

```solidity
struct SetRequest {
    uint8 samples;          // Number of random values to generate
    uint256 minRange;       // Minimum value (inclusive)
    uint256 maxRange;       // Maximum value (inclusive)
    bool withReplacement;   // Allow duplicate values
}
```

### PendingRequest (internal)

```solidity
struct PendingRequest {
    address callback;       // Contract to call with results
    bytes4 selector;        // Function selector for callback
    bytes context;          // Additional data for callback
    bytes32 userRandomNumber; // User-provided randomness
    SetRequest[] setRequests; // Randomness specifications
}
```

## Events

### ScaledRandomnessDelivered

```solidity
event ScaledRandomnessDelivered(
    uint64 indexed sequence,
    address indexed callback,
    uint256 samples
);
```

### EntropyFulfilled

```solidity
event EntropyFulfilled(uint64 indexed sequence, bytes32 randomNumber);
```

## Functions

### getFee

Get the fee required for an entropy request.

```solidity
function getFee(uint32 _gasLimit) public view returns (uint256)
```

**Parameters:**

| Name        | Type     | Description                      |
| ----------- | -------- | -------------------------------- |
| `_gasLimit` | `uint32` | Gas limit for callback execution |

**Returns:**

| Type      | Description       |
| --------- | ----------------- |
| `uint256` | Fee amount in wei |

**Example:**

```solidity
uint32 gasLimit = 500000;
uint256 fee = entropyProvider.getFee(gasLimit);
// Use this fee when calling requestAndCallbackScaledRandomness
```

***

### getEntropyContract

Get the address of the Pyth Network entropy contract.

```solidity
function getEntropyContract() external view returns (address)
```

**Returns:**

| Type      | Description                           |
| --------- | ------------------------------------- |
| `address` | Pyth Network entropy contract address |

***

### getEntropyProvider

Get the currently configured entropy provider.

```solidity
function getEntropyProvider() external view returns (address)
```

**Returns:**

| Type      | Description              |
| --------- | ------------------------ |
| `address` | Entropy provider address |

***

### getPendingRequest

Get details of a pending entropy request.

```solidity
function getPendingRequest(uint64 _sequence) external view returns (PendingRequest memory)
```

**Parameters:**

| Name        | Type     | Description             |
| ----------- | -------- | ----------------------- |
| `_sequence` | `uint64` | Request sequence number |

**Returns:**

| Type             | Description                             |
| ---------------- | --------------------------------------- |
| `PendingRequest` | Request details including callback info |

## How Pyth Entropy Works

### Request Flow

1. **Request**: Contract calls `requestAndCallbackScaledRandomness` with fee
2. **Pyth Processing**: Pyth Network generates cryptographic randomness
3. **Callback**: Pyth calls back with random number
4. **Scaling**: Provider scales randomness to requested ranges
5. **Delivery**: Callback function receives scaled results

### Lottery Drawing Example

For the Jackpot drawing:

```solidity
// Jackpot requests random numbers for drawing
SetRequest[] memory requests = new SetRequest[](2);

// Request 5 normal ball numbers without replacement
requests[0] = SetRequest({
    samples: 5,
    minRange: 1,
    maxRange: 69,          // Normal ball max
    withReplacement: false // Unique numbers
});

// Request 1 bonusball
requests[1] = SetRequest({
    samples: 1,
    minRange: 1,
    maxRange: 26,          // Bonusball max
    withReplacement: true  // Single value
});

// Request randomness (internal to Jackpot)
uint256 fee = entropy.getFee(gasLimit);
entropy.requestAndCallbackScaledRandomness{value: fee}(
    gasLimit,
    requests,
    callback.selector,
    context
);
```

## Randomness Methods

### Fisher-Yates Shuffle

Used for sampling **without replacement** (unique values):

* Guarantees no duplicate values
* Unbiased selection algorithm
* Used for normal ball selection

### Rejection Sampling

Used for **unbiased scaling**:

* Prevents modulo bias
* Ensures uniform distribution
* Used for both methods

## Security Properties

### Cryptographic Security

* Randomness generated by Pyth Network validators
* Unpredictable before reveal
* Verifiable on-chain

### Bias Prevention

* Rejection sampling eliminates modulo bias
* Fisher-Yates provides uniform permutation
* No advantage from timing or position

### Provable Fairness

* All randomness is on-chain verifiable
* Request and callback are auditable
* Results cannot be manipulated
