Contract 0x6928f1da848f31b30fcc3fdca578e1c15e629ffa 1

 
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xfcc3edbd8ebca10725f84fa5c2cef66955ee47410f11bc589a3c53b0321ac2abBuy Entries132403932021-12-06 9:30:3511 hrs 52 mins ago0xbfac460b7094c07dfadfa365e45f2ed753b8423b IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00195806
0xf7e849c27e9dccdcbe8e3ab443c8ebf4e02917dab9d99b278052f4b130a322daBuy Entries132402792021-12-06 9:24:5311 hrs 57 mins ago0x768824c81db756db707e794eb2027d7a3e1502b5 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00195806
0x68130e7fbf7160d826a5b20a679463840002b6dcbd4487516a2a8510f876a67aBuy Entries132395182021-12-06 8:46:0012 hrs 36 mins ago0x9129d4919d33112cc9b1ce6f4c7f41526cd815d2 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00195806
0xdae6f9518cf527da21168760832e8a1b5c31b721c708a75e5747b160725db89cBuy Entries132395122021-12-06 8:45:4212 hrs 37 mins ago0x3a74d0023ca2f33e59b48ee0461622253479ab53 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00195806
0x4031609377431b27228fec7906dce59ac75f910c8fb2ea8996f8c4dae04eb550Buy Entries132395002021-12-06 8:45:0212 hrs 37 mins ago0x75c98e92eac409963e27efc75d2bf556d8a7878f IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00195806
0x14c224a6976c8da35775f35d7498b3f3016ebef98a7edd6d7291b77cf49ab49cBuy Entries132394952021-12-06 8:44:4212 hrs 38 mins ago0xc69365f9fad3bd240e8ee24e16856c6a25b0aebf IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00195806
0x09b294a2356a0635f64fc82d9448dbc1db87434d4ff430fff01a757ff6772547Buy Entries132333922021-12-06 3:33:4117 hrs 49 mins ago0xd6fb1e7fbeec59d653e7e21f8d15bb4ff9c69a00 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00156968
0x099000af901e9e344c5feac38644b0641bc222be7058c7f119314b3f2bb50d5fBuy Entries132333692021-12-06 3:32:3217 hrs 50 mins ago0xe0fbc13519a376e459af1168704369d1183f7d5f IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00164468
0x0570fd69a0baecf65617c79548f064130f328812aeebec95905892740e2df7e8Buy Entries132263352021-12-05 21:35:2723 hrs 47 mins ago0x1583ae52f17cf88832eb9efa894fd2900516578a IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0x8b0afb1ba882e0d05ee2324c38e19e9ae699a2640b46b6a75e1e6180799b69afBuy Entries132196832021-12-05 15:53:081 day 5 hrs ago0x5882e5bec3b34f46ec516b7e4f7ed5c604e8f42b IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0xae43ca19d5d028ad66132352e100c27646d700ee8820557e3c2d2bb4eb11ed90Buy Entries132104002021-12-05 7:49:461 day 13 hrs ago0x4819da611933e182d798c88cdd283e54ac9b96b2 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0x952b4cd10d3ffd334af44be41c5bff86b07e789a18a60b430aed79453d3ffb76Buy Entries131889722021-12-04 13:54:182 days 7 hrs ago0x6912c468bc767e5887d911b9f13ed1f69f57ab09 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00164468
0x38b786e5feb2166484c35278a232bfec5fdc326e05ff6c179b76f4343c0874a5Buy Entries131869812021-12-04 12:12:142 days 9 hrs ago0x9046efa4953b1a071ae72284f3d66de49ec06e2f IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0x4b23e7ddf7f9a68d461c7f38608b4e4b78c26e6452eda418d4d8af0810818a0dBuy Entries131766592021-12-04 3:23:082 days 17 hrs ago0xd6fb1e7fbeec59d653e7e21f8d15bb4ff9c69a00 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001883
0x328ac30815c83070b8eabdc46b0896745039b784e2b6872b7aaba1ac0c5afc60Buy Entries131766272021-12-04 3:21:322 days 18 hrs ago0xe0fbc13519a376e459af1168704369d1183f7d5f IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0xee99cd8e7b339f151ec7fb7eefde3e068bee7825c2c0abd4ca6e6d647ebeed3aBuy Entries131718032021-12-03 23:19:452 days 22 hrs ago0xe06d4ef6392e532582a389e3b4065033fba87db8 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00188306
0xcccd13482bc1a3d25f047a7c42c06a83854c83a0bb53cf0b28d3acf9cc667189Buy Entries131627952021-12-03 15:45:403 days 5 hrs ago0x4abaf01c6733a27460cb99c6a66088e87dd599b2 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0xe87676fbdde00add8cc0fa51778b3a61cbd122ec1fb25f6ecb989979a3202de0Buy Entries131435282021-12-02 23:25:563 days 21 hrs ago0x351228ab1076acee777351a4254b37ea68cdaba9 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00164468
0x88898f251bd4d34d7523c03a7b104c207e8d91d87f292e5b0f36855817c33c7eBuy Entries131427922021-12-02 22:49:083 days 22 hrs ago0x6912c468bc767e5887d911b9f13ed1f69f57ab09 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0x71a29cae2d7ae30c07bf0c98f2590893ed1bed98d22adb2a9609fdc62716c9e5Buy Entries131398432021-12-02 20:21:024 days 1 hr ago0x6db82468a924f70ef0830935bd3276bf0f823e01 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00195806
0x61f5abac54a4541055fd6e638425aa59e4a5d3d71d13022e524e3fd8ceea7cacWithdraw Rewards131397142021-12-02 20:14:354 days 1 hr ago0x6db82468a924f70ef0830935bd3276bf0f823e01 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.000378035
0x03591814060e5b4f421c4dd5c418f669ccf73f537c8dc2bc9c3627b67a367470Buy Entries131282652021-12-02 10:29:084 days 10 hrs ago0xd1701167f3bb5bc033e3f50b3e5d9865e21d4aaa IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.0026362
0x57f99bfa8d978b4c4b66aa24c80e32b9a2bf9678c5bb03ec800d6663b2eb857bBuy Entries131282392021-12-02 10:27:504 days 10 hrs ago0xe4310545e143b6e44aefa9a96f9aca44984cb1e0 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.00164468
0x5d4dbc016d1862626909cec6afad71e2a35570844434aaf667f28094e78d2695Buy Entries131282042021-12-02 10:26:054 days 10 hrs ago0xba784b95f2e6f839a76df3a4adfb0db1ea9e1c0a IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.001958
0x681cd8bd720a0dc92a2d6ef12d52ec2ea5b11fb9b2f7fc40f67f51b720e4aeb5Buy Entries131107412021-12-01 19:16:525 days 2 hrs ago0xe4310545e143b6e44aefa9a96f9aca44984cb1e0 IN  0x6928f1da848f31b30fcc3fdca578e1c15e629ffa0 BNB0.007832
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LotteryLikePool

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
No with 200 runs

Other Settings:
constantinople EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 8 : LinkedList.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

struct LinkedNode {
    bool inited;
    uint256 value;
    uint256 prev;
    uint256 next;
}

struct LinkedList {
    uint256 head;
    uint256 last;
    mapping(uint256 => LinkedNode) mem;
    uint256 it;
    uint256 length;
}

library LinkedListLib {
    function insert(
        LinkedList storage self,
        uint256 bearingPointer,
        uint256 value
    ) internal returns (uint256 pointer) {
        LinkedNode storage node = self.mem[bearingPointer];
        require(node.inited || bearingPointer == 0, "LinkedList insert: pointer out of scope");
        self.it += 1;
        LinkedNode storage newNode = self.mem[self.it];
        newNode.inited = true;
        newNode.value = value;
        newNode.prev = bearingPointer;
        newNode.next = bearingPointer == 0 ? self.head : node.next;
        node.next = self.it;
        self.mem[newNode.prev].next = self.it;
        self.mem[newNode.next].prev = self.it;
        if (bearingPointer == 0) self.head = self.it;
        if (bearingPointer == self.last) self.last = self.it;
        self.length += 1;
        return self.it;
    }

    function remove(LinkedList storage self, uint256 pointer) internal {
        LinkedNode storage node = self.mem[pointer];
        require(node.inited, "LinkedList remove: pointer out of scope");
        node.inited = false;
        self.mem[node.prev].next = node.next;
        self.mem[node.next].prev = node.prev;
        if (self.head == pointer) self.head = node.next;
        if (self.last == pointer) self.last = node.prev;
        self.length -= 1;
    }

    function get(LinkedList storage self, uint256 pointer) internal view returns (uint256 value) {
        LinkedNode storage node = self.mem[pointer];
        require(node.inited, "LinkedList get: pointer out of scope");
        return node.value;
    }

    function getNode(LinkedList storage self, uint256 pointer) internal view returns (LinkedNode memory) {
        LinkedNode storage node = self.mem[pointer];
        require(node.inited, "LinkedList getNode: pointer out of scope");
        return node;
    }
}

File 2 of 8 : LotteryLikePool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

import "openzeppelin-solidity/contracts/math/Math.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";

import "./LinkedList.sol";
import "./TwoStageOwnable.sol";

contract LotteryLikePool is TwoStageOwnable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using LinkedListLib for LinkedList;

    /// @notice Returns the time (in seconds) the owner has to verify the random seed
    function ownerSubmittingPeriod() public virtual pure returns (uint256) {
        return 1 days;
    }

    /// @notice Returns the time (in seconds) that the participants have to withdraw their rewards after round is closed
    function rewardWithdrawalPeriod() public virtual pure returns (uint256) {
        return 6 days;
    }

    /// @notice Returns duration of one round (in seconds)
    function roundPeriod() public virtual pure returns (uint256) {
        return 1 weeks;
    }

    /// @return Block number in which transaction applies
    /// @dev Method is virtual to override it for tests
    function getBlockNumber() internal virtual view returns (uint256) {
        return block.number;
    }

    /// @return Timestamp of block in which transaction applies
    /// @dev Method is virtual to override it for tests
    function getTimestamp() internal virtual view returns (uint256) {
        return block.timestamp;
    }

    /// @return Hash of specific block
    /// @dev Method is virtual to override it for tests
    function getBlockhash(uint256 blockNumber) internal virtual view returns (bytes32) {
        return blockhash(blockNumber);
    }

    struct ActiveEntryListElement {
        Entry entry;
        LinkedNode linkedNode;
    }

    /// @dev Represents entry (or entries) for a single round
    /// @param active True if entry is active and false otherwise.
    ///     All new entries are active. But entry can be deactivated during result calculation process
    /// @param amount Amount of entries. Equals to paid amount / 1e18
    /// @param from Sum of all previous active entries amounts
    /// @param pointer Pointer in active entries list
    /// @param to The same as `from` but with added amount
    /// @param account Address of entries owner
    struct Entry {
        bool active;
        uint256 amount;
        uint256 from;
        uint256 pointer;
        uint256 to;
        address account;
    }

    /// @dev Represents single participant of a single round
    /// @param active True if account is participant of round
    /// @param rewardPaid True if participant reward paid and false if they are not paid or participant has no rewards
    /// @param winner True if participant is winner
    /// @param entriesCount Sum of participant entries amounts
    /// @param reward Reward amount of participant
    struct RoundParticipant {
        bool active;
        bool rewardPaid;
        bool winner;
        uint256 entriesCount;
        uint256 reward;
    }

    /// @dev Represents common information of round
    /// @param closed True if round is closed and winners are defined
    /// @param closedAt Timestamp (in seconds) of round closing. Equals to `0` if round not closed
    /// @param endsAt Timestamp (in seconds) of round ending. When round ended buying entries for it not possible
    /// @param index Round index
    /// @param nonWithdrawnRewards Sum of rewards that has not been withdrawn.
    ///     Increases on every `increasePool` method call and reduced by method `withdrawRewards`.
    ///     When non withdrawn rewards are reused in other round `nonWithdrawnRewards` will be equals to 0
    ///     (reusing rewards are the same as withdrawing them and increasing pool of another round)
    /// @param totalEntries Sum of entries amounts
    /// @param totalReward Amount of rewards pool. Increases on every `increasePool` call. Never reduced
    /// @param participants Array of participants addresses
    /// @param winners Array of winners addresses
    struct RoundProps {
        bool closed;
        uint256 closedAt;
        uint256 endsAt;
        uint256 index;
        uint256 nonWithdrawnRewards;
        uint256 totalEntries;
        uint256 totalReward;
        address[] participants;
        address[] winners;
    }

    /// @dev Represents technical information about round results calculation process
    /// @param sealedSeedProvided True if sealed seed provided (see method `provideSealedSeed`)
    /// @param activeEntriesAmount Sum of active entries amounts. Reduces by gaps resolving
    /// @param gapPointer Pointer of entry that should be removed from active entries list
    /// @param iteratedEntriesCount Count of iterated entries
    /// @param passedIterationsCount Count of passed iterations
    /// @param seedRevealingBlockNumber Block number after which sealed seed can be revealed.
    ///     Hash of block with this number will be used to generate random seed.
    ///     Sealed seed can not be revealed after `seedRevealingBlockNumber` + 256
    /// @param sealedSeed Sealed seed - hash of original seed
    /// @param seed Seed of round that used to calculate results
    struct RoundCalculation {
        bool sealedSeedProvided;
        uint256 activeEntriesAmount;
        uint256 gapPointer;
        uint256 iteratedEntriesCount;
        uint256 passedIterationsCount;
        uint256 seedRevealingBlockNumber;
        bytes32 sealedSeed;
        bytes32 seed;
    }

    /// @dev Represents full round information
    /// @param props Common properties of round (see `RoundProps` struct for details)
    /// @param calculation Technical information about round results calculation process
    ///     (see `RoundCalculation` struct for details)
    /// @param activeEntries List of active entries. Used in calculation.
    ///     Not moved to `RoundCalculation` structure since linked list has mapping in it
    /// @param entries Array of all entries
    /// @param participants Map of participants. Key is participant address. Value is `RoundParticipant` structure
    struct Round {
        RoundProps props;
        RoundCalculation calculation;
        LinkedList activeEntries;
        Entry[] entries;
        mapping(address => RoundParticipant) participants;
    }

    /// @dev Total amount of tokens that have been spent buying entries but not withdrawn by owner
    uint256 private _totalStaked;

    /// @dev ERC20 staking token address. Used for buying entries
    IERC20 private _stakingToken;

    /// @dev ERC20 jackpot token address. Used for paying rewards
    IERC20 private _jackpotToken;

    /// @dev Rewards dividers for first 5 winners.
    ///     Reward can be calculated using `totalReward/rewardsDivider[winnerIndex]`
    uint256[5] private rewardsDivider = [2, 4, 8, 16, 16];

    /// @dev Array of all rounds. See `Round` structure for details
    Round[] private rounds;

    /// @notice Returns total amount of tokens that have been spent buying entries but not withdrawn by owner
    function totalStaked() public view returns (uint256) {
        return _totalStaked;
    }

    /// @notice Returns address of staking token (this is the one that used for buying entries)
    function stakingToken() public view returns (IERC20) {
        return _stakingToken;
    }

    /// @notice Returns address of jackpot token (this is the one that used for paying rewards)
    function jackpotToken() public view returns (IERC20) {
        return _jackpotToken;
    }

    /// @notice Returns count of already created rounds
    function roundsCount() public view returns (uint256) {
        return rounds.length;
    }

    /// @notice Returns all entries of specific round
    /// @param roundIndex Round index for which entries list should be returned
    function roundEntries(uint256 roundIndex) public view returns (Entry[] memory) {
        return _getRound(roundIndex).entries;
    }

    /// @notice Returns common round information. See struct `RoundProps` for details
    /// @param roundIndex Round index for which information should be returned
    function round(uint256 roundIndex) public view returns (RoundProps memory) {
        return _getRound(roundIndex).props;
    }

    /// @notice Returns information about round calculations. See struct `RoundCalculation` for details
    /// @param roundIndex Round index for which information should be returned
    function roundCalculation(uint256 roundIndex) public view returns (RoundCalculation memory) {
        return _getRound(roundIndex).calculation;
    }

    /// @notice Returns round participant inforation. See struct `RoundParticipant` for details
    /// @param roundIndex Round index for which inforation should be returned
    /// @param account Address of participant for which inforation should be returned
    function roundParticipant(uint256 roundIndex, address account) public view returns (RoundParticipant memory) {
        Round storage round_ = _getRound(roundIndex);
        return round_.participants[account];
    }

    /// @dev Returns list of currently active entries. May changes when calculation in process
    /// @return head Pointer of first active entry
    /// @return last Pointer of last active entry
    /// @return lastAllocation Pointer of last created entry
    /// @return length Count of active entries
    /// @return result Array of active entries and its list's element property
    function activeEntriesList(uint256 roundIndex)
        public
        view
        returns (
            uint256 head,
            uint256 last,
            uint256 lastAllocation,
            uint256 length,
            ActiveEntryListElement[] memory result
        )
    {
        Round storage round_ = _getRound(roundIndex);
        LinkedList storage list = round_.activeEntries;
        head = list.head;
        last = list.last;
        lastAllocation = list.it;
        length = list.length;
        result = new ActiveEntryListElement[](length);
        uint256 it = list.head;
        for (uint256 index = 0; index < length; index += 1) {
            LinkedNode memory node = list.getNode(it);
            result[index] = ActiveEntryListElement({entry: round_.entries[node.value], linkedNode: node});
            it = node.next;
        }
    }

    event EntriesPurchased(
        uint256 indexed roundIndex,
        address indexed purchaser,
        uint256 indexed entryIndex,
        uint256 amount
    );
    event JackpotIncreased(uint256 indexed roundIndex, address indexed payer, uint256 amount);
    event NonWithdrawnRewardsReused(uint256 indexed fromRoundIndex, uint256 indexed inRoundIndex);
    event MissingSeedProvided(uint256 indexed roundIndex, bytes32 seed);
    event NewRoundCreated(uint256 indexed index, uint256 endsAt);
    event SealedSeedProvided(uint256 indexed roundIndex, bytes32 sealedSeed, uint256 revealingBlockNumber);
    event SeedRevealed(uint256 indexed roundIndex, bytes32 revealedSeed, bytes32 savedSeed);
    event StakeWithdrawn(uint256 amount);
    event RewardWithdrawn(uint256 indexed roundIndex, address indexed winner, uint256 amount);
    event RoundClosed(uint256 indexed index);
    event RoundEnded(uint256 indexed index);
    event WinnerDefined(uint256 indexed roundIndex, address indexed account, uint256 rewardAmount);

    /// @param stakingToken_ ERC20 token that will be used to buy entries
    /// @param jackpotToken_ ERC20 token that will be used as rewards of rounds
    /// @param firstRoundEndsAt Timestamp (in seconds) when first created round will ends
    /// @param owner_ Address of owner
    constructor(
        IERC20 stakingToken_,
        IERC20 jackpotToken_,
        uint256 firstRoundEndsAt,
        address owner_
    ) public TwoStageOwnable(owner_) {
        _stakingToken = stakingToken_;
        _jackpotToken = jackpotToken_;
        rounds.push();
        rounds[0].props.endsAt = firstRoundEndsAt;
    }

    /// @notice Calculates specific round results
    /// @param roundIndex Index of round
    /// @param iterableEntries Array of entries indexes that expected to be iterated
    /// @param iterableEntriesOffset Count of skipped iterable entries. Needed to solve race conditions
    /// @param limit Max count of iterations that should be passed in transaction
    function calculateRoundResults(
        uint256 roundIndex,
        uint256[] memory iterableEntries,
        uint256 iterableEntriesOffset,
        uint256 limit
    ) external returns (bool success) {
        require(limit > 0, "Limit not positive");
        Round storage round_ = _getRound(roundIndex);
        require(round_.calculation.seed != bytes32(0), "Seed not revealed");
        require(!round_.props.closed, "Result already has been calculated");
        require(iterableEntriesOffset <= round_.calculation.iteratedEntriesCount, "Gap in iterable entries list");
        if (round_.calculation.gapPointer == 0) {
            // if there is first calculation call
            // or if there is no resolved gap in last iteration of previous calculation
            // then next iterable entries should be provided
            require(
                iterableEntries.length.add(iterableEntriesOffset) > round_.calculation.iteratedEntriesCount,
                "Nothing to calculate"
            );
        }
        _calculateResults(round_, iterableEntries, iterableEntriesOffset, limit);
        return true;
    }

    /// @notice Creates new round
    function createNewRound() public returns (bool success) {
        uint256 timestamp = getTimestamp();
        uint256 roundsCount_ = rounds.length;
        rounds.push();
        Round storage newRound = rounds[roundsCount_];
        Round storage previousRound = rounds[roundsCount_.sub(1)];
        uint256 newRoundEndsAt;
        uint256 roundPeriod_ = roundPeriod();
        if (previousRound.props.endsAt >= timestamp) newRoundEndsAt = previousRound.props.endsAt.add(roundPeriod_);
        else {
            uint256 passedWeeksCount = timestamp.sub(previousRound.props.endsAt).div(roundPeriod_);
            newRoundEndsAt = previousRound.props.endsAt.add(passedWeeksCount.add(1).mul(roundPeriod_));
        }
        newRound.props.endsAt = newRoundEndsAt;
        emit NewRoundCreated(roundsCount_, newRoundEndsAt);
        newRound.props.index = roundsCount_;
        return true;
    }

    /// @notice Method to buy entries. Should approve `amount` * 1e18 of staking token for using by this contract
    /// @param roundIndex Index of round to participate in. Round should not be ended
    /// @param amount Amount of entries to buy
    function buyEntries(uint256 roundIndex, uint256 amount) external onlyPositiveAmount(amount) returns (bool success) {
        _updateRound();
        address participant = msg.sender;
        Round storage round_ = _getRound(roundIndex);
        require(round_.props.endsAt > getTimestamp(), "Round already ended");
        uint256 newTotalAmount = round_.calculation.activeEntriesAmount.add(amount);
        Entry[] storage entries = round_.entries;
        uint256 newEntryIndex = entries.length;
        LinkedList storage roundActiveEntries = round_.activeEntries;
        uint256 pointer = roundActiveEntries.insert(roundActiveEntries.last, newEntryIndex);
        entries.push(
            Entry({
                active: true,
                amount: amount,
                from: round_.calculation.activeEntriesAmount,
                pointer: pointer,
                to: newTotalAmount,
                account: participant
            })
        );
        round_.calculation.activeEntriesAmount = newTotalAmount;
        round_.props.totalEntries = newTotalAmount;
        RoundParticipant storage roundParticipant_ = round_.participants[participant];
        roundParticipant_.entriesCount = roundParticipant_.entriesCount.add(amount);
        if (!roundParticipant_.active) {
            roundParticipant_.active = true;
            round_.props.participants.push(participant);
        }
        uint256 stakeAmount = amount.mul(10**18);
        _totalStaked = _totalStaked.add(stakeAmount);
        emit EntriesPurchased(roundIndex, participant, newEntryIndex, amount);
        _stakingToken.safeTransferFrom(participant, address(this), stakeAmount);
        return true;
    }

    /// @notice Increases round jackpot. Should approve `amount` of jackpot token for using by this contract
    /// @param roundIndex Index of round in which jackpot should be increased. Round should not be ended
    /// @param amount Amount of increasing
    function increaseJackpot(uint256 roundIndex, uint256 amount)
        public
        onlyPositiveAmount(amount)
        returns (bool success)
    {
        _updateRound();
        Round storage round_ = _getRound(roundIndex);
        require(round_.props.endsAt > getTimestamp(), "Round already ended");
        round_.props.totalReward = round_.props.totalReward.add(amount);
        round_.props.nonWithdrawnRewards = round_.props.nonWithdrawnRewards.add(amount);
        emit JackpotIncreased(roundIndex, msg.sender, amount);
        _jackpotToken.safeTransferFrom(msg.sender, address(this), amount);
        return true;
    }

    /// @notice Provides missing seed. Method added to fill case, when owner not provides seed by himself.
    ///     Conditions of successful providing:
    ///      * Seed should not been provided before it;
    ///      * If sealed seed provided by owner then more than 256 blocks should be produced after that;
    ///      * If sealed seed not provided owner submitting period should be ended.
    ///     Sets round seed to hash of previous block. Not the most honest implementation.
    ///     But since this is only a fuse in case the owner does not do his job, that's okay.
    /// @param roundIndex Round index for which missing seed provided
    function provideMissingSeed(uint256 roundIndex) public returns (bool success) {
        Round storage round_ = _getRound(roundIndex);
        uint256 blockNumber = getBlockNumber();
        require(round_.calculation.seed == bytes32(0), "Seed already provided");
        uint256 endsAt = round_.props.endsAt;
        if (round_.calculation.sealedSeedProvided) {
            bool revealingPhase = blockNumber > round_.calculation.seedRevealingBlockNumber;
            bool blockHashable = getBlockhash(round_.calculation.seedRevealingBlockNumber) != bytes32(0);
            require(revealingPhase && !blockHashable, "Less than 256 blocks passed from providing sealed seed");
        } else require(endsAt.add(ownerSubmittingPeriod()) < getTimestamp(), "Owner submitting period not passed");
        round_.calculation.sealedSeedProvided = true;
        bytes32 seed = getBlockhash(blockNumber.sub(1));
        round_.calculation.seed = seed;
        emit MissingSeedProvided(roundIndex, seed);
        return true;
    }

    /// @notice Provides sealed seed for random. Applicable only by contract owner
    /// @param roundIndex Round index for which sealed seed provided
    /// @param sealedSeed Keccak-256 hash of original seed. Original seed should be a random 32 bytes.
    ///     Original seed also should be remembered to provide it in `revealSealedSeed` method
    function provideSealedSeed(uint256 roundIndex, bytes32 sealedSeed) public onlyOwner returns (bool success) {
        Round storage round_ = _getRound(roundIndex);
        require(!round_.calculation.sealedSeedProvided, "Sealed seed already provided");
        require(round_.props.endsAt <= getTimestamp(), "Round not ended");
        round_.calculation.sealedSeedProvided = true;
        round_.calculation.sealedSeed = sealedSeed;
        uint256 revealingBlockNumber = getBlockNumber() + 1;
        round_.calculation.seedRevealingBlockNumber = revealingBlockNumber;
        emit SealedSeedProvided(roundIndex, sealedSeed, revealingBlockNumber);
        return true;
    }

    /// @notice Will reuse non withdrawn rewards as jackpot of the current one.
    ///     "From" round should be closed and reward withdrawal period should be passed.
    ///     Also appicable when round ended but there is no participants in it
    /// @param fromRoundIndex Round from which unwithdrawn rewards should be removed
    /// @param inRoundIndex Current round index
    function reuseNonWithdrawnRewards(uint256 fromRoundIndex, uint256 inRoundIndex) public returns (bool success) {
        _updateRound();
        uint256 timestamp = getTimestamp();
        RoundProps storage fromRoundProps = _getRound(fromRoundIndex).props;
        if (fromRoundProps.participants.length > 0) {
            require(fromRoundProps.closed, "From round not closed");
            uint256 applicableAt = fromRoundProps.closedAt.add(rewardWithdrawalPeriod());
            require(timestamp >= applicableAt, "Users can withdraw their rewards");
        } else require(timestamp >= fromRoundProps.endsAt, "Round not ended");
        uint256 reusedAmount = fromRoundProps.nonWithdrawnRewards;
        require(reusedAmount > 0, "Nothing to reuse");
        RoundProps storage inRoundProps = _getRound(inRoundIndex).props;
        require(timestamp < inRoundProps.endsAt, "In round already ended");
        require(timestamp >= _getRound(inRoundIndex.sub(1)).props.endsAt, "Able to reuse only for current round");
        fromRoundProps.nonWithdrawnRewards = 0;
        inRoundProps.totalReward = inRoundProps.totalReward.add(reusedAmount);
        inRoundProps.nonWithdrawnRewards = inRoundProps.nonWithdrawnRewards.add(reusedAmount);
        emit NonWithdrawnRewardsReused(fromRoundIndex, inRoundIndex);
        return true;
    }

    /// @notice Method to reveal sealed seed. Applicable only by contract owner.
    ///     Before revealing sealed seed it should be provided via `provideSealedSeed` method.
    ///     Applicable only next to 2 blocks after sealed seed has been provided but before next 256 blocks
    /// @param roundIndex Round index for which sealed seed should be revealed
    /// @param seed Original seed. See NatSpec for `provideSealedSeed` method
    function revealSealedSeed(uint256 roundIndex, bytes32 seed) public onlyOwner returns (bool success) {
        Round storage round_ = _getRound(roundIndex);
        require(round_.calculation.seed == bytes32(0), "Seed already revealed");
        require(round_.calculation.sealedSeedProvided, "Sealed seed not provided");
        uint256 seedRevealingBlockNumber = round_.calculation.seedRevealingBlockNumber;
        require(getBlockNumber() > seedRevealingBlockNumber, "Unable to reveal sealed seed on the same block");
        bytes32 revealingBlockHash = getBlockhash(seedRevealingBlockNumber);
        require(revealingBlockHash != bytes32(0), "More than 256 blocks passed from providing sealed seed");
        require(keccak256(abi.encodePacked(msg.sender, seed)) == round_.calculation.sealedSeed, "Invalid seed");
        bytes32 newSeed = keccak256(abi.encodePacked(revealingBlockHash, seed));
        round_.calculation.seed = newSeed;
        emit SeedRevealed(roundIndex, seed, newSeed);
        return true;
    }

    /// @notice Withdraws tokens, that have been spent buying entries. Applicable only by contract owner
    /// @param amount Amount of tokens to withdraw
    function withdrawStake(uint256 amount) external onlyOwner onlyPositiveAmount(amount) returns (bool success) {
        _totalStaked = _totalStaked.sub(amount, "Staking pool is extinguished");
        emit StakeWithdrawn(amount);
        _stakingToken.safeTransfer(owner, amount);
        return true;
    }

    /// @notice Withdraws rewards of specific round
    /// @param roundIndex Round index from which rewards should be withdrawn
    function withdrawRewards(uint256 roundIndex) external returns (bool success) {
        address caller = msg.sender;
        Round storage round_ = _getRound(roundIndex);
        RoundParticipant storage participant = round_.participants[caller];
        require(participant.winner, "Not a round winner");
        require(!participant.rewardPaid, "Round reward already paid");
        uint256 amount = participant.reward;
        require(amount > 0, "Reward amount is equal to zero");
        require(round_.props.nonWithdrawnRewards >= amount, "Reward reused as next jackpot");
        participant.rewardPaid = true;
        round_.props.nonWithdrawnRewards = round_.props.nonWithdrawnRewards.sub(amount);
        emit RewardWithdrawn(roundIndex, caller, amount);
        _jackpotToken.safeTransfer(caller, amount);
        return true;
    }

    /// @dev Creates new round if the last one is ended. Also emits `RoundEnded` event in this case
    function _updateRound() internal {
        uint256 lastRoundIndex = rounds.length.sub(1);
        if (rounds[lastRoundIndex].props.endsAt > getTimestamp()) return;
        emit RoundEnded(lastRoundIndex);
        createNewRound();
    }

    /// @dev Returns round by its index. Result is storage type so it can be modified to modify state.
    ///     Reverts an error when index greater than or equals to round count
    function _getRound(uint256 index) private view returns (Round storage) {
        require(index < rounds.length, "Round not found");
        return rounds[index];
    }

    /// @dev Calculates results of round
    /// @param round_ Storage type of round to calculate
    /// @param iterableEntries Array of entries indexes that expected to be iterated
    /// @param iterableEntriesOffset Number of entries that was skipped in `iterableEntries` array.
    ///     Needed to solve race conditions
    /// @param limit Max count of iteration to calculate
    function _calculateResults(
        Round storage round_,
        uint256[] memory iterableEntries,
        uint256 iterableEntriesOffset,
        uint256 limit
    ) private {
        uint256 passedIterationsCount = round_.calculation.passedIterationsCount;
        round_.calculation.passedIterationsCount = passedIterationsCount.add(1);
        // If previous iteration found entry to be removed
        //      or if it not resolves removing previously found removable entry
        if (round_.calculation.gapPointer > 0) {
            // process entry removing
            _processGap(round_);
            // and start new iteration if limit not reached
            if (limit > 1) _calculateResults(round_, iterableEntries, iterableEntriesOffset, limit - 1);
            return;
        }
        // Generate iteration seed by hashing round seed and iteration index
        uint256 random = uint256(keccak256(abi.encodePacked(round_.calculation.seed, passedIterationsCount)));
        uint256 iteratedEntriesCount = round_.calculation.iteratedEntriesCount;
        // If there is not enough indexes in `iterableEntries` list just finish calculation
        if (iterableEntries.length.add(iterableEntriesOffset) <= iteratedEntriesCount) return;
        // Get random number from 0 inclusive to total round entries exclusive
        random = random.mod(round_.calculation.activeEntriesAmount);
        // Get expected iterable entry
        uint256 potensionalIterableEntryIndex = iterableEntries[iteratedEntriesCount.sub(iterableEntriesOffset)];
        require(potensionalIterableEntryIndex < round_.entries.length, "Invalid iterable entry index");
        Entry storage potensionalIterableEntry = round_.entries[potensionalIterableEntryIndex];
        round_.calculation.iteratedEntriesCount = iteratedEntriesCount.add(1);
        // Expected iterable entry should be active (not removed from active list)
        require(potensionalIterableEntry.active, "Expected iterable entry not active");
        // Check that iterated entry is correct
        require(
            potensionalIterableEntry.from <= random && potensionalIterableEntry.to > random,
            "Invalid expected iterable entry"
        );
        address potensionalWinningAddress = potensionalIterableEntry.account;
        RoundParticipant storage roundParticipant_ = round_.participants[potensionalWinningAddress];
        // If entry owner not a winner
        if (!roundParticipant_.winner) {
            // make it winner
            bool shouldBreak = _processWinner(round_, roundParticipant_, potensionalWinningAddress);
            // and if he is the last winner (5th or no more non winners) just stop calculation
            if (shouldBreak) return;
        } else {
            // otherwise, if he is already winner mark his entry to remove
            round_.calculation.gapPointer = potensionalIterableEntry.pointer;
        }
        // If limit not reached start new iteration
        if (limit > 1) _calculateResults(round_, iterableEntries, iterableEntriesOffset, limit - 1);
    }

    /// @dev Process winner
    /// @param round_ Round in which winner is defined
    /// @param roundParticipant_ Round participant defined as a winner properties
    /// @param potensionalWinningAddress Address of participant
    /// @return shouldBreak True if this is the last round winner
    function _processWinner(
        Round storage round_,
        RoundParticipant storage roundParticipant_,
        address potensionalWinningAddress
    ) private returns (bool shouldBreak) {
        uint256 reward = round_.props.totalReward.div(rewardsDivider[round_.props.winners.length]);
        roundParticipant_.reward = reward;
        roundParticipant_.winner = true;
        round_.props.winners.push(potensionalWinningAddress);
        uint256 newCalculatedWinnersCount = round_.props.winners.length;
        emit WinnerDefined(round_.props.index, potensionalWinningAddress, reward);
        // If this is the last round winner (5th winner or no more non winners)
        if (newCalculatedWinnersCount >= 5 || newCalculatedWinnersCount >= round_.props.participants.length) {
            // close round
            emit RoundClosed(round_.props.index);
            round_.props.closed = true;
            round_.props.closedAt = getTimestamp();
            // and stop results calculations
            return true;
        }
        // else continue results calculation
        return false;
    }

    /// @dev Method to iterate entry removing
    /// @param round_ Round in which some entry should be removed
    function _processGap(Round storage round_) private {
        LinkedList storage list = round_.activeEntries;
        uint256 lastEntryIndex = list.get(list.last);
        Entry storage lastEntry = round_.entries[lastEntryIndex];
        LinkedNode memory gapNode = list.getNode(round_.calculation.gapPointer);
        Entry storage gap = round_.entries[gapNode.value];
        // If entry to remove is the last in active entries list
        if (list.last == round_.calculation.gapPointer) {
            // then just remove it
            round_.calculation.activeEntriesAmount = round_.calculation.activeEntriesAmount.sub(lastEntry.amount);
            list.remove(round_.calculation.gapPointer);
            round_.calculation.gapPointer = 0;
            gap.active = false;
            return;
        }
        RoundParticipant storage lastParticipant = round_.participants[lastEntry.account];
        // If owner of last entry in active entries list is a winner
        if (lastParticipant.winner) {
            // Just remove the last entry and continue processing removing
            round_.calculation.activeEntriesAmount = round_.calculation.activeEntriesAmount.sub(lastEntry.amount);
            list.remove(list.last);
            lastEntry.active = false;
            return;
        }
        // Otherwise we need to move last entry instead of removable entry
        // To do this moved entry amount should be calculated first
        //      that is minimal amount between removable entry amount and last entry remove
        uint256 transferAmount = Math.min(gap.amount, lastEntry.amount);
        round_.calculation.activeEntriesAmount = round_.calculation.activeEntriesAmount.sub(transferAmount);
        if (gapNode.prev > 0) {
            Entry storage prevEntry = round_.entries[list.get(gapNode.prev)];
            if (prevEntry.account == lastEntry.account) {
                // If owner of entry before removable one is the same as owner of last entry
                //      then just move amount from last entry to entry before removable one
                return _processTransitionToPrevGap(round_, prevEntry, gap, lastEntry, transferAmount, list);
            }
        }
        if (gapNode.next > 0 && gapNode.next != list.last) {
            Entry storage nextEntry = round_.entries[list.get(gapNode.next)];
            if (nextEntry.account == lastEntry.account) {
                // If owner of entry after removable one is the same as owner of last entry
                //      then just move amount from last entry to entry after removable one
                return _processTransitionToNextGap(round_, nextEntry, gap, lastEntry, transferAmount, list);
            }
        }
        // If neighboring entries has different owner
        //      just create new entry with this owner before the removable one and reduce removable entry amount
        uint256 newEntryIndex = round_.entries.length;
        uint256 newEntryFrom = gap.from;
        gap.from = gap.from.add(transferAmount);
        gap.amount = gap.amount.sub(transferAmount);
        lastEntry.amount = lastEntry.amount.sub(transferAmount);
        lastEntry.to = lastEntry.to.sub(transferAmount);
        uint256 pointer = list.insert(gapNode.prev, newEntryIndex);
        round_.entries.push(Entry(true, transferAmount, newEntryFrom, pointer, gap.from, lastEntry.account));
        // and remove last and removable entry if its amount is zero
        _finishGapTransfer(round_, gap, lastEntry, list);
    }

    /// @dev Moves entries amount from last entry to the first before removable one
    /// @param round_ Round in which this transition applies
    /// @param prevEntry First entry before removable one
    /// @param gap Removable entry
    /// @param lastEntry Last active entry
    /// @param transferAmount Amount that should be moved
    /// @param list List of active entries
    function _processTransitionToPrevGap(
        Round storage round_,
        Entry storage prevEntry,
        Entry storage gap,
        Entry storage lastEntry,
        uint256 transferAmount,
        LinkedList storage list
    ) private {
        prevEntry.amount = prevEntry.amount.add(transferAmount);
        prevEntry.to = prevEntry.to.add(transferAmount);
        gap.from = prevEntry.to;
        gap.amount = gap.amount.sub(transferAmount);
        lastEntry.to = lastEntry.to.sub(transferAmount);
        lastEntry.amount = lastEntry.amount.sub(transferAmount);
        _finishGapTransfer(round_, gap, lastEntry, list);
    }

    /// @dev Moves entries amount from last entry to the first after removable one
    /// @param round_ Round in which this transition applies
    /// @param nextEntry First entry after removable one
    /// @param gap Removable entry
    /// @param lastEntry Last active entry
    /// @param transferAmount Amount that should be moved
    /// @param list List of active entries
    function _processTransitionToNextGap(
        Round storage round_,
        Entry storage nextEntry,
        Entry storage gap,
        Entry storage lastEntry,
        uint256 transferAmount,
        LinkedList storage list
    ) private {
        nextEntry.amount = nextEntry.amount.add(transferAmount);
        nextEntry.from = nextEntry.from.sub(transferAmount);
        gap.to = nextEntry.from;
        gap.amount = gap.amount.sub(transferAmount);
        lastEntry.to = lastEntry.to.sub(transferAmount);
        lastEntry.amount = lastEntry.amount.sub(transferAmount);
        _finishGapTransfer(round_, gap, lastEntry, list);
    }

    /// @dev Finish iteration of removing entry
    /// @param round_ Round for which iteration was applied
    /// @param gap Removable entry
    /// @param lastEntry Last active entry
    /// @param list List of active entries
    function _finishGapTransfer(
        Round storage round_,
        Entry storage gap,
        Entry storage lastEntry,
        LinkedList storage list
    ) private {
        // If removable entry amount is zero (when its amount fully compensated by creation/transition amounts)
        if (gap.amount == 0) {
            // just remove removable entry
            gap.active = false;
            list.remove(round_.calculation.gapPointer);
            // and stop calculation removing
            round_.calculation.gapPointer = 0;
        }
        // If last entry is empty (fully moved instead of removable one)
        if (lastEntry.amount == 0) {
            // remove it
            lastEntry.active = false;
            list.remove(list.last);
        }
    }

    /// @dev Allows only positive amount (`> 0`)
    /// @param amount Amount to check
    modifier onlyPositiveAmount(uint256 amount) {
        require(amount > 0, "Amount is not positive");
        _;
    }
}

File 3 of 8 : TwoStageOwnable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

abstract contract TwoStageOwnable {
    address public nominatedOwner;
    address public owner;

    event OwnerChanged(address indexed newOwner);
    event OwnerNominated(address indexed nominatedOwner);

    constructor(address owner_) internal {
        require(owner_ != address(0), "Owner cannot be zero address");
        _setOwner(owner_);
    }

    function acceptOwnership() external returns (bool success) {
        require(msg.sender == nominatedOwner, "Not nominated to ownership");
        _setOwner(nominatedOwner);
        nominatedOwner = address(0);
        return true;
    }

    function nominateNewOwner(address owner_) external onlyOwner returns (bool success) {
        _nominateNewOwner(owner_);
        return true;
    }

    modifier onlyOwner {
        require(msg.sender == owner, "Ownable: caller is not the owner");
        _;
    }

    function _nominateNewOwner(address owner_) internal {
        nominatedOwner = owner_;
        emit OwnerNominated(owner_);
    }

    function _setOwner(address newOwner) internal {
        owner = newOwner;
        emit OwnerChanged(newOwner);
    }
}

File 4 of 8 : Math.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

File 5 of 8 : 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, 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) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * 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);
        uint256 c = a - b;

        return c;
    }

    /**
     * @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) {
        // 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 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts 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) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts 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) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 6 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.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);

    /**
     * @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 7 of 8 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 8 of 8 : 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);
    }

    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);
            }
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"stakingToken_","type":"address"},{"internalType":"contract IERC20","name":"jackpotToken_","type":"address"},{"internalType":"uint256","name":"firstRoundEndsAt","type":"uint256"},{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundIndex","type":"uint256"},{"indexed":true,"internalType":"address","name":"purchaser","type":"address"},{"indexed":true,"internalType":"uint256","name":"entryIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EntriesPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundIndex","type":"uint256"},{"indexed":true,"internalType":"address","name":"payer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"JackpotIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"seed","type":"bytes32"}],"name":"MissingSeedProvided","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endsAt","type":"uint256"}],"name":"NewRoundCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromRoundIndex","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"inRoundIndex","type":"uint256"}],"name":"NonWithdrawnRewardsReused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nominatedOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundIndex","type":"uint256"},{"indexed":true,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"}],"name":"RoundClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"}],"name":"RoundEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"sealedSeed","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"revealingBlockNumber","type":"uint256"}],"name":"SealedSeedProvided","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"revealedSeed","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"savedSeed","type":"bytes32"}],"name":"SeedRevealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundIndex","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"name":"WinnerDefined","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"}],"name":"activeEntriesList","outputs":[{"internalType":"uint256","name":"head","type":"uint256"},{"internalType":"uint256","name":"last","type":"uint256"},{"internalType":"uint256","name":"lastAllocation","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"},{"components":[{"components":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"pointer","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"internalType":"struct LotteryLikePool.Entry","name":"entry","type":"tuple"},{"components":[{"internalType":"bool","name":"inited","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"prev","type":"uint256"},{"internalType":"uint256","name":"next","type":"uint256"}],"internalType":"struct LinkedNode","name":"linkedNode","type":"tuple"}],"internalType":"struct LotteryLikePool.ActiveEntryListElement[]","name":"result","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyEntries","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"},{"internalType":"uint256[]","name":"iterableEntries","type":"uint256[]"},{"internalType":"uint256","name":"iterableEntriesOffset","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"calculateRoundResults","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createNewRound","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseJackpot","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"jackpotToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"nominateNewOwner","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerSubmittingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"}],"name":"provideMissingSeed","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"},{"internalType":"bytes32","name":"sealedSeed","type":"bytes32"}],"name":"provideSealedSeed","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fromRoundIndex","type":"uint256"},{"internalType":"uint256","name":"inRoundIndex","type":"uint256"}],"name":"reuseNonWithdrawnRewards","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"},{"internalType":"bytes32","name":"seed","type":"bytes32"}],"name":"revealSealedSeed","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardWithdrawalPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"}],"name":"round","outputs":[{"components":[{"internalType":"bool","name":"closed","type":"bool"},{"internalType":"uint256","name":"closedAt","type":"uint256"},{"internalType":"uint256","name":"endsAt","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"nonWithdrawnRewards","type":"uint256"},{"internalType":"uint256","name":"totalEntries","type":"uint256"},{"internalType":"uint256","name":"totalReward","type":"uint256"},{"internalType":"address[]","name":"participants","type":"address[]"},{"internalType":"address[]","name":"winners","type":"address[]"}],"internalType":"struct LotteryLikePool.RoundProps","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"}],"name":"roundCalculation","outputs":[{"components":[{"internalType":"bool","name":"sealedSeedProvided","type":"bool"},{"internalType":"uint256","name":"activeEntriesAmount","type":"uint256"},{"internalType":"uint256","name":"gapPointer","type":"uint256"},{"internalType":"uint256","name":"iteratedEntriesCount","type":"uint256"},{"internalType":"uint256","name":"passedIterationsCount","type":"uint256"},{"internalType":"uint256","name":"seedRevealingBlockNumber","type":"uint256"},{"internalType":"bytes32","name":"sealedSeed","type":"bytes32"},{"internalType":"bytes32","name":"seed","type":"bytes32"}],"internalType":"struct LotteryLikePool.RoundCalculation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"}],"name":"roundEntries","outputs":[{"components":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"pointer","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"internalType":"struct LotteryLikePool.Entry[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"roundParticipant","outputs":[{"components":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"rewardPaid","type":"bool"},{"internalType":"bool","name":"winner","type":"bool"},{"internalType":"uint256","name":"entriesCount","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"}],"internalType":"struct LotteryLikePool.RoundParticipant","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roundPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"roundsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundIndex","type":"uint256"}],"name":"withdrawRewards","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawStake","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060a00160405280600260ff168152602001600460ff168152602001600860ff168152602001601060ff168152602001601060ff1681525060059060056200005192919062000264565b503480156200005f57600080fd5b506040516200633e3803806200633e833981810160405281019062000085919062000312565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620000f9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000f090620003c0565b60405180910390fd5b6200010a81620001dd60201b60201c565b5083600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a6001816001815401808255809150500390600052602060002090505081600a600081548110620001bb57fe5b9060005260206000209060180201600001600201819055505050505062000493565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fa2ea9883a321a3e97b8266c2b078bfeec6d50c711ed71f874a90d500ae2eaf3660405160405180910390a250565b82600581019282156200029b579160200282015b828111156200029a578251829060ff1690559160200191906001019062000278565b5b509050620002aa9190620002ae565b5090565b5b80821115620002c9576000816000905550600101620002af565b5090565b600081519050620002de8162000445565b92915050565b600081519050620002f5816200045f565b92915050565b6000815190506200030c8162000479565b92915050565b600080600080608085870312156200032957600080fd5b60006200033987828801620002e4565b94505060206200034c87828801620002e4565b93505060406200035f87828801620002fb565b92505060606200037287828801620002cd565b91505092959194509250565b60006200038d601c83620003e2565b91507f4f776e65722063616e6e6f74206265207a65726f2061646472657373000000006000830152602082019050919050565b60006020820190508181036000830152620003db816200037e565b9050919050565b600082825260208201905092915050565b600062000400826200041b565b9050919050565b60006200041482620003f3565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6200045081620003f3565b81146200045c57600080fd5b50565b6200046a8162000407565b81146200047657600080fd5b50565b62000484816200043b565b81146200049057600080fd5b50565b615e9b80620004a36000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c806379ba5097116100de5780638ec9925e11610097578063cf17083911610071578063cf170839146104ed578063dce76e4d1461051d578063dd1264e614610551578063dd1e848e146105815761018e565b80638ec9925e146104815780639342c8f41461049f5780639f5cfe03146104cf5761018e565b806379ba5097146103bb5780637dee21e8146103d9578063805581e6146103f7578063817b1cd21461042757806387e7ae5c146104455780638da5cb5b146104635761018e565b806325d5971f1161014b5780633fabe0c0116101255780633fabe0c01461031f5780634b976c3b1461034f57806353a47bb71461037f57806372f702f31461039d5761018e565b806325d5971f146102a157806334d5f37b146102d15780633bfbec14146103015761018e565b806308be8700146101935780630de819b3146101c3578063112cee44146101f3578063126fe80d146102115780631627540c146102415780631e60ad3614610271575b600080fd5b6101ad60048036038101906101a891906141dc565b6105b1565b6040516101ba9190615513565b60405180910390f35b6101dd60048036038101906101d891906140e9565b610750565b6040516101ea9190615b14565b60405180910390f35b6101fb61081f565b6040516102089190615b51565b60405180910390f35b61022b600480360381019061022691906140c0565b61082a565b6040516102389190615af8565b60405180910390f35b61025b6004803603810190610256919061406e565b6108b2565b6040516102689190615513565b60405180910390f35b61028b600480360381019061028691906140c0565b610956565b60405161029891906154f1565b60405180910390f35b6102bb60048036038101906102b691906140c0565b610a5a565b6040516102c89190615513565b60405180910390f35b6102eb60048036038101906102e691906140c0565b610c32565b6040516102f89190615b2f565b60405180910390f35b610309610dcc565b6040516103169190615b51565b60405180910390f35b610339600480360381019061033491906141a0565b610dd7565b6040516103469190615513565b60405180910390f35b610369600480360381019061036491906141dc565b6110b0565b6040516103769190615513565b60405180910390f35b6103876114c1565b6040516103949190615476565b60405180910390f35b6103a56114e5565b6040516103b2919061559b565b60405180910390f35b6103c361150f565b6040516103d09190615513565b60405180910390f35b6103e1611611565b6040516103ee9190615b51565b60405180910390f35b610411600480360381019061040c91906141a0565b61161c565b60405161041e9190615513565b60405180910390f35b61042f6117ee565b60405161043c9190615b51565b60405180910390f35b61044d6117f8565b60405161045a9190615513565b60405180910390f35b61046b61198a565b6040516104789190615476565b60405180910390f35b6104896119b0565b604051610496919061559b565b60405180910390f35b6104b960048036038101906104b491906140c0565b6119da565b6040516104c69190615513565b60405180910390f35b6104d7611c56565b6040516104e49190615b51565b60405180910390f35b610507600480360381019061050291906140c0565b611c63565b6040516105149190615513565b60405180910390f35b610537600480360381019061053291906140c0565b611e5c565b604051610548959493929190615b6c565b60405180910390f35b61056b600480360381019061056691906141dc565b61202a565b6040516105789190615513565b60405180910390f35b61059b60048036038101906105969190614125565b6122ef565b6040516105a89190615513565b60405180910390f35b600081600081116105f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615838565b60405180910390fd5b6105ff6124b2565b600061060a8561253f565b90506106146125aa565b81600001600201541161065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065390615898565b60405180910390fd5b6106768482600001600601546125b290919063ffffffff16565b816000016006018190555061069b8482600001600401546125b290919063ffffffff16565b81600001600401819055503373ffffffffffffffffffffffffffffffffffffffff16857f4130fbc98a3f18ae1e44c52a9645a7f92ba468ce7a05d81c0a89dc026c1b932c866040516106ed9190615b51565b60405180910390a3610744333086600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612607909392919063ffffffff16565b60019250505092915050565b610758613e29565b60006107638461253f565b90508060170160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900460ff161515151581526020016000820160029054906101000a900460ff161515151581526020016001820154815260200160028201548152505091505092915050565b600062093a80905090565b610832613e5e565b61083b8261253f565b600901604051806101000160405290816000820160009054906101000a900460ff161515151581526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815250509050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610944576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093b90615938565b60405180910390fd5b61094d82612690565b60019050919050565b60606109618261253f565b601601805480602002602001604051908101604052809291908181526020016000905b82821015610a4f57838290600052602060002090600602016040518060c00160405290816000820160009054906101000a900460ff16151515158152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610984565b505050509050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae390615938565b60405180910390fd5b8160008111610b30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2790615838565b60405180910390fd5b610b7c836040518060400160405280601c81526020017f5374616b696e6720706f6f6c20697320657874696e67756973686564000000008152506002546127169092919063ffffffff16565b6002819055507fa78b9f12a7da0df7ced737c5f83d0c05723bb5f43aab37e233b862710414847283604051610bb19190615b51565b60405180910390a1610c28600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166127719092919063ffffffff16565b6001915050919050565b610c3a613eab565b610c438261253f565b600001604051806101200160405290816000820160009054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201805480602002602001604051908101604052809291908181526020018280548015610d2e57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610ce4575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020018280548015610dbc57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610d72575b5050505050815250509050919050565b60006207e900905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6090615938565b60405180910390fd5b6000610e748461253f565b90506000801b816009016007015414610ec2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb990615918565b60405180910390fd5b8060090160000160009054906101000a900460ff16610f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0d906156f8565b60405180910390fd5b60008160090160050154905080610f2b6127f7565b11610f6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6290615678565b60405180910390fd5b6000610f76826127ff565b90506000801b811415610fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb5906158f8565b60405180910390fd5b82600901600601543386604051602001610fd99291906153db565b604051602081830303815290604052805190602001201461102f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102690615998565b60405180910390fd5b60008186604051602001611044929190615407565b604051602081830303815290604052805190602001209050808460090160070181905550867f107e5672d914f9cb403cf5ba0b6cadca8ea3b77331f2a24210fbe3ef540ca558878360405161109a929190615549565b60405180910390a2600194505050505092915050565b600081600081116110f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ed90615838565b60405180910390fd5b6110fe6124b2565b6000339050600061110e8661253f565b90506111186125aa565b816000016002015411611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115790615898565b60405180910390fd5b600061117c8683600901600101546125b290919063ffffffff16565b90506000826016019050600081805490509050600084601101905060006111b28260010154848461280a9092919063ffffffff16565b9050836040518060c001604052806001151581526020018c8152602001886009016001015481526020018381526020018781526020018973ffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906006020160009091909190915060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505084866009016001018190555084866000016005018190555060008660170160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506113308b82600101546125b290919063ffffffff16565b81600101819055508060000160009054906101000a900460ff166113d45760018160000160006101000a81548160ff02191690831515021790555086600001600701889080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006113f1670de0b6b3a76400008d6129aa90919063ffffffff16565b9050611408816002546125b290919063ffffffff16565b600281905550848973ffffffffffffffffffffffffffffffffffffffff168e7fef79519c5c873fe4437b5d7591c2ac60896fa489525254970cd9388f246d2fca8f6040516114569190615b51565b60405180910390a46114ad893083600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612607909392919063ffffffff16565b60019a505050505050505050505092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790615978565b60405180910390fd5b6115c960008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612a1a565b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001905090565b600062015180905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a590615938565b60405180910390fd5b60006116b98461253f565b90508060090160000160009054906101000a900460ff1615611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170790615ad8565b60405180910390fd5b6117186125aa565b81600001600201541115611761576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175890615ab8565b60405180910390fd5b60018160090160000160006101000a81548160ff021916908315150217905550828160090160060181905550600060016117996127f7565b019050808260090160050181905550847f02a2498943489e42740628e18ce0c039931c9820b2ee029fa881679440e9738d85836040516117da929190615572565b60405180910390a260019250505092915050565b6000600254905090565b6000806118036125aa565b90506000600a805490509050600a600181600181540180825580915050039060005260206000209050506000600a828154811061183c57fe5b906000526020600020906018020190506000600a611864600185612aa190919063ffffffff16565b8154811061186e57fe5b9060005260206000209060180201905060008061188961081f565b9050858360000160020154106118ba576118b38184600001600201546125b290919063ffffffff16565b915061192d565b60006118e8826118da86600001600201548a612aa190919063ffffffff16565b612aeb90919063ffffffff16565b9050611929611913836119056001856125b290919063ffffffff16565b6129aa90919063ffffffff16565b85600001600201546125b290919063ffffffff16565b9250505b818460000160020181905550847f9dabc2c637f100895272835b1380dc71381557c8025b8c7af70b855e64bd031a836040516119699190615b51565b60405180910390a28484600001600301819055506001965050505050505090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008033905060006119eb8461253f565b905060008160170160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160029054906101000a900460ff16611a83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7a90615698565b60405180910390fd5b8060000160019054906101000a900460ff1615611ad5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611acc90615878565b60405180910390fd5b60008160020154905060008111611b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b18906156b8565b60405180910390fd5b8083600001600401541015611b6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6290615638565b60405180910390fd5b60018260000160016101000a81548160ff021916908315150217905550611ba2818460000160040154612aa190919063ffffffff16565b83600001600401819055508373ffffffffffffffffffffffffffffffffffffffff16867fb886382d42263e3c08a157dd29a33c435741f36625dbc3acb6fb8c19bbf7824783604051611bf49190615b51565b60405180910390a3611c498482600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166127719092919063ffffffff16565b6001945050505050919050565b6000600a80549050905090565b600080611c6f8361253f565b90506000611c7b6127f7565b90506000801b826009016007015414611cc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc090615798565b60405180910390fd5b6000826000016002015490508260090160000160009054906101000a900460ff1615611d6857600083600901600501548311905060008060001b611d1386600901600501546127ff565b14159050818015611d22575080155b611d61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5890615a58565b60405180910390fd5b5050611dcb565b611d706125aa565b611d8a611d7b611611565b836125b290919063ffffffff16565b10611dca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc1906155d8565b60405180910390fd5b5b60018360090160000160006101000a81548160ff0219169083151502179055506000611e09611e04600185612aa190919063ffffffff16565b6127ff565b9050808460090160070181905550857f36882092d483bd52b047770e5cfcdf5e7e4697749bf2abf6f88eea7d569b5c4e82604051611e47919061552e565b60405180910390a26001945050505050919050565b60008060008060606000611e6f8761253f565b90506000816011019050806000015496508060010154955080600301549450806004015493508367ffffffffffffffff81118015611eac57600080fd5b50604051908082528060200260200182016040528015611ee657816020015b611ed3613ef9565b815260200190600190039081611ecb5790505b50925060008160000154905060005b8581101561201d57611f05613f1f565b611f188385612b3590919063ffffffff16565b9050604051806040016040528086601601836020015181548110611f3857fe5b90600052602060002090600602016040518060c00160405290816000820160009054906101000a900460ff16151515158152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200182815250868381518110611fff57fe5b60200260200101819052508060600151925050600181019050611ef5565b5050505091939590929450565b60006120346124b2565b600061203e6125aa565b9050600061204b8561253f565b600001905060008160070180549050111561211c578060000160009054906101000a900460ff166120b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a890615818565b60405180910390fd5b60006120d16120be610dcc565b83600101546125b290919063ffffffff16565b905080831015612116576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210d90615a98565b60405180910390fd5b50612164565b8060020154821015612163576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161215a90615ab8565b60405180910390fd5b5b600081600401549050600081116121b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a790615658565b60405180910390fd5b60006121bb8661253f565b600001905080600201548410612206576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121fd906159b8565b60405180910390fd5b61222261221d600188612aa190919063ffffffff16565b61253f565b6000016002015484101561226b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612262906158b8565b60405180910390fd5b6000836004018190555061228c8282600601546125b290919063ffffffff16565b81600601819055506122ab8282600401546125b290919063ffffffff16565b816004018190555085877fdf3f79258e7e555306e25bc8edefa1f545f767bc7817e5bfd89ce5380c9c832e60405160405180910390a3600194505050505092915050565b6000808211612333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232a90615618565b60405180910390fd5b600061233e8661253f565b90506000801b8160090160070154141561238d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612384906159f8565b60405180910390fd5b8060000160000160009054906101000a900460ff16156123e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123d990615758565b60405180910390fd5b806009016003015484111561242c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612423906155f8565b60405180910390fd5b6000816009016002015414156124995780600901600301546124588587516125b290919063ffffffff16565b11612498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248f90615778565b60405180910390fd5b5b6124a581868686612bf5565b6001915050949350505050565b60006124cd6001600a80549050612aa190919063ffffffff16565b90506124d76125aa565b600a82815481106124e457fe5b9060005260206000209060180201600001600201541115612505575061253d565b807faa97d4a7b3afec5f55c25ca8593dde6929d4455fad650a16fa4334004293a61860405160405180910390a261253a6117f8565b50505b565b6000600a805490508210612588576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257f90615958565b60405180910390fd5b600a828154811061259557fe5b90600052602060002090601802019050919050565b600042905090565b6000808284019050838110156125fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f490615718565b60405180910390fd5b8091505092915050565b61268a846323b872dd60e01b85858560405160240161262893929190615491565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612f17565b50505050565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2260405160405180910390a250565b600083831115829061275e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161275591906155b6565b60405180910390fd5b5060008385039050809150509392505050565b6127f28363a9059cbb60e01b84846040516024016127909291906154c8565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612f17565b505050565b600043905090565b600081409050919050565b60008084600201600085815260200190815260200160002090508060000160009054906101000a900460ff16806128415750600084145b612880576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612877906159d8565b60405180910390fd5b60018560030160008282540192505081905550600085600201600087600301548152602001908152602001600020905060018160000160006101000a81548160ff021916908315150217905550838160010181905550848160020181905550600085146128f15781600301546128f7565b85600001545b8160030181905550856003015482600301819055508560030154866002016000836002015481526020019081526020016000206003018190555085600301548660020160008360030154815260200190815260200160002060020181905550600085141561296d57856003015486600001819055505b856001015485141561298757856003015486600101819055505b600186600401600082825401925050819055508560030154925050509392505050565b6000808314156129bd5760009050612a14565b60008284029050828482816129ce57fe5b0414612a0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a06906158d8565b60405180910390fd5b809150505b92915050565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fa2ea9883a321a3e97b8266c2b078bfeec6d50c711ed71f874a90d500ae2eaf3660405160405180910390a250565b6000612ae383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612716565b905092915050565b6000612b2d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612fde565b905092915050565b612b3d613f1f565b600083600201600084815260200190815260200160002090508060000160009054906101000a900460ff16612ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9e906156d8565b60405180910390fd5b806040518060800160405290816000820160009054906101000a900460ff16151515158152602001600182015481526020016002820154815260200160038201548152505091505092915050565b600084600901600401549050612c156001826125b290919063ffffffff16565b8560090160040181905550600085600901600201541115612c5857612c398561303f565b6001821115612c5257612c5185858560018603612bf5565b5b50612f11565b6000856009016007015482604051602001612c74929190615433565b6040516020818303038152906040528051906020012060001c905060008660090160030154905080612cb08688516125b290919063ffffffff16565b11612cbd57505050612f11565b612cd787600901600101548361363b90919063ffffffff16565b9150600086612cef8784612aa190919063ffffffff16565b81518110612cf957fe5b6020026020010151905087601601805490508110612d4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d43906157b8565b60405180910390fd5b6000886016018281548110612d5d57fe5b90600052602060002090600602019050612d816001846125b290919063ffffffff16565b89600901600301819055508060000160009054906101000a900460ff16612ddd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd4906157d8565b60405180910390fd5b83816002015411158015612df45750838160040154115b612e33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2a90615738565b60405180910390fd5b60008160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008a60170160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160029054906101000a900460ff16612edf576000612ec48c8385613685565b90508015612ed9575050505050505050612f11565b50612ef0565b82600301548b600901600201819055505b6001881115612f0957612f088b8b8b60018c03612bf5565b5b505050505050505b50505050565b6060612f79826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661384e9092919063ffffffff16565b9050600081511115612fd95780806020019051810190612f999190614097565b612fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fcf90615a78565b60405180910390fd5b5b505050565b60008083118290613025576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161301c91906155b6565b60405180910390fd5b50600083858161303157fe5b049050809150509392505050565b6000816011019050600061306082600101548361386690919063ffffffff16565b9050600083601601828154811061307357fe5b9060005260206000209060060201905061308b613f1f565b6130a5856009016002015485612b3590919063ffffffff16565b90506000856016018260200151815481106130bc57fe5b90600052602060002090600602019050856009016002015485600101541415613156576130fd83600101548760090160010154612aa190919063ffffffff16565b86600901600101819055506131228660090160020154866138df90919063ffffffff16565b6000866009016002018190555060008160000160006101000a81548160ff0219169083151502179055505050505050613638565b60008660170160008560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160029054906101000a900460ff161561323e576131f484600101548860090160010154612aa190919063ffffffff16565b87600901600101819055506132168660010154876138df90919063ffffffff16565b60008460000160006101000a81548160ff021916908315150217905550505050505050613638565b6000613252836001015486600101546139fc565b905061326e818960090160010154612aa190919063ffffffff16565b8860090160010181905550600084604001511115613356576000886016016132a386604001518a61386690919063ffffffff16565b815481106132ad57fe5b906000526020600020906006020190508560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156133545761334789828689868d613a15565b5050505050505050613638565b505b6000846060015111801561337257508660010154846060015114155b156134475760008860160161339486606001518a61386690919063ffffffff16565b8154811061339e57fe5b906000526020600020906006020190508560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156134455761343889828689868d613ad1565b5050505050505050613638565b505b6000886016018054905090506000846002015490506134738386600201546125b290919063ffffffff16565b8560020181905550613492838660010154612aa190919063ffffffff16565b85600101819055506134b1838860010154612aa190919063ffffffff16565b87600101819055506134d0838860040154612aa190919063ffffffff16565b876004018190555060006134f38760400151848c61280a9092919063ffffffff16565b90508a6016016040518060c00160405280600115158152602001868152602001848152602001838152602001886002015481526020018a60050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906006020160009091909190915060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061362d8b878a8d613b8d565b505050505050505050505b50565b600061367d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613c27565b905092915050565b6000806136ba60058660000160080180549050600581106136a257fe5b01548660000160060154612aeb90919063ffffffff16565b905080846002018190555060018460000160026101000a81548160ff02191690831515021790555084600001600801839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000856000016008018054905090508373ffffffffffffffffffffffffffffffffffffffff1686600001600301547f51717f575c62af12c537bf652bd8c4fe4eb97454d8a29042b45342ba4002db4f846040516137a79190615b51565b60405180910390a36005811015806137c9575085600001600701805490508110155b156138405785600001600301547fe9f7d7fd0b133404f0ccff737d6f3594748e04bc5507adfaed35835ef989371160405160405180910390a260018660000160000160006101000a81548160ff02191690831515021790555061382a6125aa565b8660000160010181905550600192505050613847565b6000925050505b9392505050565b606061385d8484600085613c83565b90509392505050565b60008083600201600084815260200190815260200160002090508060000160009054906101000a900460ff166138d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138c890615858565b60405180910390fd5b806001015491505092915050565b600082600201600083815260200190815260200160002090508060000160009054906101000a900460ff16613949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161394090615a38565b60405180910390fd5b60008160000160006101000a81548160ff021916908315150217905550806003015483600201600083600201548152602001908152602001600020600301819055508060020154836002016000836003015481526020019081526020016000206002018190555081836000015414156139ca57806003015483600001819055505b81836001015414156139e457806002015483600101819055505b60018360040160008282540392505081905550505050565b6000818310613a0b5781613a0d565b825b905092915050565b613a2c8286600101546125b290919063ffffffff16565b8560010181905550613a4b8286600401546125b290919063ffffffff16565b856004018190555084600401548460020181905550613a77828560010154612aa190919063ffffffff16565b8460010181905550613a96828460040154612aa190919063ffffffff16565b8360040181905550613ab5828460010154612aa190919063ffffffff16565b8360010181905550613ac986858584613b8d565b505050505050565b613ae88286600101546125b290919063ffffffff16565b8560010181905550613b07828660020154612aa190919063ffffffff16565b856002018190555084600201548460040181905550613b33828560010154612aa190919063ffffffff16565b8460010181905550613b52828460040154612aa190919063ffffffff16565b8360040181905550613b71828460010154612aa190919063ffffffff16565b8360010181905550613b8586858584613b8d565b505050505050565b600083600101541415613bdf5760008360000160006101000a81548160ff021916908315150217905550613bd18460090160020154826138df90919063ffffffff16565b600084600901600201819055505b600082600101541415613c215760008260000160006101000a81548160ff021916908315150217905550613c208160010154826138df90919063ffffffff16565b5b50505050565b6000808314158290613c6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c6691906155b6565b60405180910390fd5b50828481613c7957fe5b0690509392505050565b6060823073ffffffffffffffffffffffffffffffffffffffff16311015613cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613cd6906157f8565b60405180910390fd5b613ce885613daf565b613d27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d1e90615a18565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff168587604051613d51919061545f565b60006040518083038185875af1925050503d8060008114613d8e576040519150601f19603f3d011682016040523d82523d6000602084013e613d93565b606091505b5091509150613da3828286613dc2565b92505050949350505050565b600080823b905060008111915050919050565b60608315613dd257829050613e22565b600083511115613de55782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e1991906155b6565b60405180910390fd5b9392505050565b6040518060a0016040528060001515815260200160001515815260200160001515815260200160008152602001600081525090565b604051806101000160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008019168152602001600080191681525090565b60405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001606081525090565b6040518060400160405280613f0c613f49565b8152602001613f19613f1f565b81525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b6040518060c0016040528060001515815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600081359050613fa681615e09565b92915050565b600082601f830112613fbd57600080fd5b8135613fd0613fcb82615bf3565b615bc6565b91508181835260208401935060208101905083856020840282011115613ff557600080fd5b60005b83811015614025578161400b8882614059565b845260208401935060208301925050600181019050613ff8565b5050505092915050565b60008151905061403e81615e20565b92915050565b60008135905061405381615e37565b92915050565b60008135905061406881615e4e565b92915050565b60006020828403121561408057600080fd5b600061408e84828501613f97565b91505092915050565b6000602082840312156140a957600080fd5b60006140b78482850161402f565b91505092915050565b6000602082840312156140d257600080fd5b60006140e084828501614059565b91505092915050565b600080604083850312156140fc57600080fd5b600061410a85828601614059565b925050602061411b85828601613f97565b9150509250929050565b6000806000806080858703121561413b57600080fd5b600061414987828801614059565b945050602085013567ffffffffffffffff81111561416657600080fd5b61417287828801613fac565b935050604061418387828801614059565b925050606061419487828801614059565b91505092959194509250565b600080604083850312156141b357600080fd5b60006141c185828601614059565b92505060206141d285828601614044565b9150509250929050565b600080604083850312156141ef57600080fd5b60006141fd85828601614059565b925050602061420e85828601614059565b9150509250929050565b60006142248383614278565b60208301905092915050565b600061423c83836150d0565b6101408301905092915050565b60006142558383615100565b60c08301905092915050565b61427261426d82615d0a565b615db3565b82525050565b61428181615cf8565b82525050565b61429081615cf8565b82525050565b60006142a182615c4b565b6142ab8185615ca9565b93506142b683615c1b565b8060005b838110156142e75781516142ce8882614218565b97506142d983615c82565b9250506001810190506142ba565b5085935050505092915050565b60006142ff82615c56565b6143098185615cba565b935061431483615c2b565b8060005b8381101561434557815161432c8882614230565b975061433783615c8f565b925050600181019050614318565b5085935050505092915050565b600061435d82615c61565b6143678185615ccb565b935061437283615c3b565b8060005b838110156143a357815161438a8882614249565b975061439583615c9c565b925050600181019050614376565b5085935050505092915050565b6143b981615d1c565b82525050565b6143c881615d1c565b82525050565b6143d781615d28565b82525050565b6143e681615d28565b82525050565b6143fd6143f882615d28565b615dc5565b82525050565b600061440e82615c6c565b6144188185615cdc565b9350614428818560208601615d80565b80840191505092915050565b61443d81615d5c565b82525050565b600061444e82615c77565b6144588185615ce7565b9350614468818560208601615d80565b61447181615deb565b840191505092915050565b6000614489602283615ce7565b91507f4f776e6572207375626d697474696e6720706572696f64206e6f74207061737360008301527f65640000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006144ef601c83615ce7565b91507f47617020696e206974657261626c6520656e7472696573206c697374000000006000830152602082019050919050565b600061452f601283615ce7565b91507f4c696d6974206e6f7420706f73697469766500000000000000000000000000006000830152602082019050919050565b600061456f601d83615ce7565b91507f52657761726420726575736564206173206e657874206a61636b706f740000006000830152602082019050919050565b60006145af601083615ce7565b91507f4e6f7468696e6720746f207265757365000000000000000000000000000000006000830152602082019050919050565b60006145ef602e83615ce7565b91507f556e61626c6520746f2072657665616c207365616c65642073656564206f6e2060008301527f7468652073616d6520626c6f636b0000000000000000000000000000000000006020830152604082019050919050565b6000614655601283615ce7565b91507f4e6f74206120726f756e642077696e6e657200000000000000000000000000006000830152602082019050919050565b6000614695601e83615ce7565b91507f52657761726420616d6f756e7420697320657175616c20746f207a65726f00006000830152602082019050919050565b60006146d5602883615ce7565b91507f4c696e6b65644c697374206765744e6f64653a20706f696e746572206f75742060008301527f6f662073636f70650000000000000000000000000000000000000000000000006020830152604082019050919050565b600061473b601883615ce7565b91507f5365616c65642073656564206e6f742070726f766964656400000000000000006000830152602082019050919050565b600061477b601b83615ce7565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b60006147bb601f83615ce7565b91507f496e76616c6964206578706563746564206974657261626c6520656e747279006000830152602082019050919050565b60006147fb602283615ce7565b91507f526573756c7420616c726561647920686173206265656e2063616c63756c617460008301527f65640000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614861601483615ce7565b91507f4e6f7468696e6720746f2063616c63756c6174650000000000000000000000006000830152602082019050919050565b60006148a1601583615ce7565b91507f5365656420616c72656164792070726f766964656400000000000000000000006000830152602082019050919050565b60006148e1601c83615ce7565b91507f496e76616c6964206974657261626c6520656e74727920696e646578000000006000830152602082019050919050565b6000614921602283615ce7565b91507f4578706563746564206974657261626c6520656e747279206e6f74206163746960008301527f76650000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614987602683615ce7565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006149ed601583615ce7565b91507f46726f6d20726f756e64206e6f7420636c6f73656400000000000000000000006000830152602082019050919050565b6000614a2d601683615ce7565b91507f416d6f756e74206973206e6f7420706f736974697665000000000000000000006000830152602082019050919050565b6000614a6d602483615ce7565b91507f4c696e6b65644c697374206765743a20706f696e746572206f7574206f66207360008301527f636f7065000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614ad3601983615ce7565b91507f526f756e642072657761726420616c72656164792070616964000000000000006000830152602082019050919050565b6000614b13601383615ce7565b91507f526f756e6420616c726561647920656e646564000000000000000000000000006000830152602082019050919050565b6000614b53602483615ce7565b91507f41626c6520746f207265757365206f6e6c7920666f722063757272656e74207260008301527f6f756e64000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614bb9602183615ce7565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614c1f603683615ce7565b91507f4d6f7265207468616e2032353620626c6f636b73207061737365642066726f6d60008301527f2070726f766964696e67207365616c65642073656564000000000000000000006020830152604082019050919050565b6000614c85601583615ce7565b91507f5365656420616c72656164792072657665616c656400000000000000000000006000830152602082019050919050565b6000614cc5602083615ce7565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000614d05600f83615ce7565b91507f526f756e64206e6f7420666f756e6400000000000000000000000000000000006000830152602082019050919050565b6000614d45601a83615ce7565b91507f4e6f74206e6f6d696e6174656420746f206f776e6572736869700000000000006000830152602082019050919050565b6000614d85600c83615ce7565b91507f496e76616c6964207365656400000000000000000000000000000000000000006000830152602082019050919050565b6000614dc5601683615ce7565b91507f496e20726f756e6420616c726561647920656e646564000000000000000000006000830152602082019050919050565b6000614e05602783615ce7565b91507f4c696e6b65644c69737420696e736572743a20706f696e746572206f7574206f60008301527f662073636f7065000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614e6b601183615ce7565b91507f53656564206e6f742072657665616c65640000000000000000000000000000006000830152602082019050919050565b6000614eab601d83615ce7565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000614eeb602783615ce7565b91507f4c696e6b65644c6973742072656d6f76653a20706f696e746572206f7574206f60008301527f662073636f7065000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614f51603683615ce7565b91507f4c657373207468616e2032353620626c6f636b73207061737365642066726f6d60008301527f2070726f766964696e67207365616c65642073656564000000000000000000006020830152604082019050919050565b6000614fb7602a83615ce7565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b600061501d602083615ce7565b91507f55736572732063616e20776974686472617720746865697220726577617264736000830152602082019050919050565b600061505d600f83615ce7565b91507f526f756e64206e6f7420656e64656400000000000000000000000000000000006000830152602082019050919050565b600061509d601c83615ce7565b91507f5365616c6564207365656420616c72656164792070726f7669646564000000006000830152602082019050919050565b610140820160008201516150e76000850182615100565b5060208201516150fa60c085018261517b565b50505050565b60c08201600082015161511660008501826143b0565b50602082015161512960208501826153a6565b50604082015161513c60408501826153a6565b50606082015161514f60608501826153a6565b50608082015161516260808501826153a6565b5060a082015161517560a0850182614278565b50505050565b60808201600082015161519160008501826143b0565b5060208201516151a460208501826153a6565b5060408201516151b760408501826153a6565b5060608201516151ca60608501826153a6565b50505050565b610100820160008201516151e760008501826143b0565b5060208201516151fa60208501826153a6565b50604082015161520d60408501826153a6565b50606082015161522060608501826153a6565b50608082015161523360808501826153a6565b5060a082015161524660a08501826153a6565b5060c082015161525960c08501826143ce565b5060e082015161526c60e08501826143ce565b50505050565b60a08201600082015161528860008501826143b0565b50602082015161529b60208501826143b0565b5060408201516152ae60408501826143b0565b5060608201516152c160608501826153a6565b5060808201516152d460808501826153a6565b50505050565b6000610120830160008301516152f360008601826143b0565b50602083015161530660208601826153a6565b50604083015161531960408601826153a6565b50606083015161532c60608601826153a6565b50608083015161533f60808601826153a6565b5060a083015161535260a08601826153a6565b5060c083015161536560c08601826153a6565b5060e083015184820360e086015261537d8282614296565b9150506101008301518482036101008601526153998282614296565b9150508091505092915050565b6153af81615d52565b82525050565b6153be81615d52565b82525050565b6153d56153d082615d52565b615de1565b82525050565b60006153e78285614261565b6014820191506153f782846143ec565b6020820191508190509392505050565b600061541382856143ec565b60208201915061542382846143ec565b6020820191508190509392505050565b600061543f82856143ec565b60208201915061544f82846153c4565b6020820191508190509392505050565b600061546b8284614403565b915081905092915050565b600060208201905061548b6000830184614287565b92915050565b60006060820190506154a66000830186614287565b6154b36020830185614287565b6154c060408301846153b5565b949350505050565b60006040820190506154dd6000830185614287565b6154ea60208301846153b5565b9392505050565b6000602082019050818103600083015261550b8184614352565b905092915050565b600060208201905061552860008301846143bf565b92915050565b600060208201905061554360008301846143dd565b92915050565b600060408201905061555e60008301856143dd565b61556b60208301846143dd565b9392505050565b600060408201905061558760008301856143dd565b61559460208301846153b5565b9392505050565b60006020820190506155b06000830184614434565b92915050565b600060208201905081810360008301526155d08184614443565b905092915050565b600060208201905081810360008301526155f18161447c565b9050919050565b60006020820190508181036000830152615611816144e2565b9050919050565b6000602082019050818103600083015261563181614522565b9050919050565b6000602082019050818103600083015261565181614562565b9050919050565b60006020820190508181036000830152615671816145a2565b9050919050565b60006020820190508181036000830152615691816145e2565b9050919050565b600060208201905081810360008301526156b181614648565b9050919050565b600060208201905081810360008301526156d181614688565b9050919050565b600060208201905081810360008301526156f1816146c8565b9050919050565b600060208201905081810360008301526157118161472e565b9050919050565b600060208201905081810360008301526157318161476e565b9050919050565b60006020820190508181036000830152615751816147ae565b9050919050565b60006020820190508181036000830152615771816147ee565b9050919050565b6000602082019050818103600083015261579181614854565b9050919050565b600060208201905081810360008301526157b181614894565b9050919050565b600060208201905081810360008301526157d1816148d4565b9050919050565b600060208201905081810360008301526157f181614914565b9050919050565b600060208201905081810360008301526158118161497a565b9050919050565b60006020820190508181036000830152615831816149e0565b9050919050565b6000602082019050818103600083015261585181614a20565b9050919050565b6000602082019050818103600083015261587181614a60565b9050919050565b6000602082019050818103600083015261589181614ac6565b9050919050565b600060208201905081810360008301526158b181614b06565b9050919050565b600060208201905081810360008301526158d181614b46565b9050919050565b600060208201905081810360008301526158f181614bac565b9050919050565b6000602082019050818103600083015261591181614c12565b9050919050565b6000602082019050818103600083015261593181614c78565b9050919050565b6000602082019050818103600083015261595181614cb8565b9050919050565b6000602082019050818103600083015261597181614cf8565b9050919050565b6000602082019050818103600083015261599181614d38565b9050919050565b600060208201905081810360008301526159b181614d78565b9050919050565b600060208201905081810360008301526159d181614db8565b9050919050565b600060208201905081810360008301526159f181614df8565b9050919050565b60006020820190508181036000830152615a1181614e5e565b9050919050565b60006020820190508181036000830152615a3181614e9e565b9050919050565b60006020820190508181036000830152615a5181614ede565b9050919050565b60006020820190508181036000830152615a7181614f44565b9050919050565b60006020820190508181036000830152615a9181614faa565b9050919050565b60006020820190508181036000830152615ab181615010565b9050919050565b60006020820190508181036000830152615ad181615050565b9050919050565b60006020820190508181036000830152615af181615090565b9050919050565b600061010082019050615b0e60008301846151d0565b92915050565b600060a082019050615b296000830184615272565b92915050565b60006020820190508181036000830152615b4981846152da565b905092915050565b6000602082019050615b6660008301846153b5565b92915050565b600060a082019050615b8160008301886153b5565b615b8e60208301876153b5565b615b9b60408301866153b5565b615ba860608301856153b5565b8181036080830152615bba81846142f4565b90509695505050505050565b6000604051905081810181811067ffffffffffffffff82111715615be957600080fd5b8060405250919050565b600067ffffffffffffffff821115615c0a57600080fd5b602082029050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000615d0382615d32565b9050919050565b6000615d1582615d32565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000615d6782615d6e565b9050919050565b6000615d7982615d32565b9050919050565b60005b83811015615d9e578082015181840152602081019050615d83565b83811115615dad576000848401525b50505050565b6000615dbe82615dcf565b9050919050565b6000819050919050565b6000615dda82615dfc565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b615e1281615cf8565b8114615e1d57600080fd5b50565b615e2981615d1c565b8114615e3457600080fd5b50565b615e4081615d28565b8114615e4b57600080fd5b50565b615e5781615d52565b8114615e6257600080fd5b5056fea2646970667358221220ea08ddf19a4f02c3123bf2c64b13cbcd18242681dd4a466a187ae97de111542a64736f6c634300060c0033000000000000000000000000f78d2e7936f5fe18308a3b2951a93b6c4a41f5e2000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000000000000000000000000000000000000060dbb400000000000000000000000000af2da71fec9cf9284a43143ab4e8149f909a612f

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

000000000000000000000000f78d2e7936f5fe18308a3b2951a93b6c4a41f5e2000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000000000000000000000000000000000000060dbb400000000000000000000000000af2da71fec9cf9284a43143ab4e8149f909a612f

-----Decoded View---------------
Arg [0] : stakingToken_ (address): 0xf78d2e7936f5fe18308a3b2951a93b6c4a41f5e2
Arg [1] : jackpotToken_ (address): 0xe9e7cea3dedca5984780bafc599bd69add087d56
Arg [2] : firstRoundEndsAt (uint256): 1625011200
Arg [3] : owner_ (address): 0xaf2da71fec9cf9284a43143ab4e8149f909a612f

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f78d2e7936f5fe18308a3b2951a93b6c4a41f5e2
Arg [1] : 000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d56
Arg [2] : 0000000000000000000000000000000000000000000000000000000060dbb400
Arg [3] : 000000000000000000000000af2da71fec9cf9284a43143ab4e8149f909a612f


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.