Contract 0x054DF44d9BF67E87E09De919086bf12633f6BcF5 1

 
 
Txn Hash
Method
Block
From
To
Value
0x9cf5e2c1239932c6024e93490ce06ad0ee7f0de7b1c0521b1faeb3aee8022fecApprove73311842019-03-08 22:15:311421 days 5 hrs ago0xc673a105d1814d4fc6a55eb93ae3265d914e5f5e IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0004617610
0x7c8e4d826eca613cd586578cd3c7746b8ef463cbcd005582f181988e6b2c0f56Build Token69197672018-12-20 8:33:331499 days 18 hrs ago0xbe6a8a2d8d2d2329e9a5fd1f23b15520fa8b368b IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50.075 Ether0.0005816121
0x8bdcad31d791cb65aa2760190579f941c38b3c0c43ba3fec41c9e7a9da0ca546Build Token68256882018-12-04 17:00:561515 days 10 hrs ago0x94086fcdd0dc18088661aecd819b19550f254427 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50.15 Ether0.000143655
0xc9a0b2f6e032cf22d815b29dd34e95ebfa63646aa0fa123f76b42be866953008Finished Game Wi...61892892018-08-21 20:21:361620 days 6 hrs ago0xfb0054a61b79e9973e84d801a64ddfd2ea5dc947 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.00015755
0x1d6bbd8c8179261391eaf1d2df73fc5157c772be9893b4fae8fc441664dce7c7Withdraw Prize61519602018-08-15 12:54:181626 days 14 hrs ago0x3e8c23da7de275c838f5b5361f2ec274f9ae95c0 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002183910
0x71f3ff7e425db37601b715089c9b58b32d63e7d44d1d4f79525276a49fbadefdApprove61352042018-08-12 17:06:301629 days 10 hrs ago0xdcd51d2b6595a1b1a289d530d28da0846210321d IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0004617610
0x16e174a6ccf9fe69d60d4eb173efda20b11a1be893c649f9559aa5ddb0b02dbfApprove61185902018-08-09 21:31:491632 days 5 hrs ago0xc24f2066f6f8033771e92d4837f3cc27bc1a7542 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0004617610
0x811b89963c127e14b419b6b3067f0e21835e2abc7aa3c3f9e0d88b15622bdb5bWithdraw Prize61133502018-08-09 0:13:521633 days 3 hrs ago0x29e0a3195a4a721a9938037f65b926b71496de20 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0007022121
0x821364018c678655903d98789cd111c4c69b20cc0743a81aa5a36eb12b948161Withdraw Prize61066862018-08-07 21:23:171634 days 5 hrs ago0x36bb63a1966a3412d98803b9937372307170768e IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0003316612
0xcf17a862835befa4986ffb3f5b8d226bbf51d2fd66f5c7902d23eae9059b2a8dWithdraw Prize61000022018-08-06 18:03:461635 days 9 hrs ago0x2e3a5f60a5590959b068587c47e643e18e7f5cdf IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0003343910
0xc3d6c68986ea7c7776cbba9f923214894d112724e1a8034eefd185fbb8507c9bWithdraw Prize60963812018-08-06 3:29:111635 days 23 hrs ago0xf958964e4c23ee70a85643da4cdd7cfd5353a893 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.00002621.2
0x96666cb1834907d8cab6f1e15759612948380d4ca40ab244701972576b841a12Build Token60816862018-08-03 16:18:591638 days 11 hrs ago0x03746c753f1fe3ad3b28371422108c14e8b1ea48 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50.045 Ether0.0005577620
0xb00620b76414a1c54e2c8452844579317465e990f06f8f34946887511074a3d7Withdraw Prize60809512018-08-03 13:19:021638 days 14 hrs ago0x303c824d64f58dcaf2da3903ca157d53a32a8970 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002183910
0xfb9be6d2e79f403b3d0cf6606f013727114dd8ed6eb035681d453ce55042da7cWithdraw Prize60734572018-08-02 6:30:121639 days 20 hrs ago0x0f8a313087bf0975a4189851c3a0786cd4983db6 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.000213210
0xdc5a381125114dba7eb2c12181b829e923a23cdbd2b3825a959432c69560d8f9Withdraw Prize60652972018-07-31 21:20:031641 days 5 hrs ago0x98a529e3488c2d44566881feab335b17b1c3b430 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.000120084
0xe0b1751c7ba63bed0e7d1a8941c4f727cd32381234ce594bc5b7cda63404b0b4Withdraw Prize60622882018-07-31 9:17:301641 days 18 hrs ago0x632df7fb06c4e61ec58626e5cd6f2c9d6b3c54fb IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0003583910
0xc9443c6488c398055e54709c670165c0b5f098f628a5cc77a69ba92e3ff53d29Withdraw Prize60602632018-07-31 0:47:501642 days 2 hrs ago0x41d3deae4e9cab7de5755992e957f6e775d773ea IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002763910
0x5572e9c5d7bc0659f889a05098e07bcf0420bd4b4feb9c14bd875d8b016983fbWithdraw Prize60577532018-07-30 14:42:421642 days 12 hrs ago0x1519465a9d2f3da7a788a4c4d37c37ef3544d4ee IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002183910
0x46ae1c23dd33e8267b6200d5342a2b0c9c256a8115598ec9b489f155111f616dWithdraw Prize60567232018-07-30 10:34:491642 days 16 hrs agoSybil Delegate: SolidityDev IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002620612
0x9a7c2370bf7c1d356037ef94629cfed6c4c48a1a2bf06ad063b26f42a0d19495Withdraw Prize60536842018-07-29 22:23:161643 days 4 hrs ago0xd4b16837cf28f4d2c9c4922414ac36224a3759a7 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002183910
0x9afe9b0c2c5d6af0663c6dfd4022b9f29de9b32f37213bf2e067988324182d86Withdraw Prize60521102018-07-29 16:04:001643 days 11 hrs ago0x1eea537b3cc42db38aa388ea46e83e50085ba77f IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002763910
0xaca1d7c6dc63f5571d377d5568605566d2e714b235012af072c87bc7dd0bfd18Withdraw Prize60475262018-07-28 21:59:491644 days 5 hrs ago0xeecef7df3d319d7efed0786987e5a86114c0349d IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0002183910
0x18e0856b22b40d807a2535ba9fb1e3c524edbaeaf47feb8c07639efca332c50dApprove60459412018-07-28 15:33:351644 days 11 hrs ago0x17b236c40920cde73aa3e98687f88bd356c1a6d1 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0003117610
0xb90ee596c2d127c543c2143ede3e867afc01023b8051ef1c6a0da7ef7ed6c6e7Withdraw Prize60459402018-07-28 15:33:311644 days 11 hrs ago0x687dac4ceabe3b197f333f461a32b89b55f166cb IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.000109195
0x6c44bfa984929baa135c3c18597a46b8114bf2b0e541fcc079d196f28852d60dApprove60459392018-07-28 15:33:141644 days 11 hrs ago0x17b236c40920cde73aa3e98687f88bd356c1a6d1 IN  0x054df44d9bf67e87e09de919086bf12633f6bcf50 Ether0.0004617610
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xc9a0b2f6e032cf22d815b29dd34e95ebfa63646aa0fa123f76b42be86695300861892892018-08-21 20:21:361620 days 6 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50xfb0054a61b79e9973e84d801a64ddfd2ea5dc94717.80271089 Ether
0x1d6bbd8c8179261391eaf1d2df73fc5157c772be9893b4fae8fc441664dce7c761519602018-08-15 12:54:181626 days 14 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x3e8c23da7de275c838f5b5361f2ec274f9ae95c00.29690035 Ether
0x811b89963c127e14b419b6b3067f0e21835e2abc7aa3c3f9e0d88b15622bdb5b61133502018-08-09 0:13:521633 days 3 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x29e0a3195a4a721a9938037f65b926b71496de200.15269161 Ether
0x821364018c678655903d98789cd111c4c69b20cc0743a81aa5a36eb12b94816161066862018-08-07 21:23:171634 days 5 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x36bb63a1966a3412d98803b9937372307170768e0.21207168 Ether
0xcf17a862835befa4986ffb3f5b8d226bbf51d2fd66f5c7902d23eae9059b2a8d61000022018-08-06 18:03:461635 days 9 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x2e3a5f60a5590959b068587c47e643e18e7f5cdf0.15269161 Ether
0xc3d6c68986ea7c7776cbba9f923214894d112724e1a8034eefd185fbb8507c9b60963812018-08-06 3:29:111635 days 23 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50xf958964e4c23ee70a85643da4cdd7cfd5353a8930.29690035 Ether
0xb00620b76414a1c54e2c8452844579317465e990f06f8f34946887511074a3d760809512018-08-03 13:19:021638 days 14 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x303c824d64f58dcaf2da3903ca157d53a32a89701.86198937 Ether
0xfb9be6d2e79f403b3d0cf6606f013727114dd8ed6eb035681d453ce55042da7c60734572018-08-02 6:30:121639 days 20 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x0f8a313087bf0975a4189851c3a0786cd4983db60.33931469 Ether
0xdc5a381125114dba7eb2c12181b829e923a23cdbd2b3825a959432c69560d8f960652972018-07-31 21:20:031641 days 5 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x98a529e3488c2d44566881feab335b17b1c3b4300.57683497 Ether
0xe0b1751c7ba63bed0e7d1a8941c4f727cd32381234ce594bc5b7cda63404b0b460622882018-07-31 9:17:301641 days 18 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x632df7fb06c4e61ec58626e5cd6f2c9d6b3c54fb0.44959196 Ether
0xc9443c6488c398055e54709c670165c0b5f098f628a5cc77a69ba92e3ff53d2960602632018-07-31 0:47:501642 days 2 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x41d3deae4e9cab7de5755992e957f6e775d773ea0.15269161 Ether
0x5572e9c5d7bc0659f889a05098e07bcf0420bd4b4feb9c14bd875d8b016983fb60577532018-07-30 14:42:421642 days 12 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x1519465a9d2f3da7a788a4c4d37c37ef3544d4ee0.16965734 Ether
0x46ae1c23dd33e8267b6200d5342a2b0c9c256a8115598ec9b489f155111f616d60567232018-07-30 10:34:491642 days 16 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf5Sybil Delegate: SolidityDev0.15269161 Ether
0x9a7c2370bf7c1d356037ef94629cfed6c4c48a1a2bf06ad063b26f42a0d1949560536842018-07-29 22:23:161643 days 4 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50xd4b16837cf28f4d2c9c4922414ac36224a3759a70.29690035 Ether
0x9afe9b0c2c5d6af0663c6dfd4022b9f29de9b32f37213bf2e067988324182d8660521102018-07-29 16:04:001643 days 11 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x1eea537b3cc42db38aa388ea46e83e50085ba77f0.15269161 Ether
0xaca1d7c6dc63f5571d377d5568605566d2e714b235012af072c87bc7dd0bfd1860475262018-07-28 21:59:491644 days 5 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50xeecef7df3d319d7efed0786987e5a86114c0349d0.15269161 Ether
0xb90ee596c2d127c543c2143ede3e867afc01023b8051ef1c6a0da7ef7ed6c6e760459402018-07-28 15:33:311644 days 11 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x687dac4ceabe3b197f333f461a32b89b55f166cb0.15269161 Ether
0x39cb4b1888ece1a7c6a81043d9e3de1c74fbe6541c0a9b11d92751c2c7f6ed6560453212018-07-28 13:01:401644 days 14 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x385a011398aea094c471646054412967593efbf50.32234895 Ether
0x1bf3bf5193c97f8ce3ed7cc16cb5906ee0275c7d8700f5061109690a1f1ff79b60427102018-07-28 2:26:591645 days 52 mins ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x712580f69add59bce05673534f608d3ade81f8d30.30538322 Ether
0xa7a022ffcd06258da0b35d3596ab7400c26a167cd0dc71eb30feab95e96e8e5e60420802018-07-27 23:56:381645 days 3 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50xb4bf60c6a8ae4dbe04eea3901221c1adc8444ad70.16965734 Ether
0xc833a76015b590f270375437058eea223fff1890fc52ed916bf3fc5bf1373a0960418072018-07-27 22:51:091645 days 4 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf5ENS Name vasarhelyi.eth0.30538322 Ether
0x17d3b092a08f034bf1430acade07dbba330bce6d404cbe30ee783c571580627f60411022018-07-27 20:06:381645 days 7 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50xe474d300b9b0142c21014957ced9106dc4f144cb0.21207168 Ether
0x4b1de6aca9750127463e225d0944de41ca73e18ce65b0c1fb975ee10bccf668460408122018-07-27 19:01:021645 days 8 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x53a00c4086467e3f0aa573c7ab8edde520cf99fa0.30538322 Ether
0x5df967098588a78466e72ebd4607f6b461e33189c6aadf3cc4815384c70b8f0e60391192018-07-27 12:03:281645 days 15 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf5ENS Name 0xlunacat.eth0.38172902 Ether
0xe6e97dc591169cb086b5a2cf5ec487060e3b79c7e67eebf3b5705286409b0ecc60373132018-07-27 4:36:561645 days 22 hrs ago 0x054df44d9bf67e87e09de919086bf12633f6bcf50x94086fcdd0dc18088661aecd819b19550f2544270.15269161 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CoreLayer

Compiler Version
v0.4.18+commit.9cf6e910

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-05-22
*/

pragma solidity ^0.4.18;


contract DataSourceInterface {

    function isDataSource() public pure returns (bool);

    function getGroupResult(uint matchId) external;
    function getRoundOfSixteenTeams(uint index) external;
    function getRoundOfSixteenResult(uint matchId) external;
    function getQuarterResult(uint matchId) external;
    function getSemiResult(uint matchId) external;
    function getFinalTeams() external;
    function getYellowCards() external;
    function getRedCards() external;

}


/**
* @title DataLayer.
* @author CryptoCup Team (https://cryptocup.io/about)
*/
contract DataLayer{

    
    uint256 constant WCCTOKEN_CREATION_LIMIT = 5000000;
    uint256 constant STARTING_PRICE = 45 finney;
    
    /// Epoch times based on when the prices change.
    uint256 constant FIRST_PHASE  = 1527476400;
    uint256 constant SECOND_PHASE = 1528081200;
    uint256 constant THIRD_PHASE  = 1528686000;
    uint256 constant WORLD_CUP_START = 1528945200;

    DataSourceInterface public dataSource;
    address public dataSourceAddress;

    address public adminAddress;
    uint256 public deploymentTime = 0;
    uint256 public gameFinishedTime = 0; //set this to now when oraclize was called.
    uint32 public lastCalculatedToken = 0;
    uint256 public pointsLimit = 0;
    uint32 public lastCheckedToken = 0;
    uint32 public winnerCounter = 0;
    uint32 public lastAssigned = 0;
    uint256 public auxWorstPoints = 500000000;
    uint32 public payoutRange = 0;
    uint32 public lastPrizeGiven = 0;
    uint256 public prizePool = 0;
    uint256 public adminPool = 0;
    uint256 public finalizedTime = 0;

    enum teamState { None, ROS, QUARTERS, SEMIS, FINAL }
    enum pointsValidationState { Unstarted, LimitSet, LimitCalculated, OrderChecked, TopWinnersAssigned, WinnersAssigned, Finished }
    
    /**
    * groups1     scores of the first half of matches (8 bits each)
    * groups2     scores of the second half of matches (8 bits each)
    * brackets    winner's team ids of each round (5 bits each)
    * timeStamp   creation timestamp
    * extra       number of yellow and red cards (16 bits each)
    */
    struct Token {
        uint192 groups1;
        uint192 groups2;
        uint160 brackets;
        uint64 timeStamp;
        uint32  extra;
    }

    struct GroupResult{
        uint8 teamOneGoals;
        uint8 teamTwoGoals;
    }

    struct BracketPhase{
        uint8[16] roundOfSixteenTeamsIds;
        mapping (uint8 => bool) teamExists;
        mapping (uint8 => teamState) middlePhaseTeamsIds;
        uint8[4] finalsTeamsIds;
    }

    struct Extras {
        uint16 yellowCards;
        uint16 redCards;
    }

    
    // List of all tokens
    Token[] tokens;

    GroupResult[48] groupsResults;
    BracketPhase bracketsResults;
    Extras extraResults;

    // List of all tokens that won 
    uint256[] sortedWinners;

    // List of the worst tokens (they also win)
    uint256[] worstTokens;
    pointsValidationState public pValidationState = pointsValidationState.Unstarted;

    mapping (address => uint256[]) public tokensOfOwnerMap;
    mapping (uint256 => address) public ownerOfTokenMap;
    mapping (uint256 => address) public tokensApprovedMap;
    mapping (uint256 => uint256) public tokenToPayoutMap;
    mapping (uint256 => uint16) public tokenToPointsMap;    


    event LogTokenBuilt(address creatorAddress, uint256 tokenId, Token token);
    event LogDataSourceCallbackList(uint8[] result);
    event LogDataSourceCallbackInt(uint8 result);
    event LogDataSourceCallbackTwoInt(uint8 result, uint8 result2);

}


///Author Dieter Shirley (https://github.com/dete)
contract ERC721 {

    event LogTransfer(address from, address to, uint256 tokenId);
    event LogApproval(address owner, address approved, uint256 tokenId);

    function name() public view returns (string);
    function symbol() public view returns (string);
    function totalSupply() public view returns (uint256 total);
    function balanceOf(address _owner) public view returns (uint256 balance);
    function ownerOf(uint256 _tokenId) external view returns (address owner);
    function approve(address _to, uint256 _tokenId) external;
    function transfer(address _to, uint256 _tokenId) external;
    function transferFrom(address _from, address _to, uint256 _tokenId) external;
    function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds);

}












/**
* @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 AccessControlLayer is DataLayer{

    bool public paused = false;
    bool public finalized = false;
    bool public saleOpen = true;

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

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

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

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

    /**
    * @dev Modifier that checks that the contract has finalized
    */
    modifier hasFinalized() {
        require(finalized);
        _;
    }

    /**
    * @dev Checks if pValidationState is in the provided stats
    * @param state State required to run
    */
    modifier checkState(pointsValidationState state){
        require(pValidationState == state);
        _;
    }

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

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

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

/**
* @title CryptoCupToken, main implemantations of the ERC721 standard
* @author CryptoCup Team (https://cryptocup.io/about)
*/
contract CryptocupToken is AccessControlLayer, ERC721 {

    //FUNCTIONALTIY
    /**
    * @notice checks if a user owns a token
    * @param userAddress - The address to check.
    * @param tokenId - ID of the token that needs to be verified.
    * @return true if the userAddress provided owns the token.
    */
    function _userOwnsToken(address userAddress, uint256 tokenId) internal view returns (bool){

         return ownerOfTokenMap[tokenId] == userAddress;

    }

    /**
    * @notice checks if the address provided is approved for a given token 
    * @param userAddress 
    * @param tokenId 
    * @return true if it is aproved
    */
    function _tokenIsApproved(address userAddress, uint256 tokenId) internal view returns (bool) {

        return tokensApprovedMap[tokenId] == userAddress;
    }

    /**
    * @notice transfers the token specified from sneder address to receiver address.
    * @param fromAddress the sender address that initially holds the token.
    * @param toAddress the receipient of the token.
    * @param tokenId ID of the token that will be sent.
    */
    function _transfer(address fromAddress, address toAddress, uint256 tokenId) internal {

      require(tokensOfOwnerMap[toAddress].length < 100);
      require(pValidationState == pointsValidationState.Unstarted);
      
      tokensOfOwnerMap[toAddress].push(tokenId);
      ownerOfTokenMap[tokenId] = toAddress;

      uint256[] storage tokenArray = tokensOfOwnerMap[fromAddress];
      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--;

      delete tokensApprovedMap[tokenId];

    }

    /**
    * @notice Approve the address for a given token
    * @param tokenId - ID of token to be approved
    * @param userAddress - Address that will be approved
    */
    function _approve(uint256 tokenId, address userAddress) internal {
        tokensApprovedMap[tokenId] = userAddress;
    }

    /**
    * @notice set token owner to an address
    * @dev sets token owner on the contract data structures
    * @param ownerAddress address to be set
    * @param tokenId Id of token to be used
    */
    function _setTokenOwner(address ownerAddress, uint256 tokenId) internal{

    	tokensOfOwnerMap[ownerAddress].push(tokenId);
      ownerOfTokenMap[tokenId] = ownerAddress;
    
    }

    //ERC721 INTERFACE
    function name() public view returns (string){
      return "Cryptocup";
    }

    function symbol() public view returns (string){
      return "CC";
    }

    
    function balanceOf(address userAddress) public view returns (uint256 count) {
      return tokensOfOwnerMap[userAddress].length;

    }

    function transfer(address toAddress,uint256 tokenId) external isNotPaused {

      require(toAddress != address(0));
      require(toAddress != address(this));
      require(_userOwnsToken(msg.sender, tokenId));

      _transfer(msg.sender, toAddress, tokenId);
      LogTransfer(msg.sender, toAddress, tokenId);

    }


    function transferFrom(address fromAddress, address toAddress, uint256 tokenId) external isNotPaused {

      require(toAddress != address(0));
      require(toAddress != address(this));
      require(_tokenIsApproved(msg.sender, tokenId));
      require(_userOwnsToken(fromAddress, tokenId));

      _transfer(fromAddress, toAddress, tokenId);
      LogTransfer(fromAddress, toAddress, tokenId);

    }

    function approve( address toAddress, uint256 tokenId) external isNotPaused {

        require(toAddress != address(0));
        require(_userOwnsToken(msg.sender, tokenId));

        _approve(tokenId, toAddress);
        LogApproval(msg.sender, toAddress, tokenId);

    }

    function totalSupply() public view returns (uint) {

        return tokens.length;

    }

    function ownerOf(uint256 tokenId) external view returns (address ownerAddress) {

        ownerAddress = ownerOfTokenMap[tokenId];
        require(ownerAddress != address(0));

    }

    function tokensOfOwner(address ownerAddress) external view returns(uint256[] tokenIds) {

        tokenIds = tokensOfOwnerMap[ownerAddress];

    }

}



/**
 * @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) {
    if (a == 0) {
      return 0;
    }
    uint256 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 c;
  }

  /**
  * @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) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}


/**
* @title GameLogicLayer, contract in charge of everything related to calculating points, asigning
* winners, and distributing prizes.
* @author CryptoCup Team (https://cryptocup.io/about)
*/
contract GameLogicLayer is CryptocupToken{

    using SafeMath for *;

    uint8 TEAM_RESULT_MASK_GROUPS = 15;
    uint160 RESULT_MASK_BRACKETS = 31;
    uint16 EXTRA_MASK_BRACKETS = 65535;

    uint16 private lastPosition;
    uint16 private superiorQuota;
    
    uint16[] private payDistributionAmount = [1,1,1,1,1,1,1,1,1,1,5,5,10,20,50,100,100,200,500,1500,2500];
    uint32[] private payoutDistribution;

	event LogGroupDataArrived(uint matchId, uint8 result, uint8 result2);
    event LogRoundOfSixteenArrived(uint id, uint8 result);
    event LogMiddlePhaseArrived(uint matchId, uint8 result);
    event LogFinalsArrived(uint id, uint8[4] result);
    event LogExtrasArrived(uint id, uint16 result);
    
    //ORACLIZE
    function dataSourceGetGroupResult(uint matchId) external onlyAdmin{
        dataSource.getGroupResult(matchId);
    }

    function dataSourceGetRoundOfSixteen(uint index) external onlyAdmin{
        dataSource.getRoundOfSixteenTeams(index);
    }

    function dataSourceGetRoundOfSixteenResult(uint matchId) external onlyAdmin{
        dataSource.getRoundOfSixteenResult(matchId);
    }

    function dataSourceGetQuarterResult(uint matchId) external onlyAdmin{
        dataSource.getQuarterResult(matchId);
    }
    
    function dataSourceGetSemiResult(uint matchId) external onlyAdmin{
        dataSource.getSemiResult(matchId);
    }

    function dataSourceGetFinals() external onlyAdmin{
        dataSource.getFinalTeams();
    }

    function dataSourceGetYellowCards() external onlyAdmin{
        dataSource.getYellowCards();
    }

    function dataSourceGetRedCards() external onlyAdmin{
        dataSource.getRedCards();
    }

    /**
    * @notice sets a match result to the contract storage
    * @param matchId id of match to check
    * @param result number of goals the first team scored
    * @param result2 number of goals the second team scored
    */
    
    function dataSourceCallbackGroup(uint matchId, uint8 result, uint8 result2) public {

        require (msg.sender == dataSourceAddress);
        require (matchId >= 0 && matchId <= 47);

        groupsResults[matchId].teamOneGoals = result;
        groupsResults[matchId].teamTwoGoals = result2;

        LogGroupDataArrived(matchId, result, result2);

    }

    /**
    * @notice sets the sixteen teams that made it through groups to the contract storage
    * @param id index of sixteen teams
    * @param result results to be set
    */

    function dataSourceCallbackRoundOfSixteen(uint id, uint8 result) public {

        require (msg.sender == dataSourceAddress);

        bracketsResults.roundOfSixteenTeamsIds[id] = result;
        bracketsResults.teamExists[result] = true;
        
        LogRoundOfSixteenArrived(id, result);

    }

    function dataSourceCallbackTeamId(uint matchId, uint8 result) public {
        require (msg.sender == dataSourceAddress);

        teamState state = bracketsResults.middlePhaseTeamsIds[result];

        if (matchId >= 48 && matchId <= 55){
            if (state < teamState.ROS)
                bracketsResults.middlePhaseTeamsIds[result] = teamState.ROS;
        } else if (matchId >= 56 && matchId <= 59){
            if (state < teamState.QUARTERS)
                bracketsResults.middlePhaseTeamsIds[result] = teamState.QUARTERS;
        } else if (matchId == 60 || matchId == 61){
            if (state < teamState.SEMIS)
                bracketsResults.middlePhaseTeamsIds[result] = teamState.SEMIS;
        }

        LogMiddlePhaseArrived(matchId, result);
    }

    /**
    * @notice sets the champion, second, third and fourth teams to the contract storage
    * @param id 
    * @param result ids of the four teams
    */
    function dataSourceCallbackFinals(uint id, uint8[4] result) public {

        require (msg.sender == dataSourceAddress);

        uint256 i;

        for(i = 0; i < 4; i++){
            bracketsResults.finalsTeamsIds[i] = result[i];
        }

        LogFinalsArrived(id, result);

    }

    /**
    * @notice sets the number of cards to the contract storage
    * @param id 101 for yellow cards, 102 for red cards
    * @param result amount of cards
    */
    function dataSourceCallbackExtras(uint id, uint16 result) public {

        require (msg.sender == dataSourceAddress);

        if (id == 101){
            extraResults.yellowCards = result;
        } else if (id == 102){
            extraResults.redCards = result;
        }

        LogExtrasArrived(id, result);

    }

    /**
    * @notice check if prediction for a match winner is correct
    * @param realResultOne amount of goals team one scored
    * @param realResultTwo amount of goals team two scored
    * @param tokenResultOne amount of goals team one was predicted to score
    * @param tokenResultTwo amount of goals team two was predicted to score
    * @return 
    */
    function matchWinnerOk(uint8 realResultOne, uint8 realResultTwo, uint8 tokenResultOne, uint8 tokenResultTwo) internal pure returns(bool){

        int8 realR = int8(realResultOne - realResultTwo);
        int8 tokenR = int8(tokenResultOne - tokenResultTwo);

        return (realR > 0 && tokenR > 0) || (realR < 0 && tokenR < 0) || (realR == 0 && tokenR == 0);

    }

    /**
    * @notice get points from a single match 
    * @param matchIndex 
    * @param groupsPhase token predictions
    * @return 10 if predicted score correctly, 3 if predicted only who would win
    * and 0 if otherwise
    */
    function getMatchPointsGroups (uint256 matchIndex, uint192 groupsPhase) internal view returns(uint16 matchPoints) {

        uint8 tokenResultOne = uint8(groupsPhase & TEAM_RESULT_MASK_GROUPS);
        uint8 tokenResultTwo = uint8((groupsPhase >> 4) & TEAM_RESULT_MASK_GROUPS);

        uint8 teamOneGoals = groupsResults[matchIndex].teamOneGoals;
        uint8 teamTwoGoals = groupsResults[matchIndex].teamTwoGoals;

        if (teamOneGoals == tokenResultOne && teamTwoGoals == tokenResultTwo){
            matchPoints += 10;
        } else {
            if (matchWinnerOk(teamOneGoals, teamTwoGoals, tokenResultOne, tokenResultTwo)){
                matchPoints += 3;
            }
        }

    }

    /**
    * @notice calculates points from the last two matches
    * @param brackets token predictions
    * @return amount of points gained from the last two matches
    */
    function getFinalRoundPoints (uint160 brackets) internal view returns(uint16 finalRoundPoints) {

        uint8[3] memory teamsIds;

        for (uint i = 0; i <= 2; i++){
            brackets = brackets >> 5; //discard 4th place
            teamsIds[2-i] = uint8(brackets & RESULT_MASK_BRACKETS);
        }

        if (teamsIds[0] == bracketsResults.finalsTeamsIds[0]){
            finalRoundPoints += 100;
        }

        if (teamsIds[2] == bracketsResults.finalsTeamsIds[2]){
            finalRoundPoints += 25;
        }

        if (teamsIds[0] == bracketsResults.finalsTeamsIds[1]){
            finalRoundPoints += 50;
        }

        if (teamsIds[1] == bracketsResults.finalsTeamsIds[0] || teamsIds[1] == bracketsResults.finalsTeamsIds[1]){
            finalRoundPoints += 50;
        }

    }

    /**
    * @notice calculates points for round of sixteen, quarter-finals and semifinals
    * @param size amount of matches in round
    * @param round ros, qf, sf or f
    * @param brackets predictions
    * @return amount of points
    */
    function getMiddleRoundPoints(uint8 size, teamState round, uint160 brackets) internal view returns(uint16 middleRoundResults){

        uint8 teamId;

        for (uint i = 0; i < size; i++){
            teamId = uint8(brackets & RESULT_MASK_BRACKETS);

            if (uint(bracketsResults.middlePhaseTeamsIds[teamId]) >= uint(round) ) {
                middleRoundResults+=60;
            }

            brackets = brackets >> 5;
        }

    }

    /**
    * @notice calculates points for correct predictions of group winners
    * @param brackets token predictions
    * @return amount of points
    */
    function getQualifiersPoints(uint160 brackets) internal view returns(uint16 qualifiersPoints){

        uint8 teamId;

        for (uint256 i = 0; i <= 15; i++){
            teamId = uint8(brackets & RESULT_MASK_BRACKETS);

            if (teamId == bracketsResults.roundOfSixteenTeamsIds[15-i]){
                qualifiersPoints+=30;
            } else if (bracketsResults.teamExists[teamId]){
                qualifiersPoints+=25;
            }
            
            brackets = brackets >> 5;
        }

    }

    /**
    * @notice calculates points won by yellow and red cards predictions
    * @param extras token predictions
    * @return amount of points
    */
    function getExtraPoints(uint32 extras) internal view returns(uint16 extraPoints){

        uint16 redCards = uint16(extras & EXTRA_MASK_BRACKETS);
        extras = extras >> 16;
        uint16 yellowCards = uint16(extras);

        if (redCards == extraResults.redCards){
            extraPoints+=20;
        }

        if (yellowCards == extraResults.yellowCards){
            extraPoints+=20;
        }

    }

    /**
    * @notice calculates total amount of points for a token
    * @param t token to calculate points for
    * @return total amount of points
    */
    function calculateTokenPoints (Token memory t) internal view returns(uint16 points){
        
        //Groups phase 1
        uint192 g1 = t.groups1;
        for (uint256 i = 0; i <= 23; i++){
            points+=getMatchPointsGroups(23-i, g1);
            g1 = g1 >> 8;
        }

        //Groups phase 2
        uint192 g2 = t.groups2;
        for (i = 0; i <= 23; i++){
            points+=getMatchPointsGroups(47-i, g2);
            g2 = g2 >> 8;
        }
        
        uint160 bracketsLocal = t.brackets;

        //Brackets phase 1
        points+=getFinalRoundPoints(bracketsLocal);
        bracketsLocal = bracketsLocal >> 20;

        //Brackets phase 2 
        points+=getMiddleRoundPoints(4, teamState.QUARTERS, bracketsLocal);
        bracketsLocal = bracketsLocal >> 20;

        //Brackets phase 3 
        points+=getMiddleRoundPoints(8, teamState.ROS, bracketsLocal);
        bracketsLocal = bracketsLocal >> 40;

        //Brackets phase 4
        points+=getQualifiersPoints(bracketsLocal);

        //Extras
        points+=getExtraPoints(t.extra);

    }

    /**
    * @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 = calculateTokenPoints(tokens[i]);
            tokenToPointsMap[i] = points;
            if(worstTokens.length == 0 || points <= auxWorstPoints){
                if(worstTokens.length != 0 && points < auxWorstPoints){
                  worstTokens.length = 0;
                }
                if(worstTokens.length < 100){
                    auxWorstPoints = points;
                    worstTokens.push(i);
                }
            }
        }

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

    }

    /**
    * @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;
        
        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];
                }
            }

            if(counter != 0 && (currentTokenPoints != lastTokenPoints || (inRangecounter == 0 && payoutRange == maxRange - 1))){ //Fix second condition
                    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 setLastPositions() external onlyAdmin checkState(pointsValidationState.WinnersAssigned){
        
            
        for(uint256 j = 0;j < worstTokens.length;j++){
            uint256 tokenId = worstTokens[j];
            tokenToPayoutMap[tokenId] += lastPosition.div(worstTokens.length);
        }

        uint256 balance = address(this).balance;
        adminPool = balance.mul(25).div(100);
        prizePool = balance.mul(75).div(100);

        pValidationState = pointsValidationState.Finished;
        gameFinishedTime = now;
    }

}


/**
* @title CoreLayer
* @author CryptoCup Team (https://cryptocup.io/about)
* @notice Main contract
*/
contract CoreLayer is GameLogicLayer {
    
    function CoreLayer() public {
        adminAddress = msg.sender;
        deploymentTime = now;
    }

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

    }

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

    /** 
    * @notice Builds ERC721 token with the predictions provided by the user.
    * @param groups1  - First half of the group matches scores encoded in a uint192.
    * @param groups2 -  Second half of the groups matches scores encoded in a uint192.
    * @param brackets - Bracket information encoded in a uint160.
    * @param extra -    Extra information (number of red cards and yellow cards) encoded in a uint32.
    * @dev An automatic timestamp is added for internal use.
    */
    function buildToken(uint192 groups1, uint192 groups2, uint160 brackets, uint32 extra) external payable isNotPaused {

        Token memory token = Token({
            groups1: groups1,
            groups2: groups2,
            brackets: brackets,
            timeStamp: uint64(now),
            extra: extra
        });

        require(msg.value >= _getTokenPrice());
        require(msg.sender != address(0));
        require(tokens.length < WCCTOKEN_CREATION_LIMIT);
        require(tokensOfOwnerMap[msg.sender].length < 100);
        require(now < WORLD_CUP_START); //World cup Start

        uint256 tokenId = tokens.push(token) - 1;
        require(tokenId == uint256(uint32(tokenId)));

        _setTokenOwner(msg.sender, tokenId);
        LogTokenBuilt(msg.sender, tokenId, token);

    }

    /** 
    * @param tokenId - ID of token to get.
    * @return Returns all the valuable information about a specific token.
    */
    function getToken(uint256 tokenId) external view returns (uint192 groups1, uint192 groups2, uint160 brackets, uint64 timeStamp, uint32 extra) {

        Token storage token = tokens[tokenId];

        groups1 = token.groups1;
        groups2 = token.groups2;
        brackets = token.brackets;
        timeStamp = token.timeStamp;
        extra = token.extra;

    }

    /**
    * @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 {

        adminAddress.transfer(adminPool);
        adminPool = 0;

    }

    /**
    * @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 = tokensOfOwnerMap[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));
      
    }

    
    /**
    * @notice Gets current token price 
    */
    function _getTokenPrice() internal view returns(uint256 tokenPrice){

        if ( now >= THIRD_PHASE){
            tokenPrice = (150 finney);
        } else if (now >= SECOND_PHASE) {
            tokenPrice = (110 finney);
        } else if (now >= FIRST_PHASE) {
            tokenPrice = (75 finney);
        } else {
            tokenPrice = STARTING_PRICE;
        }

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

    }

    /**
    * @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 Testing function to corroborate group data from oraclize call
    * @param x Id of the match to get
    * @return uint8 Team 1 goals
    * @return uint8 Team 2 goals
    */
    function getGroupData(uint x) external view returns(uint8 a, uint8 b){
        a = groupsResults[x].teamOneGoals;
        b = groupsResults[x].teamTwoGoals;  
    }

    /**
    * @notice Testing function to corroborate round of sixteen data from oraclize call
    * @return An array with the ids of the round of sixteen teams
    */
    function getBracketData() external view returns(uint8[16] a){
        a = bracketsResults.roundOfSixteenTeamsIds;
    }

    /**
    * @notice Testing function to corroborate brackets data from oraclize call
    * @param x Team id
    * @return The place the team reached
    */
    function getBracketDataMiddleTeamIds(uint8 x) external view returns(teamState a){
        a = bracketsResults.middlePhaseTeamsIds[x];
    }

    /**
    * @notice Testing function to corroborate finals data from oraclize call
    * @return the 4 (four) final teams ids
    */
    function getBracketDataFinals() external view returns(uint8[4] a){
        a = bracketsResults.finalsTeamsIds;
    }

    /**
    * @notice Testing function to corroborate extra data from oraclize call
    * @return amount of yellow and red cards
    */
    function getExtrasData() external view returns(uint16 a, uint16 b){
        a = extraResults.yellowCards;
        b = extraResults.redCards;  
    }

    //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 * tokensOfOwnerMap[msg.sender].length;

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

    }

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

    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[],"name":"dataSourceGetFinals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"toAddress","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dataSource","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"state","type":"bool"}],"name":"setFinalized","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"fromAddress","type":"address"},{"name":"toAddress","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"matchId","type":"uint256"}],"name":"dataSourceGetRoundOfSixteenResult","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":true,"inputs":[{"name":"","type":"uint256"}],"name":"ownerOfTokenMap","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pointsLimit","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":"id","type":"uint256"},{"name":"result","type":"uint8[4]"}],"name":"dataSourceCallbackFinals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"x","type":"uint256"}],"name":"getGroupData","outputs":[{"name":"a","type":"uint8"},{"name":"b","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastCheckedToken","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenToPointsMap","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"index","type":"uint256"}],"name":"dataSourceGetRoundOfSixteen","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawPrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"matchId","type":"uint256"}],"name":"dataSourceGetSemiResult","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastCalculatedToken","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isDataSourceCallback","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"groups1","type":"uint192"},{"name":"groups2","type":"uint192"},{"name":"brackets","type":"uint160"},{"name":"extra","type":"uint32"}],"name":"buildToken","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"setTopWinnerPrizes","outputs":[],"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":"ownerAddress","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":"setLastPositions","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastAssigned","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBracketData","outputs":[{"name":"a","type":"uint8[16]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"matchId","type":"uint256"}],"name":"dataSourceGetQuarterResult","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":"userAddress","type":"address"}],"name":"balanceOf","outputs":[{"name":"count","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"prizePool","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"matchId","type":"uint256"},{"name":"result","type":"uint8"},{"name":"result2","type":"uint8"}],"name":"dataSourceCallbackGroup","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"payoutRange","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pValidationState","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"ownerAddress","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"tokenIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"auxWorstPoints","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"result","type":"uint8"}],"name":"dataSourceCallbackRoundOfSixteen","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"dataSourceGetRedCards","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":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"matchId","type":"uint256"},{"name":"result","type":"uint8"}],"name":"dataSourceCallbackTeamId","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"saleOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"winnerCounter","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"tokensOfOwnerMap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"toAddress","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","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":true,"inputs":[],"name":"getExtrasData","outputs":[{"name":"a","type":"uint16"},{"name":"b","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"adminPool","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"dataSourceGetYellowCards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"state","type":"bool"}],"name":"setPauseState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastPrizeGiven","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dataSourceAddress","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":"groups1","type":"uint192"},{"name":"groups2","type":"uint192"},{"name":"brackets","type":"uint160"},{"name":"timeStamp","type":"uint64"},{"name":"extra","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"result","type":"uint16"}],"name":"dataSourceCallbackExtras","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"deploymentTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokensApprovedMap","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"matchId","type":"uint256"}],"name":"dataSourceGetGroupResult","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"x","type":"uint8"}],"name":"getBracketDataMiddleTeamIds","outputs":[{"name":"a","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBracketDataFinals","outputs":[{"name":"a","type":"uint8[4]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"adminAddress","outputs":[{"name":"","type":"address"}],"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":false,"name":"matchId","type":"uint256"},{"indexed":false,"name":"result","type":"uint8"},{"indexed":false,"name":"result2","type":"uint8"}],"name":"LogGroupDataArrived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"result","type":"uint8"}],"name":"LogRoundOfSixteenArrived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"matchId","type":"uint256"},{"indexed":false,"name":"result","type":"uint8"}],"name":"LogMiddlePhaseArrived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"result","type":"uint8[4]"}],"name":"LogFinalsArrived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"result","type":"uint16"}],"name":"LogExtrasArrived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"from","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"LogTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"approved","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"LogApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"creatorAddress","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"components":[{"name":"groups1","type":"uint192"},{"name":"groups2","type":"uint192"},{"name":"brackets","type":"uint160"},{"name":"timeStamp","type":"uint64"},{"name":"extra","type":"uint32"}],"indexed":false,"name":"token","type":"tuple"}],"name":"LogTokenBuilt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"result","type":"uint8[]"}],"name":"LogDataSourceCallbackList","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"result","type":"uint8"}],"name":"LogDataSourceCallbackInt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"result","type":"uint8"},{"indexed":false,"name":"result2","type":"uint8"}],"name":"LogDataSourceCallbackTwoInt","type":"event"}]

60606040526000600381905560048190556005805463ffffffff191690556006819055600780546001606060020a0319169055631dcd65006008556009805467ffffffffffffffff19169055600a819055600b819055600c8190556045805460ff19166001830217905550604b805479ffff0000000000000000000000000000000000000000000000006201000062ffffff199092169190911763ff0000001916630f00000017602060020a60c060020a031916641f000000001760c060020a61ffff0219161790556102a06040519081016040908152600180835260208301819052908201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082015260056101408201819052610160820152600a61018082015260146101a082015260326101c082015260646101e0820181905261020082015260c86102208201526101f46102408201526105dc6102608201526109c46102808201526200018490604c906015620001b6565b5034156200019157600080fd5b60028054600160a060020a03191633600160a060020a0316179055426003556200028b565b82805482825590600052602060002090600f01601090048101928215620002545791602002820160005b838211156200022257835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302620001e0565b8015620002525782816101000a81549061ffff021916905560020160208160010104928301926001030262000222565b505b506200026292915062000266565b5090565b6200028891905b808211156200026257805461ffff191681556001016200026d565b90565b614619806200029b6000396000f3006060604052600436106103345763ffffffff60e060020a60003504166304f68d49811461035157806306fdde0314610364578063095ea7b3146103ee57806318160ddd146104105780631b076edc1461043557806320b272911461046457806323b872dd1461047c57806325580656146104a457806327ea6f2b146104ba578063299e7abb146104d05780632cdc078d146104ec57806337440e9e1461050257806337a31079146105185780633a1fc7621461052b5780633c070b601461054a5780633e4852bd146105865780633fd68ca7146105ba57806345b95aa7146105e657806345dcb7881461061357806348d37a581461062957806349afcc0e1461063c5780634f2af86914610652578063582b6add1461066557806359b9a1921461068c5780635a2a3039146106bb5780635c975abb146106ce5780635dedd9cc146106e15780636352211e146106f757806363e561b61461070d578063653e2e0d1461072b5780636a22b09a1461073e5780636b6c5a7e146107515780636bbe24d41461079d578063704b6c02146107b357806370a08231146107d2578063719ce73e146107f157806378e8b8fc146108045780637ef1ab2c14610826578063810a217f146108395780638462151c1461087057806384682fbb146108e257806386b5e2b9146108f557806387ffe5a71461091157806388fdf3d4146109245780638f75362d1461094057806395d89b411461095357806397d74abd1461096657806399288dbb14610982578063a1e0c2c914610995578063a3816e90146109a8578063a9059cbb146109ca578063b3f05b97146109ec578063b3f50029146109ff578063b427c14814610a12578063b75d7e5014610a2e578063b86a1fb214610a60578063bafcea6f14610a73578063cdb88ad114610a86578063d49edbd814610a9e578063d5a3b73414610ab1578063db2e21bc14610ac4578063e4b50cb814610ad7578063e967a9b714610b43578063ecda10f514610b60578063ef8fd00414610b73578063f68f8e4214610b89578063f72758e714610b9f578063f7d4c7e314610bc8578063fc6f946814610bf5578063fdf061f014610c08578063fe67a18914610c1b578063fefaa62614610c2e575b60025433600160a060020a0390811691161461034f57600080fd5b005b341561035c57600080fd5b61034f610c41565b341561036f57600080fd5b610377610cb1565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156103b357808201518382015260200161039b565b50505050905090810190601f1680156103e05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103f957600080fd5b61034f600160a060020a0360043516602435610cf3565b341561041b57600080fd5b610423610d8b565b60405190815260200160405180910390f35b341561044057600080fd5b610448610d91565b604051600160a060020a03909116815260200160405180910390f35b341561046f57600080fd5b61034f6004351515610da0565b341561048757600080fd5b61034f600160a060020a0360043581169060243516604435610df0565b34156104af57600080fd5b61034f600435610ec0565b34156104c557600080fd5b61034f600435610f3a565b34156104db57600080fd5b61034f63ffffffff60043516610fd5565b34156104f757600080fd5b61042360043561114c565b341561050d57600080fd5b61044860043561115e565b341561052357600080fd5b610423611179565b341561053657600080fd5b61034f600160a060020a036004351661117f565b341561055557600080fd5b61034f600480359060a46024826080604051908101604052919082826080808284375093955061123c945050505050565b341561059157600080fd5b61059c600435611318565b60405160ff9283168152911660208201526040908101905180910390f35b34156105c557600080fd5b6105cd61134e565b60405163ffffffff909116815260200160405180910390f35b34156105f157600080fd5b6105fc60043561135a565b60405161ffff909116815260200160405180910390f35b341561061e57600080fd5b61034f600435611370565b341561063457600080fd5b61034f6113d3565b341561064757600080fd5b61034f600435611544565b341561065d57600080fd5b6105cd6115a7565b341561067057600080fd5b6106786115b3565b604051901515815260200160405180910390f35b61034f600160c060020a0360043581169060243516600160a060020a036044351663ffffffff606435166115b8565b34156106c657600080fd5b61034f611836565b34156106d957600080fd5b610678611be1565b34156106ec57600080fd5b61034f600435611bea565b341561070257600080fd5b610448600435611c2f565b341561071857600080fd5b61034f6004803560248101910135611c58565b341561073657600080fd5b61034f611ee7565b341561074957600080fd5b6105cd611ffc565b341561075c57600080fd5b610764612014565b604051808261020080838360005b8381101561078a578082015183820152602001610772565b5050505090500191505060405180910390f35b34156107a857600080fd5b61034f600435612070565b34156107be57600080fd5b61034f600160a060020a03600435166120d3565b34156107dd57600080fd5b610423600160a060020a0360043516612125565b34156107fc57600080fd5b610423612140565b341561080f57600080fd5b61034f60043560ff60243581169060443516612146565b341561083157600080fd5b6105cd612216565b341561084457600080fd5b61084c612222565b6040518082600681111561085c57fe5b60ff16815260200191505060405180910390f35b341561087b57600080fd5b61088f600160a060020a036004351661222b565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156108ce5780820151838201526020016108b6565b505050509050019250505060405180910390f35b34156108ed57600080fd5b6104236122ae565b341561090057600080fd5b61034f60043560ff602435166122b4565b341561091c57600080fd5b61034f612362565b341561092f57600080fd5b61034f63ffffffff600435166123bc565b341561094b57600080fd5b61034f61262c565b341561095e57600080fd5b6103776126bf565b341561097157600080fd5b61034f60043560ff60243516612700565b341561098d57600080fd5b610678612860565b34156109a057600080fd5b6105cd61286f565b34156109b357600080fd5b610423600160a060020a0360043516602435612883565b34156109d557600080fd5b61034f600160a060020a03600435166024356128b1565b34156109f757600080fd5b61067861296b565b3415610a0a57600080fd5b61034f612979565b3415610a1d57600080fd5b61034f63ffffffff600435166129f3565b3415610a3957600080fd5b610a41612ba7565b60405161ffff9283168152911660208201526040908101905180910390f35b3415610a6b57600080fd5b610423612bbc565b3415610a7e57600080fd5b61034f612bc2565b3415610a9157600080fd5b61034f6004351515612c1c565b3415610aa957600080fd5b6105cd612c4a565b3415610abc57600080fd5b610448612c5e565b3415610acf57600080fd5b61034f612c6d565b3415610ae257600080fd5b610aed600435612ce6565b604051600160c060020a039586168152939094166020840152600160a060020a0390911660408084019190915267ffffffffffffffff909116606083015263ffffffff909216608082015260a001905180910390f35b3415610b4e57600080fd5b61034f60043561ffff60243516612d73565b3415610b6b57600080fd5b610423612e11565b3415610b7e57600080fd5b610448600435612e17565b3415610b9457600080fd5b61034f600435612e32565b3415610baa57600080fd5b610bb860ff60043516612e95565b6040518082600481111561085c57fe5b3415610bd357600080fd5b610bdb612ead565b604051808260808083836000815183820152602001610772565b3415610c0057600080fd5b610448612eeb565b3415610c1357600080fd5b61034f612efa565b3415610c2657600080fd5b610423612f55565b3415610c3957600080fd5b610423612f5b565b60025433600160a060020a03908116911614610c5c57600080fd5b600054600160a060020a031663bdf7220f6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1515610c9b57600080fd5b6102c65a03f11515610cac57600080fd5b505050565b610cb96143b0565b60408051908101604052600981527f43727970746f6375700000000000000000000000000000000000000000000000602082015290505b90565b604b5460ff1615610d0357600080fd5b600160a060020a0382161515610d1857600080fd5b610d223382612f61565b1515610d2d57600080fd5b610d378183612f81565b7fc5c187f53b6bf5e61e032320e996f271e6dc6b212ee64ec28ba8e6b9e3f97a4e338383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050565b600d5490565b600054600160a060020a031681565b60025433600160a060020a03908116911614610dbb57600080fd5b604b805460ff191682151590811761ff001916610100918202179182905560ff910416151560011415610ded5742600c555b50565b604b5460ff1615610e0057600080fd5b600160a060020a0382161515610e1557600080fd5b30600160a060020a031682600160a060020a031614151515610e3657600080fd5b610e403382612faf565b1515610e4b57600080fd5b610e558382612f61565b1515610e6057600080fd5b610e6b838383612fcf565b7f0a85107a334eae0d22d21cdf13af0f8e8125039ec60baaa843d2c4c5b0680174838383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a1505050565b60025433600160a060020a03908116911614610edb57600080fd5b600054600160a060020a031663fd3acb5c8260405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b1515610f2357600080fd5b6102c65a03f11515610f3457600080fd5b50505050565b60025433600160a060020a03908116911614610f5557600080fd5b600d548110610f6357600080fd5b600060455460ff166006811115610f7657fe5b1480610f925750600160455460ff166006811115610f9057fe5b145b1515610f9d57600080fd5b60068190556045805460ff19166001179055600780546005805463ffffffff1916905567ffffffffffffffff19169055610ded613143565b600254600090819033600160a060020a03908116911614610ff557600080fd5b60018060455460ff16600681111561100957fe5b1461101357600080fd5b600d5460075463ffffffff908116860116111561102f57600080fd5b6006546000908152604a602052604090205460075461ffff909116935063ffffffff1691505b60075463ffffffff9081168501168210156110e6576000828152604a602052604090205461ffff16839011806110a957506000828152604a602052604090205461ffff16831480156110a957506006548211155b156110db5760078054600163ffffffff640100000000808404821692909201160267ffffffff00000000199091161790555b600190910190611055565b6007805463ffffffff19811663ffffffff918216870182161791829055600d5491161415610f3457600754604b5464010000000090910463ffffffff1660e060020a90910461ffff161461113957600080fd5b50506045805460ff191660021790555050565b60496020526000908152604090205481565b604760205260009081526040902054600160a060020a031681565b60065481565b60025460009033600160a060020a0390811691161461119d57600080fd5b5080600160a060020a03811663037a9d306000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156111e557600080fd5b6102c65a03f115156111f657600080fd5b50505060405180519050151561120b57600080fd5b60008054600160a060020a03928316600160a060020a03199182161790915560018054939092169216919091179055565b60015460009033600160a060020a0390811691161461125a57600080fd5b5060005b60048110156112b25781816004811061127357fe5b60200201516041826004811061128557fe5b602091828204019190066101000a81548160ff021916908360ff160217905550808060010191505061125e565b7f784f6d77c7892aa6a66f7ca1a448ae76d5da2765239a268d26fce2666a899b4283836040518281526020810182608080838360005b838110156113005780820151838201526020016112e8565b505050509050019250505060405180910390a1505050565b600080600e836030811061132857fe5b015460ff169150600e836030811061133c57fe5b0154919361010090920460ff16925050565b60075463ffffffff1681565b604a6020526000908152604090205461ffff1681565b60025433600160a060020a0390811691161461138b57600080fd5b600054600160a060020a031663132427338260405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b1515610f2357600080fd5b60006113dd6143b0565b600060068060455460ff1660068111156113f357fe5b146113fd57600080fd5b600160a060020a03331660009081526046602090815260408083208054939750929182810201905190810160405280929190818152602001828054801561146357602002820191906000526020600020905b81548152602001906001019080831161144f575b50505050509250600091505b82518210156114dd576049600084848151811061148857fe5b90602001906020020151815260200190815260200160002054840193506000604960008585815181106114b757fe5b90602001906020020151815260208101919091526040016000205560019091019061146f565b600084116114ea57600080fd5b33600160a060020a03166108fc61151f620f424061151388600a54613dee90919063ffffffff16565b9063ffffffff613e2416565b9081150290604051600060405180830381858888f193505050501515610f3457600080fd5b60025433600160a060020a0390811691161461155f57600080fd5b600054600160a060020a0316632115d3288260405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b1515610f2357600080fd5b60055463ffffffff1681565b600190565b6115c06143c2565b604b5460009060ff16156115d357600080fd5b60a06040519081016040528087600160c060020a0316815260200186600160c060020a0316815260200185600160a060020a031681526020014267ffffffffffffffff1681526020018463ffffffff168152509150611630613e3b565b34101561163c57600080fd5b33600160a060020a0316151561165157600080fd5b600d54624c4b40901061166357600080fd5b600160a060020a0333166000908152604660205260409020546064901061168957600080fd5b635b21da30421061169957600080fd5b6001600d80548060010182816116af91906143f0565b600092835260209092208591600302018151815477ffffffffffffffffffffffffffffffffffffffffffffffff1916600160c060020a0391909116178155602082015160018201805477ffffffffffffffffffffffffffffffffffffffffffffffff1916600160c060020a03929092169190911790556040820151600282018054600160a060020a031916600160a060020a039290921691909117905560608201518160020160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550608082015160029190910180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a63ffffffff9384160217905592909103925050811681146117cb57600080fd5b6117d53382613ebf565b7f123f43ae884aaab992d1eab18070123df1a4700c29c7ebe277252274795f10cd3382846040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a1505050505050565b60006118406143b0565b600254600090819081908190819081908190819033600160a060020a0390811691161461186c57600080fd5b60038060455460ff16600681111561188057fe5b1461188a57600080fd5b60009a50601e60405180591061189d5750595b9080825280602002602001820160405250600d8054919b5060009a508a9650945060c99010156118cc57600a93505b60095463ffffffff1684901015611ba057600954604c8054909163ffffffff169081106118f557fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff1661ffff1692505b6000831115611b7f576043805463ffffffff871690811061193d57fe5b6000918252602080832090910154808352604a90915260409091205490985061ffff1696506000199092019182158015611982575060095463ffffffff166000198501145b15611a4b57858714156119fd57600954604d8054909163ffffffff169081106119a757fe5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff168b019a50878a8a61ffff16815181106119e857fe5b60209081029091010152600190980197611a4b565b600954604d8054909163ffffffff16908110611a1557fe5b600091825260208083206008808404909101548c855260499092526040909320929091066004026101000a900463ffffffff1690555b63ffffffff851615801590611a7e57508587141580611a7e575082158015611a7e575060095463ffffffff166000198501145b15611b0957600091505b8861ffff16821015611ade57611aa88b61ffff8b1663ffffffff613e2416565b604960008c8581518110611ab857fe5b906020019060200201518152602081019190915260400160002055600190910190611a88565b60009a50601e604051805910611af15750595b90808252806020026020018201604052509950600098505b600954604d8054909163ffffffff16908110611b2157fe5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff168b019a50878a8a61ffff1681518110611b6257fe5b602090810290910101526001988901988796509490940193611920565b6009805463ffffffff8082166001011663ffffffff199091161790556118cc565b50506045805460ff1916600417905550506009805467ffffffff00000000191664010000000063ffffffff9390931692909202919091179055505050505050565b604b5460ff1681565b60025433600160a060020a03908116911614611c0557600080fd5b60028060455460ff166006811115611c1957fe5b14611c2357600080fd5b81610cac60438261441c565b600081815260476020526040902054600160a060020a0316801515611c5357600080fd5b919050565b6002546000908190819081908190819033600160a060020a03908116911614611c8057600080fd5b60028060455460ff166006811115611c9457fe5b14611c9e57600080fd5b60075460435464010000000090910463ffffffff169089011115611cc157600080fd5b600096505b6000198801871015611d8157888888818110611cde57fe5b9050602002013563ffffffff1663ffffffff1695508888886001018181101515611d0457fe5b6020908102929092013563ffffffff166000818152604a9093526040808420548a855293205490975061ffff928316921691909111905080611d6b57506000858152604a60205260408082205488835291205461ffff9081169116148015611d6b57508486105b1515611d7657600080fd5b600190960195611cc6565b60435415611e2757604380546000198101908110611d9b57fe5b6000918252602082200154945089908990818110611db557fe5b6020908102929092013563ffffffff166000818152604a90935260408084205488855293205490955061ffff928316921691909111905080611e1c57506000838152604a60205260408082205486835291205461ffff9081169116148015611e1c57508284105b1515611e2757600080fd5b600091505b87821015611e88576043805460018101611e46838261441c565b916000526020600020900160008b8b868181101515611e6157fe5b9050602002013563ffffffff1663ffffffff16909190915055508180600101925050611e2c565b60075460435464010000000090910463ffffffff161415611edc57600654604380546000198101908110611eb857fe5b60009182526020909120015414611ece57600080fd5b6045805460ff191660031790555b505050505050505050565b6002546000908190819033600160a060020a03908116911614611f0957600080fd5b60058060455460ff166006811115611f1d57fe5b14611f2757600080fd5b600093505b604454841015611fa6576044805485908110611f4457fe5b600091825260209091200154604454604b54919450611f85917a010000000000000000000000000000000000000000000000000000900461ffff1690613e24565b60008481526049602052604090208054909101905560019390930192611f2c565b600160a060020a033016319150611fc9606461151384601963ffffffff613dee16565b600b55611fe2606461151384604b63ffffffff613dee16565b600a5550506045805460ff19166006179055505042600455565b60075468010000000000000000900463ffffffff1681565b61201c614440565b603e601061020060405190810160405291906102008301826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116120385790505050505050905090565b60025433600160a060020a0390811691161461208b57600080fd5b600054600160a060020a031663eef719b18260405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b1515610f2357600080fd5b60025433600160a060020a039081169116146120ee57600080fd5b600160a060020a038116151561210357600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b600160a060020a031660009081526046602052604090205490565b600a5481565b60015433600160a060020a0390811691161461216157600080fd5b600083101580156121735750602f8311155b151561217e57600080fd5b81600e846030811061218c57fe5b01805460ff191660ff9290921691909117905580600e84603081106121ad57fe5b01805460ff929092166101000261ff00199092169190911790557f100b781654c22dcc0ce6b4b9bbe8c5a027182ec638a460a8331ba9907ae34a7783838360405192835260ff9182166020840152166040808301919091526060909101905180910390a1505050565b60095463ffffffff1681565b60455460ff1681565b6122336143b0565b6046600083600160a060020a0316600160a060020a031681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156122a257602002820191906000526020600020905b81548152602001906001019080831161228e575b50505050509050919050565b60085481565b60015433600160a060020a039081169116146122cf57600080fd5b80603e83601081106122dd57fe5b6020808204909201805460ff948516928490066101000a92830292850219169190911790559082166000908152603f909152604090819020805460ff191660011790557fdfd06cdf6d29b522912afa1362f9e10b447c20a3454086ba65b6b024061a26d390839083905191825260ff1660208201526040908101905180910390a15050565b60025433600160a060020a0390811691161461237d57600080fd5b600054600160a060020a03166317ab6cbb6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1515610c9b57600080fd5b6002546000908190819033600160a060020a039081169116146123de57600080fd5b60048060455460ff1660068111156123f257fe5b146123fc57600080fd5b60075460095463ffffffff640100000000928390048116929091048116870116111561242757600080fd5b600954604c8054909163ffffffff1690811061243f57fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff169350600092505b8463ffffffff1683101561256d5761ffff841615156124da576009805463ffffffff198116600163ffffffff9283160182161791829055604c805490929091169081106124b357fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff1693505b600954604380549091640100000000900463ffffffff1685019081106124fc57fe5b600091825260209091200154600954604d80549294509163ffffffff90911690811061252457fe5b6000918252602080832060088084049091015486855260499092526040909320929091066004026101000a900463ffffffff16905560001993909301926001929092019161246a565b6009805463ffffffff6401000000008083048216890182160267ffffffff00000000199092169190911791829055604c805487939192919091169081106125b057fe5b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff160217905550600760049054906101000a900463ffffffff1663ffffffff16600960049054906101000a900463ffffffff1663ffffffff161415612625576045805460ff191660051790555b5050505050565b604b54610100900460ff16151561264257600080fd5b60025433600160a060020a0390811691161461265d57600080fd5b600c54158015906126755750600c54620d2f00014210155b151561268057600080fd5b33600160a060020a03166108fc30600160a060020a0316319081150290604051600060405180830381858888f1935050505015156126bd57600080fd5b565b6126c76143b0565b60408051908101604052600281527f43430000000000000000000000000000000000000000000000000000000000006020820152905090565b60015460009033600160a060020a0390811691161461271e57600080fd5b5060ff8082166000908152604060208190529020541660308310801590612746575060378311155b1561278957600181600481111561275957fe5b10156127845760ff8216600090815260406020819052902080546001919060ff191682805b02179055505b61281e565b6038831015801561279b5750603b8311155b156127d85760028160048111156127ae57fe5b10156127845760ff8216600090815260406020819052902080546002919060ff191660018361277e565b82603c14806127e7575082603d145b1561281e5760038160048111156127fa57fe5b101561281e5760ff82166000908152604060208190529020805460ff191660031790555b7f784f7f6ed2d355b96683be36c34e25597888d55416230331b013a99ae80051f7838360405191825260ff1660208201526040908101905180910390a1505050565b604b5462010000900460ff1681565b600754640100000000900463ffffffff1681565b60466020528160005260406000208181548110151561289e57fe5b6000918252602090912001549150829050565b604b5460ff16156128c157600080fd5b600160a060020a03821615156128d657600080fd5b30600160a060020a031682600160a060020a0316141515156128f757600080fd5b6129013382612f61565b151561290c57600080fd5b612917338383612fcf565b7f0a85107a334eae0d22d21cdf13af0f8e8125039ec60baaa843d2c4c5b0680174338383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050565b604b54610100900460ff1681565b60025460009033600160a060020a0390811691161461299757600080fd5b600454158015906129af57506004546213c680014210155b15156129ba57600080fd5b50600254600160a060020a0330811631911681156108fc0282604051600060405180830381858888f193505050501515610ded57600080fd5b600454600090819015612a0557600080fd5b600d5460075463ffffffff9081168501161115612a2157600080fd5b60055463ffffffff1691505b60055463ffffffff908116840116821015612b8457612adf600d83815481101515612a5457fe5b906000526020600020906003020160a060405190810160409081528254600160c060020a0390811683526001840154166020830152600290920154600160a060020a0381169282019290925274010000000000000000000000000000000000000000820467ffffffffffffffff16606082015260e060020a90910463ffffffff166080820152613f25565b6000838152604a60205260409020805461ffff191661ffff83161790556044549091501580612b1457506008548161ffff1611155b15612b795760445415801590612b2f57506008548161ffff16105b15612b43576000612b4160448261441c565b505b6044546064901015612b795761ffff81166008556044805460018101612b69838261441c565b5060009182526020909120018290555b600190910190612a2d565b50506005805463ffffffff19811663ffffffff9182169390930116919091179055565b60425461ffff80821692620100009092041690565b600b5481565b60025433600160a060020a03908116911614612bdd57600080fd5b600054600160a060020a03166378dc70176040518163ffffffff1660e060020a028152600401600060405180830381600087803b1515610c9b57600080fd5b60025433600160a060020a03908116911614612c3757600080fd5b604b805460ff1916911515919091179055565b600954640100000000900463ffffffff1681565b600154600160a060020a031681565b604b54600090610100900460ff161515612c8657600080fd5b50600160a060020a03331660009081526046602052604081208054669fdf42f6e480000291612cb59190614469565b600160a060020a03331681156108fc0282604051600060405180830381858888f193505050501515610ded57600080fd5b600080600080600080600d87815481101515612cfe57fe5b6000918252602090912060039091020180546001820154600290920154600160c060020a039182169a929091169850600160a060020a038116975067ffffffffffffffff74010000000000000000000000000000000000000000820416965063ffffffff60e060020a90910416945092505050565b60015433600160a060020a03908116911614612d8e57600080fd5b8160651415612dad576042805461ffff191661ffff8316179055612dcf565b8160661415612dcf576042805463ffff000019166201000061ffff8416021790555b7fb585e111b4b80c29f5c70336537a97a40ad665f43005009ccc5f0c3d62604bed828260405191825261ffff1660208201526040908101905180910390a15050565b60035481565b604860205260009081526040902054600160a060020a031681565b60025433600160a060020a03908116911614612e4d57600080fd5b600054600160a060020a031663a6d4b5c28260405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b1515610f2357600080fd5b60ff9081166000908152604060208190529020541690565b612eb5614487565b604160046080604051908101604052825460ff168152919060808301826001602086018084116120385790505050505050905090565b600254600160a060020a031681565b60025433600160a060020a03908116911614612f1557600080fd5b600254600b54600160a060020a039091169080156108fc0290604051600060405180830381858888f193505050501515612f4e57600080fd5b6000600b55565b600c5481565b60045481565b600090815260476020526040902054600160a060020a0391821691161490565b6000918252604860205260409091208054600160a060020a031916600160a060020a03909216919091179055565b600090815260486020526040902054600160a060020a0391821691161490565b600160a060020a038216600090815260466020526040812054819060649010612ff757600080fd5b600060455460ff16600681111561300a57fe5b1461301457600080fd5b600160a060020a038416600090815260466020526040902080546001810161303c838261441c565b5060009182526020808320919091018590558482526047815260408083208054600160a060020a031916600160a060020a03898116919091179091558816835260469091528120925090505b81548110156130f3578282828154811015156130a057fe5b90600052602060002090015414156130eb578154829060001981019081106130c457fe5b90600052602060002090015482828154811015156130de57fe5b6000918252602090912001555b600101613088565b81548290600019810190811061310557fe5b6000918252602082200155815461312083600019830161441c565b50505060009081526048602052604090208054600160a060020a03191690555050565b600d54606590101561324e576102a0604051908101604090815262046ba482526202e50460208301526201d4c090820152620169546060820152620124f8608082015261f42460a082015261cd1460c082015261a60460e0820152619c40610100820152618b1061012082015260006101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082015261321690604d9060156144a1565b50604b805460d060020a63ffffffff0219167c0a000000000000000000000000000000000000000000000000000000001790556126bd565b600d5460c990101561335a576102a0604051908101604090815262040d1c82526202867c602083015262019c1c90820152620126ec606082015261f618608082015261bb8060a0820152618aac60c082015261501460e0820152614e20610100820152614c2c610120820152614844610140820152614588610160820152600061018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082015261332290604d9060156144a1565b50604b805460d060020a63ffffffff0219167c14000000000000000000000000000000000000000000000000000000001790556126bd565b600d5461012d901015613468576102a060405190810160409081526203fa5c82526202603460208301526201895c90820152620114f4606082015261ed1c608082015261b28460a0820152618aac60c082015261501460e08201526145ec6101008201526130d4610120820152612cec610140820152612af86101608201526129ae61018082015260006101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082015261343090604d9060156144a1565b50604b805460d060020a63ffffffff0219167c1e000000000000000000000000000000000000000000000000000000001790556126bd565b600d546101f5901015613576576102a060405190810160409081526203a408825262021d68602083015262015ae09082015261f938606082015261d228608082015261ab1860a082015261840860c082015261497060e082015261445c6101008201526130d461012082015261251c610140820152611d4c610160820152611bbc610180820152611a2c6101a082015260006101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082015261353e90604d9060156144a1565b50604b805460d060020a63ffffffff0219167c32000000000000000000000000000000000000000000000000000000001790556126bd565b600d546103e99010156136ac576102a06040519081016040908152620354bc82526201ddbc602083015262011a6c9082015261ccb0606082015261ab7c608082015261846c60a0820152615d5c60c0820152613e8060e08201526132c8610100820152612710610120820152612328610140820152611b58610160820152611388610180820152610fa06101a0820152610e106101c082015260006101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082015261364d90604d9060156144a1565b50604b805460d060020a61ffff0219167b0fa000000000000000000000000000000000000000000000000000001760e060020a61ffff0219167c64000000000000000000000000000000000000000000000000000000001790556126bd565b600d546107d19010156137e2576102a0604051908101604090815262031ed482526201bd50602083015261fa009082015261ac446060820152618b74608082015261684c60a08201526155f060c0820152613a9860e0820152612af861010082015261251c6101208201526121346101408201526119646101608201526111f86101808201526109c46101a08201526107d06101c08201526107086101e08201526000610200820181905261022082018190526102408201819052610260820181905261028082015261378390604d9060156144a1565b50604b805460d060020a61ffff0219167b09c400000000000000000000000000000000000000000000000000001760e060020a61ffff0219167cc8000000000000000000000000000000000000000000000000000000001790556126bd565b600d54610bb990101561391a576102a060405190810160409081526202e310825262019960602083015261d28c9082015261885460608201526172746080820152614b6460a0820152613bc460c08201526136b060e082015261290461010082015261206c610120820152611f40610140820152611770610160820152610ed86101808201526109c46101a08201526107d06101c08201526105dc6101e082015261044c61020082015260006102208201819052610240820181905261026082018190526102808201526138ba90604d9060156144a1565b50604b805460d060020a61ffff0219167b09c400000000000000000000000000000000000000000000000000001760e060020a61ffff0219167d012c000000000000000000000000000000000000000000000000000000001790556126bd565b600d54611389901015613a53576102a060405190810160409081526202b750825262018894602083015261b928908201526176c0606082015261607c6080820152613c8c60a0820152613a9860c0820152612ee060e08201526127d8610100820152611e78610120820152611ce861014082015261157c610160820152610ce46101808201526107d06101a08201526105dc6101c08201526104b06101e082015261038461020082015261029e6102208201526000610240820181905261026082018190526102808201526139f390604d9060156144a1565b50604b805460d060020a61ffff0219167b07d000000000000000000000000000000000000000000000000000001760e060020a61ffff0219167d01f4000000000000000000000000000000000000000000000000000000001790556126bd565b600d54612711901015613b8d576102a06040519081016040908152620267a08252620151e4602083015261985890820152615a3c60608201526149d46080820152613a9860a08201526136b060c0820152612af860e08201526124546101008201526117d4610120820152611770610140820152611388610160820152610ed86101808201526105dc6101a082015261044c6101c08201526103846101e08201526102bc6102008201526101f461022082015261016861024082015260006102608201819052610280820152613b2d90604d9060156144a1565b50604b805460d060020a61ffff0219167b05dc00000000000000000000000000000000000000000000000000001760e060020a61ffff0219167d03e8000000000000000000000000000000000000000000000000000000001790556126bd565b600d546161a9901015613cc6576102a06040519081016040908152620205948252620112386020830152617a4490820152614844606082015261445c60808201526136b060a08201526134bc60c082015261290460e0820152611d4c61010082015261157c610120820152611388610140820152610fa0610160820152610bb86101808201526103e86101a08201526103846101c08201526102bc6101e082015261025861020082015261019061022082015260c861024082015260986102608201526000610280820152613c6690604d9060156144a1565b50604b805460d060020a61ffff0219167b03e800000000000000000000000000000000000000000000000000001760e060020a61ffff0219167d09c4000000000000000000000000000000000000000000000000000000001790556126bd565b6102a060405190810160409081526201d4c0825261f6186020830152616978908201526149706060820152614394608082015261358460a08201526132c860c082015261271060e082015261189c610100820152611388610120820152611194610140820152610f3c6101608201526109c46101808201526103846101a08201526103206101c08201526102586101e08201526101f461020082015261015e610220820152609661024082015260646102608201526046610280820152613d9190604d9060156144a1565b50604b805460d060020a61ffff0219167b038400000000000000000000000000000000000000000000000000001760e060020a61ffff0219167d138800000000000000000000000000000000000000000000000000000000179055565b600080831515613e015760009150613e1d565b50828202828482811515613e1157fe5b0414613e1957fe5b8091505b5092915050565b6000808284811515613e3257fe5b04949350505050565b6000635b1de5b04210613e575750670214e8348c4f0000613e95565b635b14ab304210613e715750670186cc6acd4b0000613e95565b635b0b70b04210613e8b575067010a741a46278000613e95565b50669fdf42f6e480005b669fdf42f6e480008110158015613eb457506702c68af0bb1400008111155b1515610cf057600080fd5b600160a060020a0382166000908152604660205260409020805460018101613ee7838261441c565b5060009182526020808320919091018390559181526047909152604090208054600160a060020a031916600160a060020a0392909216919091179055565b60008080808085519350600092505b60178311613f6b57613f49836017038561403d565b90940193610100600160c060020a039094169390930492600190920191613f34565b85602001519150600092505b60178311613fae57613f8c83602f038361403d565b90940193600190920191610100600160c060020a039092169190910490613f77565b85604001519050613fbe816140dd565b9094019362100000600160a060020a0390911604613fdf60046002836141c8565b9094019362100000600160a060020a039091160461400060086001836141c8565b9094019365010000000000600160a060020a03909116046140208161424b565b8501945061403186608001516142e6565b90940195945050505050565b604b546000906301000000900482811660ff908116916010600160c060020a0386160416168280600e876030811061407157fe5b015460ff169150600e876030811061408557fe5b015460ff610100909104811691508281169085161480156140ab57508260ff168160ff16145b156140bb57600a850194506140d3565b6140c782828686614350565b156140d3576003850194505b5050505092915050565b60006140e761454f565b60005b6002811161413557604b546020600160a060020a0395861604946401000000009091048516168260028390036003811061412057fe5b60ff90921660209290920201526001016140ea565b60415460ff16825160ff16141561414d576064830192505b60415462010000900460ff16604083015160ff16141561416e576019830192505b604154610100900460ff16825160ff16141561418b576032830192505b60415460ff16602083015160ff1614806141b55750604154610100900460ff16602083015160ff16145b156141c1576032830192505b5050919050565b600080805b8560ff1681101561424257604b5464010000000090048416600160a060020a031691508460048111156141fc57fe5b60ff80841660009081526040602081905290205416600481111561421c57fe5b1061422857603c830192505b6020600160a060020a0390941693909304926001016141cd565b50509392505050565b600080805b600f81116141c157604b5464010000000090048416600160a060020a03169150603e600f8290036010811061428157fe5b60208082049092015460ff858116939092066101000a90041614156142ab57601e830192506142cc565b60ff8083166000908152603f602052604090205416156142cc576019830192505b6020600160a060020a039094169390930492600101614250565b604b546042546201000063ffffffff841681900493600093780100000000000000000000000000000000000000000000000090041661ffff908116928592900416821415614335576014830192505b60425461ffff828116911614156141c1575050601401919050565b600083850382840381830b839013801561436d575060008160000b135b80614389575060008260000b128015614389575060008160000b125b806143a557508160000b60001480156143a557508060000b6000145b979650505050505050565b60206040519081016040526000815290565b60a0604051908101604090815260008083526020830181905290820181905260608201819052608082015290565b815481835581811511610cac57600302816003028360005260206000209182019101610cac9190614569565b815481835581811511610cac57600083815260209020610cac9181019083016145b2565b6102006040519081016040526010815b6000815260001990910190602001816144505790505090565b5080546000825590600052602060002090810190610ded91906145b2565b608060405190810160405260008152600360208201614450565b8280548282559060005260206000209060070160089004810192821561453f5791602002820160005b8382111561450d57835183826101000a81548163ffffffff021916908362ffffff16021790555092602001926004016020816003010492830192600103026144ca565b801561453d5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261450d565b505b5061454b9291506145cc565b5090565b606060405190810160405260008152600260208201614450565b610cf091905b8082111561454b57805477ffffffffffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690556000600282015560030161456f565b610cf091905b8082111561454b57600081556001016145b8565b610cf091905b8082111561454b57805463ffffffff191681556001016145d25600a165627a7a72305820955b297a0de8941e133b44c5e8dda2c24d97efb52c653db4c300752cbdddae150029

Swarm Source

bzzr://955b297a0de8941e133b44c5e8dda2c24d97efb52c653db4c300752cbdddae15
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

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.