Contract 0x653441299ec28e0301d640006e2cec4776eba671

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x0ab82dd0be380ee01720076b78eb526a36daba2fdf807d08de35e696ccca8efcSettle Lottery201089302021-10-11 19:01:1852 days 3 hrs ago0x23b1cb63f3432460a69304a68276e7fc601bd3f9 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000777711
0x1dfed5b77a1f50cb0cf91aa90f492bac41acd8cf97903807839445d6dcf8d805Withdraw Link191965222021-09-17 7:22:4576 days 15 hrs ago0x3898ff1b0368997e08d8e06f143ed57b3909bbf7 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000094484
0xd9206da28823578f4d91d4de145ff45f635067ff5be99c1ff93b97ef873e44eaSettle Lottery190538012021-09-13 8:00:4680 days 14 hrs ago0x3898ff1b0368997e08d8e06f143ed57b3909bbf7 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000141402
0x261153a158fd14f77fd3c5d69147135f8044fb4026698999c9b0f152e3a5677eSettle Lottery189630712021-09-10 18:46:2083 days 4 hrs ago0x3898ff1b0368997e08d8e06f143ed57b3909bbf7 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.0001296185
0x65d91269c92273e5b74ede8e69b073d843bbe94ff0bc92c73aba7d14b30624a6Enter Lottery183144422021-08-23 18:14:36101 days 4 hrs ago0x4274a49fbeb724d75b8ba7bfc55fc8495a15ad1e IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000045939301
0x9c9e3fef940d2674bd153f5fde70650e811fcf33ea39ce0bbee8e3b464e674acSettle Lottery183079902021-08-23 14:20:02101 days 8 hrs ago0x0214c5c41f5249166aab9a12213ac0e2119d2cc8 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000117835
0x2f2866a15e2311c3b28527c265e1711ccc653742e6c63a2b4f61386d372f0209Settle Lottery183079122021-08-23 14:17:22101 days 8 hrs ago0xf21e035976bbfe749f262c13ae27cbe163d1795d IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.002521576
0xe0d93d0c7d2e63b6567a785128d3a70326b0035b1f1b5c7835f8eec8e556f6d4Enter Lottery183078092021-08-23 14:13:48101 days 8 hrs ago0x0214c5c41f5249166aab9a12213ac0e2119d2cc8 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000668176
0x94de1ab23af5e725717824344e45b7d9fa325fd564c889ca7f39cb8b75eeb517Enter Lottery182962142021-08-23 6:52:36101 days 15 hrs ago0x024948d3378b064911f8f679fde56ed3d64e5252 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.00096488
0xc589b43f1216f6f028c656f96932ebfa356add7e67910b35e8b246a97eaa112cEnter Lottery182217982021-08-21 6:13:08103 days 16 hrs ago0x39eea67514c31b061b6746398f5aba858db01afc IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000180903378
0x6bea8a5cf1ee51c87af08fe697c7bfdc588b8fecc4d69ceecf90df7aeea1aa06Withdraw Link181911452021-08-20 10:42:54104 days 12 hrs ago0x4274a49fbeb724d75b8ba7bfc55fc8495a15ad1e IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000047460514
0x25cf878f1aef65fba8ca6f6c577ac1db9eebcbc2d7c9ddd135909f268454ed16Enter Lottery181900902021-08-20 10:04:32104 days 12 hrs ago0x024948d3378b064911f8f679fde56ed3d64e5252 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000527270534
0xe1c320590072161f284d419e28fbd40a348cfd332ae434c84ab3d7ec76a10805Pause Next Lotte...181683142021-08-19 19:33:50105 days 3 hrs ago0x4274a49fbeb724d75b8ba7bfc55fc8495a15ad1e IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.0000557292
0xa85418719eeb660a9fd8a7aef374697ef8c7cd451667680df75d28c11675255dEnter Lottery181161442021-08-18 9:55:37106 days 12 hrs ago0xf21e035976bbfe749f262c13ae27cbe163d1795d IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.00029911279
0x550ce32d01d7d88cec9251b26df9af3c09842acfd263897894090782203fd439Enter Lottery179790212021-08-14 15:39:02110 days 7 hrs ago0x44001ceccd4d73fc785f55ef7265b33117b85669 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000289464
0xd7d3f2a545f82298ca5f9c31c929057b2e051256d2b3c9ba93a3ecfe58711131Enter Lottery179560922021-08-14 1:09:09110 days 21 hrs agoBruceTheGoose IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000096488
0x66176e7df3283b387f59dbd04faee112321f3594cbe23e4ffab9d5006f1b82e1Enter Lottery179333272021-08-13 8:46:16111 days 14 hrs ago0x7ae00498e7f721c04cd55e2025fa84ab9be3056c IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000096584487
0x8ee81b9eb3c789bdf79cddd1f3df4077c9cea759684f1acc1f4c5a82b423e577Enter Lottery179320982021-08-13 7:57:22111 days 14 hrs ago0x368947b0fe259b31907d252fb0c9a7b8a51e1489 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000156925381
0x41128dc701a6f7d1869609066e16330abfd7c0369f6a8397fd2f89f5299a6f2dEnter Lottery179320982021-08-13 7:57:22111 days 14 hrs ago0x368947b0fe259b31907d252fb0c9a7b8a51e1489 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.0001649164
0xb2d728cc10570b4718ee96ddccf149a12c67807d140c566ef20e7e2d4a4e672cSettle Lottery179320582021-08-13 7:55:58111 days 14 hrs ago0x30ae6e0632a1cb1108d92364e1d1c8dbae271589 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.001070949275
0x2d5513593138acf6dbc876813eba60a788014745f68b57318d628a60ca4e32c7Enter Lottery179320422021-08-13 7:55:26111 days 14 hrs ago0x779bf353a2d5d183192f1aad447d4b29c25cf48e IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.002758616
0xa78551956dfffea58a800a13121997eeb765df1719546784651138a92af8da19Enter Lottery179289542021-08-13 5:51:19111 days 16 hrs ago0x2063a5502bae0ceb7c9c8ab8fc27b61f3d1e19e3 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.00096488
0x7a918629553f89fc74f2cc7769a3f1e3c294ec2f6f2624bf0f7fe9d1823787b7Enter Lottery179274502021-08-13 4:53:49111 days 17 hrs ago0xddefb6166643657187c587237c3868f0fb3e37de IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000096584487
0xfdf2a464dd075199902200851ec342fe54d641dddfe45bb7b20c2edb4bf7b65aEnter Lottery179257152021-08-13 3:39:11111 days 19 hrs ago0xddefb6166643657187c587237c3868f0fb3e37de IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.000108172696
0xfda645905595e206ce7e0b4ba7f162a3aa5080a514ffed064d7867a92a9661f2Enter Lottery179232672021-08-13 2:00:13111 days 20 hrs ago0x256dd4241fb28b325466ed1c443171c6830fdf98 IN  0x653441299ec28e0301d640006e2cec4776eba6710 MATIC0.00009745288
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LotteryContract

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : LotteryContract.sol
pragma solidity ^0.6.0;

import "./interfaces/IERC20.sol";
import "./VRFConsumerBase.sol";
import "@openzeppelin/contracts/utils/Address.sol";
// import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract LotteryContract is VRFConsumerBase, ReentrancyGuard, Ownable {
    using Address for address;
    using SafeMath for uint256;

    struct LotteryConfig {
        uint256 numOfWinners;
        uint256 playersLimit;
        uint256 registrationAmount;
        uint256 adminFeePercentage;
        uint256 randomSeed;
        uint256 startedAt;
    }

    address[] public lotteryPlayers;
    address public feeAddress;
    enum LotteryStatus {
        NOTSTARTED,
        INPROGRESS,
        CLOSED
    }
    mapping(uint256 => address) public winnerAddresses;
    uint256[] public winnerIndexes;
    uint256 public totalLotteryPool;
    uint256 public adminFeesAmount;
    uint256 public rewardPoolAmount;

    IERC20 public lotteryToken;
    IERC20 public buyToken;
    LotteryStatus public lotteryStatus;
    LotteryConfig public lotteryConfig;

    bytes32 internal keyHash;
    uint256 internal fee;
    uint256 internal randomResult;
    bool internal areWinnersGenerated;
    bool internal isRandomNumberGenerated;

    bool public pauseLottery;

    uint256 public loserLotteryAmount;
    // event MaxParticipationCompleted(address indexed _from);

    event RandomNumberGenerated(uint256 indexed randomness);

    event WinnersGenerated(uint256[] winnerIndexes);

    event LotterySettled(
        uint256 _rewardPoolAmount,
        uint256 _players,
        uint256 _adminFees
    );

    event LotteryPaused();

    event LotteryUnPaused();

    event EmergencyWithdrawn();

    // LotterySettled(rewardPoolAmount, players, adminFeesAmount);

    event LotteryStarted(
        uint256 playersLimit,
        uint256 numOfWinners,
        uint256 registrationAmount,
        uint256 startedAt
    );

    event LotteryReset();

    /**
     * @dev Sets the value for adminAddress which establishes the Admin of the contract
     * Only the adminAddress will be able to set the lottery configuration,
     * start the lottery and reset the lottery.
     *
     * It also sets the required fees, keyHash etc. for the ChainLink Oracle RNG
     *
     * Also initializes the LOT ERC20 TOKEN that is minted/burned by the participating lottery players.
     *
     * The adminAdress value is immutable along with the initial
     * configuration of VRF Smart Contract. They can only be set once during
     * construction.
     */
    constructor(
        IERC20 _buyToken,
        IERC20 _lotteryToken,
        address _feeAddress,
        address _vrfCoordinator,
        address _link,
        bytes32 _keyHash
    )
        public
        VRFConsumerBase(
            _vrfCoordinator, // VRF Coordinator
            _link // LINK Token
        )
        Ownable()
    {
        feeAddress = _feeAddress;
        lotteryStatus = LotteryStatus.NOTSTARTED;
        totalLotteryPool = 0;
        keyHash = _keyHash;
        fee = 0.0001 * 10**18; // 0.0001 LINK
        areWinnersGenerated = false;
        isRandomNumberGenerated = false;
        buyToken = _buyToken; // ERC20 contract
        lotteryToken = _lotteryToken; // ERC20 contract
        // isOnlyETHAccepted = _isOnlyETHAccepted;
    }

    function pauseNextLottery() public onlyOwner {
        // require(
        //     msg.sender == adminAddress,
        //     "Starting the Lottery requires Admin Access"
        // );
        pauseLottery = true;
        emit LotteryPaused();
    }

    function unPauseNextLottery() public onlyOwner {
        // require(
        //     msg.sender == adminAddress,
        //     "Starting the Lottery requires Admin Access"
        // );
        pauseLottery = false;
        emit LotteryUnPaused();
        // resetLottery();
    }

    function withdrawLink() external onlyOwner {
        LINK.transfer(owner(), LINK.balanceOf(address(this)));
    }

    function changeFeeAddress(address _feeAddress) public onlyOwner {
        require(_feeAddress != address(0), "Incorrect fee address");
        feeAddress = _feeAddress;
    }

    /**
     * @dev Calls ChainLink Oracle's inherited function for
     * Random Number Generation.
     *
     * Requirements:
     *
     * - the contract must have a balance of at least `fee` required for VRF.
     */
    function getRandomNumber(uint256 userProvidedSeed)
        internal
        returns (bytes32 requestId)
    {
        require(
            LINK.balanceOf(address(this)) >= fee,
            "Not enough LINK - fill contract with faucet"
        );
        isRandomNumberGenerated = false;
        return requestRandomness(keyHash, fee, userProvidedSeed);
    }

    /**
     * @dev The callback function of ChainLink Oracle when the
     * Random Number Generation is completed. An event is fired
     * to notify the same and the randomResult is saved.
     *
     * Emits an {RandomNumberGenerated} event indicating the random number is
     * generated by the Oracle.
     *
     */
    function fulfillRandomness(bytes32 requestId, uint256 randomness)
        internal
        override
    {
        randomResult = randomness;
        isRandomNumberGenerated = true;
        emit RandomNumberGenerated(randomness);
    }

    /**
     * @dev Sets the Lottery Config, initializes an instance of
     * ERC20 contract that the lottery is based on and starts the lottery.
     *
     * Emits an {LotteryStarted} event indicating the Admin has started the Lottery.
     *
     * Requirements:
     *
     * - Cannot be called if the lottery is in progress.
     * - Only the address set at `adminAddress` can call this function.
     * - Number of winners `numOfWinners` should be less than or equal to half the number of
     *   players `playersLimit`.
     */
    function setLotteryRules(
        uint256 numOfWinners,
        uint256 playersLimit,
        uint256 registrationAmount,
        uint256 adminFeePercentage,
        uint256 randomSeed
    ) public onlyOwner {
        // require(
        //     msg.sender == adminAddress,
        //     "Starting the Lottery requires Admin Access"
        // );
        require(
            lotteryStatus == LotteryStatus.NOTSTARTED,
            "Error: An existing lottery is in progress"
        );
        require(
            numOfWinners <= playersLimit.div(2),
            "Number of winners should be less than or equal to half the number of players"
        );
        lotteryConfig = LotteryConfig(
            numOfWinners,
            playersLimit,
            registrationAmount,
            adminFeePercentage,
            // lotteryTokenAddress,
            randomSeed,
            block.timestamp
        );
        lotteryStatus = LotteryStatus.INPROGRESS;

        loserLotteryAmount = (registrationAmount.mul(1e18)).div(
            10**buyToken.decimals()
        );

        emit LotteryStarted(
            // lotteryTokenAddress,
            playersLimit,
            numOfWinners,
            registrationAmount,
            block.timestamp
        );
    }

    /**
     * @dev Player enters the lottery and the registration amount is
     * transferred from the player to the contract.
     *
     * Returns participant's index. This is similar to unique registration id.
     * Emits an {MaxParticipationCompleted} event indicating that all the required players have entered the lottery.
     *
     * The participant is also issued an equal amount of LOT tokens once he registers for the lottery.
     * This LOT tokens are fundamental to the lottery contract and are used internally.
     * The winners will need to burn their LOT tokens to claim the lottery winnings.
     * The other participants of the lottery can keep hold of these tokens and use for other applications.
     *
     * Requirements:
     *
     * - The player has set the necessary allowance to the Contract.
     * - The Lottery is in progress.
     * - Number of players allowed to enter in the lottery should be
     *   less than or equal to the allowed players `lotteryConfig.playersLimit`.
     */
    function enterLottery() public returns (uint256) {
        require(
            lotteryPlayers.length < lotteryConfig.playersLimit,
            "Max Participation for the Lottery Reached"
        );

        // require(
        //     lotteryPlayers.length == 0 && !pauseLottery,
        //     "Lottery is paused"
        // );

        if (lotteryPlayers.length == 0) {
            require(!pauseLottery, "Lottery is paused");
        }

        require(
            lotteryStatus == LotteryStatus.INPROGRESS,
            "The Lottery is not started or closed"
        );
        lotteryPlayers.push(msg.sender);

        buyToken.transferFrom(
            msg.sender,
            address(this),
            lotteryConfig.registrationAmount
        );

        totalLotteryPool = totalLotteryPool.add(
            lotteryConfig.registrationAmount
        );
        // call _mint from constructor ERC20
        // Not giving loser lottery tokens !!
        // lotteryToken.mint(msg.sender, lotteryConfig.registrationAmount);

        if (lotteryPlayers.length == lotteryConfig.playersLimit) {
            // emit MaxParticipationCompleted(msg.sender); // this is not needed now
            getRandomNumber(lotteryConfig.randomSeed);
        }
        return (lotteryPlayers.length).sub(1);
    }

    /**
     * @dev Settles the lottery, the winners are calculated based on
     * the random number generated. The Admin fee is calculated and
     * transferred back to Admin `adminAddress`.
     *
     * Emits an {WinnersGenerated} event indicating that the winners for the lottery have been generated.
     * Emits {LotterySettled} event indicating that the winnings have been transferred to the Admin and the Lottery is closed.
     *
     * Requirements:
     *
     * - The random number has been generated
     * - The Lottery is in progress.
     */
    function settleLottery() external {
        require(
            isRandomNumberGenerated,
            "Lottery Configuration still in progress. Please try in a short while"
        );
        require(
            lotteryStatus == LotteryStatus.INPROGRESS,
            "The Lottery is not started or closed"
        );
        for (uint256 i = 0; i < lotteryConfig.numOfWinners; i = i.add(1)) {
            uint256 winningIndex = randomResult.mod(lotteryConfig.playersLimit);
            uint256 counter = 0;
            while (winnerAddresses[winningIndex] != address(0)) {
                randomResult = getRandomNumberBlockchain(i, randomResult);
                winningIndex = randomResult.mod(lotteryConfig.playersLimit);
                counter = counter.add(1);
                if (counter == lotteryConfig.playersLimit) {
                    while (winnerAddresses[winningIndex] != address(0)) {
                        winningIndex = (winningIndex.add(1)).mod(
                            lotteryConfig.playersLimit
                        );
                    }
                    counter = 0;
                }
            }
            winnerAddresses[winningIndex] = lotteryPlayers[winningIndex];
            winnerIndexes.push(winningIndex);
            randomResult = getRandomNumberBlockchain(i, randomResult);
        }
        areWinnersGenerated = true;
        emit WinnersGenerated(winnerIndexes);
        adminFeesAmount = (
            (totalLotteryPool.mul(lotteryConfig.adminFeePercentage)).div(100)
        );
        rewardPoolAmount = (totalLotteryPool.sub(adminFeesAmount)).div(
            lotteryConfig.numOfWinners
        );
        lotteryStatus = LotteryStatus.CLOSED;

        // if (isOnlyETHAccepted) {
        //     (bool status, ) = payable(adminAddress).call{
        //         value: adminFeesAmount
        //     }("");
        //     require(status, "Admin fees not transferred");
        // } else {
        buyToken.transfer(feeAddress, adminFeesAmount);
        // }

        emit LotterySettled(
            rewardPoolAmount,
            lotteryConfig.numOfWinners,
            adminFeesAmount
        );
        collectRewards();
    }

    function getWinningAmount() public view returns (uint256) {
        uint256 expectedTotalLotteryPool = lotteryConfig.playersLimit.mul(
            lotteryConfig.registrationAmount
        );
        uint256 adminFees = (
            (expectedTotalLotteryPool.mul(lotteryConfig.adminFeePercentage))
                .div(100)
        );
        uint256 rewardPool = (expectedTotalLotteryPool.sub(adminFees)).div(
            lotteryConfig.numOfWinners
        );

        return rewardPool;
    }

    function getCurrentlyActivePlayers() public view returns (uint256) {
        return lotteryPlayers.length;
    }

    /**
     * @dev The winners of the lottery can call this function to transfer their winnings
     * from the lottery contract to their own address. The winners will need to burn their
     * LOT tokens to claim the lottery rewards. This is executed by the lottery contract itself.
     *
     *
     * Requirements:
     *
     * - The Lottery is settled i.e. the lotteryStatus is CLOSED.
     */
    /**
     * @dev The winners of the lottery can call this function to transfer their winnings
     * from the lottery contract to their own address. The winners will need to burn their
     * LOT tokens to claim the lottery rewards. This is executed by the lottery contract itself.
     *
     *
     * Requirements:
     *
     * - The Lottery is settled i.e. the lotteryStatus is CLOSED.
     */
    function collectRewards() private nonReentrant {
        // require(
        //     lotteryStatus == LotteryStatus.CLOSED,
        //     "The Lottery is not settled. Please try in a short while."
        // );

        bool isWinner = false;

        for (uint256 i = 0; i < lotteryConfig.playersLimit; i = i.add(1)) {
            address player = lotteryPlayers[i];
            // if (address(msg.sender) == winnerAddresses[winnerIndexes[i]]) {
            for (uint256 j = 0; j < lotteryConfig.numOfWinners; j = j.add(1)) {
                address winner = winnerAddresses[winnerIndexes[j]];

                if (winner != address(0) && winner == player) {
                    isWinner = true;
                    winnerAddresses[winnerIndexes[j]] = address(0);
                    break;
                }
            }

            if (isWinner) {
                // _burn(address(msg.sender), lotteryConfig.registrationAmount);
                // lotteryToken.burnFrom(msg.sender, lotteryConfig.registrationAmount);
                // if (isOnlyETHAccepted) {
                //     (bool status, ) = payable(player).call{
                //         value: rewardPoolAmount
                //     }("");
                //     require(status, "Amount not transferred to winner");
                // } else {
                buyToken.transfer(address(player), rewardPoolAmount);
                // }
            } else {
                lotteryToken.mint(player, loserLotteryAmount);
            }

            isWinner = false;
        }

        resetLottery();
    }

    /**
     * @dev Generates a random number based on the blockHash and random offset
     */
    function getRandomNumberBlockchain(uint256 offset, uint256 randomness)
        internal
        view
        returns (uint256)
    {
        bytes32 offsetBlockhash = blockhash(block.number.sub(offset));
        uint256 randomBlockchainNumber = uint256(offsetBlockhash);
        uint256 finalRandomNumber = randomness + randomBlockchainNumber;
        if (finalRandomNumber >= randomness) {
            return finalRandomNumber;
        } else {
            if (randomness >= randomBlockchainNumber) {
                return randomness.sub(randomBlockchainNumber);
            }
            return randomBlockchainNumber.sub(randomness);
        }
    }

    /**
     * It can be called by admin to withdraw all the amount in case of
     * any failure to play lottery. It will be distributed later on amongst the
     * participants.
     */
    function emergencyWithdraw() external onlyOwner {
        buyToken.transfer(msg.sender, buyToken.balanceOf(address(this)));
        emit EmergencyWithdrawn();
    }

    /**
     * @dev Resets the lottery, clears the existing state variable values and the lottery
     * can be initialized again.
     *
     * Emits {LotteryReset} event indicating that the lottery config and contract state is reset.
     *
     * Requirements:
     *
     * - Only the address set at `adminAddress` can call this function.
     * - The Lottery has closed.
     */
    function resetLottery() private {
        // require(
        //     msg.sender == adminAddress,
        //     "Resetting the Lottery requires Admin Access"
        // );
        // require(
        //     lotteryStatus == LotteryStatus.CLOSED,
        //     "Lottery Still in Progress"
        // );
        uint256 tokenBalance = lotteryToken.balanceOf(address(this));
        if (tokenBalance > 0) {
            buyToken.transfer(feeAddress, tokenBalance);
        }
        // delete lotteryConfig;
        delete randomResult;
        lotteryStatus = LotteryStatus.INPROGRESS;
        delete totalLotteryPool;
        delete adminFeesAmount;
        delete rewardPoolAmount;
        for (uint256 i = 0; i < lotteryPlayers.length; i = i.add(1)) {
            delete winnerAddresses[i];
        }
        isRandomNumberGenerated = false;
        areWinnersGenerated = false;
        delete winnerIndexes;
        delete lotteryPlayers;
        emit LotteryReset();
    }
}

File 2 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    function mint(address receipient, uint256 amount) external returns (bool);

    function burnFrom(address from, uint256 amount) external;

    function decimals() external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

File 3 of 10 : VRFConsumerBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/math/SafeMath.sol";

import "./interfaces/LinkTokenInterface.sol";

import "./VRFRequestIDBase.sol";

/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.)
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request.
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {

  using SafeMath for uint256;

  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
   * @notice principles to keep in mind when implementing your fulfillRandomness
   * @notice method.
   *
   * @dev VRFConsumerBase expects its subcontracts to have a method with this
   * @dev signature, and will call it once it has verified the proof
   * @dev associated with the randomness. (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomness the VRF output
   */
  function fulfillRandomness(bytes32 requestId, uint256 randomness)
    internal virtual;

  /**
   * @notice requestRandomness initiates a request for VRF output given _seed
   *
   * @dev The fulfillRandomness method receives the output, once it's provided
   * @dev by the Oracle, and verified by the vrfCoordinator.
   *
   * @dev The _keyHash must already be registered with the VRFCoordinator, and
   * @dev the _fee must exceed the fee specified during registration of the
   * @dev _keyHash.
   *
   * @dev The _seed parameter is vestigial, and is kept only for API
   * @dev compatibility with older versions. It can't *hurt* to mix in some of
   * @dev your own randomness, here, but it's not necessary because the VRF
   * @dev oracle will mix the hash of the block containing your request into the
   * @dev VRF seed it ultimately uses.
   *
   * @param _keyHash ID of public key against which randomness is generated
   * @param _fee The amount of LINK to send with the request
   * @param _seed seed mixed into the input of the VRF.
   *
   * @return requestId unique ID for this request
   *
   * @dev The returned requestId can be used to distinguish responses to
   * @dev concurrent requests. It is passed as the first argument to
   * @dev fulfillRandomness.
   */
  function requestRandomness(bytes32 _keyHash, uint256 _fee, uint256 _seed)
    internal returns (bytes32 requestId)
  {
    LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, _seed));
    // This is the seed passed to VRFCoordinator. The oracle will mix this with
    // the hash of the block containing this request to obtain the seed/input
    // which is finally passed to the VRF cryptographic machinery.
    uint256 vRFSeed  = makeVRFInputSeed(_keyHash, _seed, address(this), nonces[_keyHash]);
    // nonces[_keyHash] must stay in sync with
    // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
    // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
    // This provides protection against the user repeating their input seed,
    // which would result in a predictable/duplicate output, if multiple such
    // requests appeared in the same block.
    nonces[_keyHash] = nonces[_keyHash].add(1);
    return makeRequestId(_keyHash, vRFSeed);
  }

  LinkTokenInterface immutable internal LINK;
  address immutable private vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 /* keyHash */ => uint256 /* nonce */) private nonces;

  /**
   * @param _vrfCoordinator address of VRFCoordinator contract
   * @param _link address of LINK token contract
   *
   * @dev https://docs.chain.link/docs/link-token-contracts
   */
  constructor(address _vrfCoordinator, address _link) public {
    vrfCoordinator = _vrfCoordinator;
    LINK = LinkTokenInterface(_link);
  }

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external {
    require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
    fulfillRandomness(requestId, randomness);
  }
}

File 4 of 10 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 5 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../utils/Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 6 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 7 of 10 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 8 of 10 : LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);
  function approve(address spender, uint256 value) external returns (bool success);
  function balanceOf(address owner) external view returns (uint256 balance);
  function decimals() external view returns (uint8 decimalPlaces);
  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);
  function increaseApproval(address spender, uint256 subtractedValue) external;
  function name() external view returns (string memory tokenName);
  function symbol() external view returns (string memory tokenSymbol);
  function totalSupply() external view returns (uint256 totalTokensIssued);
  function transfer(address to, uint256 value) external returns (bool success);
  function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success);
  function transferFrom(address from, address to, uint256 value) external returns (bool success);
}

File 9 of 10 : VRFRequestIDBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract VRFRequestIDBase {

  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF output due to repetition of the
   * @dev user-supplied seed, that seed is combined in a hash with the
   * @dev user-specific nonce, and the address of the consuming contract. The
   * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
   * @dev the final seed, but the nonce does protect against repetition in
   * @dev requests which are included in a single block.
   *
   * @param _userSeed VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(bytes32 _keyHash, uint256 _userSeed,
    address _requester, uint256 _nonce)
    internal pure returns (uint256)
  {
    return  uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
  }

  /**
   * @notice Returns the id for this request
   * @param _keyHash The serviceAgreement ID to be used for this request
   * @param _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(
    bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}

File 10 of 10 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"_buyToken","type":"address"},{"internalType":"contract IERC20","name":"_lotteryToken","type":"address"},{"internalType":"address","name":"_feeAddress","type":"address"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"EmergencyWithdrawn","type":"event"},{"anonymous":false,"inputs":[],"name":"LotteryPaused","type":"event"},{"anonymous":false,"inputs":[],"name":"LotteryReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_rewardPoolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_players","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_adminFees","type":"uint256"}],"name":"LotterySettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"playersLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numOfWinners","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"registrationAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startedAt","type":"uint256"}],"name":"LotteryStarted","type":"event"},{"anonymous":false,"inputs":[],"name":"LotteryUnPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"RandomNumberGenerated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"winnerIndexes","type":"uint256[]"}],"name":"WinnersGenerated","type":"event"},{"inputs":[],"name":"adminFeesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddress","type":"address"}],"name":"changeFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enterLottery","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentlyActivePlayers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWinningAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"loserLotteryAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lotteryConfig","outputs":[{"internalType":"uint256","name":"numOfWinners","type":"uint256"},{"internalType":"uint256","name":"playersLimit","type":"uint256"},{"internalType":"uint256","name":"registrationAmount","type":"uint256"},{"internalType":"uint256","name":"adminFeePercentage","type":"uint256"},{"internalType":"uint256","name":"randomSeed","type":"uint256"},{"internalType":"uint256","name":"startedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lotteryPlayers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lotteryStatus","outputs":[{"internalType":"enum LotteryContract.LotteryStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lotteryToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseLottery","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseNextLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPoolAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numOfWinners","type":"uint256"},{"internalType":"uint256","name":"playersLimit","type":"uint256"},{"internalType":"uint256","name":"registrationAmount","type":"uint256"},{"internalType":"uint256","name":"adminFeePercentage","type":"uint256"},{"internalType":"uint256","name":"randomSeed","type":"uint256"}],"name":"setLotteryRules","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalLotteryPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unPauseNextLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"winnerAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"winnerIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c060405234801561001057600080fd5b506040516121ec3803806121ec833981810160405260c081101561003357600080fd5b5080516020820151604083015160608085015160808087015160a0978801516001600160601b031984861b81169099529381901b90971690526001805593949293919290600061008161013a565b600280546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600480546001600160a01b039586166001600160a01b031991821617909155600b80546000600755601293909355655af3107a40006013556015805461ffff191690556001600160a81b03199092169685169690961790555050600a8054909316911617905561013e565b3390565b60805160601c60a05160601c61207161017b60003980610c165280611c76525080610ab85280610b0d528061199b5280611c4752506120716000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80638dc654a2116100f9578063c1af578511610097578063f2fde38b11610071578063f2fde38b1461032e578063f9b93a1d14610354578063fc5ab87c14610371578063fdce40d3146103ac576101a9565b8063c1af578514610301578063cd843b7714610309578063db2e21bc14610326576101a9565b8063a4821719116100d3578063a4821719146102cd578063ab73e144146102d5578063ae97f5fd146102f1578063bb7152a7146102f9576101a9565b80638dc654a21461029a57806394539467146102a257806394985ddd146102aa576101a9565b806353b52215116101665780635bfd0af6116101405780635bfd0af61461027a5780636dad2a9114610282578063715018a61461028a5780638da5cb5b14610292576101a9565b806353b522151461026257806358509f2f1461026a5780635ad726b414610272576101a9565b806303b604f4146101ae578063045f9c97146101b85780630d683dd9146101f1578063285e14061461021a57806341275358146102405780635268cd9314610248575b600080fd5b6101b66103e1565b005b6101d5600480360360208110156101ce57600080fd5b503561047a565b604080516001600160a01b039092168252519081900360200190f35b6101f9610495565b6040518082600281111561020957fe5b815260200191505060405180910390f35b6101b66004803603602081101561023057600080fd5b50356001600160a01b03166104a5565b6101d561057c565b61025061058b565b60408051918252519081900360200190f35b610250610591565b610250610597565b6101b661059d565b61025061093f565b610250610945565b6101b6610999565b6101d5610a45565b6101b6610a54565b6101d5610bfc565b6101b6600480360360408110156102c057600080fd5b5080359060200135610c0b565b6101d5610c92565b6102dd610ca1565b604080519115158252519081900360200190f35b610250610cb0565b6101b6610cb6565b610250610d54565b6102506004803603602081101561031f57600080fd5b5035610f58565b6101b6610f76565b6101b66004803603602081101561034457600080fd5b50356001600160a01b03166110fe565b6101d56004803603602081101561036a57600080fd5b5035611201565b610379611228565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b6101b6600480360360a08110156103c257600080fd5b508035906020810135906040810135906060810135906080013561123d565b6103e9611474565b6001600160a01b03166103fa610a45565b6001600160a01b031614610443576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6015805462ff0000191690556040517f6b696c23438b6736443b11696dd8279c0189de0e47d44803ce815621e396083190600090a1565b6005602052600090815260409020546001600160a01b031681565b600b54600160a01b900460ff1681565b6104ad611474565b6001600160a01b03166104be610a45565b6001600160a01b031614610507576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6001600160a01b03811661055a576040805162461bcd60e51b8152602060048201526015602482015274496e636f727265637420666565206164647265737360581b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031681565b60085481565b60035490565b60165481565b601554610100900460ff166105e35760405162461bcd60e51b8152600401808060200182810382526044815260200180611ff86044913960600191505060405180910390fd5b6001600b54600160a01b900460ff1660028111156105fd57fe5b146106395760405162461bcd60e51b8152600401808060200182810382526024815260200180611fd46024913960400191505060405180910390fd5b60005b600c5481101561079457600d546014546000916106599190611478565b905060005b6000828152600560205260409020546001600160a01b0316156106f957610687836014546114e1565b6014819055600d546106999190611478565b91506106a681600161152b565b600d549091508114156106f4575b6000828152600560205260409020546001600160a01b0316156106f057600d546106e9906106e384600161152b565b90611478565b91506106b4565b5060005b61065e565b6003828154811061070657fe5b600091825260208083209091015484835260059091526040822080546001600160a01b0319166001600160a01b039092169190911790556006805460018101825591527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0182905560145461077c9084906114e1565b6014555061078d905081600161152b565b905061063c565b506015805460ff19166001179055604080516020808252600680549183018290527fa13f7b4dbc201a7d6c6a72975f8f690748efea2d6504de79984ffeee6973c6059390929182918201908490801561080c57602002820191906000526020600020905b8154815260200190600101908083116107f8575b50509250505060405180910390a1600f54600754610836916064916108309161158c565b906115e5565b6008819055600c5460075461084f92610830919061164c565b600955600b805460ff60a01b1916600160a11b1790819055600480546008546040805163a9059cbb60e01b81526001600160a01b039384169481019490945260248401919091525192169163a9059cbb916044808201926020929091908290030181600087803b1580156108c257600080fd5b505af11580156108d6573d6000803e3d6000fd5b505050506040513d60208110156108ec57600080fd5b5050600954600c5460085460408051938452602084019290925282820152517f782c72f86b2d0a9b6d7639cb60b06064c5b3f21796fde3d2cda7ba94a8eb02d79181900360600190a161093d6116a9565b565b60095481565b600e54600d5460009182916109599161158c565b9050600061097a6064610830600c600301548561158c90919063ffffffff16565b600c5490915060009061099190610830858561164c565b935050505090565b6109a1611474565b6001600160a01b03166109b2610a45565b6001600160a01b0316146109fb576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6002546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600280546001600160a01b0319169055565b6002546001600160a01b031690565b610a5c611474565b6001600160a01b0316610a6d610a45565b6001600160a01b031614610ab6576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb610aed610a45565b604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b158015610b5357600080fd5b505afa158015610b67573d6000803e3d6000fd5b505050506040513d6020811015610b7d57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610bce57600080fd5b505af1158015610be2573d6000803e3d6000fd5b505050506040513d6020811015610bf857600080fd5b5050565b600a546001600160a01b031681565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c88576040805162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604482015290519081900360640190fd5b610bf88282611951565b600b546001600160a01b031681565b60155462010000900460ff1681565b60075481565b610cbe611474565b6001600160a01b0316610ccf610a45565b6001600160a01b031614610d18576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6015805462ff00001916620100001790556040517fc1a06552b071d5308a563af238d8ac7d9bf3a311d71ee8e7add408f9209404fe90600090a1565b600d5460035460009111610d995760405162461bcd60e51b8152600401808060200182810382526029815260200180611f6a6029913960400191505060405180910390fd5b600354610df25760155462010000900460ff1615610df2576040805162461bcd60e51b8152602060048201526011602482015270131bdd1d195c9e481a5cc81c185d5cd959607a1b604482015290519081900360640190fd5b6001600b54600160a01b900460ff166002811115610e0c57fe5b14610e485760405162461bcd60e51b8152600401808060200182810382526024815260200180611fd46024913960400191505060405180910390fd5b6003805460018101825560009182527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191633908117909155600b54600e54604080516323b872dd60e01b815260048101949094523060248501526044840191909152516001600160a01b0391909116926323b872dd92606480820193602093909283900390910190829087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b505050506040513d6020811015610f1757600080fd5b5050600e54600754610f289161152b565b600755600d546003541415610f4557601054610f4390611994565b505b600354610f5390600161164c565b905090565b60068181548110610f6557fe5b600091825260209091200154905081565b610f7e611474565b6001600160a01b0316610f8f610a45565b6001600160a01b031614610fd8576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b600b54604080516370a0823160e01b815230600482015290516001600160a01b039092169163a9059cbb91339184916370a08231916024808301926020929190829003018186803b15801561102c57600080fd5b505afa158015611040573d6000803e3d6000fd5b505050506040513d602081101561105657600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b1580156110a757600080fd5b505af11580156110bb573d6000803e3d6000fd5b505050506040513d60208110156110d157600080fd5b50506040517fcd310f174a338d5afb2b17ebca2bda872a317a1e5ec53f6277803b93e8644eb990600090a1565b611106611474565b6001600160a01b0316611117610a45565b6001600160a01b031614611160576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6001600160a01b0381166111a55760405162461bcd60e51b8152600401808060200182810382526026815260200180611ea46026913960400191505060405180910390fd5b6002546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6003818154811061120e57fe5b6000918252602090912001546001600160a01b0316905081565b600c54600d54600e54600f5460105460115486565b611245611474565b6001600160a01b0316611256610a45565b6001600160a01b03161461129f576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6000600b54600160a01b900460ff1660028111156112b957fe5b146112f55760405162461bcd60e51b8152600401808060200182810382526029815260200180611eca6029913960400191505060405180910390fd5b6113008460026115e5565b85111561133e5760405162461bcd60e51b815260040180806020018281038252604c815260200180611f1e604c913960600191505060405180910390fd5b6040805160c081018252868152602080820187905281830186905260608201859052608082018490524260a0909201829052600c889055600d879055600e869055600f8590556010849055601191909155600b805460ff60a01b1916600160a01b1790819055825163313ce56760e01b81529251611424936001600160a01b039092169263313ce5679260048181019391829003018186803b1580156113e357600080fd5b505afa1580156113f7573d6000803e3d6000fd5b505050506040513d602081101561140d57600080fd5b5051600a0a61083085670de0b6b3a764000061158c565b601655604080518581526020810187905280820185905242606082015290517fce72aaaa67c222d8ec98e00408e79a7eadb369594351a5a7d7fec6609d108ba29181900360800190a15050505050565b3390565b60008082116114ce576040805162461bcd60e51b815260206004820152601860248201527f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000604482015290519081900360640190fd5b8183816114d757fe5b0690505b92915050565b6000806114ee438561164c565b409050808381018481106115065792506114db915050565b81851061152157611517858361164c565b93505050506114db565b611517828661164c565b600082820183811015611585576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008261159b575060006114db565b828202828482816115a857fe5b04146115855760405162461bcd60e51b8152600401808060200182810382526021815260200180611f936021913960400191505060405180910390fd5b600080821161163b576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161164457fe5b049392505050565b6000828211156116a3576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60026001541415611701576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556000805b600d548110156119415760006003828154811061172357fe5b60009182526020822001546001600160a01b031691505b600c54811015611810576000600560006006848154811061175757fe5b600091825260208083209091015483528201929092526040019020546001600160a01b03169050801580159061179e5750826001600160a01b0316816001600160a01b0316145b156117fd5760019450600060056000600685815481106117ba57fe5b9060005260206000200154815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050611810565b5061180981600161152b565b905061173a565b5082156118a357600b546009546040805163a9059cbb60e01b81526001600160a01b03858116600483015260248201939093529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561187157600080fd5b505af1158015611885573d6000803e3d6000fd5b505050506040513d602081101561189b57600080fd5b5061192a9050565b600a54601654604080516340c10f1960e01b81526001600160a01b0385811660048301526024820193909352905191909216916340c10f199160448083019260209291908290030181600087803b1580156118fd57600080fd5b505af1158015611911573d6000803e3d6000fd5b505050506040513d602081101561192757600080fd5b50505b506000915061193a81600161152b565b905061170a565b5061194a611a8b565b5060018055565b60148190556015805461ff00191661010017905560405181907facb85192b17e57cdd6ffdc2af021cc70c3a2269771b37b82dd36695fec903af590600090a25050565b60006013547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611a0657600080fd5b505afa158015611a1a573d6000803e3d6000fd5b505050506040513d6020811015611a3057600080fd5b50511015611a6f5760405162461bcd60e51b815260040180806020018281038252602b815260200180611ef3602b913960400191505060405180910390fd5b6015805461ff00191690556012546013546114db919084611c43565b600a54604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611ad657600080fd5b505afa158015611aea573d6000803e3d6000fd5b505050506040513d6020811015611b0057600080fd5b505190508015611b9157600b54600480546040805163a9059cbb60e01b81526001600160a01b0392831693810193909352602483018590525192169163a9059cbb916044808201926020929091908290030181600087803b158015611b6457600080fd5b505af1158015611b78573d6000803e3d6000fd5b505050506040513d6020811015611b8e57600080fd5b50505b60006014819055600b805460ff60a01b1916600160a01b1790556007819055600881905560098190555b600354811015611bf357600081815260056020526040902080546001600160a01b0319169055611bec81600161152b565b9050611bbb565b506015805461ffff19169055611c0b60066000611e69565b611c1760036000611e69565b6040517fc07cdc0437f4a5523d938e3a96f2e751ce4a8e8784c5ce2316c7f833ac26772090600090a150565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000085878660405160200180838152602001828152602001925050506040516020818303038152906040526040518463ffffffff1660e01b815260040180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611d1f578181015183820152602001611d07565b50505050905090810190601f168015611d4c5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611d6d57600080fd5b505af1158015611d81573d6000803e3d6000fd5b505050506040513d6020811015611d9757600080fd5b5050600084815260208190526040812054611db790869085903090611df6565b600086815260208190526040902054909150611dd490600161152b565b600086815260208190526040902055611ded8582611e3d565b95945050505050565b60408051602080820196909652808201949094526001600160a01b039290921660608401526080808401919091528151808403909101815260a09092019052805191012090565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b5080546000825590600052602060002090810190611e879190611e8a565b50565b5b80821115611e9f5760008155600101611e8b565b509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734572726f723a20416e206578697374696e67206c6f747465727920697320696e2070726f67726573734e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e74726163742077697468206661756365744e756d626572206f662077696e6e6572732073686f756c64206265206c657373207468616e206f7220657175616c20746f2068616c6620746865206e756d626572206f6620706c61796572734d61782050617274696369706174696f6e20666f7220746865204c6f74746572792052656163686564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546865204c6f7474657279206973206e6f742073746172746564206f7220636c6f7365644c6f747465727920436f6e66696775726174696f6e207374696c6c20696e2070726f67726573732e20506c656173652074727920696e20612073686f7274207768696c65a26469706673582212207c38cd001e2b9673d82e02aa35277b5c2ae3b8f3f400d09dd0a34bb6060fc82e64736f6c634300060c00330000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000b032512a23ef041bec2e48e9b3f07286408b2b26000000000000000000000000445c96b55e6846a039f90ed21f979afebd2392d60000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1f86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000b032512a23ef041bec2e48e9b3f07286408b2b26000000000000000000000000445c96b55e6846a039f90ed21f979afebd2392d60000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1f86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da

-----Decoded View---------------
Arg [0] : _buyToken (address): 0x2791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [1] : _lotteryToken (address): 0xb032512a23ef041bec2e48e9b3f07286408b2b26
Arg [2] : _feeAddress (address): 0x445c96b55e6846a039f90ed21f979afebd2392d6
Arg [3] : _vrfCoordinator (address): 0x3d2341adb2d31f1c5530cdc622016af293177ae0
Arg [4] : _link (address): 0xb0897686c545045afc77cf20ec7a532e3120e0f1
Arg [5] : _keyHash (bytes32): 0xf86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [1] : 000000000000000000000000b032512a23ef041bec2e48e9b3f07286408b2b26
Arg [2] : 000000000000000000000000445c96b55e6846a039f90ed21f979afebd2392d6
Arg [3] : 0000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0
Arg [4] : 000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1
Arg [5] : f86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.