PancakeSwap Lottery fork

How to create PancakeSwap Lottery fork and collect 0-30% fees for every trade.

Introduction

We will use Goerli test network.

tx - short name for transaction

Table of contents

Deploy with Remix

  1. Remix editor

    Go to Remix editor and create there file: Lottery.sol

  2. Lottery contract code

    Copy Pancakeswap Lottery contract code from the Bscscan: https://bscscan.com/address/0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c#contracts copy pancakeswap lottery contract code And paste it into the new Lottery.sol file: paste the contract code in the new file

  3. Contract preparation

    Set up basic lottery rules
    MAX_TREASURY_FEE - Your commission
    maxPriceTicketInCake - Maximum ticket price
    minPriceTicketInCake - Minimum ticket price
    MIN_DISCOUNT_DIVISOR - Minimum discount if the user buys many tickets at once
    MIN_LENGTH_LOTTERY - Minimum round duration
    MAX_LENGTH_LOTTERY - Maximum round duration
    editing lottery parameters

    Set the address where the commission will be transferred and who will be able to manage the lottery by adding this code to the constructor
    injectorAddress = msg.sender;
    operatorAddress = msg.sender;
    treasuryAddress = msg.sender;

    msg.sender; - Returns the address of the account from which the lottery contract will be deployed
    editing address for commission

    Add this code to the contract constructor. currentLotteryId++;
    _lotteries[currentLotteryId] = Lottery({
        status: Status.Claimable,
        startTime: block.timestamp,
        endTime: block.timestamp,
        priceTicketInCake: 0,
        discountDivisor: 0,
        rewardsBreakdown: [uint256(250),uint256(375),uint256(625),uint256(1250),uint256(2500),uint256(5000)],
        treasuryFee: 2000,
        cakePerBracket: [uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0)],
        countWinnersPerBracket: [uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0)],
        firstTicketId: currentTicketId,
        firstTicketIdNextLottery: currentTicketId,
        amountCollectedInCake: pendingInjectionNextLottery,
        finalNumber: 1000000
    });
    Comment out this line in the methodcloseLottery
    Editing the random number generator Add the bytes32 _seed parameter to the drawFinalNumberAndMakeLotteryClaimable function of the IPancakeSwapLottery interface
    Editing the random number generator Add the bytes32 _seed parameter to the drawFinalNumberAndMakeLotteryClaimable function
    Редактирование генератора случайных чисел Comment out the line
    require(_lotteryId == randomGenerator.viewLatestLotteryId(), "Numbers not drawn");
    in the drawFinalNumberAndMakeLotteryClaimable method
    редактирование генератора случайных чисел Replace the random number generator in the drawFinalNumberAndMakeLotteryClaimable method
    to this code
    uint256 randomness = uint(keccak256(abi.encodePacked(
        block.timestamp,
        _seed,
        _lotteryId,
        _lotteries[_lotteryId].firstTicketId,
        _lotteries[_lotteryId].firstTicketIdNextLottery,
        _lotteries[_lotteryId].amountCollectedInCake,
        block.coinbase,
        block.difficulty,
        block.gaslimit,
        tx.gasprice
    )));
    uint32 finalNumber = uint32(1000000 + (randomness % 1000000));

    редактирование генератора случайных чисел

  4. Contract Compilation

    Go to "Solidity Compiler" tab. Change compiler version with 0.8.18 if it's different. Enable optimization option to 99999 and click button "Compile": compile button

  5. Deploy contract

    Go to "Deploy & run transaction" tab. Select Injected Web3 in the ENVIRONMENT drop-down. It will use your external wallet. We will use Metamask wallet. If you didn't login in the wallet then login it now, reload page, come back and compile lottery contract one more time. And again chose Injected Web3 option. Chose Goerli network in the Metamask. Select PancakeSwapLottery in the CONTRACT drop-down (probably it's already made by default).
    deploying pancakeswap lottery contract
    Set an address of your ERC20 token in the _CAKETOKENADDRESS field.
    Set 0x0000000000000000000000000000000000000000 in the _RANDOMGENERATORADDRESS field
    Now you can see something like this in the deploy tab:
    settings on the pancakeswap lottery deployment in the deploy tab
    So now click on "transact" button and confirm a modal window from external wallet with transaction fee: deploy option on the deploy tab

  6. Save Lottery contract address

    After transaction has been mined you can see all details in the Remix terminal: info about transaction where we deployed the pancakeswap lottery contract Copy a transaction hash and go to Goerli etherscan. Paste this hash in the search field and go to a new contract page. Copy his address and save it somewhere. info about mined transaction on the Etherscan pancakeswap lottery contract address on the Etherscan

  7. Now we have this data:


    PancakeSwapLottery:
    0xad661a60bd10caf905a177ac36cefdab43744a8a

Frontend

Main changes in this interface template:

  • Removed all (or almost all) info about pancakeswap
  • Installing Our Lottery Contract
  • Set lottery page as default
  • Changed source styles just a little.

  1. Cloning PancakeSwap Lottery

    Create a new directory: Lottery. Copy front-endcode in this directory then install dependencies
    yarn
    After installing the dependencies, you will see the following

  2. Home page customization

    Let's make the lottery the main page
    Open file\apps\web\src\pages\_app.tsx
    Add an import
    import Lottery from "./lottery" Changing the main page adding imports
    Add a lottery call <Lottery {...pageProps} /> and comment out the code below as shown in the image Home page change

  3. Setting up a contract

    Open the file \apps\web\src\utils\addressHelpers.ts and add the following code
    return '0xad661a60bd10caf905a177ac36cefdab43744a8a'

    Enter the address of your lottery contract that you created earlier
    Lottery contract

  4. Blockchain setup

    Set up the blockchain that will run the lottery
    Open \apps\web\src\config\constants\supportChains.ts
    And enter your network ID
    working network Open file \apps\web\src\hooks\useProviderOrSigner.ts
    And enter your network ID
    working network Open \apps\web\src\utils\contractHelpers.ts
    And enter your network ID
    working network Open file \apps\web\src\state\lottery\helpers.ts And specify your network ID in all calls to multicallv2 working network Open \apps\web\src\state\lottery\fetchUnclaimedUserRewards.ts And specify your network ID in all calls to multicallv2 working network

  5. Setting up a token

    Open \apps\web\src\utils\contractHelpers.ts
    Specify your network ID and the address of your token work network and token address Open \apps\web\src\config\constants\tokenLists\pancake-default.tokenlist.json
    Add information about your token as shown in the example
    {
      "name": "WEENUS",
      "symbol": "WEENUS",
      "address": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
      "chainId": 5,
      "decimals": 18,
      "logoURI": "https://pancakeswap.finance/images/lottery/star-small.png"
    }
    Information about the token Open file \apps\web\src\views\Lottery\components\BuyTicketsModal\BuyTicketsModal.tsx
    And find the line const { balance: userCake, fetchStatus } = useTokenBalance(bscTokens.cake.address) Replace bscTokens.cake.address with the address of your token
    Token address Replace all references to "CAKE" with to the character of your token.
    To do this, just edit the files in the folder \apps\web\src\views\Lottery\
    Be careful. Replace only strings

  6. Launch of the project

    To start the project, run the command in the root directory yarn dev If done correctly, the lottery will be available at http://localhost:3000/ Ready fork pancakeswap lottery

These were the minimum actions needed for the lottery to work and to collect the commission.

Lottery Rounds control

  1. Round life cycle

    In the lottery rounds have the following states

    • Open - The round is active. Users can buy tickets
    • Close - The round is closed. Waiting for the calculation of winnings
    • Pending - Waiting for results. Users cannot buy tickets
    • Claimable - Winning this round is calculated. Users can find out the result and get a reward

    Life cycle:
    Open > Close > Pending > Claimable
    To manage the lifecycle of rounds in a contract, the appropriate methods are

  2. Connection with a contract

    To manage the rounds, you need to interact with the contract. To do this, you need to connect to the contract. For interaction with the contract will use Remix
    Go to Remix editor and select contract file Lottery.sol

    Compile the contract by compile instructions

    Go to "Deploy & run transaction" tab. Select Injected Web3 in the ENVIRONMENT drop-down. It will use your external wallet. We will use Metamask wallet. If you didn't login in the wallet then login it now, reload page, come back and compile lottery contract one more time. And again chose Injected Web3 option. Chose Goerli network in the Metamask. Select PancakeSwapLottery in the CONTRACT drop-down (probably it's already made by default).
    Connection to a contract Enter your contract address and click "At Address" Connection to a contract After that, the contract control panel will appear at the bottom. Connection to a contract Click on it to display the control panel. Connection to a contract

  3. Active round number

    Most contract methods use the current round number. To find out it, execute the "currentLotteryId" method current round number After pressing the button, the current lottery round will be shown

  4. Start of a new round

    To start a new round, use the startLottery
    method Method parameters:

    • _endTime - The time the round will end. Value in UnixTimestamp
    • _priceTicketInCake - Price of a ticket in the current round. Meaning in Wei
    • _discountDivisor - Discount when buying several tickets at once in one transaction.
      Calculation formula _discountDivisor = needValue% * 100.
      Example: 0.5% = 0.5 * 100 = 50, 2% = 2 * 100 = 200
    • _rewardsBreakdown - Win percentage for each matched combination of balls
      An array of six numbers. The sum of the numbers must be equal to 10000
      Calculation formula V = needValue% * 100
      Example:
      Desired win distribution percentage: [0%, 7%, 13%, 20%, 25%, 30%]
      Method call data: [0, 700, 1300, 2000, 2500, 3500]
    • _treasuryFee - Your commission in the current round
      Calculation formula V = needValue% * 100
    Specify the desired parameters and click "transact" to start a new round. start of a new round

  5. Closing the round

    When the time of the round is over, it must be closed. To close, use the "closeLottery" method Method parameters:

    • _lotteryId - Number of the round to be closed

    Specify current round number and click "transact" to close the round

  6. Winning combination calculation

    The final step in the life cycle of a round is the calculation of the winning numbers. To do this, use the drawFinalNumberAndMakeLotteryClaimable method winning calculation Method parameters:

    • _lotteryId - Round number
    • _seed - Random set of bytes of length 32.
      Example: Let's create 32 random numbers through the service Random.org how to generate random The service will generate 32 random numbers random numbers HEX string of these numbers will be
      0xf708a0a28a75973d69ea1d04065f62d57c135def2d750beb0ed39ae55a262cf9
    • _autoInjection - TRUE | FALSE, if set to TRUE, the balance of not won tokens will be automatically transferred to a new round

    To calculate the winning numbers, specify the parameters and click "transact" to calculate the winnings Win calculation After that, the round is over. You can now start a new round