ETH Price: $2,092.21 (-11.97%)

Contract

0xE78B5Cdbf2dE2233909B8eB00b38C30148dC9144
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...149454602022-06-11 17:18:24996 days ago1654967904IN
0xE78B5Cdb...148dC9144
0 ETH0.0017304669.26563119
Set Approval For...94658842020-02-12 3:54:111847 days ago1581479651IN
0xE78B5Cdb...148dC9144
0 ETH0.000227975
Admin Withdraw B...68655512018-12-11 7:11:162275 days ago1544512276IN
0xE78B5Cdb...148dC9144
0 ETH0.0002104210
Withdraw Prize68256222018-12-04 16:46:262281 days ago1543941986IN
0xE78B5Cdb...148dC9144
0 ETH0.000214910
Withdraw Prize68248702018-12-04 13:47:412281 days ago1543931261IN
0xE78B5Cdb...148dC9144
0 ETH0.000285528
Withdraw Prize68214762018-12-04 0:17:512282 days ago1543882671IN
0xE78B5Cdb...148dC9144
0 ETH0.000107455
Withdraw Prize68206172018-12-03 20:57:192282 days ago1543870639IN
0xE78B5Cdb...148dC9144
0 ETH0.0002115310
Withdraw Prize68201612018-12-03 19:20:572282 days ago1543864857IN
0xE78B5Cdb...148dC9144
0 ETH0.000214910
Withdraw Prize67982892018-11-30 4:29:242286 days ago1543552164IN
0xE78B5Cdb...148dC9144
0 ETH0.0002259610
Set End67732382018-11-26 0:54:122290 days ago1543193652IN
0xE78B5Cdb...148dC9144
0 ETH0.0009415610
Set Winner Prize...67732282018-11-26 0:50:082290 days ago1543193408IN
0xE78B5Cdb...148dC9144
0 ETH0.0004096610
Set Winner Prize...67732112018-11-26 0:46:532290 days ago1543193213IN
0xE78B5Cdb...148dC9144
0 ETH0.0002336210
Set Top Winner P...67732002018-11-26 0:44:562290 days ago1543193096IN
0xE78B5Cdb...148dC9144
0 ETH0.0032676910
Check Order67731922018-11-26 0:43:172290 days ago1543192997IN
0xE78B5Cdb...148dC9144
0 ETH0.0030896410
Calculate Winner...67731642018-11-26 0:36:532290 days ago1543192613IN
0xE78B5Cdb...148dC9144
0 ETH0.0005491510
Calculate Winner...67731422018-11-26 0:31:562290 days ago1543192316IN
0xE78B5Cdb...148dC9144
0 ETH0.0005793910
Calculate Winner...67731312018-11-26 0:30:112290 days ago1543192211IN
0xE78B5Cdb...148dC9144
0 ETH0.0006839710
Set Limit67731002018-11-26 0:23:352290 days ago1543191815IN
0xE78B5Cdb...148dC9144
0 ETH0.0020043710
Calculate Points...67730782018-11-26 0:16:212290 days ago1543191381IN
0xE78B5Cdb...148dC9144
0 ETH0.028485210
Calculate Points...67730732018-11-26 0:15:342290 days ago1543191334IN
0xE78B5Cdb...148dC9144
0 ETH0.0387525610
Calculate Points...67730662018-11-26 0:14:142290 days ago1543191254IN
0xE78B5Cdb...148dC9144
0 ETH0.0388910810
Calculate Points...67730462018-11-26 0:09:372290 days ago1543190977IN
0xE78B5Cdb...148dC9144
0 ETH0.0699936110
Calculate Points...67730392018-11-26 0:07:582290 days ago1543190878IN
0xE78B5Cdb...148dC9144
0 ETH0.0699936110
Data Source Get ...67730192018-11-26 0:04:052290 days ago1543190645IN
0xE78B5Cdb...148dC9144
0 ETH0.0004815510
Data Source Get ...67730132018-11-26 0:02:452290 days ago1543190565IN
0xE78B5Cdb...148dC9144
0 ETH0.0011601110
View all transactions

Latest 12 internal transactions

Advanced mode:
Parent Transaction Hash Block
From
To
68655512018-12-11 7:11:162275 days ago1544512276
0xE78B5Cdb...148dC9144
0.376 ETH
68256222018-12-04 16:46:262281 days ago1543941986
0xE78B5Cdb...148dC9144
0.13536 ETH
68248702018-12-04 13:47:412281 days ago1543931261
0xE78B5Cdb...148dC9144
1.32822 ETH
68214762018-12-04 0:17:512282 days ago1543882671
0xE78B5Cdb...148dC9144
0.1204704 ETH
68206172018-12-03 20:57:192282 days ago1543870639
0xE78B5Cdb...148dC9144
0.8196048 ETH
68201612018-12-03 19:20:572282 days ago1543864857
0xE78B5Cdb...148dC9144
0.9803448 ETH
67607702018-11-24 0:12:032292 days ago1543018323
0xE78B5Cdb...148dC9144
0.0075 ETH
67305072018-11-19 0:37:432297 days ago1542587863
0xE78B5Cdb...148dC9144
0.005 ETH
67303042018-11-18 23:41:172297 days ago1542584477
0xE78B5Cdb...148dC9144
0.005 ETH
67302852018-11-18 23:35:522297 days ago1542584152
0xE78B5Cdb...148dC9144
0.005 ETH
67302682018-11-18 23:30:422297 days ago1542583842
0xE78B5Cdb...148dC9144
0.005 ETH
67302182018-11-18 23:21:032297 days ago1542583263
0xE78B5Cdb...148dC9144
0.005 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CryptocupNFL

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-10-17
*/

pragma solidity ^0.4.24;

// File: contracts/libs/PointsCalculator.sol

library PointsCalculator {

    uint8 constant MATCHES_NUMBER = 20;
    uint8 constant BONUS_MATCHES = 5;
    
    uint16 constant EXTRA_STATS_MASK = 65535;
    uint8 constant MATCH_UNDEROVER_MASK = 1;
    uint8 constant MATCH_RESULT_MASK = 3;
    uint8 constant MATCH_TOUCHDOWNS_MASK = 31;
    uint8 constant BONUS_STAT_MASK = 63;

    struct MatchResult{
        uint8 result; /*  0-> draw, 1-> won 1, 2-> won 2 */
        uint8 under49;
        uint8 touchdowns;
    }

    struct Extras {
        uint16 interceptions;
        uint16 missedFieldGoals;
        uint16 overtimes;
        uint16 sacks;
        uint16 fieldGoals;
        uint16 fumbles;
    }

    struct BonusMatch {
        uint16 bonus;
    }    
    
    /**
    * @notice get points from a single match 
    * @param matchIndex index of the match
    * @param matches token predictions
    * @return 
    */
    function getMatchPoints (uint256 matchIndex, uint160 matches, MatchResult[] matchResults, bool[] starMatches) private pure returns(uint16 matchPoints) {

        uint8 tResult = uint8(matches & MATCH_RESULT_MASK);
        uint8 tUnder49 = uint8((matches >> 2) & MATCH_UNDEROVER_MASK);
        uint8 tTouchdowns = uint8((matches >> 3) & MATCH_TOUCHDOWNS_MASK);

        uint8 rResult = matchResults[matchIndex].result;
        uint8 rUnder49 = matchResults[matchIndex].under49;
        uint8 rTouchdowns = matchResults[matchIndex].touchdowns;
        
        if (rResult == tResult) {
            matchPoints += 5;
            if(rResult == 0) {
                matchPoints += 5;
            }
            if(starMatches[matchIndex]) {
                matchPoints += 2;
            }
        }
        if(tUnder49 == rUnder49) {
            matchPoints += 1;
        }
        if(tTouchdowns == rTouchdowns) {
            matchPoints += 4;
        }
    }

    /**
    * @notice calculates points won by yellow and red cards predictions
    * @param extras token predictions
    * @return amount of points
    */
    function getExtraPoints(uint96 extras, Extras extraStats) private pure returns(uint16 extraPoints){

        uint16 interceptions = uint16(extras & EXTRA_STATS_MASK);
        extras = extras >> 16;
        uint16 missedFieldGoals = uint16(extras & EXTRA_STATS_MASK);
        extras = extras >> 16;
        uint16 overtimes = uint16(extras & EXTRA_STATS_MASK);
        extras = extras >> 16;
        uint16 sacks = uint16(extras & EXTRA_STATS_MASK);
        extras = extras >> 16;
        uint16 fieldGoals = uint16(extras & EXTRA_STATS_MASK);
        extras = extras >> 16;
        uint16 fumbles = uint16(extras & EXTRA_STATS_MASK);

        if (interceptions == extraStats.interceptions){
            extraPoints += 6;
        }
        
        if (missedFieldGoals == extraStats.missedFieldGoals){
            extraPoints += 6;
        }

        if (overtimes == extraStats.overtimes){
            extraPoints += 6;
        }

        if (sacks == extraStats.sacks){
            extraPoints += 6;
        }

        if (fieldGoals == extraStats.fieldGoals){
            extraPoints += 6;
        }

        if (fumbles == extraStats.fumbles){
            extraPoints += 6;
        }

    }

    /**
    *
    *
    *
    */
    function getBonusPoints (uint256 bonusId, uint32 bonuses, BonusMatch[] bonusMatches) private pure returns(uint16 bonusPoints) {
        uint8 bonus = uint8(bonuses & BONUS_STAT_MASK);

        if(bonusMatches[bonusId].bonus == bonus) {
            bonusPoints += 2;
        }
    }


    function calculateTokenPoints (uint160 tMatchResults, uint32 tBonusMatches, uint96 tExtraStats, MatchResult[] storage matchResults, Extras storage extraStats, BonusMatch[] storage bonusMatches, bool[] starMatches) 
    external pure returns(uint16 points){
        
        //Matches
        uint160 m = tMatchResults;
        for (uint256 i = 0; i < MATCHES_NUMBER; i++){
            points += getMatchPoints(MATCHES_NUMBER - i - 1, m, matchResults, starMatches);
            m = m >> 8;
        }

        //BonusMatches
        uint32 b = tBonusMatches;
        for(uint256 j = 0; j < BONUS_MATCHES; j++) {
            points += getBonusPoints(BONUS_MATCHES - j - 1, b, bonusMatches);
            b = b >> 6;
        }

        //Extras
        points += getExtraPoints(tExtraStats, extraStats);

    }
}

// File: contracts/dataSource/DataSourceInterface.sol

contract DataSourceInterface {

    function isDataSource() public pure returns (bool);

    function getMatchResults() external;
    function getExtraStats() external;
    function getBonusResults() external;

}

// File: contracts/game/GameStorage.sol

// Matches
    // 0  Baltimore,Cleveland   Bonus
    // 1  Denver,New York       Bonus
    // 2  Atlanta,Pittsburgh
    // 3  New York,Carolina
    // 4 Minnesota,Philadelphia Bonus
    // 5 Arizona,San Francisco
    // 6 Los Angeles,Seattle
    // 7 Dallas,Houston         Star





contract GameStorage{

    event LogTokenBuilt(address creatorAddress, uint256 tokenId, string message, uint160 m, uint96 e, uint32 b);
    event LogTokenGift(address creatorAddress, address giftedAddress, uint256 tokenId, string message, uint160 m, uint96 e, uint32 b);
    event LogPrepaidTokenBuilt(address creatorAddress, bytes32 secret);
    event LogPrepaidRedeemed(address redeemer, uint256 tokenId, string message, uint160 m, uint96 e, uint32 b);

    uint256 constant STARTING_PRICE = 50 finney;
    uint256 constant FIRST_PHASE  = 1540393200;
    uint256 constant EVENT_START = 1541084400;

    uint8 constant MATCHES_NUMBER = 20;
    uint8 constant BONUS_MATCHES = 5;

    //6, 12, 18    
    bool[] internal starMatches = [false, false, false, false, false, false, true, false, false, false, false, false, true, false, false, false, false, false, true, false];
    
    uint16 constant EXTRA_STATS_MASK = 65535;
    uint8 constant MATCH_UNDEROVER_MASK = 1;
    uint8 constant MATCH_RESULT_MASK = 3;
    uint8 constant MATCH_TOUCHDOWNS_MASK = 31;
    uint8 constant BONUS_STAT_MASK = 63;

    uint256 public prizePool = 0;
    uint256 public adminPool = 0;

    mapping (uint256 => uint16) public tokenToPointsMap;    
    mapping (uint256 => uint256) public tokenToPayoutMap;
    mapping (bytes32 => uint8) public secretsMap;


    address public dataSourceAddress;
    DataSourceInterface internal dataSource;


    enum pointsValidationState { Unstarted, LimitSet, LimitCalculated, OrderChecked, TopWinnersAssigned, WinnersAssigned, Finished }
    pointsValidationState public pValidationState = pointsValidationState.Unstarted;

    uint256 internal pointsLimit = 0;
    uint32 internal lastCalculatedToken = 0;
    uint32 internal lastCheckedToken = 0;
    uint32 internal winnerCounter = 0;
    uint32 internal lastAssigned = 0;
    uint32 internal payoutRange = 0;
    uint32 internal lastPrizeGiven = 0;

    uint16 internal superiorQuota;
    
    uint16[] internal payDistributionAmount = [1,1,1,1,1,1,1,1,1,1,5,5,10,20,50,100,100,200,500,1500,2500];
    uint24[21] internal payoutDistribution;

    uint256[] internal sortedWinners;

    PointsCalculator.MatchResult[] public matchResults;
    PointsCalculator.BonusMatch[] public bonusMatches;
    PointsCalculator.Extras public extraStats;


}

// File: contracts/CryptocupStorage.sol

contract CryptocupStorage is GameStorage {

}

// File: contracts/ticket/TicketInterface.sol

/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
interface TicketInterface {

    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );
    event Approval(
        address indexed owner,
        address indexed approved,
        uint256 indexed tokenId
    );
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );


    function balanceOf(address owner) public view returns (uint256 balance);
    function ownerOf(uint256 tokenId) public view returns (address owner);
    function getOwnedTokens(address _from) public view returns(uint256[]);


    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);

    function transferFrom(address from, address to, uint256 tokenId) public;
    function safeTransferFrom(address from, address to, uint256 tokenId) public;

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) public;

}

// File: contracts/ticket/TicketStorage.sol

contract TicketStorage is TicketInterface{

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant ERC721_RECEIVED = 0x150b7a02;

    struct Token {
        uint160 matches;
        uint32 bonusMatches;
        uint96 extraStats;
        uint64 timeStamp;
        string message;  
    }
    
    // List of all tokens
    Token[] tokens;

    mapping (uint256 => address) public tokenOwner;
    mapping (uint256 => address) public tokenApprovals;
    mapping (address => uint256[]) internal ownedTokens;
    mapping (address => mapping (address => bool)) public operatorApprovals;

}

// File: contracts/libs/SafeMath.sol

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (_a == 0) {
      return 0;
    }

    c = _a * _b;
    assert(c / _a == _b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
    // assert(_b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = _a / _b;
    // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
    return _a / _b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
    assert(_b <= _a);
    return _a - _b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    c = _a + _b;
    assert(c >= _a);
    return c;
  }
}

// File: contracts/helpers/AddressUtils.sol

/**
 * Utility library of inline functions on addresses
 */
library AddressUtils {

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract,
   * as the code is not actually created until after the constructor finishes.
   * @param _addr address to check
   * @return whether the target address is a contract
   */
  function isContract(address _addr) internal view returns (bool) {
    uint256 size;
    // XXX Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address.
    // See https://ethereum.stackexchange.com/a/14016/36603
    // for more details about how this works.
    // TODO Check this again before the Serenity release, because all addresses will be
    // contracts then.
    // solium-disable-next-line security/no-inline-assembly
    assembly { size := extcodesize(_addr) }
    return size > 0;
  }

}

// File: contracts/access/AccessStorage.sol

contract AccessStorage{

	bool public paused = false;
    bool public finalized = false;
    
    address public adminAddress;
    address public dataSourceAddress;
    address public marketplaceAddress;

    uint256 internal deploymentTime = 0;
    uint256 public gameFinishedTime = 0; 
    uint256 public finalizedTime = 0;

}

// File: contracts/access/AccessRegistry.sol

/**
* @title AccessControlLayer
* @author CryptoCup Team (https://cryptocup.io/about)
* @dev Containes basic admin modifiers to restrict access to some functions. Allows
* for pauseing, and setting emergency stops.
*/
contract AccessRegistry is AccessStorage {


   /**
   * @dev Main modifier to limit access to delicate functions.
   */
    modifier onlyAdmin() {
        require(msg.sender == adminAddress, "Only admin.");
        _;
    }

    /**
   * @dev Main modifier to limit access to delicate functions.
   */
    modifier onlyDataSource() {
        require(msg.sender == dataSourceAddress, "Only dataSource.");
        _;
    }

    /**
   * @dev Main modifier to limit access to delicate functions.
   */
    modifier onlyMarketPlace() {
        require(msg.sender == marketplaceAddress, "Only marketplace.");
        _;
    }


    /**
    * @dev Modifier that checks that the contract is not paused
    */
    modifier isNotPaused() {
        require(!paused, "Only if not paused.");
        _;
    }

    /**
    * @dev Modifier that checks that the contract is paused
    */
    modifier isPaused() {
        require(paused, "Only if paused.");
        _;
    }

    /**
    * @dev Modifier that checks that the contract has finished successfully
    */
    modifier hasFinished() {
        require((gameFinishedTime != 0) && now >= (gameFinishedTime + (15 days)), "Only if game has finished.");
        _;
    }

    /**
    * @dev Modifier that checks that the contract has finalized
    */
    modifier hasFinalized() {
        require(finalized, "Only if game has finalized.");
        _;
    }

    function setPause () internal {
        paused = true;
    }

    function unSetPause() internal {
        paused = false;
    }

    /**
    * @dev Transfer contract's ownership
    * @param _newAdmin Address to be set
    */
    function setAdmin(address _newAdmin) external onlyAdmin {

        require(_newAdmin != address(0));
        adminAddress = _newAdmin;
    }

     /**
    * @dev Adds contract's mkt
    * @param _newMkt Address to be set
    */
    function setMarketplaceAddress(address _newMkt) external onlyAdmin {

        require(_newMkt != address(0));
        marketplaceAddress = _newMkt;
    }

    /**
    * @dev Sets the contract pause state
    * @param state True to pause
    */
    function setPauseState(bool state) external onlyAdmin {
        paused = state;
    }

    /**
    * @dev Sets the contract to finalized
    * @param state True to finalize
    */
    function setFinalized(bool state) external onlyAdmin {
        paused = state;
        finalized = state;
        if(finalized == true)
            finalizedTime = now;
    }
}

// File: contracts/ticket/TicketRegistry.sol

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract TicketRegistry is TicketInterface, TicketStorage, AccessRegistry{

    using SafeMath for uint256;
    using AddressUtils for address;
    
    /**
     * @dev Gets the balance of the specified address
     * @param _owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address _owner) public view returns (uint256) {
        require(_owner != address(0));
        return ownedTokens[_owner].length;
    }

    /**
     * @dev Gets the owner of the specified token ID
     * @param _tokenId uint256 ID of the token to query the owner of
     * @return owner address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 _tokenId) public view returns (address) {
        address owner = tokenOwner[_tokenId];
        require(owner != address(0));
        return owner;
    }

    /**
     * @dev Gets tokens of owner
     * @param _from address of the owner
     * @return array with token ids
     */
    function getOwnedTokens(address _from) public view returns(uint256[]) {
        return ownedTokens[_from];   
    }

    /**
     * @dev Returns whether the specified token exists
     * @param _tokenId uint256 ID of the token to query the existence of
     * @return whether the token exists
     */
    function exists(uint256 _tokenId) public view returns (bool) {
        address owner = tokenOwner[_tokenId];
        return owner != address(0);
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param _to address to be approved for the given token ID
     * @param _tokenId uint256 ID of the token to be approved
     */
    function approve(address _to, uint256 _tokenId) public {
        address owner = ownerOf(_tokenId);
        require(_to != owner);
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

        tokenApprovals[_tokenId] = _to;
        emit Approval(owner, _to, _tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * @param _tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 _tokenId) public view returns (address) {
        return tokenApprovals[_tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf
     * @param _to operator address to set the approval
     * @param _approved representing the status of the approval to be set
     */
    function setApprovalForAll(address _to, bool _approved) public {
        require(_to != msg.sender);
        operatorApprovals[msg.sender][_to] = _approved;
        emit ApprovalForAll(msg.sender, _to, _approved);
    }

    /**
     * @dev Tells whether an operator is approved by a given owner
     * @param _owner owner address which you want to query the approval of
     * @param _operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address _owner, address _operator) public view returns (bool)  {
        return operatorApprovals[_owner][_operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address
     * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
     * Requires the msg sender to be the owner, approved, or operator
     * @param _from current owner of the token
     * @param _to address to receive the ownership of the given token ID
     * @param _tokenId uint256 ID of the token to be transferred
    */
    function transferFrom(address _from, address _to, uint256 _tokenId) public isNotPaused{
        
        require(isApprovedOrOwner(msg.sender, _tokenId));
        require(_from != address(0));
        require(_to != address(0));
        require (_from != _to);
        
        clearApproval(_from, _tokenId);
        removeTokenFrom(_from, _tokenId);
        addTokenTo(_to, _tokenId);

        emit Transfer(_from, _to, _tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     *
     * Requires the msg sender to be the owner, approved, or operator
     * @param _from current owner of the token
     * @param _to address to receive the ownership of the given token ID
     * @param _tokenId uint256 ID of the token to be transferred
    */
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) public {
        // solium-disable-next-line arg-overflow
        safeTransferFrom(_from, _to, _tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg sender to be the owner, approved, or operator
     * @param _from current owner of the token
     * @param _to address to receive the ownership of the given token ID
     * @param _tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) public {
        transferFrom(_from, _to, _tokenId);
        // solium-disable-next-line arg-overflow
        // require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
    }


    /**
     * @dev Returns whether the given spender can transfer a given token ID
     * @param _spender address of the spender to query
     * @param _tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     *  is an operator of the owner, or is the owner of the token
     */
    function isApprovedOrOwner(address _spender, uint256 _tokenId) internal view returns (bool){
        address owner = ownerOf(_tokenId);
        // Disable solium check because of
        // https://github.com/duaraghav8/Solium/issues/175
        // solium-disable-next-line operator-whitespace
        return (
            _spender == owner ||
            getApproved(_tokenId) == _spender ||
            isApprovedForAll(owner, _spender)
        );
    }

    /**
     * @dev Internal function to mint a new token
     * Reverts if the given token ID already exists
     * @param _to The address that will own the minted token
     * @param _tokenId uint256 ID of the token to be minted by the msg.sender
     */
    function _mint(address _to, uint256 _tokenId) internal {
        require(_to != address(0));
        addTokenTo(_to, _tokenId);
        //emit Transfer(address(0), _to, _tokenId);
    }

    /**
     * @dev Internal function to clear current approval of a given token ID
     * Reverts if the given address is not indeed the owner of the token
     * @param _owner owner of the token
     * @param _tokenId uint256 ID of the token to be transferred
     */
    function clearApproval(address _owner, uint256 _tokenId) internal {
        require(ownerOf(_tokenId) == _owner);
        if (tokenApprovals[_tokenId] != address(0)) {
            tokenApprovals[_tokenId] = address(0);
        }
    }

    /**
     * @dev Internal function to add a token ID to the list of a given address
     * @param _to address representing the new owner of the given token ID
     * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function addTokenTo(address _to, uint256 _tokenId) internal {
        require(tokenOwner[_tokenId] == address(0));
        tokenOwner[_tokenId] = _to;
        ownedTokens[_to].push(_tokenId);
    }

    /**
     * @dev Internal function to remove a token ID from the list of a given address
     * @param _from address representing the previous owner of the given token ID
     * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function removeTokenFrom(address _from, uint256 _tokenId) internal {

        require(ownerOf(_tokenId) == _from);
        require(ownedTokens[_from].length < 100);

        tokenOwner[_tokenId] = address(0);

        uint256[] storage tokenArray = ownedTokens[_from];
        for (uint256 i = 0; i < tokenArray.length; i++){
            if(tokenArray[i] == _tokenId){
                tokenArray[i] = tokenArray[tokenArray.length-1];
            }
        }
        
        delete tokenArray[tokenArray.length-1];
        tokenArray.length--;

    }



}

// File: contracts/libs/PayoutDistribution.sol

library PayoutDistribution {

	function getDistribution(uint256 tokenCount) external pure returns (uint24[21] payoutDistribution) {

		if(tokenCount < 101){
            payoutDistribution = [289700, 189700, 120000, 92500, 75000, 62500, 52500, 42500, 40000, 35600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        }else if(tokenCount < 201){
            payoutDistribution = [265500, 165500, 105500, 75500, 63000, 48000, 35500, 20500, 20000, 19500, 18500, 17800, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        }else if(tokenCount < 301){
            payoutDistribution = [260700, 155700, 100700, 70900, 60700, 45700, 35500, 20500, 17900, 12500, 11500, 11000, 10670, 0, 0, 0, 0, 0, 0, 0, 0];
        }else if(tokenCount < 501){
            payoutDistribution = [238600, 138600, 88800, 63800, 53800, 43800, 33800, 18800, 17500, 12500, 9500, 7500, 7100, 6700, 0, 0, 0, 0, 0, 0, 0];
        }else if(tokenCount < 1001){
            payoutDistribution = [218300, 122300, 72300, 52400, 43900, 33900, 23900, 16000, 13000, 10000, 9000, 7000, 5000, 4000, 3600, 0, 0, 0, 0, 0, 0];
        }else if(tokenCount < 2001){
            payoutDistribution = [204500, 114000, 64000, 44100, 35700, 26700, 22000, 15000, 11000, 9500, 8500, 6500, 4600, 2500, 2000, 1800, 0, 0, 0, 0, 0];
        }else if(tokenCount < 3001){
            payoutDistribution = [189200, 104800, 53900, 34900, 29300, 19300, 15300, 14000, 10500, 8300, 8000, 6000, 3800, 2500, 2000, 1500, 1100, 0, 0, 0, 0];
        }else if(tokenCount < 5001){
            payoutDistribution = [178000, 100500, 47400, 30400, 24700, 15500, 15000, 12000, 10200, 7800, 7400, 5500, 3300, 2000, 1500, 1200, 900, 670, 0, 0, 0];
        }else if(tokenCount < 10001){
            payoutDistribution = [157600, 86500, 39000, 23100, 18900, 15000, 14000, 11000, 9300, 6100, 6000, 5000, 3800, 1500, 1100, 900, 700, 500, 360, 0, 0];
        }else if(tokenCount < 25001){
            payoutDistribution = [132500, 70200, 31300, 18500, 17500, 14000, 13500, 10500, 7500, 5500, 5000, 4000, 3000, 1000, 900, 700, 600, 400, 200, 152, 0];
        } else {
            payoutDistribution = [120000, 63000,  27000, 18800, 17300, 13700, 13000, 10000, 6300, 5000, 4500, 3900, 2500, 900, 800, 600, 500, 350, 150, 100, 70];
        }
	}

	function getSuperiorQuota(uint256 tokenCount) external pure returns (uint16 superiorQuota){

		if(tokenCount < 101){
            superiorQuota = 10;
        }else if(tokenCount < 201){
            superiorQuota = 20;
        }else if(tokenCount < 301){
            superiorQuota = 30;
        }else if(tokenCount < 501){
            superiorQuota = 50;
        }else if(tokenCount < 1001){
            superiorQuota = 100;
        }else if(tokenCount < 2001){
            superiorQuota = 200;
        }else if(tokenCount < 3001){
            superiorQuota = 300;
        }else if(tokenCount < 5001){
            superiorQuota = 500;
        }else if(tokenCount < 10001){
            superiorQuota = 1000;
        }else if(tokenCount < 25001){
            superiorQuota = 2500;
        } else {
            superiorQuota = 5000;
        }
	}

}

// File: contracts/game/GameRegistry.sol

contract GameRegistry is CryptocupStorage, TicketRegistry{
	
    using PointsCalculator for PointsCalculator.MatchResult;
    using PointsCalculator for PointsCalculator.BonusMatch;
    using PointsCalculator for PointsCalculator.Extras;

     /**
    * @dev Checks if pValidationState is in the provided stats
    * @param state State required to run
    */
    modifier checkState(pointsValidationState state){
        require(pValidationState == state, "Points validation stage invalid.");
        _;
    }
    
    /**
    * @notice Gets current token price 
    */
    function _getTokenPrice() internal view returns(uint256 tokenPrice){

        if (now >= FIRST_PHASE) {
            tokenPrice = (80 finney);
        } else {
            tokenPrice = STARTING_PRICE;
        }

        require(tokenPrice >= STARTING_PRICE && tokenPrice <= (80 finney));

    }

    function _prepareMatchResultsArray() internal {
        matchResults.length = MATCHES_NUMBER;
    }

    function _prepareBonusResultsArray() internal {
        bonusMatches.length = BONUS_MATCHES;
    }

    /** 
    * @notice Builds ERC721 token with the predictions provided by the user.
    * @param matches  - Matches results (who wins, amount of points)
    * @param bonusMatches -  Stats from bonus matches
    * @param extraStats - Total number of extra stats like touchdonws, etc.
    * @dev An automatic timestamp is added for internal use.
    */
    function _createToken(uint160 matches, uint32 bonusMatches, uint96 extraStats, string userMessage) internal returns (uint256){

        Token memory token = Token({
            matches: matches,
            bonusMatches: bonusMatches,
            extraStats: extraStats,
            timeStamp: uint64(now),
            message: userMessage
        });

        uint256 tokenId = tokens.push(token) - 1;
        require(tokenId == uint256(uint32(tokenId)), "Failed to convert tokenId to uint256.");
        
        return tokenId;
    }

    /**
    * @dev Sets the data source contract address 
    * @param _address Address to be set
    */
    function setDataSourceAddress(address _address) external onlyAdmin {
        
        DataSourceInterface c = DataSourceInterface(_address);

        require(c.isDataSource());

        dataSource = c;
        dataSourceAddress = _address;
    }


    /**
    * @notice Called by the development team once the World Cup has ended (adminPool is set) 
    * @dev Allows dev team to retrieve adminPool
    */
    function adminWithdrawBalance() external onlyAdmin {

        uint256 adminPrize = adminPool;

        adminPool = 0;
        adminAddress.transfer(adminPrize);

    }


     /**
    * @notice Let the admin cash-out the entire contract balance 10 days after game has finished.
    */
    function finishedGameWithdraw() external onlyAdmin hasFinished{

        uint256 balance = address(this).balance;
        adminAddress.transfer(balance);

    }
    
    /**
    * @notice Let the admin cash-out the entire contract balance 10 days after game has finished.
    */
    function emergencyWithdrawAdmin() external hasFinalized onlyAdmin{

        require(finalizedTime != 0 &&  now >= finalizedTime + 10 days );
        msg.sender.transfer(address(this).balance);

    }


    function isDataSourceCallback() external pure returns (bool){
        return true;
    }

    function dataSourceGetMatchesResults() external onlyAdmin {
        dataSource.getMatchResults();
    }

    function dataSourceGetBonusResults() external onlyAdmin{
        dataSource.getBonusResults();
    }

    function dataSourceGetExtraStats() external onlyAdmin{
        dataSource.getExtraStats();
    }

    function dataSourceCallbackMatch(uint160 matches) external onlyDataSource{
        uint160 m = matches;
        for(uint256 i = 0; i < MATCHES_NUMBER; i++) {
            matchResults[MATCHES_NUMBER - i - 1].result = uint8(m & MATCH_RESULT_MASK);
            matchResults[MATCHES_NUMBER - i - 1].under49 = uint8((m >> 2) & MATCH_UNDEROVER_MASK);
            matchResults[MATCHES_NUMBER - i - 1].touchdowns = uint8((m >> 3) & MATCH_TOUCHDOWNS_MASK);
            m = m >> 8;
        }
    }

    function dataSourceCallbackBonus(uint32 bonusResults) external onlyDataSource{
        uint32 b = bonusResults;
        for(uint256 i = 0; i < BONUS_MATCHES; i++) {
            bonusMatches[BONUS_MATCHES - i - 1].bonus = uint8(b & BONUS_STAT_MASK);
            b = b >> 6;
        }
    }

    function dataSourceCallbackExtras(uint96 es) external onlyDataSource{
        uint96 e = es;
        extraStats.interceptions = uint16(e & EXTRA_STATS_MASK);
        e = e >> 16;
        extraStats.missedFieldGoals = uint16(e & EXTRA_STATS_MASK);
        e = e >> 16;
        extraStats.overtimes = uint16(e & EXTRA_STATS_MASK);
        e = e >> 16;
        extraStats.sacks = uint16(e & EXTRA_STATS_MASK);
        e = e >> 16;
        extraStats.fieldGoals = uint16(e & EXTRA_STATS_MASK);
        e = e >> 16;
        extraStats.fumbles = uint16(e & EXTRA_STATS_MASK);
    }

    /**
    * @notice Sets the points of all the tokens between the last chunk set and the amount given.
    * @dev This function uses all the data collected earlier by oraclize to calculate points.
    * @param amount The amount of tokens that should be analyzed.
    */
    function calculatePointsBlock(uint32 amount) external{

        require (gameFinishedTime == 0);
        require(amount + lastCheckedToken <= tokens.length);

        for (uint256 i = lastCalculatedToken; i < (lastCalculatedToken + amount); i++) {
            uint16 points = PointsCalculator.calculateTokenPoints(tokens[i].matches, tokens[i].bonusMatches,
                tokens[i].extraStats, matchResults, extraStats, bonusMatches, starMatches);
            tokenToPointsMap[i] = points;
        }

        lastCalculatedToken += amount;
    }

    /**
    * @notice Sets the structures for payout distribution, last position and superior quota. Payout distribution is the
    * percentage of the pot each position gets, last position is the percentage of the pot the last position gets,
    * and superior quota is the total amount OF winners that are given a prize.
    * @dev Each of this structures is dynamic and is assigned depending on the total amount of tokens in the game  
    */
    function setPayoutDistributionId () internal {

        uint24[21] memory auxArr = PayoutDistribution.getDistribution(tokens.length);

        for(uint256 i = 0; i < auxArr.length; i++){
            payoutDistribution[i] = auxArr[i];
        }
        
        superiorQuota = PayoutDistribution.getSuperiorQuota(tokens.length);
    }

    /**
    * @notice Sets the id of the last token that will be given a prize.
    * @dev This is done to offload some of the calculations needed for sorting, and to cap the number of sorts
    * needed to just the winners and not the whole array of tokens.
    * @param tokenId last token id
    */
    function setLimit(uint256 tokenId) external onlyAdmin{
        require(tokenId < tokens.length);
        require(pValidationState == pointsValidationState.Unstarted || pValidationState == pointsValidationState.LimitSet);
        pointsLimit = tokenId;
        pValidationState = pointsValidationState.LimitSet;
        lastCheckedToken = 0;
        lastCalculatedToken = 0;
        winnerCounter = 0;
        
        setPause();
        setPayoutDistributionId();
    }


    /**
    * @notice Sets the 10th percentile of the sorted array of points
    * @param amount tokens in a chunk
    */
    function calculateWinners(uint32 amount) external onlyAdmin checkState(pointsValidationState.LimitSet){
        require(amount + lastCheckedToken <= tokens.length);
        uint256 points = tokenToPointsMap[pointsLimit];

        for(uint256 i = lastCheckedToken; i < lastCheckedToken + amount; i++){
            if(tokenToPointsMap[i] > points ||
                (tokenToPointsMap[i] == points && i <= pointsLimit)){
                winnerCounter++;
            }
        }
        lastCheckedToken += amount;

        if(lastCheckedToken == tokens.length){
            require(superiorQuota == winnerCounter);
            pValidationState = pointsValidationState.LimitCalculated;
        }
    }

    /**
    * @notice Checks if the order given offchain coincides with the order of the actual previously calculated points
    * in the smart contract.
    * @dev the token sorting is done offchain so as to save on the huge amount of gas and complications that 
    * could occur from doing all the sorting onchain.
    * @param sortedChunk chunk sorted by points
    */
    function checkOrder(uint32[] sortedChunk) external onlyAdmin checkState(pointsValidationState.LimitCalculated){
        require(sortedChunk.length + sortedWinners.length <= winnerCounter);

        for(uint256 i = 0; i < sortedChunk.length - 1; i++){
            uint256 id = sortedChunk[i];
            uint256 sigId = sortedChunk[i+1];
            require(tokenToPointsMap[id] > tokenToPointsMap[sigId] || (tokenToPointsMap[id] == tokenToPointsMap[sigId] &&
                id < sigId));
        }

        if(sortedWinners.length != 0){
            uint256 id2 = sortedWinners[sortedWinners.length-1];
            uint256 sigId2 = sortedChunk[0];
            require(tokenToPointsMap[id2] > tokenToPointsMap[sigId2] ||
                (tokenToPointsMap[id2] == tokenToPointsMap[sigId2] && id2 < sigId2));
        }

        for(uint256 j = 0; j < sortedChunk.length; j++){
            sortedWinners.push(sortedChunk[j]);
        }

        if(sortedWinners.length == winnerCounter){
            require(sortedWinners[sortedWinners.length-1] == pointsLimit);
            pValidationState = pointsValidationState.OrderChecked;
        }

    }

    /**
    * @notice If anything during the point calculation and sorting part should fail, this function can reset 
    * data structures to their initial position, so as to  
    */
    function resetWinners(uint256 newLength) external onlyAdmin checkState(pointsValidationState.LimitCalculated){
        
        sortedWinners.length = newLength;
    
    }

    /**
    * @notice Assigns prize percentage for the lucky top 30 winners. Each token will be assigned a uint256 inside
    * tokenToPayoutMap structure that represents the size of the pot that belongs to that token. If any tokens
    * tie inside of the first 30 tokens, the prize will be summed and divided equally. 
    */
    function setTopWinnerPrizes() external onlyAdmin checkState(pointsValidationState.OrderChecked){

        uint256 percent = 0;
        uint[] memory tokensEquals = new uint[](30);
        uint16 tokenEqualsCounter = 0;
        uint256 currentTokenId;
        uint256 currentTokenPoints;
        uint256 lastTokenPoints;
        uint32 counter = 0;
        uint256 maxRange = 13;
        if(tokens.length < 201){
            maxRange = 10;
        }
        

        while(payoutRange < maxRange){
            uint256 inRangecounter = payDistributionAmount[payoutRange];
            while(inRangecounter > 0){
                currentTokenId = sortedWinners[counter];
                currentTokenPoints = tokenToPointsMap[currentTokenId];

                inRangecounter--;

                //Special case for the last one
                if(inRangecounter == 0 && payoutRange == maxRange - 1){
                    if(currentTokenPoints == lastTokenPoints){
                        percent += payoutDistribution[payoutRange];
                        tokensEquals[tokenEqualsCounter] = currentTokenId;
                        tokenEqualsCounter++;
                    } else {
                        tokenToPayoutMap[currentTokenId] = payoutDistribution[payoutRange];
                    }
                }

                //Fix second condition
                if(counter != 0 && (currentTokenPoints != lastTokenPoints || (inRangecounter == 0 && payoutRange == maxRange - 1))){ 
                    for(uint256 i = 0; i < tokenEqualsCounter; i++){
                        tokenToPayoutMap[tokensEquals[i]] = percent.div(tokenEqualsCounter);
                    }
                    percent = 0;
                    tokensEquals = new uint[](30);
                    tokenEqualsCounter = 0;
                }

                percent += payoutDistribution[payoutRange];
                tokensEquals[tokenEqualsCounter] = currentTokenId;
                
                tokenEqualsCounter++;
                counter++;

                lastTokenPoints = currentTokenPoints;
            }
            payoutRange++;
        }

        pValidationState = pointsValidationState.TopWinnersAssigned;
        lastPrizeGiven = counter;
    }

    /**
    * @notice Sets prize percentage to every address that wins from the position 30th onwards
    * @dev If there are less than 300 tokens playing, then this function will set nothing.
    * @param amount tokens in a chunk
    */
    function setWinnerPrizes(uint32 amount) external onlyAdmin checkState(pointsValidationState.TopWinnersAssigned){
        require(lastPrizeGiven + amount <= winnerCounter);
        
        uint16 inRangeCounter = payDistributionAmount[payoutRange];
        for(uint256 i = 0; i < amount; i++){
            if (inRangeCounter == 0){
                payoutRange++;
                inRangeCounter = payDistributionAmount[payoutRange];
            }

            uint256 tokenId = sortedWinners[i + lastPrizeGiven];

            tokenToPayoutMap[tokenId] = payoutDistribution[payoutRange];

            inRangeCounter--;
        }
        //i + amount prize was not given yet, so amount -1
        lastPrizeGiven += amount;
        payDistributionAmount[payoutRange] = inRangeCounter;

        if(lastPrizeGiven == winnerCounter){
            pValidationState = pointsValidationState.WinnersAssigned;
            return;
        }
    }


     /**
    * @notice Sets prizes for last tokens and sets prize pool amount
    */
    function setEnd() external onlyAdmin checkState(pointsValidationState.WinnersAssigned){
            
        uint256 balance = address(this).balance;
        adminPool = balance.mul(10).div(100);
        prizePool = balance.mul(90).div(100);

        pValidationState = pointsValidationState.Finished;
        gameFinishedTime = now;
        unSetPause();
    }

}

// File: contracts/CryptocupNFL.sol

contract CryptocupNFL is GameRegistry {

	constructor() public {
        adminAddress = msg.sender;
        deploymentTime = now;

        _prepareMatchResultsArray();
        _prepareBonusResultsArray();
    }

     /** 
    * @dev Only accept eth from the admin
    */
    function() external payable {
        require(msg.sender == adminAddress || msg.sender == marketplaceAddress);

    }

    function buildToken(uint160 matches, uint32 bonusMatches, uint96 extraStats, string message) external payable isNotPaused returns(uint256){

        require(msg.value >= _getTokenPrice(), "Eth sent is not enough.");
        require(msg.sender != address(0), "Sender cannot be 0 address.");
        require(ownedTokens[msg.sender].length < 100, "Sender cannot have more than 100 tokens.");
        require(now < EVENT_START, "Event already started."); //Event Start
        require (bytes(message).length <= 100);
        

        uint256 tokenId = _createToken(matches, bonusMatches, extraStats, message);
        
        _mint(msg.sender, tokenId);
        
        emit LogTokenBuilt(msg.sender, tokenId, message, matches, extraStats, bonusMatches);

        return tokenId;
    }

    function giftToken(address giftedAddress, uint160 matches, uint32 bonusMatches, uint96 extraStats, string message) external payable isNotPaused returns(uint256){

        require(msg.value >= _getTokenPrice(), "Eth sent is not enough.");
        require(msg.sender != address(0), "Sender cannot be 0 address.");
        require(ownedTokens[giftedAddress].length < 100, "Sender cannot have more than 100 tokens.");
        require(now < EVENT_START, "Event already started."); //Event Start
        require (bytes(message).length <= 100);

        uint256 tokenId = _createToken(matches, bonusMatches, extraStats, message);

        _mint(giftedAddress, tokenId);
        
        emit LogTokenGift(msg.sender, giftedAddress, tokenId, message, matches, extraStats, bonusMatches);

        return tokenId;
    }

    function buildPrepaidToken(bytes32 secret) external payable onlyAdmin isNotPaused {

        require(msg.value >= _getTokenPrice(), "Eth sent is not enough.");
        require(msg.sender != address(0), "Sender cannot be 0 address.");
        require(now < EVENT_START, "Event already started."); //Event Start

        secretsMap[secret] = 1;
        
        emit LogPrepaidTokenBuilt(msg.sender, secret);
    }

    function redeemPrepaidToken(bytes32 preSecret, uint160 matches, uint32 bonusMatches, uint96 extraStats, string message) external isNotPaused returns(uint256){

        require(msg.sender != address(0), "Sender cannot be 0 address.");
        require(ownedTokens[msg.sender].length < 100, "Sender cannot have more than 100 tokens.");
        require(now < EVENT_START, "Event already started."); //Event Start
        require (bytes(message).length <= 100);

        bytes32 secret = keccak256(preSecret);

        require (secretsMap[secret] == 1, "Invalid secret.");
        
        secretsMap[secret] = 0;

        uint256 tokenId = _createToken(matches, bonusMatches, extraStats, message);
        _mint(msg.sender, tokenId);
        
        emit LogPrepaidRedeemed(msg.sender, tokenId, message, matches, extraStats, bonusMatches);

        return tokenId;
    }


    /** 
    * @param tokenId - ID of token to get.
    * @return Returns all the valuable information about a specific token.
    */
    function getToken(uint256 tokenId) external view returns (uint160 matches, uint32 bonusMatches, uint96 extraStats, uint64 timeStamp, string message) {

        Token storage token = tokens[tokenId];

        matches = token.matches;
        bonusMatches = token.bonusMatches;
        extraStats = token.extraStats;
        timeStamp = token.timeStamp;
        message = token.message;

    }

    /**
    * @notice Allows any user to retrieve their asigned prize. This would be the sum of the price of all the tokens
    * owned by the caller of this function.
    * @dev If the caller has no prize, the function will revert costing no gas to the caller.
    */
    function withdrawPrize() external checkState(pointsValidationState.Finished){
        
        uint256 prize = 0;
        uint256[] memory tokenList = ownedTokens[msg.sender];
        
        for(uint256 i = 0;i < tokenList.length; i++){
            prize += tokenToPayoutMap[tokenList[i]];
            tokenToPayoutMap[tokenList[i]] = 0;
        }
        
        require(prize > 0);
        msg.sender.transfer((prizePool.mul(prize)).div(1000000));   
    }


    //EMERGENCY CALLS
    //If something goes wrong or fails, these functions will allow retribution for token holders 

    /**
    * @notice if there is an unresolvable problem, users can call to this function to get a refund.
    */
    function emergencyWithdraw() external hasFinalized{

        uint256 balance = STARTING_PRICE * ownedTokens[msg.sender].length;

        delete ownedTokens[msg.sender];
        msg.sender.transfer(balance);

    }

}

Contract Security Audit

Contract ABI

API
[{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"operatorApprovals","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"dataSourceGetBonusResults","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"dataSourceGetExtraStats","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"state","type":"bool"}],"name":"setFinalized","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"secretsMap","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"setLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint32"}],"name":"calculateWinners","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenToPayoutMap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setDataSourceAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenToPointsMap","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawPrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"matches","type":"uint160"}],"name":"dataSourceCallbackMatch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isDataSourceCallback","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"setTopWinnerPrizes","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"preSecret","type":"bytes32"},{"name":"matches","type":"uint160"},{"name":"bonusMatches","type":"uint32"},{"name":"extraStats","type":"uint96"},{"name":"message","type":"string"}],"name":"redeemPrepaidToken","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newLength","type":"uint256"}],"name":"resetWinners","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sortedChunk","type":"uint32[]"}],"name":"checkOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newAdmin","type":"address"}],"name":"setAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"matches","type":"uint160"},{"name":"bonusMatches","type":"uint32"},{"name":"extraStats","type":"uint96"},{"name":"message","type":"string"}],"name":"buildToken","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"prizePool","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"setEnd","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pValidationState","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"es","type":"uint96"}],"name":"dataSourceCallbackExtras","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint32"}],"name":"setWinnerPrizes","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"emergencyWithdrawAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"bonusResults","type":"uint32"}],"name":"dataSourceCallbackBonus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenApprovals","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"finalized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"finishedGameWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint32"}],"name":"calculatePointsBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newMkt","type":"address"}],"name":"setMarketplaceAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"adminPool","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"giftedAddress","type":"address"},{"name":"matches","type":"uint160"},{"name":"bonusMatches","type":"uint32"},{"name":"extraStats","type":"uint96"},{"name":"message","type":"string"}],"name":"giftToken","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"state","type":"bool"}],"name":"setPauseState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"dataSourceAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"dataSourceGetMatchesResults","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"secret","type":"bytes32"}],"name":"buildPrepaidToken","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_from","type":"address"}],"name":"getOwnedTokens","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"marketplaceAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"emergencyWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getToken","outputs":[{"name":"matches","type":"uint160"},{"name":"bonusMatches","type":"uint32"},{"name":"extraStats","type":"uint96"},{"name":"timeStamp","type":"uint64"},{"name":"message","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"bonusMatches","outputs":[{"name":"bonus","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"matchResults","outputs":[{"name":"result","type":"uint8"},{"name":"under49","type":"uint8"},{"name":"touchdowns","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"adminAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"extraStats","outputs":[{"name":"interceptions","type":"uint16"},{"name":"missedFieldGoals","type":"uint16"},{"name":"overtimes","type":"uint16"},{"name":"sacks","type":"uint16"},{"name":"fieldGoals","type":"uint16"},{"name":"fumbles","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"adminWithdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"finalizedTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gameFinishedTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"creatorAddress","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"message","type":"string"},{"indexed":false,"name":"m","type":"uint160"},{"indexed":false,"name":"e","type":"uint96"},{"indexed":false,"name":"b","type":"uint32"}],"name":"LogTokenBuilt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"creatorAddress","type":"address"},{"indexed":false,"name":"giftedAddress","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"message","type":"string"},{"indexed":false,"name":"m","type":"uint160"},{"indexed":false,"name":"e","type":"uint96"},{"indexed":false,"name":"b","type":"uint32"}],"name":"LogTokenGift","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"creatorAddress","type":"address"},{"indexed":false,"name":"secret","type":"bytes32"}],"name":"LogPrepaidTokenBuilt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"redeemer","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"message","type":"string"},{"indexed":false,"name":"m","type":"uint160"},{"indexed":false,"name":"e","type":"uint96"},{"indexed":false,"name":"b","type":"uint32"}],"name":"LogPrepaidRedeemed","type":"event"}]

6103006040526000608081815260a082905260c082905260e082905261010082905261012082905260016101408190526101608390526101808390526101a08390526101c08390526101e08390526102008190526102208390526102408390526102608390526102808390526102a08390526102c0526102e0829052620000899190601462000208565b506000600181815560028290556007805460a060020a60ff021916905560089190915560098054600160c060020a0319169055604080516102a08101825282815260208101839052908101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915260056101408201819052610160820152600a610180820181905260146101a083015260326101c083015260646101e0830181905261020083015260c86102208301526101f46102408301526105dc6102608301526109c461028083015262000175916015620002b4565b506017805461ffff191690556000601a819055601b819055601c553480156200019d57600080fd5b50601780546201000060b060020a03191633620100000217905542601a55620001ce640100000000620001e7810204565b620001e1640100000000620001f9810204565b6200041c565b6014620001f6600f8262000360565b50565b6005620001f66010826200038c565b82805482825590600052602060002090601f01602090048101928215620002a25791602002820160005b838211156200027157835183826101000a81548160ff021916908315150217905550926020019260010160208160000104928301926001030262000232565b8015620002a05782816101000a81549060ff021916905560010160208160000104928301926001030262000271565b505b50620002b0929150620003b3565b5090565b82805482825590600052602060002090600f01601090048101928215620003525791602002820160005b838211156200032057835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302620002de565b8015620003505782816101000a81549061ffff021916905560020160208160010104928301926001030262000320565b505b50620002b0929150620003d7565b815481835581811115620003875760008381526020902062000387918101908301620003f9565b505050565b815481835581811115620003875760008381526020902062000387918101908301620003d7565b620003d491905b80821115620002b057805460ff19168155600101620003ba565b90565b620003d491905b80821115620002b057805461ffff19168155600101620003de565b620003d491905b80821115620002b057805462ffffff1916815560010162000400565b614606806200042c6000396000f3006080604052600436106102b05763ffffffff60e060020a600035041663081812fc81146102e6578063095ea7b31461031a5780630d95e0541461033e5780630fe081ea146103795780631caaa4871461038e5780632065b966146103a657806320b27291146103bb578063237bcb2d146103d557806323b872dd1461040357806327ea6f2b1461042d578063299e7abb146104455780632cdc078d146104635780633a1fc7621461048d57806342842e0e146104ae57806345b95aa7146104d857806348d37a58146105075780634f558e791461051c5780634feb22d014610534578063582b6add146105555780635a2a30391461056a5780635bd34b601461057f5780635c975abb146105cc5780635dedd9cc146105e15780636352211e146105f957806363e561b614610611578063704b6c021461063157806370a0823114610652578063716dba9e14610673578063719ce73e146106af578063746a3aa8146106c4578063810a217f146106d95780638857179a1461071257806388fdf3d4146107385780638f75362d14610756578063a22cb4651461076b578063a72841ee14610791578063acdeb5b9146107af578063b3f05b97146107c7578063b3f50029146107dc578063b427c148146107f1578063b47cc5561461080f578063b86a1fb214610830578063b88d4fde14610845578063bf60c386146108b4578063cdb88ad1146108f8578063d5a3b73414610912578063d5b92d0814610927578063d9ac31fe1461093c578063d9d6165514610947578063daa17f49146109b8578063db2e21bc146109cd578063e4b50cb8146109e2578063e985e9c514610adc578063eb941fec14610b03578063f17b342814610b1b578063fc6f946814610b58578063fcef338614610b6d578063fdf061f014610bc0578063fe67a18914610bd5578063fefaa62614610bea575b601754620100009004600160a060020a03163314806102d95750601954600160a060020a031633145b15156102e457600080fd5b005b3480156102f257600080fd5b506102fe600435610bff565b60408051600160a060020a039092168252519081900360200190f35b34801561032657600080fd5b506102e4600160a060020a0360043516602435610c1a565b34801561034a57600080fd5b50610365600160a060020a0360043581169060243516610cc3565b604080519115158252519081900360200190f35b34801561038557600080fd5b506102e4610ce3565b34801561039a57600080fd5b506102fe600435610da6565b3480156103b257600080fd5b506102e4610dc1565b3480156103c757600080fd5b506102e46004351515610e6a565b3480156103e157600080fd5b506103ed600435610ef5565b6040805160ff9092168252519081900360200190f35b34801561040f57600080fd5b506102e4600160a060020a0360043581169060243516604435610f0a565b34801561043957600080fd5b506102e460043561100f565b34801561045157600080fd5b506102e463ffffffff600435166110fb565b34801561046f57600080fd5b5061047b600435611352565b60408051918252519081900360200190f35b34801561049957600080fd5b506102e4600160a060020a0360043516611364565b3480156104ba57600080fd5b506102e4600160a060020a0360043581169060243516604435611466565b3480156104e457600080fd5b506104f0600435611487565b6040805161ffff9092168252519081900360200190f35b34801561051357600080fd5b506102e461149d565b34801561052857600080fd5b50610365600435611647565b34801561054057600080fd5b506102e4600160a060020a0360043516611664565b34801561056157600080fd5b506103656117c9565b34801561057657600080fd5b506102e46117cf565b34801561058b57600080fd5b5061047b600480359060248035600160a060020a03169160443563ffffffff16916064356bffffffffffffffffffffffff1691608435918201910135611c50565b3480156105d857600080fd5b50610365611f51565b3480156105ed57600080fd5b506102e4600435611f5a565b34801561060557600080fd5b506102fe60043561201a565b34801561061d57600080fd5b506102e46004803560248101910135612044565b34801561063d57600080fd5b506102e4600160a060020a0360043516612375565b34801561065e57600080fd5b5061047b600160a060020a0360043516612417565b61047b60048035600160a060020a0316906024803563ffffffff16916044356bffffffffffffffffffffffff169160643590810191013561244a565b3480156106bb57600080fd5b5061047b61270f565b3480156106d057600080fd5b506102e4612715565b3480156106e557600080fd5b506106ee612839565b604051808260068111156106fe57fe5b60ff16815260200191505060405180910390f35b34801561071e57600080fd5b506102e46bffffffffffffffffffffffff60043516612849565b34801561074457600080fd5b506102e463ffffffff6004351661297b565b34801561076257600080fd5b506102e4612ca6565b34801561077757600080fd5b506102e4600160a060020a03600435166024351515612dad565b34801561079d57600080fd5b506102e463ffffffff60043516612e31565b3480156107bb57600080fd5b506102fe600435612efb565b3480156107d357600080fd5b50610365612f16565b3480156107e857600080fd5b506102e4612f24565b3480156107fd57600080fd5b506102e463ffffffff6004351661302d565b34801561081b57600080fd5b506102e4600160a060020a03600435166132ad565b34801561083c57600080fd5b5061047b61333a565b34801561085157600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526102e494600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506133409650505050505050565b61047b600160a060020a0360048035821691602480359091169163ffffffff60443516916bffffffffffffffffffffffff606435169160843591820191013561334b565b34801561090457600080fd5b506102e46004351515613625565b34801561091e57600080fd5b506102fe61368e565b34801561093357600080fd5b506102e461369d565b6102e4600435613746565b34801561095357600080fd5b50610968600160a060020a036004351661392a565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156109a457818101518382015260200161098c565b505050509050019250505060405180910390f35b3480156109c457600080fd5b506102fe613996565b3480156109d957600080fd5b506102e46139a5565b3480156109ee57600080fd5b506109fa600435613a5c565b6040518086600160a060020a0316600160a060020a031681526020018563ffffffff1663ffffffff168152602001846bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020018367ffffffffffffffff1667ffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610a9d578181015183820152602001610a85565b50505050905090810190601f168015610aca5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b348015610ae857600080fd5b50610365600160a060020a0360043581169060243516613b76565b348015610b0f57600080fd5b506104f0600435613ba4565b348015610b2757600080fd5b50610b33600435613bc7565b6040805160ff9485168152928416602084015292168183015290519081900360600190f35b348015610b6457600080fd5b506102fe613bfa565b348015610b7957600080fd5b50610b82613c0f565b6040805161ffff978816815295871660208701529386168585015291851660608501528416608084015290921660a082015290519081900360c00190f35b348015610bcc57600080fd5b506102e4613c5b565b348015610be157600080fd5b5061047b613cff565b348015610bf657600080fd5b5061047b613d05565b600090815260146020526040902054600160a060020a031690565b6000610c258261201a565b9050600160a060020a038381169082161415610c4057600080fd5b33600160a060020a0382161480610c5c5750610c5c8133613b76565b1515610c6757600080fd5b6000828152601460205260408082208054600160a060020a031916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b601660209081526000928352604080842090915290825290205460ff1681565b601754620100009004600160a060020a03163314610d39576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600760009054906101000a9004600160a060020a0316600160a060020a031663cadc027b6040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015610d8c57600080fd5b505af1158015610da0573d6000803e3d6000fd5b50505050565b601360205260009081526040902054600160a060020a031681565b601754620100009004600160a060020a03163314610e17576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600760009054906101000a9004600160a060020a0316600160a060020a03166337dfffcc6040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015610d8c57600080fd5b601754620100009004600160a060020a03163314610ec0576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b6017805460ff191682151590811761ff001916610100918202179182905560ff910416151560011415610ef25742601c555b50565b60056020526000908152604090205460ff1681565b60175460ff1615610f53576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b610f5d3382613d0b565b1515610f6857600080fd5b600160a060020a0383161515610f7d57600080fd5b600160a060020a0382161515610f9257600080fd5b600160a060020a038381169083161415610fab57600080fd5b610fb58382613d6a565b610fbf8382613dcc565b610fc98282613ee6565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b601754620100009004600160a060020a03163314611065576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b601254811061107357600080fd5b600060075460a060020a900460ff16600681111561108d57fe5b14806110b05750600160075460a060020a900460ff1660068111156110ae57fe5b145b15156110bb57600080fd5b60088190556007805460a060020a60ff02191660a060020a179055600980546bffffffffffffffffffffffff191690556110f3613f54565b610ef2613f63565b6017546000908190620100009004600160a060020a03163314611156576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60018060075460a060020a900460ff16600681111561117157fe5b146111b4576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b60125460095463ffffffff640100000000909104811686011611156111d857600080fd5b60085460009081526003602052604090205460095461ffff9091169350640100000000900463ffffffff1691505b60095463ffffffff64010000000090910481168501168210156112a65760008281526003602052604090205461ffff16831080611261575060008281526003602052604090205461ffff168314801561126157506008548211155b1561129b5760098054600163ffffffff6801000000000000000080840482169290920116026bffffffff0000000000000000199091161790555b600190910190611206565b6009805463ffffffff640100000000808304821688018216810267ffffffff00000000199093169290921792839055601254919092049091161415610da05760095468010000000000000000810463ffffffff16780100000000000000000000000000000000000000000000000090910461ffff161461132557600080fd5b50506007805460a060020a60ff021916740200000000000000000000000000000000000000001790555050565b60046020526000908152604090205481565b601754600090620100009004600160a060020a031633146113bd576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b81905080600160a060020a031663037a9d306040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156113fe57600080fd5b505af1158015611412573d6000803e3d6000fd5b505050506040513d602081101561142857600080fd5b5051151561143557600080fd5b60078054600160a060020a03928316600160a060020a03199182161790915560188054939092169216919091179055565b6114828383836020604051908101604052806000815250613340565b505050565b60036020526000908152604090205461ffff1681565b600060608160068060075460a060020a900460ff1660068111156114bd57fe5b14611500576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b33600090815260156020908152604080832080548251818502810185019093528083529397509092909183018282801561155957602002820191906000526020600020905b815481526020019060010190808311611545575b50505050509250600091505b82518210156115d65760046000848481518110151561158057fe5b906020019060200201518152602001908152602001600020548401935060006004600085858151811015156115b157fe5b6020908102909101810151825281019190915260400160002055600190910190611565565b600084116115e357600080fd5b33600160a060020a03166108fc611618620f424061160c8860015461413390919063ffffffff16565b9063ffffffff61415c16565b6040518115909202916000818181858888f19350505050158015611640573d6000803e3d6000fd5b5050505050565b600090815260136020526040902054600160a060020a0316151590565b6018546000908190600160a060020a031633146116cb576040805160e560020a62461bcd02815260206004820152601060248201527f4f6e6c792064617461536f757263652e00000000000000000000000000000000604482015290519081900360640190fd5b5081905060005b601481101561148257600f80546003841691906000196014859003019081106116f757fe5b6000918252602090912001805460ff191660ff92909216919091179055600f80546004600160a060020a03851604600116919060148490036000190190811061173c57fe5b6000918252602090912001805460ff929092166101000261ff0019909216919091179055600f80546008600160a060020a03851604601f16919060001960148590030190811061178857fe5b6000918252602090912001805460ff92909216620100000262ff000019909216919091179055610100600160a060020a0390921691909104906001016116d2565b60015b90565b60006060600080600080600080600080601760029054906101000a9004600160a060020a0316600160a060020a031633600160a060020a031614151561184d576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60038060075460a060020a900460ff16600681111561186857fe5b146118ab576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b60408051601e8082526103e0820190925260009c5090602082016103c0803883395050601254919b5060009a508a9650600d95505060c911156118ed57600a93505b600954608060020a900463ffffffff16841115611be757600954600a80549091608060020a900463ffffffff1690811061192357fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff1692505b6000831115611bab57600e805463ffffffff871690811061196557fe5b6000918252602080832090910154808352600390915260409091205490985061ffff16965060001990920191821580156119b2575060095463ffffffff608060020a909104166000198501145b15611a725785871415611a2857600954600b90608060020a900463ffffffff16601581106119dc57fe5b600a91828204019190066003029054906101000a900462ffffff1662ffffff168b019a50878a8a61ffff16815181101515611a1357fe5b60209081029091010152600190980197611a72565b600954600b90608060020a900463ffffffff1660158110611a4557fe5b600a808204929092015460008b8152600460205260409020929091066003026101000a900462ffffff1690555b63ffffffff851615801590611aad57508587141580611aad575082158015611aad575060095463ffffffff608060020a909104166000198501145b15611b3a57600091505b8861ffff16821015611b0e57611ad78b61ffff8b1663ffffffff61415c16565b600460008c85815181101515611ae957fe5b6020908102909101810151825281019190915260400160002055600190910190611ab7565b60408051601e8082526103e0820190925260009c5090602082016103c080388339019050509950600098505b600954600b90608060020a900463ffffffff1660158110611b5757fe5b600a91828204019190066003029054906101000a900462ffffff1662ffffff168b019a50878a8a61ffff16815181101515611b8e57fe5b602090810290910101526001988901988796509490940193611948565b60098054600163ffffffff608060020a808404821692909201160273ffffffff00000000000000000000000000000000199091161790556118ed565b5050600780547404000000000000000000000000000000000000000060a060020a60ff021990911617905550506009805477ffffffff0000000000000000000000000000000000000000191663ffffffff9290921660a060020a02919091179055505050505050565b6017546000908190819060ff1615611ca0576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b331515611ce5576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b33600090815260156020526040902054606411611d72576040805160e560020a62461bcd02815260206004820152602860248201527f53656e6465722063616e6e6f742068617665206d6f7265207468616e2031303060448201527f20746f6b656e732e000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b635bdb14f04210611dbb576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b6064841115611dc957600080fd5b604080518a81528151908190036020908101909120600081815260059092529190205490925060ff16600114611e49576040805160e560020a62461bcd02815260206004820152600f60248201527f496e76616c6964207365637265742e0000000000000000000000000000000000604482015290519081900360640190fd5b600082815260056020908152604091829020805460ff191690558151601f8701829004820281018201909252858252611e9c918a918a918a918a908a908190840183828082843750614171945050505050565b9050611ea83382614395565b604080513380825260208201849052600160a060020a038b1660608301526bffffffffffffffffffffffff8916608083015263ffffffff8a1660a083015260c09282018381529282018790527fcc7ceaf1ba8bfaf7a8d8aaa8f7026b92859b0a0974c9badd135b883073d4a92b9290918491899189918e918d918f919060e0820187878082843760405192018290039a509098505050505050505050a198975050505050505050565b60175460ff1681565b601754620100009004600160a060020a03163314611fb0576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60028060075460a060020a900460ff166006811115611fcb57fe5b1461200e576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b81611482600e82614410565b600081815260136020526040812054600160a060020a031680151561203e57600080fd5b92915050565b600080600080600080601760029054906101000a9004600160a060020a0316600160a060020a031633600160a060020a03161415156120bb576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60028060075460a060020a900460ff1660068111156120d657fe5b14612119576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b600954600e546801000000000000000090910463ffffffff16908901111561214057600080fd5b600096505b60001988018710156122005788888881811061215d57fe5b9050602002013563ffffffff1663ffffffff169550888888600101818110151561218357fe5b6020908102929092013563ffffffff16600081815260039093526040808420548a855293205490975061ffff9283169216919091119050806121ea57506000858152600360205260408082205488835291205461ffff90811691161480156121ea57508486105b15156121f557600080fd5b600190960195612145565b600e54156122a857600e8054600019810190811061221a57fe5b9060005260206000200154935088886000818110151561223657fe5b6020908102929092013563ffffffff166000818152600390935260408084205488855293205490955061ffff92831692169190911190508061229d57506000838152600360205260408082205486835291205461ffff908116911614801561229d57508284105b15156122a857600080fd5b600091505b878210156122f757600e8989848181106122c357fe5b835460018082018655600095865260209586902092909502939093013563ffffffff169201919091555091909101906122ad565b600954600e546801000000000000000090910463ffffffff16141561236a57600854600e8054600019810190811061232b57fe5b906000526020600020015414151561234257600080fd5b6007805460a060020a60ff021916740300000000000000000000000000000000000000001790555b505050505050505050565b601754620100009004600160a060020a031633146123cb576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600160a060020a03811615156123e057600080fd5b60178054600160a060020a03909216620100000275ffffffffffffffffffffffffffffffffffffffff000019909216919091179055565b6000600160a060020a038216151561242e57600080fd5b50600160a060020a031660009081526015602052604090205490565b601754600090819060ff1615612498576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b6124a06143b4565b3410156124f7576040805160e560020a62461bcd02815260206004820152601760248201527f4574682073656e74206973206e6f7420656e6f7567682e000000000000000000604482015290519081900360640190fd5b33151561253c576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b336000908152601560205260409020546064116125c9576040805160e560020a62461bcd02815260206004820152602860248201527f53656e6465722063616e6e6f742068617665206d6f7265207468616e2031303060448201527f20746f6b656e732e000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b635bdb14f04210612612576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b606483111561262057600080fd5b61265c87878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750614171945050505050565b90506126683382614395565b604080513380825260208201849052600160a060020a038a1660608301526bffffffffffffffffffffffff8816608083015263ffffffff891660a083015260c09282018381529282018690527fc9b6356917c8e6595e04f058f37ae084434790be9b87f82ffe091de4fa9ae6239290918491889188918d918c918e919060e0820187878082843760405192018290039a509098505050505050505050a19695505050505050565b60015481565b601754600090620100009004600160a060020a0316331461276e576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60058060075460a060020a900460ff16600681111561278957fe5b146127cc576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b303191506127e6606461160c84600a63ffffffff61413316565b6002556127ff606461160c84605a63ffffffff61413316565b6001556007805460a060020a60ff0219167406000000000000000000000000000000000000000017905542601b55612835614404565b5050565b60075460a060020a900460ff1681565b601854600090600160a060020a031633146128ae576040805160e560020a62461bcd02815260206004820152601060248201527f4f6e6c792064617461536f757263652e00000000000000000000000000000000604482015290519081900360640190fd5b506011805461ffff80841661ffff199092169190911763ffff00001916620100006bffffffffffffffffffffffff94851681900483811682029290921765ffff000000001916918516819004838116640100000000029290921767ffff00000000000019169185168190048381166601000000000000029290921769ffff000000000000000019169185168190048381166801000000000000000002929092176bffff0000000000000000000019169190941693909304166a010000000000000000000002919091179055565b60175460009081908190620100009004600160a060020a031633146129d8576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60048060075460a060020a900460ff1660068111156129f357fe5b14612a36576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b60095463ffffffff680100000000000000008204811660a060020a90920481168701161115612a6457600080fd5b600954600a80549091608060020a900463ffffffff16908110612a8357fe5b600091825260208220601082040154600f9091166002026101000a900461ffff16945092505b8463ffffffff16831015612bc65761ffff84161515612b39576009805473ffffffff00000000000000000000000000000000198116608060020a9182900463ffffffff908116600101811683029190911792839055600a805490939290920416908110612b1257fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff1693505b600954600e8054909160a060020a900463ffffffff168501908110612b5a57fe5b600091825260209091200154600954909250600b90608060020a900463ffffffff1660158110612b8657fe5b600a80820492909201546000858152600460205260409020929091066003026101000a900462ffffff169055600019939093019260019290920191612aa9565b6009805463ffffffff60a060020a8083048216890182160277ffffffff0000000000000000000000000000000000000000199092169190911791829055600a805487939192608060020a909204909116908110612c1f57fe5b6000918252602090912060108204018054600f9092166002026101000a61ffff81810219909316939092169190910291909117905560095468010000000000000000810463ffffffff90811660a060020a909204161415611640576007805460a060020a60ff02191674050000000000000000000000000000000000000000179055611640565b601754610100900460ff161515612d07576040805160e560020a62461bcd02815260206004820152601b60248201527f4f6e6c792069662067616d65206861732066696e616c697a65642e0000000000604482015290519081900360640190fd5b601754620100009004600160a060020a03163314612d5d576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b601c5415801590612d755750601c54620d2f00014210155b1515612d8057600080fd5b6040513390303180156108fc02916000818181858888f19350505050158015610ef2573d6000803e3d6000fd5b600160a060020a038216331415612dc357600080fd5b336000818152601660209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b6018546000908190600160a060020a03163314612e98576040805160e560020a62461bcd02815260206004820152601060248201527f4f6e6c792064617461536f757263652e00000000000000000000000000000000604482015290519081900360640190fd5b5081905060005b60058110156114825760108054603f84169190600019600585900301908110612ec457fe5b6000918252602090912001805461ffff191661ffff92909216919091179055604063ffffffff929092169190910490600101612e9f565b601460205260009081526040902054600160a060020a031681565b601754610100900460ff1681565b601754600090620100009004600160a060020a03163314612f7d576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b601b5415801590612f955750601b546213c680014210155b1515612feb576040805160e560020a62461bcd02815260206004820152601a60248201527f4f6e6c792069662067616d65206861732066696e69736865642e000000000000604482015290519081900360640190fd5b50601754604051303191620100009004600160a060020a03169082156108fc029083906000818181858888f19350505050158015612835573d6000803e3d6000fd5b601b5460009081901561303f57600080fd5b60125460095463ffffffff6401000000009091048116850116111561306357600080fd5b60095463ffffffff1691505b60095463ffffffff90811684011682101561328a57732e2ae45a3e2ff04a441e043be45dfba3f7a083ed63f9ebe6cb6012848154811015156130ad57fe5b600091825260209091206003909102015460128054600160a060020a0390921691869081106130d857fe5b906000526020600020906003020160000160149054906101000a900463ffffffff1660128681548110151561310957fe5b906000526020600020906003020160010160009054906101000a90046bffffffffffffffffffffffff16600f6011601060006040518863ffffffff1660e060020a0281526004018088600160a060020a0316600160a060020a031681526020018763ffffffff1663ffffffff168152602001866bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200185815260200184815260200183815260200180602001828103825283818154815260200191508054801561321057602002820191906000526020600020906000905b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116131df5790505b50509850505050505050505060206040518083038186803b15801561323457600080fd5b505af4158015613248573d6000803e3d6000fd5b505050506040513d602081101561325e57600080fd5b50516000838152600360205260409020805461ffff191661ffff8316179055600190920191905061306f565b50506009805463ffffffff19811663ffffffff9182169390930116919091179055565b601754620100009004600160a060020a03163314613303576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600160a060020a038116151561331857600080fd5b60198054600160a060020a031916600160a060020a0392909216919091179055565b60025481565b610da0848484610f0a565b601754600090819060ff1615613399576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b6133a16143b4565b3410156133f8576040805160e560020a62461bcd02815260206004820152601760248201527f4574682073656e74206973206e6f7420656e6f7567682e000000000000000000604482015290519081900360640190fd5b33151561343d576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b600160a060020a0388166000908152601560205260409020546064116134d3576040805160e560020a62461bcd02815260206004820152602860248201527f53656e6465722063616e6e6f742068617665206d6f7265207468616e2031303060448201527f20746f6b656e732e000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b635bdb14f0421061351c576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b606483111561352a57600080fd5b61356687878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750614171945050505050565b90506135728882614395565b6040805133808252600160a060020a03808c16602084015292820184905291891660808201526bffffffffffffffffffffffff871660a082015263ffffffff881660c082015260e0606082018181529082018690527fd224a9a732ef51c0945b6f3d79bda4f9b5ef8b81a967d7ea8e63575c9e0c7f9492918b918591899189918e918d918f91610100820187878082843760405192018290039b50909950505050505050505050a1979650505050505050565b601754620100009004600160a060020a0316331461367b576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b6017805460ff1916911515919091179055565b601854600160a060020a031681565b601754620100009004600160a060020a031633146136f3576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600760009054906101000a9004600160a060020a0316600160a060020a03166313bb13116040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015610d8c57600080fd5b601754620100009004600160a060020a0316331461379c576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60175460ff16156137e5576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b6137ed6143b4565b341015613844576040805160e560020a62461bcd02815260206004820152601760248201527f4574682073656e74206973206e6f7420656e6f7567682e000000000000000000604482015290519081900360640190fd5b331515613889576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b635bdb14f042106138d2576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b600081815260056020908152604091829020805460ff19166001179055815133815290810183905281517f5af1975c023a376dd6e2d2a7d941656d6014c52ec7793a6fcbc82358099b6803929181900390910190a150565b600160a060020a03811660009081526015602090815260409182902080548351818402810184019094528084526060939283018282801561398a57602002820191906000526020600020905b815481526020019060010190808311613976575b50505050509050919050565b601954600160a060020a031681565b601754600090610100900460ff161515613a09576040805160e560020a62461bcd02815260206004820152601b60248201527f4f6e6c792069662067616d65206861732066696e616c697a65642e0000000000604482015290519081900360640190fd5b50336000908152601560205260408120805466b1a2bc2ec500000291613a2f9190614434565b604051339082156108fc029083906000818181858888f19350505050158015612835573d6000803e3d6000fd5b60008060008060606000601287815481101515613a7557fe5b6000918252602091829020600391909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f8101889004880285018801909252818452600160a060020a0385169c5060a060020a90940463ffffffff169a506bffffffffffffffffffffffff821699506c0100000000000000000000000090910467ffffffffffffffff16975092945092909190830182828015613b655780601f10613b3a57610100808354040283529160200191613b65565b820191906000526020600020905b815481529060010190602001808311613b4857829003601f168201915b505050505091505091939590929450565b600160a060020a03918216600090815260166020908152604080832093909416825291909152205460ff1690565b6010805482908110613bb257fe5b60009182526020909120015461ffff16905081565b600f805482908110613bd557fe5b60009182526020909120015460ff808216925061010082048116916201000090041683565b601754620100009004600160a060020a031681565b60115461ffff808216916201000081048216916401000000008204811691660100000000000081048216916801000000000000000082048116916a010000000000000000000090041686565b601754600090620100009004600160a060020a03163314613cb4576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b5060028054600091829055601754604051919262010000909104600160a060020a0316916108fc84150291849190818181858888f19350505050158015612835573d6000803e3d6000fd5b601c5481565b601b5481565b600080613d178361201a565b905080600160a060020a031684600160a060020a03161480613d52575083600160a060020a0316613d4784610bff565b600160a060020a0316145b80613d625750613d628185613b76565b949350505050565b81600160a060020a0316613d7d8261201a565b600160a060020a031614613d9057600080fd5b600081815260146020526040902054600160a060020a0316156128355760009081526014602052604090208054600160a060020a031916905550565b60008083600160a060020a0316613de28461201a565b600160a060020a031614613df557600080fd5b600160a060020a038416600090815260156020526040902054606411613e1a57600080fd5b505060008181526013602090815260408083208054600160a060020a0319169055600160a060020a038516835260159091528120905b8154811015613eb957828282815481101515613e6857fe5b90600052602060002001541415613eb157815482906000198101908110613e8b57fe5b90600052602060002001548282815481101515613ea457fe5b6000918252602090912001555b600101613e50565b815482906000198101908110613ecb57fe5b60009182526020822001558154611640836000198301614410565b600081815260136020526040902054600160a060020a031615613f0857600080fd5b60008181526013602090815260408083208054600160a060020a03909616600160a060020a03199096168617905593825260158152928120805460018101825590825292902090910155565b6017805460ff19166001179055565b613f6b614452565b600073fab06e5f52820a397f1b9c79e59c84897e168813633b345a876012805490506040518263ffffffff1660e060020a028152600401808281526020019150506102a06040518083038186803b158015613fc557600080fd5b505af4158015613fd9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102a0811015613fff57600080fd5b509150600090505b60158110156140625781816015811061401c57fe5b6020020151600b826015811061402e57fe5b600a91828204019190066003026101000a81548162ffffff021916908362ffffff1602179055508080600101915050614007565b73fab06e5f52820a397f1b9c79e59c84897e16881363ec8263996012805490506040518263ffffffff1660e060020a0281526004018082815260200191505060206040518083038186803b1580156140b957600080fd5b505af41580156140cd573d6000803e3d6000fd5b505050506040513d60208110156140e357600080fd5b50516009805461ffff90921678010000000000000000000000000000000000000000000000000279ffff000000000000000000000000000000000000000000000000199092169190911790555050565b60008215156141445750600061203e565b5081810281838281151561415457fe5b041461203e57fe5b6000818381151561416957fe5b049392505050565b600061417b614472565b506040805160a081018252600160a060020a03878116825263ffffffff87811660208085019182526bffffffffffffffffffffffff8981169686019687524267ffffffffffffffff90811660608801908152608088018b815260128054600180820180845560009384528c517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444600390940293840180549b51600160a060020a0319909c1691909d161777ffffffff0000000000000000000000000000000000000000191660a060020a9a909b1699909902999099178a559a517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34458c01805494516bffffffffffffffffffffffff19909516919096161773ffffffffffffffff00000000000000000000000019166c010000000000000000000000009390941692909202929092179092555180519697919694959394889493614302937fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3446019201906144a2565b50505003905063ffffffff8116811461438b576040805160e560020a62461bcd02815260206004820152602560248201527f4661696c656420746f20636f6e7665727420746f6b656e496420746f2075696e60448201527f743235362e000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b9695505050505050565b600160a060020a03821615156143aa57600080fd5b6128358282613ee6565b6000635bd088f042106143d0575067011c37937e0800006143da565b5066b1a2bc2ec500005b66b1a2bc2ec5000081101580156143f9575067011c37937e0800008111155b15156117cc57600080fd5b6017805460ff19169055565b81548183558181111561148257600083815260209020611482918101908301614520565b5080546000825590600052602060002090810190610ef29190614520565b6102a0604051908101604052806015906020820280388339509192915050565b6040805160a081018252600080825260208201819052918101829052606080820192909252608081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106144e357805160ff1916838001178555614510565b82800160010185558215614510579182015b828111156145105782518255916020019190600101906144f5565b5061451c929150614520565b5090565b6117cc91905b8082111561451c5760008155600101614526560053656e6465722063616e6e6f74206265203020616464726573732e00000000004f6e6c792061646d696e2e0000000000000000000000000000000000000000004576656e7420616c726561647920737461727465642e00000000000000000000506f696e74732076616c69646174696f6e20737461676520696e76616c69642e4f6e6c79206966206e6f74207061757365642e00000000000000000000000000a165627a7a72305820e1378936021c34c8727a49e5ce6ccb1e23120da769c9f755a61123be90acb2f90029

Deployed Bytecode

0x6080604052600436106102b05763ffffffff60e060020a600035041663081812fc81146102e6578063095ea7b31461031a5780630d95e0541461033e5780630fe081ea146103795780631caaa4871461038e5780632065b966146103a657806320b27291146103bb578063237bcb2d146103d557806323b872dd1461040357806327ea6f2b1461042d578063299e7abb146104455780632cdc078d146104635780633a1fc7621461048d57806342842e0e146104ae57806345b95aa7146104d857806348d37a58146105075780634f558e791461051c5780634feb22d014610534578063582b6add146105555780635a2a30391461056a5780635bd34b601461057f5780635c975abb146105cc5780635dedd9cc146105e15780636352211e146105f957806363e561b614610611578063704b6c021461063157806370a0823114610652578063716dba9e14610673578063719ce73e146106af578063746a3aa8146106c4578063810a217f146106d95780638857179a1461071257806388fdf3d4146107385780638f75362d14610756578063a22cb4651461076b578063a72841ee14610791578063acdeb5b9146107af578063b3f05b97146107c7578063b3f50029146107dc578063b427c148146107f1578063b47cc5561461080f578063b86a1fb214610830578063b88d4fde14610845578063bf60c386146108b4578063cdb88ad1146108f8578063d5a3b73414610912578063d5b92d0814610927578063d9ac31fe1461093c578063d9d6165514610947578063daa17f49146109b8578063db2e21bc146109cd578063e4b50cb8146109e2578063e985e9c514610adc578063eb941fec14610b03578063f17b342814610b1b578063fc6f946814610b58578063fcef338614610b6d578063fdf061f014610bc0578063fe67a18914610bd5578063fefaa62614610bea575b601754620100009004600160a060020a03163314806102d95750601954600160a060020a031633145b15156102e457600080fd5b005b3480156102f257600080fd5b506102fe600435610bff565b60408051600160a060020a039092168252519081900360200190f35b34801561032657600080fd5b506102e4600160a060020a0360043516602435610c1a565b34801561034a57600080fd5b50610365600160a060020a0360043581169060243516610cc3565b604080519115158252519081900360200190f35b34801561038557600080fd5b506102e4610ce3565b34801561039a57600080fd5b506102fe600435610da6565b3480156103b257600080fd5b506102e4610dc1565b3480156103c757600080fd5b506102e46004351515610e6a565b3480156103e157600080fd5b506103ed600435610ef5565b6040805160ff9092168252519081900360200190f35b34801561040f57600080fd5b506102e4600160a060020a0360043581169060243516604435610f0a565b34801561043957600080fd5b506102e460043561100f565b34801561045157600080fd5b506102e463ffffffff600435166110fb565b34801561046f57600080fd5b5061047b600435611352565b60408051918252519081900360200190f35b34801561049957600080fd5b506102e4600160a060020a0360043516611364565b3480156104ba57600080fd5b506102e4600160a060020a0360043581169060243516604435611466565b3480156104e457600080fd5b506104f0600435611487565b6040805161ffff9092168252519081900360200190f35b34801561051357600080fd5b506102e461149d565b34801561052857600080fd5b50610365600435611647565b34801561054057600080fd5b506102e4600160a060020a0360043516611664565b34801561056157600080fd5b506103656117c9565b34801561057657600080fd5b506102e46117cf565b34801561058b57600080fd5b5061047b600480359060248035600160a060020a03169160443563ffffffff16916064356bffffffffffffffffffffffff1691608435918201910135611c50565b3480156105d857600080fd5b50610365611f51565b3480156105ed57600080fd5b506102e4600435611f5a565b34801561060557600080fd5b506102fe60043561201a565b34801561061d57600080fd5b506102e46004803560248101910135612044565b34801561063d57600080fd5b506102e4600160a060020a0360043516612375565b34801561065e57600080fd5b5061047b600160a060020a0360043516612417565b61047b60048035600160a060020a0316906024803563ffffffff16916044356bffffffffffffffffffffffff169160643590810191013561244a565b3480156106bb57600080fd5b5061047b61270f565b3480156106d057600080fd5b506102e4612715565b3480156106e557600080fd5b506106ee612839565b604051808260068111156106fe57fe5b60ff16815260200191505060405180910390f35b34801561071e57600080fd5b506102e46bffffffffffffffffffffffff60043516612849565b34801561074457600080fd5b506102e463ffffffff6004351661297b565b34801561076257600080fd5b506102e4612ca6565b34801561077757600080fd5b506102e4600160a060020a03600435166024351515612dad565b34801561079d57600080fd5b506102e463ffffffff60043516612e31565b3480156107bb57600080fd5b506102fe600435612efb565b3480156107d357600080fd5b50610365612f16565b3480156107e857600080fd5b506102e4612f24565b3480156107fd57600080fd5b506102e463ffffffff6004351661302d565b34801561081b57600080fd5b506102e4600160a060020a03600435166132ad565b34801561083c57600080fd5b5061047b61333a565b34801561085157600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526102e494600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506133409650505050505050565b61047b600160a060020a0360048035821691602480359091169163ffffffff60443516916bffffffffffffffffffffffff606435169160843591820191013561334b565b34801561090457600080fd5b506102e46004351515613625565b34801561091e57600080fd5b506102fe61368e565b34801561093357600080fd5b506102e461369d565b6102e4600435613746565b34801561095357600080fd5b50610968600160a060020a036004351661392a565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156109a457818101518382015260200161098c565b505050509050019250505060405180910390f35b3480156109c457600080fd5b506102fe613996565b3480156109d957600080fd5b506102e46139a5565b3480156109ee57600080fd5b506109fa600435613a5c565b6040518086600160a060020a0316600160a060020a031681526020018563ffffffff1663ffffffff168152602001846bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020018367ffffffffffffffff1667ffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610a9d578181015183820152602001610a85565b50505050905090810190601f168015610aca5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b348015610ae857600080fd5b50610365600160a060020a0360043581169060243516613b76565b348015610b0f57600080fd5b506104f0600435613ba4565b348015610b2757600080fd5b50610b33600435613bc7565b6040805160ff9485168152928416602084015292168183015290519081900360600190f35b348015610b6457600080fd5b506102fe613bfa565b348015610b7957600080fd5b50610b82613c0f565b6040805161ffff978816815295871660208701529386168585015291851660608501528416608084015290921660a082015290519081900360c00190f35b348015610bcc57600080fd5b506102e4613c5b565b348015610be157600080fd5b5061047b613cff565b348015610bf657600080fd5b5061047b613d05565b600090815260146020526040902054600160a060020a031690565b6000610c258261201a565b9050600160a060020a038381169082161415610c4057600080fd5b33600160a060020a0382161480610c5c5750610c5c8133613b76565b1515610c6757600080fd5b6000828152601460205260408082208054600160a060020a031916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b601660209081526000928352604080842090915290825290205460ff1681565b601754620100009004600160a060020a03163314610d39576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600760009054906101000a9004600160a060020a0316600160a060020a031663cadc027b6040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015610d8c57600080fd5b505af1158015610da0573d6000803e3d6000fd5b50505050565b601360205260009081526040902054600160a060020a031681565b601754620100009004600160a060020a03163314610e17576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600760009054906101000a9004600160a060020a0316600160a060020a03166337dfffcc6040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015610d8c57600080fd5b601754620100009004600160a060020a03163314610ec0576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b6017805460ff191682151590811761ff001916610100918202179182905560ff910416151560011415610ef25742601c555b50565b60056020526000908152604090205460ff1681565b60175460ff1615610f53576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b610f5d3382613d0b565b1515610f6857600080fd5b600160a060020a0383161515610f7d57600080fd5b600160a060020a0382161515610f9257600080fd5b600160a060020a038381169083161415610fab57600080fd5b610fb58382613d6a565b610fbf8382613dcc565b610fc98282613ee6565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b601754620100009004600160a060020a03163314611065576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b601254811061107357600080fd5b600060075460a060020a900460ff16600681111561108d57fe5b14806110b05750600160075460a060020a900460ff1660068111156110ae57fe5b145b15156110bb57600080fd5b60088190556007805460a060020a60ff02191660a060020a179055600980546bffffffffffffffffffffffff191690556110f3613f54565b610ef2613f63565b6017546000908190620100009004600160a060020a03163314611156576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60018060075460a060020a900460ff16600681111561117157fe5b146111b4576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b60125460095463ffffffff640100000000909104811686011611156111d857600080fd5b60085460009081526003602052604090205460095461ffff9091169350640100000000900463ffffffff1691505b60095463ffffffff64010000000090910481168501168210156112a65760008281526003602052604090205461ffff16831080611261575060008281526003602052604090205461ffff168314801561126157506008548211155b1561129b5760098054600163ffffffff6801000000000000000080840482169290920116026bffffffff0000000000000000199091161790555b600190910190611206565b6009805463ffffffff640100000000808304821688018216810267ffffffff00000000199093169290921792839055601254919092049091161415610da05760095468010000000000000000810463ffffffff16780100000000000000000000000000000000000000000000000090910461ffff161461132557600080fd5b50506007805460a060020a60ff021916740200000000000000000000000000000000000000001790555050565b60046020526000908152604090205481565b601754600090620100009004600160a060020a031633146113bd576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b81905080600160a060020a031663037a9d306040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156113fe57600080fd5b505af1158015611412573d6000803e3d6000fd5b505050506040513d602081101561142857600080fd5b5051151561143557600080fd5b60078054600160a060020a03928316600160a060020a03199182161790915560188054939092169216919091179055565b6114828383836020604051908101604052806000815250613340565b505050565b60036020526000908152604090205461ffff1681565b600060608160068060075460a060020a900460ff1660068111156114bd57fe5b14611500576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b33600090815260156020908152604080832080548251818502810185019093528083529397509092909183018282801561155957602002820191906000526020600020905b815481526020019060010190808311611545575b50505050509250600091505b82518210156115d65760046000848481518110151561158057fe5b906020019060200201518152602001908152602001600020548401935060006004600085858151811015156115b157fe5b6020908102909101810151825281019190915260400160002055600190910190611565565b600084116115e357600080fd5b33600160a060020a03166108fc611618620f424061160c8860015461413390919063ffffffff16565b9063ffffffff61415c16565b6040518115909202916000818181858888f19350505050158015611640573d6000803e3d6000fd5b5050505050565b600090815260136020526040902054600160a060020a0316151590565b6018546000908190600160a060020a031633146116cb576040805160e560020a62461bcd02815260206004820152601060248201527f4f6e6c792064617461536f757263652e00000000000000000000000000000000604482015290519081900360640190fd5b5081905060005b601481101561148257600f80546003841691906000196014859003019081106116f757fe5b6000918252602090912001805460ff191660ff92909216919091179055600f80546004600160a060020a03851604600116919060148490036000190190811061173c57fe5b6000918252602090912001805460ff929092166101000261ff0019909216919091179055600f80546008600160a060020a03851604601f16919060001960148590030190811061178857fe5b6000918252602090912001805460ff92909216620100000262ff000019909216919091179055610100600160a060020a0390921691909104906001016116d2565b60015b90565b60006060600080600080600080600080601760029054906101000a9004600160a060020a0316600160a060020a031633600160a060020a031614151561184d576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60038060075460a060020a900460ff16600681111561186857fe5b146118ab576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b60408051601e8082526103e0820190925260009c5090602082016103c0803883395050601254919b5060009a508a9650600d95505060c911156118ed57600a93505b600954608060020a900463ffffffff16841115611be757600954600a80549091608060020a900463ffffffff1690811061192357fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff1692505b6000831115611bab57600e805463ffffffff871690811061196557fe5b6000918252602080832090910154808352600390915260409091205490985061ffff16965060001990920191821580156119b2575060095463ffffffff608060020a909104166000198501145b15611a725785871415611a2857600954600b90608060020a900463ffffffff16601581106119dc57fe5b600a91828204019190066003029054906101000a900462ffffff1662ffffff168b019a50878a8a61ffff16815181101515611a1357fe5b60209081029091010152600190980197611a72565b600954600b90608060020a900463ffffffff1660158110611a4557fe5b600a808204929092015460008b8152600460205260409020929091066003026101000a900462ffffff1690555b63ffffffff851615801590611aad57508587141580611aad575082158015611aad575060095463ffffffff608060020a909104166000198501145b15611b3a57600091505b8861ffff16821015611b0e57611ad78b61ffff8b1663ffffffff61415c16565b600460008c85815181101515611ae957fe5b6020908102909101810151825281019190915260400160002055600190910190611ab7565b60408051601e8082526103e0820190925260009c5090602082016103c080388339019050509950600098505b600954600b90608060020a900463ffffffff1660158110611b5757fe5b600a91828204019190066003029054906101000a900462ffffff1662ffffff168b019a50878a8a61ffff16815181101515611b8e57fe5b602090810290910101526001988901988796509490940193611948565b60098054600163ffffffff608060020a808404821692909201160273ffffffff00000000000000000000000000000000199091161790556118ed565b5050600780547404000000000000000000000000000000000000000060a060020a60ff021990911617905550506009805477ffffffff0000000000000000000000000000000000000000191663ffffffff9290921660a060020a02919091179055505050505050565b6017546000908190819060ff1615611ca0576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b331515611ce5576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b33600090815260156020526040902054606411611d72576040805160e560020a62461bcd02815260206004820152602860248201527f53656e6465722063616e6e6f742068617665206d6f7265207468616e2031303060448201527f20746f6b656e732e000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b635bdb14f04210611dbb576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b6064841115611dc957600080fd5b604080518a81528151908190036020908101909120600081815260059092529190205490925060ff16600114611e49576040805160e560020a62461bcd02815260206004820152600f60248201527f496e76616c6964207365637265742e0000000000000000000000000000000000604482015290519081900360640190fd5b600082815260056020908152604091829020805460ff191690558151601f8701829004820281018201909252858252611e9c918a918a918a918a908a908190840183828082843750614171945050505050565b9050611ea83382614395565b604080513380825260208201849052600160a060020a038b1660608301526bffffffffffffffffffffffff8916608083015263ffffffff8a1660a083015260c09282018381529282018790527fcc7ceaf1ba8bfaf7a8d8aaa8f7026b92859b0a0974c9badd135b883073d4a92b9290918491899189918e918d918f919060e0820187878082843760405192018290039a509098505050505050505050a198975050505050505050565b60175460ff1681565b601754620100009004600160a060020a03163314611fb0576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60028060075460a060020a900460ff166006811115611fcb57fe5b1461200e576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b81611482600e82614410565b600081815260136020526040812054600160a060020a031680151561203e57600080fd5b92915050565b600080600080600080601760029054906101000a9004600160a060020a0316600160a060020a031633600160a060020a03161415156120bb576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60028060075460a060020a900460ff1660068111156120d657fe5b14612119576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b600954600e546801000000000000000090910463ffffffff16908901111561214057600080fd5b600096505b60001988018710156122005788888881811061215d57fe5b9050602002013563ffffffff1663ffffffff169550888888600101818110151561218357fe5b6020908102929092013563ffffffff16600081815260039093526040808420548a855293205490975061ffff9283169216919091119050806121ea57506000858152600360205260408082205488835291205461ffff90811691161480156121ea57508486105b15156121f557600080fd5b600190960195612145565b600e54156122a857600e8054600019810190811061221a57fe5b9060005260206000200154935088886000818110151561223657fe5b6020908102929092013563ffffffff166000818152600390935260408084205488855293205490955061ffff92831692169190911190508061229d57506000838152600360205260408082205486835291205461ffff908116911614801561229d57508284105b15156122a857600080fd5b600091505b878210156122f757600e8989848181106122c357fe5b835460018082018655600095865260209586902092909502939093013563ffffffff169201919091555091909101906122ad565b600954600e546801000000000000000090910463ffffffff16141561236a57600854600e8054600019810190811061232b57fe5b906000526020600020015414151561234257600080fd5b6007805460a060020a60ff021916740300000000000000000000000000000000000000001790555b505050505050505050565b601754620100009004600160a060020a031633146123cb576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600160a060020a03811615156123e057600080fd5b60178054600160a060020a03909216620100000275ffffffffffffffffffffffffffffffffffffffff000019909216919091179055565b6000600160a060020a038216151561242e57600080fd5b50600160a060020a031660009081526015602052604090205490565b601754600090819060ff1615612498576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b6124a06143b4565b3410156124f7576040805160e560020a62461bcd02815260206004820152601760248201527f4574682073656e74206973206e6f7420656e6f7567682e000000000000000000604482015290519081900360640190fd5b33151561253c576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b336000908152601560205260409020546064116125c9576040805160e560020a62461bcd02815260206004820152602860248201527f53656e6465722063616e6e6f742068617665206d6f7265207468616e2031303060448201527f20746f6b656e732e000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b635bdb14f04210612612576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b606483111561262057600080fd5b61265c87878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750614171945050505050565b90506126683382614395565b604080513380825260208201849052600160a060020a038a1660608301526bffffffffffffffffffffffff8816608083015263ffffffff891660a083015260c09282018381529282018690527fc9b6356917c8e6595e04f058f37ae084434790be9b87f82ffe091de4fa9ae6239290918491889188918d918c918e919060e0820187878082843760405192018290039a509098505050505050505050a19695505050505050565b60015481565b601754600090620100009004600160a060020a0316331461276e576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60058060075460a060020a900460ff16600681111561278957fe5b146127cc576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b303191506127e6606461160c84600a63ffffffff61413316565b6002556127ff606461160c84605a63ffffffff61413316565b6001556007805460a060020a60ff0219167406000000000000000000000000000000000000000017905542601b55612835614404565b5050565b60075460a060020a900460ff1681565b601854600090600160a060020a031633146128ae576040805160e560020a62461bcd02815260206004820152601060248201527f4f6e6c792064617461536f757263652e00000000000000000000000000000000604482015290519081900360640190fd5b506011805461ffff80841661ffff199092169190911763ffff00001916620100006bffffffffffffffffffffffff94851681900483811682029290921765ffff000000001916918516819004838116640100000000029290921767ffff00000000000019169185168190048381166601000000000000029290921769ffff000000000000000019169185168190048381166801000000000000000002929092176bffff0000000000000000000019169190941693909304166a010000000000000000000002919091179055565b60175460009081908190620100009004600160a060020a031633146129d8576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60048060075460a060020a900460ff1660068111156129f357fe5b14612a36576040805160e560020a62461bcd028152602060048201819052602482015260008051602061459b833981519152604482015290519081900360640190fd5b60095463ffffffff680100000000000000008204811660a060020a90920481168701161115612a6457600080fd5b600954600a80549091608060020a900463ffffffff16908110612a8357fe5b600091825260208220601082040154600f9091166002026101000a900461ffff16945092505b8463ffffffff16831015612bc65761ffff84161515612b39576009805473ffffffff00000000000000000000000000000000198116608060020a9182900463ffffffff908116600101811683029190911792839055600a805490939290920416908110612b1257fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff1693505b600954600e8054909160a060020a900463ffffffff168501908110612b5a57fe5b600091825260209091200154600954909250600b90608060020a900463ffffffff1660158110612b8657fe5b600a80820492909201546000858152600460205260409020929091066003026101000a900462ffffff169055600019939093019260019290920191612aa9565b6009805463ffffffff60a060020a8083048216890182160277ffffffff0000000000000000000000000000000000000000199092169190911791829055600a805487939192608060020a909204909116908110612c1f57fe5b6000918252602090912060108204018054600f9092166002026101000a61ffff81810219909316939092169190910291909117905560095468010000000000000000810463ffffffff90811660a060020a909204161415611640576007805460a060020a60ff02191674050000000000000000000000000000000000000000179055611640565b601754610100900460ff161515612d07576040805160e560020a62461bcd02815260206004820152601b60248201527f4f6e6c792069662067616d65206861732066696e616c697a65642e0000000000604482015290519081900360640190fd5b601754620100009004600160a060020a03163314612d5d576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b601c5415801590612d755750601c54620d2f00014210155b1515612d8057600080fd5b6040513390303180156108fc02916000818181858888f19350505050158015610ef2573d6000803e3d6000fd5b600160a060020a038216331415612dc357600080fd5b336000818152601660209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b6018546000908190600160a060020a03163314612e98576040805160e560020a62461bcd02815260206004820152601060248201527f4f6e6c792064617461536f757263652e00000000000000000000000000000000604482015290519081900360640190fd5b5081905060005b60058110156114825760108054603f84169190600019600585900301908110612ec457fe5b6000918252602090912001805461ffff191661ffff92909216919091179055604063ffffffff929092169190910490600101612e9f565b601460205260009081526040902054600160a060020a031681565b601754610100900460ff1681565b601754600090620100009004600160a060020a03163314612f7d576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b601b5415801590612f955750601b546213c680014210155b1515612feb576040805160e560020a62461bcd02815260206004820152601a60248201527f4f6e6c792069662067616d65206861732066696e69736865642e000000000000604482015290519081900360640190fd5b50601754604051303191620100009004600160a060020a03169082156108fc029083906000818181858888f19350505050158015612835573d6000803e3d6000fd5b601b5460009081901561303f57600080fd5b60125460095463ffffffff6401000000009091048116850116111561306357600080fd5b60095463ffffffff1691505b60095463ffffffff90811684011682101561328a57732e2ae45a3e2ff04a441e043be45dfba3f7a083ed63f9ebe6cb6012848154811015156130ad57fe5b600091825260209091206003909102015460128054600160a060020a0390921691869081106130d857fe5b906000526020600020906003020160000160149054906101000a900463ffffffff1660128681548110151561310957fe5b906000526020600020906003020160010160009054906101000a90046bffffffffffffffffffffffff16600f6011601060006040518863ffffffff1660e060020a0281526004018088600160a060020a0316600160a060020a031681526020018763ffffffff1663ffffffff168152602001866bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200185815260200184815260200183815260200180602001828103825283818154815260200191508054801561321057602002820191906000526020600020906000905b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116131df5790505b50509850505050505050505060206040518083038186803b15801561323457600080fd5b505af4158015613248573d6000803e3d6000fd5b505050506040513d602081101561325e57600080fd5b50516000838152600360205260409020805461ffff191661ffff8316179055600190920191905061306f565b50506009805463ffffffff19811663ffffffff9182169390930116919091179055565b601754620100009004600160a060020a03163314613303576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600160a060020a038116151561331857600080fd5b60198054600160a060020a031916600160a060020a0392909216919091179055565b60025481565b610da0848484610f0a565b601754600090819060ff1615613399576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b6133a16143b4565b3410156133f8576040805160e560020a62461bcd02815260206004820152601760248201527f4574682073656e74206973206e6f7420656e6f7567682e000000000000000000604482015290519081900360640190fd5b33151561343d576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b600160a060020a0388166000908152601560205260409020546064116134d3576040805160e560020a62461bcd02815260206004820152602860248201527f53656e6465722063616e6e6f742068617665206d6f7265207468616e2031303060448201527f20746f6b656e732e000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b635bdb14f0421061351c576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b606483111561352a57600080fd5b61356687878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750614171945050505050565b90506135728882614395565b6040805133808252600160a060020a03808c16602084015292820184905291891660808201526bffffffffffffffffffffffff871660a082015263ffffffff881660c082015260e0606082018181529082018690527fd224a9a732ef51c0945b6f3d79bda4f9b5ef8b81a967d7ea8e63575c9e0c7f9492918b918591899189918e918d918f91610100820187878082843760405192018290039b50909950505050505050505050a1979650505050505050565b601754620100009004600160a060020a0316331461367b576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b6017805460ff1916911515919091179055565b601854600160a060020a031681565b601754620100009004600160a060020a031633146136f3576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b600760009054906101000a9004600160a060020a0316600160a060020a03166313bb13116040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015610d8c57600080fd5b601754620100009004600160a060020a0316331461379c576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b60175460ff16156137e5576040805160e560020a62461bcd02815260206004820152601360248201526000805160206145bb833981519152604482015290519081900360640190fd5b6137ed6143b4565b341015613844576040805160e560020a62461bcd02815260206004820152601760248201527f4574682073656e74206973206e6f7420656e6f7567682e000000000000000000604482015290519081900360640190fd5b331515613889576040805160e560020a62461bcd02815260206004820152601b602482015260008051602061453b833981519152604482015290519081900360640190fd5b635bdb14f042106138d2576040805160e560020a62461bcd028152602060048201526016602482015260008051602061457b833981519152604482015290519081900360640190fd5b600081815260056020908152604091829020805460ff19166001179055815133815290810183905281517f5af1975c023a376dd6e2d2a7d941656d6014c52ec7793a6fcbc82358099b6803929181900390910190a150565b600160a060020a03811660009081526015602090815260409182902080548351818402810184019094528084526060939283018282801561398a57602002820191906000526020600020905b815481526020019060010190808311613976575b50505050509050919050565b601954600160a060020a031681565b601754600090610100900460ff161515613a09576040805160e560020a62461bcd02815260206004820152601b60248201527f4f6e6c792069662067616d65206861732066696e616c697a65642e0000000000604482015290519081900360640190fd5b50336000908152601560205260408120805466b1a2bc2ec500000291613a2f9190614434565b604051339082156108fc029083906000818181858888f19350505050158015612835573d6000803e3d6000fd5b60008060008060606000601287815481101515613a7557fe5b6000918252602091829020600391909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f8101889004880285018801909252818452600160a060020a0385169c5060a060020a90940463ffffffff169a506bffffffffffffffffffffffff821699506c0100000000000000000000000090910467ffffffffffffffff16975092945092909190830182828015613b655780601f10613b3a57610100808354040283529160200191613b65565b820191906000526020600020905b815481529060010190602001808311613b4857829003601f168201915b505050505091505091939590929450565b600160a060020a03918216600090815260166020908152604080832093909416825291909152205460ff1690565b6010805482908110613bb257fe5b60009182526020909120015461ffff16905081565b600f805482908110613bd557fe5b60009182526020909120015460ff808216925061010082048116916201000090041683565b601754620100009004600160a060020a031681565b60115461ffff808216916201000081048216916401000000008204811691660100000000000081048216916801000000000000000082048116916a010000000000000000000090041686565b601754600090620100009004600160a060020a03163314613cb4576040805160e560020a62461bcd02815260206004820152600b602482015260008051602061455b833981519152604482015290519081900360640190fd5b5060028054600091829055601754604051919262010000909104600160a060020a0316916108fc84150291849190818181858888f19350505050158015612835573d6000803e3d6000fd5b601c5481565b601b5481565b600080613d178361201a565b905080600160a060020a031684600160a060020a03161480613d52575083600160a060020a0316613d4784610bff565b600160a060020a0316145b80613d625750613d628185613b76565b949350505050565b81600160a060020a0316613d7d8261201a565b600160a060020a031614613d9057600080fd5b600081815260146020526040902054600160a060020a0316156128355760009081526014602052604090208054600160a060020a031916905550565b60008083600160a060020a0316613de28461201a565b600160a060020a031614613df557600080fd5b600160a060020a038416600090815260156020526040902054606411613e1a57600080fd5b505060008181526013602090815260408083208054600160a060020a0319169055600160a060020a038516835260159091528120905b8154811015613eb957828282815481101515613e6857fe5b90600052602060002001541415613eb157815482906000198101908110613e8b57fe5b90600052602060002001548282815481101515613ea457fe5b6000918252602090912001555b600101613e50565b815482906000198101908110613ecb57fe5b60009182526020822001558154611640836000198301614410565b600081815260136020526040902054600160a060020a031615613f0857600080fd5b60008181526013602090815260408083208054600160a060020a03909616600160a060020a03199096168617905593825260158152928120805460018101825590825292902090910155565b6017805460ff19166001179055565b613f6b614452565b600073fab06e5f52820a397f1b9c79e59c84897e168813633b345a876012805490506040518263ffffffff1660e060020a028152600401808281526020019150506102a06040518083038186803b158015613fc557600080fd5b505af4158015613fd9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102a0811015613fff57600080fd5b509150600090505b60158110156140625781816015811061401c57fe5b6020020151600b826015811061402e57fe5b600a91828204019190066003026101000a81548162ffffff021916908362ffffff1602179055508080600101915050614007565b73fab06e5f52820a397f1b9c79e59c84897e16881363ec8263996012805490506040518263ffffffff1660e060020a0281526004018082815260200191505060206040518083038186803b1580156140b957600080fd5b505af41580156140cd573d6000803e3d6000fd5b505050506040513d60208110156140e357600080fd5b50516009805461ffff90921678010000000000000000000000000000000000000000000000000279ffff000000000000000000000000000000000000000000000000199092169190911790555050565b60008215156141445750600061203e565b5081810281838281151561415457fe5b041461203e57fe5b6000818381151561416957fe5b049392505050565b600061417b614472565b506040805160a081018252600160a060020a03878116825263ffffffff87811660208085019182526bffffffffffffffffffffffff8981169686019687524267ffffffffffffffff90811660608801908152608088018b815260128054600180820180845560009384528c517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444600390940293840180549b51600160a060020a0319909c1691909d161777ffffffff0000000000000000000000000000000000000000191660a060020a9a909b1699909902999099178a559a517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34458c01805494516bffffffffffffffffffffffff19909516919096161773ffffffffffffffff00000000000000000000000019166c010000000000000000000000009390941692909202929092179092555180519697919694959394889493614302937fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3446019201906144a2565b50505003905063ffffffff8116811461438b576040805160e560020a62461bcd02815260206004820152602560248201527f4661696c656420746f20636f6e7665727420746f6b656e496420746f2075696e60448201527f743235362e000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b9695505050505050565b600160a060020a03821615156143aa57600080fd5b6128358282613ee6565b6000635bd088f042106143d0575067011c37937e0800006143da565b5066b1a2bc2ec500005b66b1a2bc2ec5000081101580156143f9575067011c37937e0800008111155b15156117cc57600080fd5b6017805460ff19169055565b81548183558181111561148257600083815260209020611482918101908301614520565b5080546000825590600052602060002090810190610ef29190614520565b6102a0604051908101604052806015906020820280388339509192915050565b6040805160a081018252600080825260208201819052918101829052606080820192909252608081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106144e357805160ff1916838001178555614510565b82800160010185558215614510579182015b828111156145105782518255916020019190600101906144f5565b5061451c929150614520565b5090565b6117cc91905b8082111561451c5760008155600101614526560053656e6465722063616e6e6f74206265203020616464726573732e00000000004f6e6c792061646d696e2e0000000000000000000000000000000000000000004576656e7420616c726561647920737461727465642e00000000000000000000506f696e74732076616c69646174696f6e20737461676520696e76616c69642e4f6e6c79206966206e6f74207061757365642e00000000000000000000000000a165627a7a72305820e1378936021c34c8727a49e5ce6ccb1e23120da769c9f755a61123be90acb2f90029

Libraries Used

PayoutDistribution : 0xfab06e5f52820a397f1b9c79e59c84897e168813Unverified
PointsCalculator : 0x2e2ae45a3e2ff04a441e043be45dfba3f7a083edUnverified

Swarm Source

bzzr://e1378936021c34c8727a49e5ce6ccb1e23120da769c9f755a61123be90acb2f9

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.