# PayoutCalculator

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

Calculates prize payouts using a two-tier system with guaranteed minimums and premium pool allocation. Implements the 12-tier prize distribution based on match combinations.

## State Variables

| Variable                   | Type                                              | Description                                  |
| -------------------------- | ------------------------------------------------- | -------------------------------------------- |
| `jackpot`                  | `IJackpot`                                        | Immutable reference to Jackpot contract      |
| `minimumPayout`            | `uint256`                                         | Base minimum payout amount (USDC)            |
| `premiumTierMinAllocation` | `uint256`                                         | Min % of pool for premium tiers (1e18 scale) |
| `minPayoutTiers`           | `bool[12]`                                        | Which tiers receive minimum payouts          |
| `premiumTierWeights`       | `uint256[12]`                                     | Premium pool allocation weights              |
| `drawingTierInfo`          | `mapping(uint256 => DrawingTierInfo)`             | Frozen tier config per drawing               |
| `tierPayouts`              | `mapping(uint256 => mapping(uint256 => uint256))` | Calculated payouts                           |

## Constants

```solidity
uint256 PRECISE_UNIT = 1e18;
uint8 NORMAL_BALL_COUNT = 5;
uint8 TOTAL_TIER_COUNT = 12;  // matches(0-5) × bonusball(0,1) = 12 tiers
```

## Structs

### DrawingTierInfo

```solidity
struct DrawingTierInfo {
    uint256 minPayout;                    // Minimum payout for eligible tiers
    uint256 premiumTierMinAllocation;     // Min allocation for premium tiers
    bool[12] minPayoutTiers;              // Tier eligibility for min payouts
    uint256[12] premiumTierWeights;       // Premium pool weights
}
```

## Events

### PrizeTierPayoutsCalculated

```solidity
event PrizeTierPayoutsCalculated(uint256 drawingId, uint256[12] tierPayouts);
```

## Prize Tier System

The system uses 12 tiers based on matches and bonusball:

| Tier | Normal Matches | Bonusball | Formula                  |
| ---- | -------------- | --------- | ------------------------ |
| 0    | 0              | No        | `0*2 + 0 = 0`            |
| 1    | 0              | Yes       | `0*2 + 1 = 1`            |
| 2    | 1              | No        | `1*2 + 0 = 2`            |
| 3    | 1              | Yes       | `1*2 + 1 = 3`            |
| 4    | 2              | No        | `2*2 + 0 = 4`            |
| 5    | 2              | Yes       | `2*2 + 1 = 5`            |
| 6    | 3              | No        | `3*2 + 0 = 6`            |
| 7    | 3              | Yes       | `3*2 + 1 = 7`            |
| 8    | 4              | No        | `4*2 + 0 = 8`            |
| 9    | 4              | Yes       | `4*2 + 1 = 9`            |
| 10   | 5              | No        | `5*2 + 0 = 10`           |
| 11   | 5              | Yes       | `5*2 + 1 = 11` (Jackpot) |

## Functions

### getTierPayout

Get the calculated payout for a specific tier in a drawing.

```solidity
function getTierPayout(uint256 _drawingId, uint256 _tierId) external view returns (uint256)
```

**Parameters:**

| Name         | Type      | Description      |
| ------------ | --------- | ---------------- |
| `_drawingId` | `uint256` | Drawing to query |
| `_tierId`    | `uint256` | Tier ID (0-11)   |

**Returns:**

| Type      | Description                                 |
| --------- | ------------------------------------------- |
| `uint256` | Payout amount per winning ticket (USDC wei) |

**Example:**

```solidity
// Get jackpot (tier 11) payout for current drawing
uint256 drawingId = jackpot.currentDrawingId();
uint256 jackpotPayout = payoutCalculator.getTierPayout(drawingId, 11);
```

***

### getDrawingTierPayouts

Get all tier payouts for a specific drawing.

```solidity
function getDrawingTierPayouts(uint256 _drawingId) external view returns (uint256[12] memory)
```

**Parameters:**

| Name         | Type      | Description      |
| ------------ | --------- | ---------------- |
| `_drawingId` | `uint256` | Drawing to query |

**Returns:**

| Type          | Description                              |
| ------------- | ---------------------------------------- |
| `uint256[12]` | Array of payout amounts for all 12 tiers |

**Example:**

```solidity
uint256[12] memory payouts = payoutCalculator.getDrawingTierPayouts(drawingId);

// Display all payouts
for (uint256 i = 0; i < 12; i++) {
    uint256 matches = i / 2;
    bool bonusball = i % 2 == 1;
    console.log("Matches:", matches, "Bonusball:", bonusball, "Payout:", payouts[i]);
}
```

***

### getExpectedDrawingTierPayouts

Estimate expected payouts for a drawing (settled or current).

```solidity
function getExpectedDrawingTierPayouts(
    uint256 _drawingId,
    uint256 _prizePool,
    uint8 _normalMax,
    uint8 _bonusballMax
) external view returns (uint256[12] memory)
```

**Parameters:**

| Name            | Type      | Description                |
| --------------- | --------- | -------------------------- |
| `_drawingId`    | `uint256` | Drawing to calculate for   |
| `_prizePool`    | `uint256` | Total prize pool available |
| `_normalMax`    | `uint8`   | Maximum normal ball number |
| `_bonusballMax` | `uint8`   | Maximum bonusball number   |

**Returns:**

| Type          | Description                            |
| ------------- | -------------------------------------- |
| `uint256[12]` | Estimated payout amounts for all tiers |

**Example:**

```solidity
uint256 drawingId = jackpot.currentDrawingId();
IJackpot.DrawingState memory state = jackpot.getDrawingState(drawingId);

uint256[12] memory expectedPayouts = payoutCalculator.getExpectedDrawingTierPayouts(
    drawingId,
    state.prizePool,
    state.ballMax,
    state.bonusballMax
);

// Show expected jackpot
uint256 expectedJackpot = expectedPayouts[11];
```

***

### getMinPayoutTiers

Get current minimum payout tier configuration.

```solidity
function getMinPayoutTiers() external view returns (bool[12] memory)
```

**Returns:**

| Type       | Description                                              |
| ---------- | -------------------------------------------------------- |
| `bool[12]` | Boolean array indicating min payout eligibility per tier |

***

### getPremiumTierWeights

Get current premium pool allocation weights.

```solidity
function getPremiumTierWeights() external view returns (uint256[12] memory)
```

**Returns:**

| Type          | Description                                   |
| ------------- | --------------------------------------------- |
| `uint256[12]` | Weight allocation for each tier (sum to 1e18) |

***

### getDrawingTierInfo

Get the frozen tier configuration for a specific drawing.

```solidity
function getDrawingTierInfo(uint256 _drawingId) external view returns (DrawingTierInfo memory)
```

**Parameters:**

| Name         | Type      | Description      |
| ------------ | --------- | ---------------- |
| `_drawingId` | `uint256` | Drawing to query |

**Returns:**

| Type              | Description                                       |
| ----------------- | ------------------------------------------------- |
| `DrawingTierInfo` | Complete tier configuration used for that drawing |

## Payout Calculation Logic

### Two-Phase System

1. **Minimum Payouts**: Guaranteed minimum amount for eligible tiers
2. **Premium Pool**: Remaining pool distributed by weight allocation

### Calculation Flow

```
Prize Pool
    │
    ├─► Minimum Payout Allocation (if enabled)
    │   └─► Distributed to eligible tiers
    │
    └─► Premium Pool (remaining)
        └─► Distributed by tier weights
```

### Premium Protection

If minimum payouts would consume too much of the pool:

* `(premiumMinAllocation × prizePool) + minimumPayoutAllocation >= prizePool`
* Minimum payouts are disabled for that drawing
* Entire pool distributed by premium weights

## Integration Example

```solidity
contract PayoutDisplay {
    IPayoutCalculator public calculator;
    IJackpot public jackpot;

    function displayExpectedPayouts() external view returns (string memory) {
        uint256 drawingId = jackpot.currentDrawingId();
        IJackpot.DrawingState memory state = jackpot.getDrawingState(drawingId);

        uint256[12] memory payouts = calculator.getExpectedDrawingTierPayouts(
            drawingId,
            state.prizePool,
            state.ballMax,
            state.bonusballMax
        );

        // Format payouts for display
        // Tier 11 (5 matches + bonusball) = Jackpot
        // Tier 10 (5 matches, no bonusball) = 2nd prize
        // etc.
    }

    function getTierForTicket(uint256 matches, bool bonusballMatch)
        external
        pure
        returns (uint256)
    {
        return matches * 2 + (bonusballMatch ? 1 : 0);
    }
}
```


---

# 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/payout-calculator.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.
