# Lottery

## Contract info

**Contract name:** PancakeSwapLottery\
**Contract address:** 0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c\
**Random number generator address:** 0x8c6375Aab6e5B26a30bF241EBBf29AD6e6c503c2\
(*Random number generator contract must be deployed first*)

View [PancakeSwapLottery.sol on BscScan](https://bscscan.com/address/0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c#code).

View the [PancakeSwap: Lottery contract on BscScan](https://bscscan.com/address/0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c).

## Audits

The PancakeSwap Lottery V2 has been audited twice so far. View the results below:

[Peckshield's Lottery V2 Audit](https://github.com/peckshield/publications/blob/master/audit_reports/PeckShield-Audit-Report-PancakeswapLottery-v1.0.pdf)

[Slowmist's Lottery V2 Audit](https://github.com/slowmist/Knowledge-Base/blob/master/open-report/Smart%20Contract%20Security%20Audit%20Report%20-%20PancakeSwap%20Lottery.pdf)

## Lottery Status states

The lottery has four `Status` states, `Pending`, `Open`, `Close`, and `Claimable`, that determine which actions can and cannot be taken at a given time.

## Read/View functions

### viewCurrentLotteryId

```
function viewCurrentLotteryId() external view override returns (uint256);
```

Returns the Id# of the current Lottery round as an integer. Round Id#s correlate to round number, and are incremental, e.g. the ninth round of Lottery will be `9`.

### viewLottery

```
function viewLottery(uint256 _lotteryId) external view returns (Lottery memory);
```

Returns information on specified Lottery round as tuple (see Lottery structure below).

```
        uint256 startTime;
        uint256 endTime;
        uint256 priceTicketInCake;
        uint256 discountDivisor;
        uint256[6] rewardsBreakdown; // 0: 1 matching number // 5: 6 matching numbers
        uint256 treasuryFee; // 500: 5% // 200: 2% // 50: 0.5%
        uint256[6] cakePerBracket;
        uint256[6] countWinnersPerBracket;
        uint256 firstTicketId;
        uint256 firstTicketIdNextLottery;
        uint256 amountCollectedInCake;
        uint32 finalNumber;
```

| Name                       | Type        | Description                                                                                                                                                                                                          |
| -------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `startTime`                | uint256     | Starting block for Lottery round.                                                                                                                                                                                    |
| `endTime`                  | uint256     | Ending block for Lottery round (approximately 12 hours after a round begins).                                                                                                                                        |
| `priceTicketInCake`        | uint256     | The price of a ticket in CAKE (approximately $5 USD).                                                                                                                                                                |
| `discountDivisor`          | uint256     | The divisor used to calculate bulk ticket discount.                                                                                                                                                                  |
| `rewardsBreakdown`         | uint256\[6] | The division of rewards across brackets (total must add up to 10,000).                                                                                                                                               |
| `treasuryFee`              | uint256     | Amount taken from funds raised per round that's moved to treasury address (maximum 3000).                                                                                                                            |
| `cakePerBracket`           | uint256\[6] | The amount of CAKE to distribute to winners of each bracket.                                                                                                                                                         |
| `countWinnersPerBracket`   | uint256\[6] | Moves through brackets, starting from the highest, accounting for winners when value > 0.                                                                                                                            |
| `firstTicketId`            | uint256     | Id of the first ticket, set with the opening of the Lottery round, that determines the range of eligible tickets for the current round.                                                                              |
| `firstTicketIdNextLottery` | uint256     | Id of the first ticket, set at the closing of current round, that determines the range of eligible tickets for the current round.                                                                                    |
| `amountCollectedInCake`    | uint256     | The amount of CAKE collected through ticket sales for the Lottery round.                                                                                                                                             |
| `finalNumber`              | uint32      | The final number determined by `randomResult` obtained from the number generator contract ([RandomNumberGenerator.sol](https://bscscan.com/address/0x8c6375Aab6e5B26a30bF241EBBf29AD6e6c503c2)) using Chainlink VRF. |

### viewNumbersAndStatusesForTicketIds

```
function viewNumbersAndStatusesForTicketIds(uint256[] calldata _ticketIds)
    external
    view
    returns (uint32[] memory, bool[] memory);
```

Returns the corresponding numbers and the statuses of `ticketIds` array of tickets defined by their `ticketId`.

### viewRewardsForTicketId

```
function viewRewardsForTicketId(
    uint256 _lotteryId,
    uint256 _ticketId,
    uint32 _bracket;
```

Calculates rewards for a ticket after draw given the `lotteryId`, `ticketId`, and `bracket`. Filling and querying will provide a link to detailed price information on [BscScan](https://bscscan.com/address/0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c#readContract).

| Name        | Type    | Description                                                           |
| ----------- | ------- | --------------------------------------------------------------------- |
| `lotteryId` | uint256 | The id of the Lottery.                                                |
| `ticketId`  | uint256 | The id of the ticket.                                                 |
| `bracket`   | uint32  | Bracket for the `ticketId` to verify the claim and calculate rewards. |

### viewUserInfoForLotteryId

```
    function viewUserInfoForLottery(
        address _user,
        uint256 _lotteryId,
        uint256 _cursor,
        uint256 _size
    )
        external
        view
        returns (
            uint256[] memory,
            uint32[] memory,
            bool[] memory,
            uint256
        )
```

Returns user `lotteryTicketIds`, `ticketNumbers`, and `ticketStatuses` of a user for a given Lottery (defined by `lotteryID`).

| Name        | Type    | Description                                    |
| ----------- | ------- | ---------------------------------------------- |
| `user`      | address | The address of the user.                       |
| `lotteryId` | uint256 | The id of the Lottery.                         |
| `cursor`    | uint256 | Cursor to start where to retrieve the tickets. |
| `size`      | uint256 | The number of tickets to retrieve.             |

### calculateRewardsForTicketId

```
    function _calculateRewardsForTicketId(
        uint256 _lotteryId,
        uint256 _ticketId,
        uint32 _bracket
    ) internal view returns (uint256);
```

Calculates rewards for a ticket after draw given the `lotteryId`, `ticketId`, and `bracket`.

| Name        | Type    | Description                                                           |
| ----------- | ------- | --------------------------------------------------------------------- |
| `lotteryId` | uint256 | The id of the Lottery.                                                |
| `ticketId`  | uint256 | The id of the ticket.                                                 |
| `bracket`   | uint32  | Bracket for the `ticketId` to verify the claim and calculate rewards. |

### calculateTotalPriceForBulkTickets

```
    function calculateTotalPriceForBulkTickets(
        uint256 _discountDivisor,
        uint256 _priceTicket,
        uint256 _numberTickets
    ) external pure returns (uint256);
```

Calculates the price for a set of tickets accounting for bulk discount.

discountDivisor:

$$totalPriceForBulkTickets = priceSingleTicket \cdot numberTickets \cdot \frac{(discountDivisor + 1 - numberTickets)}{discountDivisor}$$

Filling and querying will provide a link to detailed price information on BscScan.

| Name              | Type    | Description                    |
| ----------------- | ------- | ------------------------------ |
| `discountDivisor` | uint256 | The divisor for the discount.  |
| `priceTickets`    | uint256 | The price of a ticket in CAKE. |
| `numberTickets`   | uint256 | The number of tickets to buy.  |

## Write functions (users)

### buyTickets

```
function buyTickets(uint256 _lotteryId, uint32[] calldata _ticketNumbers) external override notContract nonReentrant;
```

Buy tickets for the current `Open` Lottery round (between 1 and 100 per purchase). Calculates the price per ticket using `calculateTotalPriceForBulkTickets`.

| Name            | Type    | Description                                              |
| --------------- | ------- | -------------------------------------------------------- |
| `lotteryId`     | uint256 | The id of the lottery.                                   |
| `ticketNumbers` | uint32  | Array of ticket numbers between 1,000,000 and 1,999,999. |

### claimTickets

```
    function claimTickets(
        uint256 _lotteryId,
        uint256[] calldata _ticketIds,
        uint32[] calldata _brackets
    ) external override notContract nonReentrant;
```

Claim a set of winning tickets for a `Claimable` Lottery round. Checks `lotteryId` to determine if round is claimable, ownership of `ticketId`, eligibility of ticket (`ticketId` falls between `firstTicketId` and `firstTicketIdNextLottery`), and whether `ticketId` falls within eligible prize `bracket` (between 0 and 5).

| Name        | Type    | Description                           |
| ----------- | ------- | ------------------------------------- |
| `lotteryId` | uint256 | The id of the Lottery.                |
| `ticketIds` | uint32  | Array of `ticketId`s.                 |
| `brackets`  | uint32  | Array of brackets for the ticket ids. |

## Write functions (operator/admin)

### closeLottery

```
function closeLottery(uint256 _lotteryId) external override onlyOperator;
```

Closes the `Open` Lottery to `Close` state. Emits `LotteryClose` event.

| Name        | Type    | Description            |
| ----------- | ------- | ---------------------- |
| `lotteryId` | uint256 | The id of the Lottery. |

### drawFinalNumberAndMakeLotteryClaimable

```
    function drawFinalNumberAndMakeLotteryClaimable(uint256 _lotteryId, bool _autoInjection) external override onlyOperator nonReentrant;
```

Lottery must be in `Close` state. Draws the final Lottery number for results from `randomResult`, calculates the rewards for brackets after accounting for treasury fee, makes Lottery state `Claimable`, and transfers treasury fee to treasury address.

| Name            | Type    | Description                 |
| --------------- | ------- | --------------------------- |
| `lotteryId`     | uint256 | The id of the Lottery.      |
| `autoInjection` | bool    | Automatic injection status. |

### changeRandomNumberGenerator

```
    function changeRandomGenerator(address _randomGeneratorAddress) external onlyOwner;
```

Changes the random number generator contract address. Lottery must be `Claimable`.

| Name                     | Type    | Description                   |
| ------------------------ | ------- | ----------------------------- |
| `randomGeneratorAddress` | address | The random generator address. |

### injectFunds

```
function injectFunds(uint256 _lotteryId, uint256 _amount) external override onlyOwner;
```

Inject funds into a Lottery. Lottery must be `Open`.

| Name        | Type    | Description                       |
| ----------- | ------- | --------------------------------- |
| `lotteryId` | uint256 | The id of the Lottery.            |
| `amount`    | uint256 | Amount, in CAKE token, to inject. |

### startLottery

```
    function startLottery(
        uint256 _endTime,
        uint256 _priceTicketInCake,
        uint256 _discountDivisor,
        uint256[6] calldata _rewardsBreakdown,
        uint256 _treasuryFee
    ) external override onlyOperator;
```

Starts the Lottery, setting it to `Open` state. Status must be `Claimable`.

| Name                | Type        | Description                                                |
| ------------------- | ----------- | ---------------------------------------------------------- |
| `endTime`           | uint256     | End time of the Lottery.                                   |
| `priceTicketInCake` | uint256     | Price of a ticket in CAKE.                                 |
| `discountDivisor`   | uint256     | The divisor to calculate the discount magnitude for bulks. |
| `rewardsBreakdown`  | uint256\[6] | Breakdown of rewards per bracket (must sum to 10,000).     |
| `trasuryFee`        | uint256     | Treasury fee (10,000 = 100%, 100 = 1%).                    |

### recoverWrongTokens

```
function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner;
```

Allows admin to recover incorrect tokens sent to address mistakenly. Cannot be CAKE tokens.

| Name           | Type    | Description                           |
| -------------- | ------- | ------------------------------------- |
| `tokenAddress` | address | The address of the token to withdraw. |
| `tokenAmount`  | uint256 | The number of tokens to withdraw.     |

### setMinAndMaxTicketPriceInCake

```
function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner;
```

Allows admin to set upper and lower limit of ticket price in CAKE value. Minimum price must be lower than maximum price.

| Name                   | Type    | Description                |
| ---------------------- | ------- | -------------------------- |
| `minPriceTicketInCake` | uint256 | The minimum price in CAKE. |
| `maxPriceTicketInCake` | uint256 | The maximum price in CAKE. |

### setMaxNumberTicketsPerBuy

```
function setMaxNumberTicketsPerBuy(uint256 _maxNumberTicketsPerBuy) external onlyOwner;
```

Set max number of tickets purchasable at a time (presently 100). Max number of tickets must be higher than 0.

| Name                     | Type    | Description                            |
| ------------------------ | ------- | -------------------------------------- |
| `maxNumberTicketsPerBuy` | uint256 | Max number of tickets in one purchase. |

### setOperatorAndTreasuryAndInjectorAddress

```
function setOperatorAndTreasuryAddresses(address _operatorAddress, address _treasuryAddress) external onlyOwner;
```

Sets the address of the Lottery operator.

| Name              | Type    | Description                  |
| ----------------- | ------- | ---------------------------- |
| `operatorAddress` | address | The address of the operator. |
| `treasuryAddress` | address | The address of the treasury. |
| `injectorAddress` | address | The address of the injector. |

## Events (User)

### TicketsPurchase

```
TicketsPurchase(address indexed buyer, uint256 indexed lotteryId, uint256 numberTickets);
```

Lottery tickets are purchased.

Emitter: `buyTickets` [go to buyTickets](#buytickets)

### TicketsClaim

```
TicketsClaim(address indexed claimer, uint256 amount, uint256 indexed lotteryId, uint256 numberTickets);
```

Lottery tickets are claimed post-draw.

Emitter: `claimTickets` [go to claimTickets](#claimtickets)

## Events (admin)

### AdminTokenRecovery

```
AdminTokenRecovery(address token, uint256 amount);
```

Admin recovers incorrect tokens from Lottery address.

Emitter: `recoverWrongTokens` [go to recoverWrongTokens](#recoverwrongtokens)

### LotteryClose

```
LotteryClose(uint256 indexed lotteryId, uint256 firstTicketIdNextLottery);
```

The Lottery is closed. lotteryId is indexed and `firstTicketIdNextLottery` is determined by `currentTicketId`.

Emitter: `closeLottery` [go to closeLottery](#closelottery)

### LotteryInjection

```
LotteryInjection(uint256 indexed lotteryId, uint256 amount);
```

Funds are injected into Lottery.

Emitter: `injectFunds` [go to injectFunds](#injectfunds)

### LotteryOpen

```
LotteryOpen(
        uint256 indexed lotteryId,
        uint256 startTime,
        uint256 endTime,
        uint256 priceTicketInCake,
        uint256 firstTicketId
    );
```

The Lottery is opened. `firstTicketId` is set from `currentTicketId`,

Emitter: `startLottery` [go to startLottery](#startlottery)

### LotteryNumberDrawn

```
LotteryNumberDrawn(uint256 indexed lotteryId, uint256 finalNumber, uint256 countWinningTickets);
```

Lottery numbers are drawn for Lottery round.

Emitter: `drawFinalNumberAndMakeLotteryClaimable` go to [drawFinalNumberAndMakeLotteryClaimable](#drawfinalnumberandmakelotteryclaimable)

### NewOperatorAndTreasuryAndInjectorAddresses

```
NewOperatorAndTreasuryAndInjectorAddresses(address operator, address treasury);
```

New operator address is set.

Emitter: `setOperatorAndTreasuryAndInjectorAddresses` [go to setOperatorAndTreasuryAndInjectorAddresses](#setoperatorandtreasuryandinjectoraddress)

### NewRandomNumberGenerator

```
NewRandomGenerator(address indexed randomGenerator);
```

New random number generator address is set.

Emitter: `changeRandomGenerator` [go to changeRandomGenerator](#changerandomnumbergenerator)


---

# 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.payswap.org/francais/developers/smart-contracts/lottery.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.
