Contract 0xE2589492184982f5A128F407a94775114e03F962

  Note: Our ETH balance display is temporarily unavailable. Please check back later.

Contract Overview

Balance:
Txn Hash Method
Block
From
To
Value
0x029b85a6fcd1fe062519c39a6076366090904b862f988983e95f0948b2bb34e50x60806040181817722023-12-05 15:53:32170 days 22 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  Create: TherundownConsumer0 ETH0.000097999980.00001
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TherundownConsumer

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 17 : TherundownConsumer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

// internal
import "../../utils/proxy/solidity-0.8.0/ProxyOwned.sol";
import "../../utils/proxy/solidity-0.8.0/ProxyPausable.sol";
import "./GamesQueue.sol";

// interface
import "../../interfaces/ISportPositionalMarketManager.sol";
import "../../interfaces/ITherundownConsumerVerifier.sol";
import "../../interfaces/IGamesOddsObtainer.sol";
import "../../interfaces/ISportPositionalMarket.sol";
import "../../interfaces/IGamesPlayerProps.sol";

/// @title Consumer contract which stores all data from CL data feed (Link to docs: https://market.link/nodes/TheRundown/integrations), also creates all sports markets based on that data
/// @author gruja
contract TherundownConsumer is Initializable, ProxyOwned, ProxyPausable {
    /* ========== CONSTANTS =========== */

    uint public constant CANCELLED = 0;
    uint public constant HOME_WIN = 1;
    uint public constant AWAY_WIN = 2;
    uint public constant RESULT_DRAW = 3;
    uint public constant MIN_TAG_NUMBER = 9000;
    uint public constant STATUS_RETIRED = 201;

    /* ========== CONSUMER STATE VARIABLES ========== */

    struct GameCreate {
        bytes32 gameId;
        uint256 startTime;
        int24 homeOdds;
        int24 awayOdds;
        int24 drawOdds;
        string homeTeam;
        string awayTeam;
    }

    struct GameResolve {
        bytes32 gameId;
        uint8 homeScore;
        uint8 awayScore;
        uint8 statusId;
        uint40 lastUpdated;
    }

    struct GameOdds {
        bytes32 gameId;
        int24 homeOdds;
        int24 awayOdds;
        int24 drawOdds;
    }

    /* ========== STATE VARIABLES ========== */

    // global params
    address public wrapperAddress;
    mapping(address => bool) public whitelistedAddresses;

    // Maps <RequestId, Result>
    mapping(bytes32 => bytes[]) private requestIdGamesCreated; // deprecated see Wrapper
    mapping(bytes32 => bytes[]) private requestIdGamesResolved; // deprecated see Wrapper
    mapping(bytes32 => bytes[]) private requestIdGamesOdds; // deprecated see Wrapper

    // Maps <GameId, Game>
    mapping(bytes32 => GameCreate) public gameCreated;
    mapping(bytes32 => GameResolve) public gameResolved;
    mapping(bytes32 => GameOdds) private gameOdds; // deprecated see GamesOddsObtainer
    mapping(bytes32 => uint) public sportsIdPerGame;
    mapping(bytes32 => bool) public gameFulfilledCreated;
    mapping(bytes32 => bool) public gameFulfilledResolved;

    // sports props
    mapping(uint => bool) public supportedSport;
    mapping(uint => bool) public twoPositionSport;
    mapping(uint => bool) public supportResolveGameStatuses;
    mapping(uint => bool) public cancelGameStatuses;

    // market props
    ISportPositionalMarketManager public sportsManager;
    mapping(bytes32 => address) public marketPerGameId;
    mapping(address => bytes32) public gameIdPerMarket;
    mapping(address => bool) public marketResolved;
    mapping(address => bool) public marketCanceled;

    // game
    GamesQueue public queues;
    mapping(bytes32 => uint) private oddsLastPulledForGame; // deprecated see GamesOddsObtainer
    mapping(uint => bytes32[]) private gamesPerDate; // deprecated use gamesPerDatePerSport
    mapping(uint => mapping(uint => bool)) public isSportOnADate;
    mapping(address => bool) private invalidOdds; // deprecated see GamesOddsObtainer
    mapping(address => bool) public marketCreated;
    mapping(uint => mapping(uint => bytes32[])) public gamesPerDatePerSport;
    mapping(address => bool) public isPausedByCanceledStatus;
    mapping(address => bool) private canMarketBeUpdated; // deprecated
    mapping(bytes32 => uint) public gameOnADate;

    ITherundownConsumerVerifier public verifier;
    mapping(bytes32 => GameOdds) private backupOdds; // deprecated see GamesOddsObtainer
    IGamesOddsObtainer public oddsObtainer;
    uint public maxNumberOfMarketsToResolve;
    IGamesPlayerProps public playerProps;
    mapping(uint => bool) public ignoreChildCancellationPerSportIfDraw;
    uint public maxNumberOfMarketsToCreate;
    mapping(string => address) public marketForTeamName;

    /* ========== CONSTRUCTOR ========== */

    function initialize(
        address _owner,
        uint[] memory _supportedSportIds,
        address _sportsManager,
        uint[] memory _twoPositionSports,
        GamesQueue _queues,
        uint[] memory _resolvedStatuses,
        uint[] memory _cancelGameStatuses
    ) external initializer {
        setOwner(_owner);

        for (uint i; i < _supportedSportIds.length; i++) {
            supportedSport[_supportedSportIds[i]] = true;
        }
        for (uint i; i < _twoPositionSports.length; i++) {
            twoPositionSport[_twoPositionSports[i]] = true;
        }
        for (uint i; i < _resolvedStatuses.length; i++) {
            supportResolveGameStatuses[_resolvedStatuses[i]] = true;
        }
        for (uint i; i < _cancelGameStatuses.length; i++) {
            cancelGameStatuses[_cancelGameStatuses[i]] = true;
        }

        sportsManager = ISportPositionalMarketManager(_sportsManager);
        queues = _queues;
        whitelistedAddresses[_owner] = true;
    }

    /* ========== CONSUMER FULFILL FUNCTIONS ========== */

    /// @notice fulfill all data necessary to create sport markets
    /// @param _requestId unique request id form CL
    /// @param _games array of a games that needed to be stored and transfered to markets
    /// @param _sportId sports id which is provided from CL (Example: NBA = 4)
    /// @param _date date on which game/games are played
    function fulfillGamesCreated(
        bytes32 _requestId,
        bytes[] memory _games,
        uint _sportId,
        uint _date
    ) external onlyWrapper {
        uint doubleChanceMultiplier = sportsManager.doesSportSupportDoubleChance(_sportId) ? 3 : 0;
        uint numOfMarkets = twoPositionSport[_sportId] ? _games.length : _games.length * (1 + doubleChanceMultiplier);

        if (_games.length > 0) {
            isSportOnADate[_date][_sportId] = true;
        }

        for (uint i = 0; i < _games.length; i++) {
            GameCreate memory gameForProcessing = abi.decode(_games[i], (GameCreate));
            // new game
            if (
                !gameFulfilledCreated[gameForProcessing.gameId] &&
                !verifier.isInvalidNames(gameForProcessing.homeTeam, gameForProcessing.awayTeam) &&
                gameForProcessing.startTime > block.timestamp
            ) {
                _updateGameOnADate(gameForProcessing.gameId, _date, _sportId);
                _createGameFulfill(_requestId, gameForProcessing, _sportId, numOfMarkets);
            }
            // old game UFC checking fighters
            else if (gameFulfilledCreated[gameForProcessing.gameId]) {
                GameCreate memory currentGameValues = getGameCreatedById(gameForProcessing.gameId);

                // if name (away or home) not the same
                if (
                    (!verifier.areTeamsEqual(gameForProcessing.homeTeam, currentGameValues.homeTeam) ||
                        !verifier.areTeamsEqual(gameForProcessing.awayTeam, currentGameValues.awayTeam))
                ) {
                    // double-check if market exists -> cancel market -> create new for queue
                    if (marketCreated[marketPerGameId[gameForProcessing.gameId]]) {
                        if (_sportId == 7) {
                            _cancelMarket(gameForProcessing.gameId, false);
                            _updateGameOnADate(gameForProcessing.gameId, _date, _sportId);
                            _createGameFulfill(_requestId, gameForProcessing, _sportId, numOfMarkets);
                        } else {
                            _pauseOrUnpauseMarket(marketPerGameId[gameForProcessing.gameId], true);
                            oddsObtainer.pauseUnpauseChildMarkets(marketPerGameId[gameForProcessing.gameId], true);
                            _pauseOrUnpausePlayerProps(marketPerGameId[gameForProcessing.gameId], true, false, false);
                        }
                    }
                    // checking time
                } else if (gameForProcessing.startTime != currentGameValues.startTime) {
                    _updateGameOnADate(gameForProcessing.gameId, _date, _sportId);
                    // if NEW start time is in future
                    if (gameForProcessing.startTime > block.timestamp) {
                        // this checks is for new markets
                        sportsManager.updateDatesForMarket(
                            marketPerGameId[gameForProcessing.gameId],
                            gameForProcessing.startTime
                        );
                        gameCreated[gameForProcessing.gameId] = gameForProcessing;
                    } else {
                        // double-check if market existst
                        if (
                            marketCreated[marketPerGameId[gameForProcessing.gameId]] &&
                            currentGameValues.startTime > block.timestamp
                        ) {
                            _pauseOrUnpauseMarket(marketPerGameId[gameForProcessing.gameId], true);
                            oddsObtainer.pauseUnpauseChildMarkets(marketPerGameId[gameForProcessing.gameId], true);
                            _pauseOrUnpausePlayerProps(marketPerGameId[gameForProcessing.gameId], true, false, false);
                            emit GameTimeMovedAhead(
                                marketPerGameId[gameForProcessing.gameId],
                                gameForProcessing.gameId,
                                currentGameValues.startTime,
                                gameForProcessing.startTime
                            );
                        }
                    }
                }
            }
        }
    }

    /// @notice fulfill all data necessary to resolve sport markets
    /// @param _requestId unique request id form CL
    /// @param _games array of a games that needed to be resolved
    /// @param _sportId sports id which is provided from CL (Example: NBA = 4)
    function fulfillGamesResolved(
        bytes32 _requestId,
        bytes[] memory _games,
        uint _sportId
    ) external onlyWrapper {
        uint numberOfMarketsToResolve = _games.length;
        for (uint i = 0; i < _games.length; i++) {
            GameResolve memory game = abi.decode(_games[i], (GameResolve));
            address _main = marketPerGameId[game.gameId];
            numberOfMarketsToResolve = numberOfMarketsToResolve + oddsObtainer.numberOfChildMarkets(_main);
        }
        for (uint i = 0; i < _games.length; i++) {
            GameResolve memory game = abi.decode(_games[i], (GameResolve));
            // if game is not resolved already and there is market for that game
            if (!gameFulfilledResolved[game.gameId] && marketPerGameId[game.gameId] != address(0)) {
                _resolveGameFulfill(_requestId, game, _sportId, numberOfMarketsToResolve);
            }
        }
    }

    /// @notice fulfill all data necessary to populate odds of a game
    /// @param _requestId unique request id form CL
    /// @param _games array of a games that needed to update the odds
    function fulfillGamesOdds(bytes32 _requestId, bytes[] memory _games) external onlyWrapper {
        for (uint i = 0; i < _games.length; i++) {
            IGamesOddsObtainer.GameOdds memory game = abi.decode(_games[i], (IGamesOddsObtainer.GameOdds));
            // game needs to be fulfilled and market needed to be created
            if (gameFulfilledCreated[game.gameId] && marketPerGameId[game.gameId] != address(0)) {
                oddsObtainer.obtainOdds(
                    _requestId,
                    game,
                    sportsIdPerGame[game.gameId],
                    marketPerGameId[game.gameId],
                    twoPositionSport[sportsIdPerGame[game.gameId]],
                    false
                );
            }
        }
    }

    /// @notice creates market for a given game id
    /// @param _gameId game id
    function createMarketForGame(bytes32 _gameId) public {
        require(
            marketPerGameId[_gameId] == address(0) ||
                (marketCanceled[marketPerGameId[_gameId]] && marketPerGameId[_gameId] != address(0)),
            "ID1"
        );
        require(gameFulfilledCreated[_gameId], "ID2");
        require(queues.gamesCreateQueue(queues.firstCreated()) == _gameId, "ID3");
        _createMarket(_gameId, true);
    }

    /// @notice creates markets for a given game ids
    /// @param _gameIds game ids as array
    function createAllMarketsForGames(bytes32[] memory _gameIds) external {
        for (uint i; i < _gameIds.length; i++) {
            createMarketForGame(_gameIds[i]);
        }
    }

    /// @notice resolve market for a given game id
    /// @param _gameId game id
    function resolveMarketForGame(bytes32 _gameId) public {
        require(!isGameResolvedOrCanceled(_gameId), "ID4");
        require(gameFulfilledResolved[_gameId], "ID5");
        _resolveMarket(_gameId, false);
    }

    /// @notice resolve all markets for a given game ids
    /// @param _gameIds game ids as array
    function resolveAllMarketsForGames(bytes32[] memory _gameIds) external {
        for (uint i; i < _gameIds.length; i++) {
            resolveMarketForGame(_gameIds[i]);
        }
    }

    /// @notice resolve market for a given market address
    /// @param _market market address
    /// @param _outcome outcome of a game (1: home win, 2: away win, 3: draw, 0: cancel market)
    /// @param _homeScore score of home team
    /// @param _awayScore score of away team
    function resolveMarketManually(
        address _market,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore,
        bool _useBackupOdds
    ) external isAddressWhitelisted canGameBeResolved(gameIdPerMarket[_market], _outcome, _homeScore, _awayScore) {
        _resolveMarketManually(_market, _outcome, _homeScore, _awayScore, _useBackupOdds);
    }

    /// @notice pause/unpause market for a given market address
    /// @param _market market address
    /// @param _pause pause = true, unpause = false
    function pauseOrUnpauseMarketManually(address _market, bool _pause) external isAddressWhitelisted {
        require(gameIdPerMarket[_market] != 0 && gameFulfilledCreated[gameIdPerMarket[_market]], "ID20");
        _pauseOrUnpauseMarketManually(_market, _pause);
    }

    /// @notice reopen game for processing the creation again
    /// @param gameId gameId
    function reopenGameForCreationProcessing(bytes32 gameId) external isAddressWhitelisted {
        require(gameFulfilledCreated[gameId], "ID22");
        gameFulfilledCreated[gameId] = false;
        gameFulfilledResolved[gameId] = false;
    }

    /// @notice setting isPausedByCanceledStatus from obtainer see @GamesOddsObtainer
    /// @param _market market address
    /// @param _flag flag true/false
    function setPausedByCanceledStatus(address _market, bool _flag) external canExecute {
        isPausedByCanceledStatus[_market] = _flag;
    }

    /// @notice pause market from obtainer see @GamesOddsObtainer
    /// @param _market market address
    /// @param _pause flag true/false
    function pauseOrUnpauseMarket(address _market, bool _pause) external canExecute {
        _pauseOrUnpauseMarket(_market, _pause);
    }

    /// @notice pause market from obtainer see @GamesOddsObtainer
    /// @param _main market address
    /// @param _pause flag true/false
    /// @param _invalidOdds flag true/false for invalid odds
    /// @param _circuitBreaker flag true/false for circuit breaker
    function pauseOrUnpauseMarketForPlayerProps(
        address _main,
        bool _pause,
        bool _invalidOdds,
        bool _circuitBreaker
    ) external canExecute {
        _pauseOrUnpausePlayerProps(_main, _pause, _invalidOdds, _circuitBreaker);
    }

    /// @notice setting gameid per market
    /// @param _gameId game id
    /// @param _child child market address
    function setGameIdPerChildMarket(bytes32 _gameId, address _child) external canExecute {
        gameIdPerMarket[_child] = _gameId;
    }

    /* ========== VIEW FUNCTIONS ========== */

    /// @notice view function which returns game created object based on id of a game
    /// @param _gameId game id
    /// @return GameCreate game create object
    function getGameCreatedById(bytes32 _gameId) public view returns (GameCreate memory) {
        return gameCreated[_gameId];
    }

    /// @notice view function which returns game startTime
    /// @param _gameId game id
    function getGameStartTime(bytes32 _gameId) external view returns (uint256) {
        return gameCreated[_gameId].startTime;
    }

    /// @notice view function which returns lastUpdated from GameResolved struct
    /// @param _gameId game id
    function getLastUpdatedFromGameResolve(bytes32 _gameId) external view returns (uint40) {
        return gameResolved[_gameId].lastUpdated;
    }

    /// @notice view function which returns games on certan date and sportid
    /// @param _sportId date
    /// @param _date date
    /// @return bytes32[] list of games
    function getGamesPerDatePerSport(uint _sportId, uint _date) external view returns (bytes32[] memory) {
        return gamesPerDatePerSport[_sportId][_date];
    }

    /// @notice view function which returns props (sportid and game date)
    /// @param _market market address
    /// @return _sportId sport ids
    /// @return _gameDate game date on which game is playing
    function getGamePropsForOdds(address _market)
        external
        view
        returns (
            uint _sportId,
            uint _gameDate,
            bytes32 _id
        )
    {
        return (sportsIdPerGame[gameIdPerMarket[_market]], gameOnADate[gameIdPerMarket[_market]], gameIdPerMarket[_market]);
    }

    /// @notice view function which returns if game is resolved or canceled and ready for market to be resolved or canceled
    /// @param _gameId game id for which game is looking
    /// @return bool is it ready for resolve or cancel true/false
    function isGameResolvedOrCanceled(bytes32 _gameId) public view returns (bool) {
        return marketResolved[marketPerGameId[_gameId]] || marketCanceled[marketPerGameId[_gameId]];
    }

    /// @notice view function which returns if sport is two positional (no draw, example: NBA)
    /// @param _sportsId sport id for which is looking
    /// @return bool is sport two positional true/false
    function isSportTwoPositionsSport(uint _sportsId) public view returns (bool) {
        return twoPositionSport[_sportsId];
    }

    /// @notice view function which returns if market is child or not
    /// @param _market address of the checked market
    /// @return bool if the _market is child or not (true/false)
    function isChildMarket(address _market) public view returns (bool) {
        return oddsObtainer.childMarketMainMarket(_market) != address(0);
    }

    /// @notice view function which returns normalized odds up to 100 (Example: 50-40-10)
    /// @param _market market
    /// @return uint[] odds array normalized
    function getNormalizedOddsForMarket(address _market) external view returns (uint[] memory) {
        return marketCreated[_market] ? _getNormalizedOdds(gameIdPerMarket[_market]) : _getNormalizedChildOdds(_market);
    }

    /* ========== INTERNALS ========== */

    function _createGameFulfill(
        bytes32 requestId,
        GameCreate memory _game,
        uint _sportId,
        uint _numberOfGames
    ) internal {
        bool automaticCreation = _numberOfGames < maxNumberOfMarketsToCreate;
        gameCreated[_game.gameId] = _game;
        sportsIdPerGame[_game.gameId] = _sportId;
        if (!automaticCreation) {
            queues.enqueueGamesCreated(_game.gameId, _game.startTime, _sportId);
        }
        gameFulfilledCreated[_game.gameId] = true;
        oddsObtainer.setFirstOdds(_game.gameId, _game.homeOdds, _game.awayOdds, _game.drawOdds);

        emit GameCreated(requestId, _sportId, _game.gameId, _game, queues.lastCreated(), _getNormalizedOdds(_game.gameId));

        if (automaticCreation) {
            _createMarket(_game.gameId, false);
        }
    }

    function _resolveGameFulfill(
        bytes32 requestId,
        GameResolve memory _game,
        uint _sportId,
        uint _numberOfMarketsToResolve
    ) internal {
        GameCreate memory singleGameCreated = getGameCreatedById(_game.gameId);

        // if status is resolved OR (status is canceled AND start time has passed fulfill game to be resolved)
        if (
            _isGameStatusResolved(_game) ||
            (cancelGameStatuses[_game.statusId] && singleGameCreated.startTime < block.timestamp)
        ) {
            gameResolved[_game.gameId] = _game;
            gameFulfilledResolved[_game.gameId] = true;

            emit GameResolved(requestId, _sportId, _game.gameId, _game, queues.lastResolved());

            if (_numberOfMarketsToResolve >= maxNumberOfMarketsToResolve) {
                queues.enqueueGamesResolved(_game.gameId);
            } else {
                _resolveMarket(_game.gameId, true);
            }
        }
        // if status is canceled AND start time has not passed only pause market
        else if (cancelGameStatuses[_game.statusId] && singleGameCreated.startTime >= block.timestamp) {
            isPausedByCanceledStatus[marketPerGameId[_game.gameId]] = true;
            _pauseOrUnpauseMarket(marketPerGameId[_game.gameId], true);
            oddsObtainer.pauseUnpauseChildMarkets(marketPerGameId[_game.gameId], true);
            _pauseOrUnpausePlayerProps(marketPerGameId[_game.gameId], true, false, false);
        }
    }

    function _createMarket(bytes32 _gameId, bool _removeFromQueue) internal {
        GameCreate memory game = getGameCreatedById(_gameId);
        // only markets in a future, if not dequeue that creation
        if (game.startTime > block.timestamp) {
            uint[] memory tags = _calculateTags(sportsIdPerGame[_gameId]);

            // create
            ISportPositionalMarket market = sportsManager.createMarket(
                _gameId,
                string(abi.encodePacked(game.homeTeam, " vs ", game.awayTeam)), // gameLabel
                game.startTime, //maturity
                0, //initialMint
                twoPositionSport[sportsIdPerGame[_gameId]] ? 2 : 3,
                tags, //tags
                false,
                address(0)
            );

            marketPerGameId[game.gameId] = address(market);
            gameIdPerMarket[address(market)] = game.gameId;
            marketCreated[address(market)] = true;

            oddsObtainer.setFirstNormalizedOdds(game.gameId, address(market));
            marketForTeamName[game.homeTeam] = address(market);
            marketForTeamName[game.awayTeam] = address(market);

            if (_removeFromQueue) {
                queues.dequeueGamesCreated();
            }
            emit CreateSportsMarket(address(market), game.gameId, game, tags, _getNormalizedOdds(game.gameId));
        } else {
            if (_removeFromQueue) {
                queues.dequeueGamesCreated();
            }
        }
    }

    function _resolveMarket(bytes32 _gameId, bool _resolveMarketWithoutQueue) internal {
        GameResolve memory game = gameResolved[_gameId];
        GameCreate memory singleGameCreated = getGameCreatedById(_gameId);

        if (_isGameStatusResolved(game)) {
            if (oddsObtainer.invalidOdds(marketPerGameId[game.gameId])) {
                _pauseOrUnpauseMarket(marketPerGameId[game.gameId], false);
                oddsObtainer.pauseUnpauseChildMarkets(marketPerGameId[game.gameId], false);
                _pauseOrUnpausePlayerProps(marketPerGameId[game.gameId], false, false, false);
            }

            (uint _outcome, uint8 _homeScore, uint8 _awayScore) = _calculateOutcome(game);

            // if result is draw and game is two positional
            if (_outcome == RESULT_DRAW && twoPositionSport[sportsIdPerGame[game.gameId]]) {
                if (ignoreChildCancellationPerSportIfDraw[sportsIdPerGame[game.gameId]]) {
                    _cancelMainResolveChild(
                        marketPerGameId[game.gameId],
                        _outcome,
                        _homeScore,
                        _awayScore,
                        !_resolveMarketWithoutQueue
                    );
                } else {
                    _cancelMarket(game.gameId, !_resolveMarketWithoutQueue);
                }
            } else {
                // if market is paused only remove from queue
                if (!sportsManager.isMarketPaused(marketPerGameId[game.gameId])) {
                    _setMarketCancelOrResolved(
                        marketPerGameId[game.gameId],
                        _outcome,
                        _homeScore,
                        _awayScore,
                        game.statusId
                    );
                    if (!_resolveMarketWithoutQueue) {
                        _cleanStorageQueue();
                    }

                    emit ResolveSportsMarket(marketPerGameId[game.gameId], game.gameId, _outcome);
                } else {
                    if (!_resolveMarketWithoutQueue) {
                        _cleanStorageQueue();
                    }
                }
            }
            // if status is canceled and start time of a game passed cancel market
        } else if (cancelGameStatuses[game.statusId] && singleGameCreated.startTime < block.timestamp) {
            _cancelMarket(game.gameId, !_resolveMarketWithoutQueue);
        }
    }

    function _resolveMarketManually(
        address _market,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore,
        bool _useBackupOdds
    ) internal {
        if (_useBackupOdds) {
            require(_outcome == CANCELLED, "ID17");
            require(
                oddsObtainer.areOddsValid(
                    gameIdPerMarket[_market],
                    _useBackupOdds,
                    twoPositionSport[sportsIdPerGame[gameIdPerMarket[_market]]]
                )
            );
            oddsObtainer.setBackupOddsAsMainOddsForGame(gameIdPerMarket[_market]);
        }

        _pauseOrUnpauseMarket(_market, false);
        oddsObtainer.pauseUnpauseChildMarkets(_market, false);
        _pauseOrUnpausePlayerProps(_market, false, false, false);
        _setMarketCancelOrResolved(
            _market,
            _outcome,
            _homeScore,
            _awayScore,
            twoPositionSport[sportsIdPerGame[gameIdPerMarket[_market]]] ? 8 : 11
        );
        gameResolved[gameIdPerMarket[_market]] = GameResolve(
            gameIdPerMarket[_market],
            _homeScore,
            _awayScore,
            twoPositionSport[sportsIdPerGame[gameIdPerMarket[_market]]] ? 8 : 11,
            0
        );

        emit GameResolved(
            gameIdPerMarket[_market], // no req. from CL (manual resolve) so just put gameID
            sportsIdPerGame[gameIdPerMarket[_market]],
            gameIdPerMarket[_market],
            gameResolved[gameIdPerMarket[_market]],
            0
        );

        if (_outcome == CANCELLED) {
            emit CancelSportsMarket(_market, gameIdPerMarket[_market]);
        } else {
            emit ResolveSportsMarket(_market, gameIdPerMarket[_market], _outcome);
        }
    }

    function _pauseOrUnpauseMarketManually(address _market, bool _pause) internal {
        _pauseOrUnpauseMarket(_market, _pause);
        oddsObtainer.pauseUnpauseCurrentActiveChildMarket(gameIdPerMarket[_market], _market, _pause);
    }

    function _pauseOrUnpausePlayerProps(
        address _market,
        bool _pause,
        bool _invalidOdds,
        bool _circuitBreaker
    ) internal {
        playerProps.pauseAllPlayerPropsMarketForMain(_market, _pause, _invalidOdds, _circuitBreaker);
    }

    function _pauseOrUnpauseMarket(address _market, bool _pause) internal {
        if (sportsManager.isMarketPaused(_market) != _pause) {
            sportsManager.setMarketPaused(_market, _pause);
            emit PauseSportsMarket(_market, _pause);
        }
    }

    function _cancelMarket(bytes32 _gameId, bool cleanStorage) internal {
        _setMarketCancelOrResolved(marketPerGameId[_gameId], CANCELLED, 0, 0, 0);
        if (cleanStorage) {
            _cleanStorageQueue();
        }

        emit CancelSportsMarket(marketPerGameId[_gameId], _gameId);
    }

    function _setMarketCancelOrResolved(
        address _market,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore,
        uint8 _status
    ) internal {
        sportsManager.resolveMarket(_market, _outcome);
        if (_status == STATUS_RETIRED) {
            oddsObtainer.resolveChildMarkets(_market, 0, 0, 0);
        } else {
            oddsObtainer.resolveChildMarkets(_market, _outcome, _homeScore, _awayScore);
            if (_outcome == CANCELLED) {
                playerProps.cancelPlayerPropsMarketForMain(_market);
            }
        }
        marketCanceled[_market] = _outcome == CANCELLED;
        marketResolved[_market] = _outcome != CANCELLED;
    }

    function _cancelMainResolveChild(
        address _market,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore,
        bool _cleanStorage
    ) internal {
        sportsManager.resolveMarket(_market, 0); // cancel main
        oddsObtainer.resolveChildMarkets(_market, _outcome, _homeScore, _awayScore);
        marketCanceled[_market] = false;
        marketResolved[_market] = true; // must be true because of player props resolve
        if (_cleanStorage) {
            _cleanStorageQueue();
        }
        emit CancelSportsMarket(_market, gameIdPerMarket[_market]);
    }

    function _cleanStorageQueue() internal {
        queues.dequeueGamesResolved();
    }

    function _calculateTags(uint _sportsId) internal pure returns (uint[] memory) {
        uint[] memory result = new uint[](1);
        result[0] = MIN_TAG_NUMBER + _sportsId;
        return result;
    }

    function _isGameStatusResolved(GameResolve memory _game) internal view returns (bool) {
        return supportResolveGameStatuses[_game.statusId];
    }

    function _calculateOutcome(GameResolve memory _game)
        internal
        pure
        returns (
            uint,
            uint8,
            uint8
        )
    {
        if (_game.homeScore == _game.awayScore) {
            return (RESULT_DRAW, _game.homeScore, _game.awayScore);
        }
        return
            _game.homeScore > _game.awayScore
                ? (HOME_WIN, _game.homeScore, _game.awayScore)
                : (AWAY_WIN, _game.homeScore, _game.awayScore);
    }

    function _updateGameOnADate(
        bytes32 _gameId,
        uint _date,
        uint _sportId
    ) internal {
        if (gameOnADate[_gameId] != _date) {
            gamesPerDatePerSport[_sportId][_date].push(_gameId);
            gameOnADate[_gameId] = _date;
        }
    }

    function _getNormalizedOdds(bytes32 _gameId) internal view returns (uint[] memory) {
        return oddsObtainer.getNormalizedOdds(_gameId);
    }

    function _getNormalizedChildOdds(address _market) internal view returns (uint[] memory) {
        return
            oddsObtainer.childMarketCreated(_market)
                ? oddsObtainer.getNormalizedOddsForMarket(_market)
                : playerProps.getNormalizedOddsForMarket(_market);
    }

    /* ========== CONTRACT MANAGEMENT ========== */

    /// @notice sets if sport is suported or not (delete from supported sport)
    /// @param _sportId sport id which needs to be supported or not
    /// @param _isSupported true/false (supported or not)
    function setSupportedSport(uint _sportId, bool _isSupported) external onlyOwner {
        require(supportedSport[_sportId] != _isSupported);
        supportedSport[_sportId] = _isSupported;
        emit SupportedSportsChanged(_sportId, _isSupported);
    }

    /// @notice sets resolved status which is supported or not
    /// @param _status status ID which needs to be supported or not
    /// @param _isSupported true/false (supported or not)
    function setSupportedResolvedStatuses(uint _status, bool _isSupported) external onlyOwner {
        require(supportResolveGameStatuses[_status] != _isSupported);
        supportResolveGameStatuses[_status] = _isSupported;
        emit SupportedResolvedStatusChanged(_status, _isSupported);
    }

    /// @notice sets cancel status which is supported or not
    /// @param _status ststus ID which needs to be supported or not
    /// @param _isSupported true/false (supported or not)
    function setSupportedCancelStatuses(uint _status, bool _isSupported) external onlyOwner {
        require(cancelGameStatuses[_status] != _isSupported);
        cancelGameStatuses[_status] = _isSupported;
        emit SupportedCancelStatusChanged(_status, _isSupported);
    }

    /// @notice sets ignoring children cancelation
    /// @param _sportId sport if
    /// @param _flag true/false
    function setIgnoreChildCancellationPerSportIfDraw(uint _sportId, bool _flag) external onlyOwner {
        ignoreChildCancellationPerSportIfDraw[_sportId] = _flag;
        emit IgnoreChildCancellationPerSportIfDraw(_sportId, _flag);
    }

    /// @notice sets if sport is two positional (Example: NBA)
    /// @param _sportId sport ID which is two positional
    /// @param _isTwoPosition true/false (two positional sport or not)
    function setTwoPositionSport(uint _sportId, bool _isTwoPosition) external onlyOwner {
        require(supportedSport[_sportId] && twoPositionSport[_sportId] != _isTwoPosition);
        twoPositionSport[_sportId] = _isTwoPosition;
        emit TwoPositionSportChanged(_sportId, _isTwoPosition);
    }

    /// @notice sets how many markets (main + children) are processed without queue
    /// @param _maxNumberOfMarketsToResolve max number of markets for automatic resolve w/o queue entering
    function setNewMaxNumberOfMarketsToResolveAndResolve(uint _maxNumberOfMarketsToResolve, uint _maxNumberOfMarketsToCreate)
        external
        onlyOwner
    {
        require(
            maxNumberOfMarketsToResolve != _maxNumberOfMarketsToResolve ||
                maxNumberOfMarketsToCreate != _maxNumberOfMarketsToCreate
        );
        maxNumberOfMarketsToResolve = _maxNumberOfMarketsToResolve;
        maxNumberOfMarketsToCreate = _maxNumberOfMarketsToCreate;
        emit NewMaxNumberOfMarketsToResolveAndCreate(_maxNumberOfMarketsToResolve, _maxNumberOfMarketsToCreate);
    }

    /// @notice sets wrapper, manager, queue  address
    /// @param _wrapperAddress wrapper address
    /// @param _queues queue address
    /// @param _sportsManager sport manager address
    function setSportContracts(
        address _wrapperAddress,
        GamesQueue _queues,
        address _sportsManager,
        address _verifier,
        address _oddsObtainer,
        address _playerProps
    ) external onlyOwner {
        sportsManager = ISportPositionalMarketManager(_sportsManager);
        queues = _queues;
        wrapperAddress = _wrapperAddress;
        verifier = ITherundownConsumerVerifier(_verifier);
        oddsObtainer = IGamesOddsObtainer(_oddsObtainer);
        playerProps = IGamesPlayerProps(_playerProps);

        emit NewSportContracts(_wrapperAddress, _queues, _sportsManager, _verifier, _oddsObtainer, _playerProps);
    }

    /// @notice adding/removing whitelist address depending on a flag
    /// @param _whitelistAddress address that needed to be whitelisted/ ore removed from WL
    /// @param _flag adding or removing from whitelist (true: add, false: remove)
    function addToWhitelist(address _whitelistAddress, bool _flag) external onlyOwner {
        require(_whitelistAddress != address(0) && whitelistedAddresses[_whitelistAddress] != _flag);
        whitelistedAddresses[_whitelistAddress] = _flag;
        emit AddedIntoWhitelist(_whitelistAddress, _flag);
    }

    /* ========== MODIFIERS ========== */

    modifier onlyWrapper() {
        require(msg.sender == wrapperAddress, "ID9");
        _;
    }

    modifier canExecute() {
        require(msg.sender == address(oddsObtainer) || msg.sender == address(playerProps), "ID18");
        _;
    }

    modifier isAddressWhitelisted() {
        require(whitelistedAddresses[msg.sender], "ID10");
        _;
    }

    modifier canGameBeResolved(
        bytes32 _gameId,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore
    ) {
        require(!isGameResolvedOrCanceled(_gameId), "ID13");
        require(marketPerGameId[_gameId] != address(0), "ID14");
        require(
            verifier.isValidOutcomeForGame(twoPositionSport[sportsIdPerGame[_gameId]], _outcome) &&
                verifier.isValidOutcomeWithResult(_outcome, _homeScore, _awayScore),
            "ID15"
        );
        _;
    }
    /* ========== EVENTS ========== */

    event GameCreated(
        bytes32 _requestId,
        uint _sportId,
        bytes32 _id,
        GameCreate _game,
        uint _queueIndex,
        uint[] _normalizedOdds
    );
    event GameResolved(bytes32 _requestId, uint _sportId, bytes32 _id, GameResolve _game, uint _queueIndex);
    event CreateSportsMarket(address _marketAddress, bytes32 _id, GameCreate _game, uint[] _tags, uint[] _normalizedOdds);
    event ResolveSportsMarket(address _marketAddress, bytes32 _id, uint _outcome);
    event PauseSportsMarket(address _marketAddress, bool _pause);
    event CancelSportsMarket(address _marketAddress, bytes32 _id);
    event SupportedSportsChanged(uint _sportId, bool _isSupported);
    event SupportedResolvedStatusChanged(uint _status, bool _isSupported);
    event SupportedCancelStatusChanged(uint _status, bool _isSupported);
    event TwoPositionSportChanged(uint _sportId, bool _isTwoPosition);
    event NewSportContracts(
        address _wrapperAddress,
        GamesQueue _queues,
        address _sportsManager,
        address _verifier,
        address _oddsObtainer,
        address _playerProps
    );
    event AddedIntoWhitelist(address _whitelistAddress, bool _flag);
    event NewMaxNumberOfMarketsToResolveAndCreate(uint _maxNumberResolve, uint _maxNumberCreate);
    event GameTimeMovedAhead(address _market, bytes32 _gameId, uint _oldStartTime, uint _newStartTime);
    event IgnoreChildCancellationPerSportIfDraw(uint _sportId, bool _flag);
}

File 2 of 17 : PausableUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    function __Pausable_init() internal onlyInitializing {
        __Context_init_unchained();
        __Pausable_init_unchained();
    }

    function __Pausable_init_unchained() internal onlyInitializing {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
    uint256[49] private __gap;
}

File 3 of 17 : Initializable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)

pragma solidity ^0.8.0;

import "../../utils/AddressUpgradeable.sol";

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
 * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() initializer {}
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        // If the contract is initializing we ignore whether _initialized is set in order to support multiple
        // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
        // contract may have been reentered.
        require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} modifier, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    function _isConstructor() private view returns (bool) {
        return !AddressUpgradeable.isContract(address(this));
    }
}

File 4 of 17 : ProxyOwned.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// Clone of syntetix contract without constructor
contract ProxyOwned {
    address public owner;
    address public nominatedOwner;
    bool private _initialized;
    bool private _transferredAtInit;

    function setOwner(address _owner) public {
        require(_owner != address(0), "Owner address cannot be 0");
        require(!_initialized, "Already initialized, use nominateNewOwner");
        _initialized = true;
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }

    function nominateNewOwner(address _owner) external onlyOwner {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }

    function acceptOwnership() external {
        require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }

    function transferOwnershipAtInit(address proxyAddress) external onlyOwner {
        require(proxyAddress != address(0), "Invalid address");
        require(!_transferredAtInit, "Already transferred");
        owner = proxyAddress;
        _transferredAtInit = true;
        emit OwnerChanged(owner, proxyAddress);
    }

    modifier onlyOwner {
        _onlyOwner();
        _;
    }

    function _onlyOwner() private view {
        require(msg.sender == owner, "Only the contract owner may perform this action");
    }

    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}

File 5 of 17 : ProxyPausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// Inheritance
import "./ProxyOwned.sol";

// Clone of syntetix contract without constructor

contract ProxyPausable is ProxyOwned {
    uint public lastPauseTime;
    bool public paused;

    

    /**
     * @notice Change the paused state of the contract
     * @dev Only the contract owner may call this.
     */
    function setPaused(bool _paused) external onlyOwner {
        // Ensure we're actually changing the state before we do anything
        if (_paused == paused) {
            return;
        }

        // Set our paused state.
        paused = _paused;

        // If applicable, set the last pause time.
        if (paused) {
            lastPauseTime = block.timestamp;
        }

        // Let everyone know that our pause state has changed.
        emit PauseChanged(paused);
    }

    event PauseChanged(bool isPaused);

    modifier notPaused {
        require(!paused, "This action cannot be performed while the contract is paused");
        _;
    }
}

File 6 of 17 : GamesQueue.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

// internal
import "../../utils/proxy/solidity-0.8.0/ProxyOwned.sol";
import "../../utils/proxy/solidity-0.8.0/ProxyPausable.sol";

/// @title Storage for games (created or resolved), calculation for order-making bot processing
/// @author gruja
contract GamesQueue is Initializable, ProxyOwned, ProxyPausable {
    // create games queue
    mapping(uint => bytes32) public gamesCreateQueue;
    mapping(bytes32 => bool) public existingGamesInCreatedQueue;
    uint public firstCreated;
    uint public lastCreated;
    mapping(bytes32 => uint) private gameStartPerGameId;

    // resolve games queue
    bytes32[] public unproccessedGames;
    mapping(bytes32 => uint) public unproccessedGamesIndex;
    mapping(uint => bytes32) public gamesResolvedQueue;
    mapping(bytes32 => bool) public existingGamesInResolvedQueue;
    uint public firstResolved;
    uint public lastResolved;

    address public consumer;
    mapping(address => bool) public whitelistedAddresses;

    /// @notice public initialize proxy method
    /// @param _owner future owner of a contract
    function initialize(address _owner) public initializer {
        setOwner(_owner);
        firstCreated = 1;
        lastCreated = 0;
        firstResolved = 1;
        lastResolved = 0;
    }

    /// @notice putting game in a crated queue and fill up unprocessed games array
    /// @param data id of a game in byte32
    /// @param startTime game start time
    /// @param sportsId id of a sport (Example: NBA = 4 etc.)
    function enqueueGamesCreated(
        bytes32 data,
        uint startTime,
        uint sportsId
    ) public canExecuteFunction {
        lastCreated += 1;
        gamesCreateQueue[lastCreated] = data;

        existingGamesInCreatedQueue[data] = true;

        emit EnqueueGamesCreated(data, sportsId, lastCreated);
    }

    /// @notice removing first game in a queue from created queue
    /// @return data returns id of a game which is removed
    function dequeueGamesCreated() public canExecuteFunction returns (bytes32 data) {
        require(lastCreated >= firstCreated, "No more elements in a queue");

        data = gamesCreateQueue[firstCreated];

        delete gamesCreateQueue[firstCreated];
        firstCreated += 1;

        emit DequeueGamesCreated(data, firstResolved - 1);
    }

    /// @notice putting game in a resolved queue
    /// @param data id of a game in byte32
    function enqueueGamesResolved(bytes32 data) public canExecuteFunction {
        lastResolved += 1;
        gamesResolvedQueue[lastResolved] = data;
        existingGamesInResolvedQueue[data] = true;

        emit EnqueueGamesResolved(data, lastCreated);
    }

    /// @notice removing first game in a queue from resolved queue
    /// @return data returns id of a game which is removed
    function dequeueGamesResolved() public canExecuteFunction returns (bytes32 data) {
        require(lastResolved >= firstResolved, "No more elements in a queue");

        data = gamesResolvedQueue[firstResolved];

        delete gamesResolvedQueue[firstResolved];
        firstResolved += 1;

        emit DequeueGamesResolved(data, firstResolved - 1);
    }

    /// @notice sets the consumer contract address, which only owner can execute
    /// @param _consumer address of a consumer contract
    function setConsumerAddress(address _consumer) external onlyOwner {
        require(_consumer != address(0), "Invalid address");
        consumer = _consumer;
        emit NewConsumerAddress(_consumer);
    }

    /// @notice adding/removing whitelist address depending on a flag
    /// @param _whitelistAddress address that needed to be whitelisted/ ore removed from WL
    /// @param _flag adding or removing from whitelist (true: add, false: remove)
    function addToWhitelist(address _whitelistAddress, bool _flag) external onlyOwner {
        require(_whitelistAddress != address(0) && whitelistedAddresses[_whitelistAddress] != _flag, "Invalid");
        whitelistedAddresses[_whitelistAddress] = _flag;
        emit AddedIntoWhitelist(_whitelistAddress, _flag);
    }

    modifier canExecuteFunction() {
        require(msg.sender == consumer || whitelistedAddresses[msg.sender], "Only consumer or whitelisted address");
        _;
    }

    event EnqueueGamesCreated(bytes32 _gameId, uint _sportId, uint _index);
    event EnqueueGamesResolved(bytes32 _gameId, uint _index);
    event DequeueGamesCreated(bytes32 _gameId, uint _index);
    event DequeueGamesResolved(bytes32 _gameId, uint _index);
    event NewConsumerAddress(address _consumer);
    event AddedIntoWhitelist(address _whitelistAddress, bool _flag);
}

File 7 of 17 : ISportPositionalMarketManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../interfaces/ISportPositionalMarket.sol";

interface ISportPositionalMarketManager {
    /* ========== VIEWS / VARIABLES ========== */

    function marketCreationEnabled() external view returns (bool);

    function totalDeposited() external view returns (uint);

    function numActiveMarkets() external view returns (uint);

    function activeMarkets(uint index, uint pageSize) external view returns (address[] memory);

    function numMaturedMarkets() external view returns (uint);

    function maturedMarkets(uint index, uint pageSize) external view returns (address[] memory);

    function isActiveMarket(address candidate) external view returns (bool);

    function isDoubleChanceMarket(address candidate) external view returns (bool);

    function doesSportSupportDoubleChance(uint _sport) external view returns (bool);

    function isDoubleChanceSupported() external view returns (bool);

    function isKnownMarket(address candidate) external view returns (bool);

    function getActiveMarketAddress(uint _index) external view returns (address);

    function transformCollateral(uint value) external view returns (uint);

    function reverseTransformCollateral(uint value) external view returns (uint);

    function isMarketPaused(address _market) external view returns (bool);

    function expiryDuration() external view returns (uint);

    function isWhitelistedAddress(address _address) external view returns (bool);

    function getOddsObtainer() external view returns (address obtainer);

    /* ========== MUTATIVE FUNCTIONS ========== */

    function createMarket(
        bytes32 gameId,
        string memory gameLabel,
        uint maturity,
        uint initialMint, // initial sUSD to mint options for,
        uint positionCount,
        uint[] memory tags,
        bool isChild,
        address parentMarket
    ) external returns (ISportPositionalMarket);

    function setMarketPaused(address _market, bool _paused) external;

    function updateDatesForMarket(address _market, uint256 _newStartTime) external;

    function resolveMarket(address market, uint outcome) external;

    function expireMarkets(address[] calldata market) external;

    function transferSusdTo(
        address sender,
        address receiver,
        uint amount
    ) external;

    function queryMintsAndMaturityStatusForPlayerProps(address[] memory _playerPropsMarkets)
        external
        view
        returns (
            bool[] memory _hasAnyMintsArray,
            bool[] memory _isMaturedArray,
            bool[] memory _isResolvedArray,
            uint[] memory _maturities
        );
}

File 8 of 17 : ITherundownConsumerVerifier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface ITherundownConsumerVerifier {
    // view functions
    function isInvalidNames(string memory _teamA, string memory _teamB) external view returns (bool);

    function areTeamsEqual(string memory _teamA, string memory _teamB) external view returns (bool);

    function isSupportedMarketType(string memory _market) external view returns (bool);

    function areOddsArrayInThreshold(
        uint _sportId,
        uint[] memory _currentOddsArray,
        uint[] memory _newOddsArray,
        bool _isTwoPositionalSport
    ) external view returns (bool);

    function areOddsValid(
        bool _isTwoPositionalSport,
        int24 _homeOdds,
        int24 _awayOdds,
        int24 _drawOdds
    ) external view returns (bool);

    function areSpreadOddsValid(
        int16 spreadHome,
        int24 spreadHomeOdds,
        int16 spreadAway,
        int24 spreadAwayOdds
    ) external view returns (bool);

    function areTotalOddsValid(
        uint24 totalOver,
        int24 totalOverOdds,
        uint24 totalUnder,
        int24 totalUnderOdds
    ) external view returns (bool);

    function areOddsAndLinesValidForPlayer(
        uint16 _line,
        int24 _overOdds,
        int24 _underOdds
    ) external pure returns (bool);

    function isValidOutcomeForGame(bool _isTwoPositionalSport, uint _outcome) external view returns (bool);

    function isValidOutcomeWithResult(
        uint _outcome,
        uint _homeScore,
        uint _awayScore
    ) external view returns (bool);

    function calculateAndNormalizeOdds(int[] memory _americanOdds) external view returns (uint[] memory);

    function getBookmakerIdsBySportId(uint256 _sportId) external view returns (uint256[] memory);

    function getBookmakerIdsBySportIdForPlayerProps(uint256 _sportId) external view returns (uint256[] memory);

    function getStringIDsFromBytesArrayIDs(bytes32[] memory _ids) external view returns (string[] memory);

    function convertUintToString(uint8[] memory _options) external view returns (string[] memory);
}

File 9 of 17 : IGamesOddsObtainer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IGamesOddsObtainer {
    struct GameOdds {
        bytes32 gameId;
        int24 homeOdds;
        int24 awayOdds;
        int24 drawOdds;
        int16 spreadHome;
        int24 spreadHomeOdds;
        int16 spreadAway;
        int24 spreadAwayOdds;
        uint24 totalOver;
        int24 totalOverOdds;
        uint24 totalUnder;
        int24 totalUnderOdds;
    }

    // view

    function getActiveChildMarketsFromParent(address _parent) external view returns (address, address);

    function getSpreadTotalsChildMarketsFromParent(address _parent)
        external
        view
        returns (
            uint numOfSpreadMarkets,
            address[] memory spreadMarkets,
            uint numOfTotalsMarkets,
            address[] memory totalMarkets
        );

    function areOddsValid(
        bytes32 _gameId,
        bool _useBackup,
        bool _isTwoPositional
    ) external view returns (bool);

    function invalidOdds(address _market) external view returns (bool);

    function playersReportTimestamp(address _market) external view returns (uint);

    function getNormalizedOdds(bytes32 _gameId) external view returns (uint[] memory);

    function getNormalizedOddsForMarket(address _market) external view returns (uint[] memory);

    function getOddsForGames(bytes32[] memory _gameIds) external view returns (int24[] memory odds);

    function mainMarketChildMarketIndex(address _main, uint _index) external view returns (address);

    function numberOfChildMarkets(address _main) external view returns (uint);

    function mainMarketSpreadChildMarket(address _main, int16 _spread) external view returns (address);

    function mainMarketTotalChildMarket(address _main, uint24 _total) external view returns (address);

    function childMarketMainMarket(address _market) external view returns (address);

    function childMarketTotal(address _market) external view returns (uint24);

    function currentActiveTotalChildMarket(address _main) external view returns (address);

    function currentActiveSpreadChildMarket(address _main) external view returns (address);

    function isSpreadChildMarket(address _child) external view returns (bool);

    function childMarketCreated(address _child) external view returns (bool);

    function getOddsForGame(bytes32 _gameId)
        external
        view
        returns (
            int24,
            int24,
            int24,
            int24,
            int24,
            int24,
            int24
        );

    function getLinesForGame(bytes32 _gameId)
        external
        view
        returns (
            int16,
            int16,
            uint24,
            uint24
        );

    // executable

    function obtainOdds(
        bytes32 requestId,
        GameOdds memory _game,
        uint _sportId,
        address _main,
        bool _isTwoPositional,
        bool _isPlayersReport
    ) external;

    function setFirstOdds(
        bytes32 _gameId,
        int24 _homeOdds,
        int24 _awayOdds,
        int24 _drawOdds
    ) external;

    function setFirstNormalizedOdds(bytes32 _gameId, address _market) external;

    function setBackupOddsAsMainOddsForGame(bytes32 _gameId) external;

    function pauseUnpauseChildMarkets(address _main, bool _flag) external;

    function pauseUnpauseCurrentActiveChildMarket(
        bytes32 _gameId,
        address _main,
        bool _flag
    ) external;

    function resolveChildMarkets(
        address _market,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore
    ) external;

    function setChildMarketGameId(bytes32 gameId, address market) external;
}

File 10 of 17 : ISportPositionalMarket.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16;

import "../interfaces/IPositionalMarketManager.sol";
import "../interfaces/IPosition.sol";
import "../interfaces/IPriceFeed.sol";

interface ISportPositionalMarket {
    /* ========== TYPES ========== */

    enum Phase {
        Trading,
        Maturity,
        Expiry
    }
    enum Side {
        Cancelled,
        Home,
        Away,
        Draw
    }

    /* ========== VIEWS / VARIABLES ========== */

    function getOptions()
        external
        view
        returns (
            IPosition home,
            IPosition away,
            IPosition draw
        );

    function times() external view returns (uint maturity, uint destruction);

    function getGameDetails() external view returns (bytes32 gameId, string memory gameLabel);

    function getGameId() external view returns (bytes32);

    function deposited() external view returns (uint);

    function optionsCount() external view returns (uint);

    function creator() external view returns (address);

    function resolved() external view returns (bool);

    function cancelled() external view returns (bool);

    function paused() external view returns (bool);

    function phase() external view returns (Phase);

    function canResolve() external view returns (bool);

    function result() external view returns (Side);

    function isChild() external view returns (bool);

    function optionsInitialized() external view returns (bool);

    function tags(uint idx) external view returns (uint);

    function getTags() external view returns (uint tag1, uint tag2);

    function getTagsLength() external view returns (uint tagsLength);

    function getParentMarketPositions() external view returns (IPosition position1, IPosition position2);

    function getParentMarketPositionsUint() external view returns (uint position1, uint position2);

    function getStampedOdds()
        external
        view
        returns (
            uint,
            uint,
            uint
        );

    function balancesOf(address account)
        external
        view
        returns (
            uint home,
            uint away,
            uint draw
        );

    function totalSupplies()
        external
        view
        returns (
            uint home,
            uint away,
            uint draw
        );

    function isDoubleChance() external view returns (bool);

    function parentMarket() external view returns (ISportPositionalMarket);

    /* ========== MUTATIVE FUNCTIONS ========== */

    function setPaused(bool _paused) external;

    function updateDates(uint256 _maturity, uint256 _expiry) external;

    function mint(uint value) external;

    function exerciseOptions() external;

    function restoreInvalidOdds(
        uint _homeOdds,
        uint _awayOdds,
        uint _drawOdds
    ) external;
}

File 11 of 17 : IGamesPlayerProps.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IGamesPlayerProps {
    struct PlayerProps {
        bytes32 gameId;
        bytes32 playerId;
        uint8 option;
        string playerName;
        uint16 line;
        int24 overOdds;
        int24 underOdds;
    }

    struct PlayerPropsResolver {
        bytes32 gameId;
        bytes32 playerId;
        uint8 option;
        uint16 score;
        uint8 statusId;
    }

    function obtainPlayerProps(PlayerProps memory _player, uint _sportId) external;

    function resolvePlayerProps(PlayerPropsResolver memory _result) external;

    function cancelMarketFromManager(address _market) external;

    function pauseAllPlayerPropsMarketForMain(
        address _main,
        bool _flag,
        bool _invalidOddsOnMain,
        bool _circuitBreakerMain
    ) external;

    function createFulfilledForPlayerProps(
        bytes32 gameId,
        bytes32 playerId,
        uint8 option
    ) external view returns (bool);

    function cancelPlayerPropsMarketForMain(address _main) external;

    function getNormalizedOddsForMarket(address _market) external view returns (uint[] memory);

    function mainMarketChildMarketIndex(address _main, uint _index) external view returns (address);

    function numberOfChildMarkets(address _main) external view returns (uint);

    function doesSportSupportPlayerProps(uint _sportId) external view returns (bool);

    function pausedByInvalidOddsOnMain(address _main) external view returns (bool);

    function pausedByCircuitBreakerOnMain(address _main) external view returns (bool);

    function playerIdPerChildMarket(address _market) external view returns (bytes32);

    function optionIdPerChildMarket(address _market) external view returns (uint8);

    function getAllOptionsWithPlayersForGameId(bytes32 _gameId)
        external
        view
        returns (
            bytes32[] memory _playerIds,
            uint8[] memory _options,
            bool[] memory _isResolved,
            address[][] memory _childMarketsPerOption
        );

    function getPlayerPropsDataForMarket(address _market)
        external
        view
        returns (
            address,
            bytes32,
            bytes32,
            uint8
        );

    function getPlayerPropForOption(
        bytes32 gameId,
        bytes32 playerId,
        uint8 option
    )
        external
        view
        returns (
            uint16,
            int24,
            int24,
            bool
        );

    function fulfillPlayerPropsCLResolved(bytes[] memory _playerProps) external;
}

File 12 of 17 : ContextUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";

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

    function __Context_init_unchained() internal onlyInitializing {
    }
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
    uint256[50] private __gap;
}

File 13 of 17 : AddressUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

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

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 14 of 17 : IPositionalMarketManager.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.16;

import "../interfaces/IPositionalMarket.sol";

interface IPositionalMarketManager {
    /* ========== VIEWS / VARIABLES ========== */

    function durations() external view returns (uint expiryDuration, uint maxTimeToMaturity);

    function capitalRequirement() external view returns (uint);

    function marketCreationEnabled() external view returns (bool);

    function onlyAMMMintingAndBurning() external view returns (bool);

    function transformCollateral(uint value) external view returns (uint);

    function reverseTransformCollateral(uint value) external view returns (uint);

    function totalDeposited() external view returns (uint);

    function numActiveMarkets() external view returns (uint);

    function activeMarkets(uint index, uint pageSize) external view returns (address[] memory);

    function numMaturedMarkets() external view returns (uint);

    function maturedMarkets(uint index, uint pageSize) external view returns (address[] memory);

    function isActiveMarket(address candidate) external view returns (bool);

    function isKnownMarket(address candidate) external view returns (bool);

    function getThalesAMM() external view returns (address);

    /* ========== MUTATIVE FUNCTIONS ========== */

    function createMarket(
        bytes32 oracleKey,
        uint strikePrice,
        uint maturity,
        uint initialMint // initial sUSD to mint options for,
    ) external returns (IPositionalMarket);

    function resolveMarket(address market) external;

    function expireMarkets(address[] calldata market) external;

    function transferSusdTo(
        address sender,
        address receiver,
        uint amount
    ) external;
}

File 15 of 17 : IPosition.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.16;

import "./IPositionalMarket.sol";

interface IPosition {
    /* ========== VIEWS / VARIABLES ========== */

    function getBalanceOf(address account) external view returns (uint);

    function getTotalSupply() external view returns (uint);

    function exerciseWithAmount(address claimant, uint amount) external;
}

File 16 of 17 : IPriceFeed.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.16;

interface IPriceFeed {
    // Structs
    struct RateAndUpdatedTime {
        uint216 rate;
        uint40 time;
    }

    // Mutative functions
    function addAggregator(bytes32 currencyKey, address aggregatorAddress) external;

    function removeAggregator(bytes32 currencyKey) external;

    // Views

    function rateForCurrency(bytes32 currencyKey) external view returns (uint);

    function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time);

    function getRates() external view returns (uint[] memory);

    function getCurrencies() external view returns (bytes32[] memory);
}

File 17 of 17 : IPositionalMarket.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.16;

import "../interfaces/IPositionalMarketManager.sol";
import "../interfaces/IPosition.sol";
import "../interfaces/IPriceFeed.sol";

interface IPositionalMarket {
    /* ========== TYPES ========== */

    enum Phase {
        Trading,
        Maturity,
        Expiry
    }
    enum Side {
        Up,
        Down
    }

    /* ========== VIEWS / VARIABLES ========== */

    function getOptions() external view returns (IPosition up, IPosition down);

    function times() external view returns (uint maturity, uint destructino);

    function getOracleDetails()
        external
        view
        returns (
            bytes32 key,
            uint strikePrice,
            uint finalPrice
        );

    function fees() external view returns (uint poolFee, uint creatorFee);

    function deposited() external view returns (uint);

    function creator() external view returns (address);

    function resolved() external view returns (bool);

    function phase() external view returns (Phase);

    function oraclePrice() external view returns (uint);

    function oraclePriceAndTimestamp() external view returns (uint price, uint updatedAt);

    function canResolve() external view returns (bool);

    function result() external view returns (Side);

    function balancesOf(address account) external view returns (uint up, uint down);

    function totalSupplies() external view returns (uint up, uint down);

    function getMaximumBurnable(address account) external view returns (uint amount);

    /* ========== MUTATIVE FUNCTIONS ========== */

    function mint(uint value) external;

    function exerciseOptions() external returns (uint);

    function burnOptions(uint amount) external;

    function burnOptionsMaximum() external;
}

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

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_whitelistAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"_flag","type":"bool"}],"name":"AddedIntoWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"CancelSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"}],"indexed":false,"internalType":"struct TherundownConsumer.GameCreate","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256[]","name":"_tags","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"}],"name":"CreateSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"}],"indexed":false,"internalType":"struct TherundownConsumer.GameCreate","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"_queueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"}],"name":"GameCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint8","name":"homeScore","type":"uint8"},{"internalType":"uint8","name":"awayScore","type":"uint8"},{"internalType":"uint8","name":"statusId","type":"uint8"},{"internalType":"uint40","name":"lastUpdated","type":"uint40"}],"indexed":false,"internalType":"struct TherundownConsumer.GameResolve","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"_queueIndex","type":"uint256"}],"name":"GameResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_market","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_oldStartTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newStartTime","type":"uint256"}],"name":"GameTimeMovedAhead","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_flag","type":"bool"}],"name":"IgnoreChildCancellationPerSportIfDraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_maxNumberResolve","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_maxNumberCreate","type":"uint256"}],"name":"NewMaxNumberOfMarketsToResolveAndCreate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_wrapperAddress","type":"address"},{"indexed":false,"internalType":"contract GamesQueue","name":"_queues","type":"address"},{"indexed":false,"internalType":"address","name":"_sportsManager","type":"address"},{"indexed":false,"internalType":"address","name":"_verifier","type":"address"},{"indexed":false,"internalType":"address","name":"_oddsObtainer","type":"address"},{"indexed":false,"internalType":"address","name":"_playerProps","type":"address"}],"name":"NewSportContracts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"_pause","type":"bool"}],"name":"PauseSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_outcome","type":"uint256"}],"name":"ResolveSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_status","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"SupportedCancelStatusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_status","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"SupportedResolvedStatusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"SupportedSportsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_isTwoPosition","type":"bool"}],"name":"TwoPositionSportChanged","type":"event"},{"inputs":[],"name":"AWAY_WIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CANCELLED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HOME_WIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_TAG_NUMBER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESULT_DRAW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STATUS_RETIRED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_whitelistAddress","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"cancelGameStatuses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"}],"name":"createAllMarketsForGames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"createMarketForGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"bytes[]","name":"_games","type":"bytes[]"},{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"uint256","name":"_date","type":"uint256"}],"name":"fulfillGamesCreated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"bytes[]","name":"_games","type":"bytes[]"}],"name":"fulfillGamesOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"bytes[]","name":"_games","type":"bytes[]"},{"internalType":"uint256","name":"_sportId","type":"uint256"}],"name":"fulfillGamesResolved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameCreated","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameFulfilledCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameFulfilledResolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gameIdPerMarket","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameOnADate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameResolved","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint8","name":"homeScore","type":"uint8"},{"internalType":"uint8","name":"awayScore","type":"uint8"},{"internalType":"uint8","name":"statusId","type":"uint8"},{"internalType":"uint40","name":"lastUpdated","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"gamesPerDatePerSport","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getGameCreatedById","outputs":[{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"}],"internalType":"struct TherundownConsumer.GameCreate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"getGamePropsForOdds","outputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"uint256","name":"_gameDate","type":"uint256"},{"internalType":"bytes32","name":"_id","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getGameStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"uint256","name":"_date","type":"uint256"}],"name":"getGamesPerDatePerSport","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getLastUpdatedFromGameResolve","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"getNormalizedOddsForMarket","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ignoreChildCancellationPerSportIfDraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256[]","name":"_supportedSportIds","type":"uint256[]"},{"internalType":"address","name":"_sportsManager","type":"address"},{"internalType":"uint256[]","name":"_twoPositionSports","type":"uint256[]"},{"internalType":"contract GamesQueue","name":"_queues","type":"address"},{"internalType":"uint256[]","name":"_resolvedStatuses","type":"uint256[]"},{"internalType":"uint256[]","name":"_cancelGameStatuses","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"isChildMarket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"isGameResolvedOrCanceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPausedByCanceledStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"isSportOnADate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportsId","type":"uint256"}],"name":"isSportTwoPositionsSport","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"marketCanceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"marketCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"marketForTeamName","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"marketPerGameId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"marketResolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNumberOfMarketsToCreate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNumberOfMarketsToResolve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oddsObtainer","outputs":[{"internalType":"contract IGamesOddsObtainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"bool","name":"_pause","type":"bool"}],"name":"pauseOrUnpauseMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_main","type":"address"},{"internalType":"bool","name":"_pause","type":"bool"},{"internalType":"bool","name":"_invalidOdds","type":"bool"},{"internalType":"bool","name":"_circuitBreaker","type":"bool"}],"name":"pauseOrUnpauseMarketForPlayerProps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"bool","name":"_pause","type":"bool"}],"name":"pauseOrUnpauseMarketManually","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"playerProps","outputs":[{"internalType":"contract IGamesPlayerProps","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"queues","outputs":[{"internalType":"contract GamesQueue","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"reopenGameForCreationProcessing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"}],"name":"resolveAllMarketsForGames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"resolveMarketForGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"_outcome","type":"uint256"},{"internalType":"uint8","name":"_homeScore","type":"uint8"},{"internalType":"uint8","name":"_awayScore","type":"uint8"},{"internalType":"bool","name":"_useBackupOdds","type":"bool"}],"name":"resolveMarketManually","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"address","name":"_child","type":"address"}],"name":"setGameIdPerChildMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setIgnoreChildCancellationPerSportIfDraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxNumberOfMarketsToResolve","type":"uint256"},{"internalType":"uint256","name":"_maxNumberOfMarketsToCreate","type":"uint256"}],"name":"setNewMaxNumberOfMarketsToResolveAndResolve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setPausedByCanceledStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wrapperAddress","type":"address"},{"internalType":"contract GamesQueue","name":"_queues","type":"address"},{"internalType":"address","name":"_sportsManager","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"address","name":"_oddsObtainer","type":"address"},{"internalType":"address","name":"_playerProps","type":"address"}],"name":"setSportContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_status","type":"uint256"},{"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"setSupportedCancelStatuses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_status","type":"uint256"},{"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"setSupportedResolvedStatuses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"setSupportedSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"bool","name":"_isTwoPosition","type":"bool"}],"name":"setTwoPositionSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"sportsIdPerGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sportsManager","outputs":[{"internalType":"contract ISportPositionalMarketManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supportResolveGameStatuses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supportedSport","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"transferOwnershipAtInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"twoPositionSport","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract ITherundownConsumerVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrapperAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50615e5e80620000216000396000f3fe608060405234801561001057600080fd5b50600436106104545760003560e01c806370aadcc411610241578063c13937361161013b578063e3f4c7c9116100c3578063ed5e00eb11610087578063ed5e00eb14610b85578063f89c6f1814610b98578063fa59104f14610bc1578063fceb01f214610be4578063feee9ca314610bf757600080fd5b8063e3f4c7c914610ae8578063e48ef05c14610afb578063e59aff4b14610b2f578063e7015ab214610b42578063e87a6b8514610b6257600080fd5b8063c72eccbf1161010a578063c72eccbf14610a80578063d8a4b40c14610a89578063db0d457914610a9c578063dec72d6314610abc578063e2ec13fc14610adf57600080fd5b8063c139373614610a27578063c3b83f5f14610a3a578063c48e62f114610a4d578063c4c2e6f614610a6d57600080fd5b806391b4ded9116101c9578063ad6b22ce1161018d578063ad6b22ce1461098f578063ae71dcdf146109a2578063af4cbdfc146109aa578063bc93233f146109f1578063be27f89d14610a0457600080fd5b806391b4ded914610938578063a3b08bce14610941578063a400a89114610949578063a50267a51461095c578063ac2c957c1461097c57600080fd5b80638067cd53116102105780638067cd53146108b7578063861de52c146108ca5780638c4e8cb5146108e95780638da5cb5b1461090c5780638ec2c5a61461092557600080fd5b806370aadcc41461085457806376d423db1461087457806379ba5097146108975780637df8b8021461089f57600080fd5b806331ef892111610352578063557db448116102da5780635d7fb8e21161029e5780635d7fb8e2146107d5578063627e7b42146107e8578063630e2c35146107fb57806367674b141461080e57806369a5492e1461083157600080fd5b8063557db4481461072e57806356e4194d146107545780635849e50b146107825780635b9fbe07146107a55780635c975abb146107c857600080fd5b806346cd86221161032157806346cd8622146106bf578063489f4b97146106d25780634cf5d715146106e55780634eac3e931461070857806353a47bb71461071b57600080fd5b806331ef89211461066e5780633d975d4e146106815780633ec70ca514610694578063459c0bd0146106b757600080fd5b806316c38b3c116103e05780632b7ac3f3116103a45780632b7ac3f3146106255780632f73199d146106385780632fff70201461064b578063300a02981461065357806331dca3841461065b57600080fd5b806316c38b3c146105c05780631afed5cc146105d35780632082af14146105dc5780632830aeb0146105ef5780632a4a3e7c1461060257600080fd5b80630b5cde46116104275780630b5cde46146104cc57806310063fdc1461054e57806313251f5e1461057957806313af40351461059a5780631627540c146105ad57600080fd5b80630259f5fd1461045957806304dc46d01461046e57806306c933d814610481578063099177e9146104b9575b600080fd5b61046c610467366004615044565b610c25565b005b61046c61047c36600461533f565b610c98565b6104a461048f366004614f2c565b60046020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61046c6104c7366004615158565b610cf1565b6105176104da36600461530f565b6009602052600090815260409020805460019091015460ff80821691610100810482169162010000820416906301000000900464ffffffffff1685565b6040805195865260ff948516602087015292841692850192909252909116606083015264ffffffffff16608082015260a0016104b0565b601254610561906001600160a01b031681565b6040516001600160a01b0390911681526020016104b0565b61058c61058736600461571e565b610f4e565b6040519081526020016104b0565b61046c6105a8366004614f2c565b610f8c565b61046c6105bb366004614f2c565b6110c7565b61046c6105ce3660046152d7565b61111d565b61058c61232881565b61046c6105ea3660046156d9565b611193565b61046c6105fd36600461507c565b611231565b6104a4610610366004614f2c565b601e6020526000908152604090205460ff1681565b602154610561906001600160a01b031681565b61046c6106463660046153a7565b611282565b61058c600181565b61058c600281565b61046c6106693660046156d9565b611461565b61046c61067c3660046156fd565b6114dd565b61046c61068f366004615363565b611541565b6104a46106a236600461530f565b600d6020526000908152604090205460ff1681565b61058c600381565b61046c6106cd3660046156d9565b6116b7565b6104a46106e036600461530f565b611733565b6104a46106f336600461530f565b600f6020526000908152604090205460ff1681565b61046c6107163660046150d7565b611790565b600154610561906001600160a01b031681565b61074161073c36600461530f565b611872565b6040516104b09796959493929190615b61565b610767610762366004614f2c565b6119cd565b604080519384526020840192909252908201526060016104b0565b6104a461079036600461530f565b60266020526000908152604090205460ff1681565b6104a46107b3366004614f2c565b60156020526000908152604090205460ff1681565b6003546104a49060ff1681565b602554610561906001600160a01b031681565b61046c6107f6366004614f6b565b611a0c565b61046c6108093660046156d9565b611cea565b6104a461081c36600461530f565b600c6020526000908152604090205460ff1681565b6104a461083f36600461530f565b600e6020526000908152604090205460ff1681565b61058c61086236600461530f565b600b6020526000908152604090205481565b61058c61088236600461530f565b60009081526008602052604090206001015490565b61046c611d66565b6003546105619061010090046001600160a01b031681565b61046c6108c53660046151bf565b611e63565b61058c6108d836600461530f565b602080526000908152604090205481565b6104a46108f7366004614f2c565b601c6020526000908152604090205460ff1681565b600054610561906201000090046001600160a01b031681565b61046c61093336600461530f565b611eb5565b61058c60025481565b61058c60c981565b61046c6109573660046153f4565b6120c4565b61096f61096a3660046156fd565b612872565b6040516104b0919061591c565b61046c61098a3660046151bf565b6128dd565b602354610561906001600160a01b031681565b61058c600081565b6109db6109b836600461530f565b6000908152600960205260409020600101546301000000900464ffffffffff1690565b60405164ffffffffff90911681526020016104b0565b61046c6109ff366004615044565b61292b565b6104a4610a1236600461530f565b6000908152600f602052604090205460ff1690565b61046c610a3536600461530f565b6129c9565b61046c610a48366004614f2c565b612a6c565b610a60610a5b36600461530f565b612b85565b6040516104b09190615c39565b6104a4610a7b366004614f2c565b612d57565b61058c60275481565b61046c610a973660046156d9565b612de9565b610aaf610aaa366004614f2c565b612e43565b6040516104b09190615960565b6104a4610aca366004614f2c565b60166020526000908152604090205460ff1681565b61058c60245481565b601754610561906001600160a01b031681565b610561610b09366004615448565b80516020818301810180516028825292820191909301209152546001600160a01b031681565b61046c610b3d36600461530f565b612e96565b61058c610b50366004614f2c565b60146020526000908152604090205481565b6104a4610b7036600461530f565b60106020526000908152604090205460ff1681565b61046c610b93366004615044565b612f21565b610561610ba636600461530f565b6013602052600090815260409020546001600160a01b031681565b6104a4610bcf36600461530f565b60116020526000908152604090205460ff1681565b61046c610bf2366004615044565b612f6a565b6104a4610c053660046156fd565b601a60209081526000928352604080842090915290825290205460ff1681565b6023546001600160a01b0316331480610c4857506025546001600160a01b031633145b610c6d5760405162461bcd60e51b8152600401610c6490615bfe565b60405180910390fd5b6001600160a01b03919091166000908152601e60205260409020805460ff1916911515919091179055565b6023546001600160a01b0316331480610cbb57506025546001600160a01b031633145b610cd75760405162461bcd60e51b8152600401610c6490615bfe565b6001600160a01b0316600090815260146020526040902055565b3360009081526004602052604090205460ff16610d205760405162461bcd60e51b8152600401610c6490615be0565b6001600160a01b038516600090815260146020526040902054848484610d4584611733565b15610d7b5760405162461bcd60e51b8152600401610c64906020808252600490820152634944313360e01b604082015260600190565b6000848152601360205260409020546001600160a01b0316610dc85760405162461bcd60e51b8152600401610c649060208082526004908201526312510c4d60e21b604082015260600190565b6021546000858152600b60209081526040808320548352600f909152908190205490516343ce062f60e11b815260ff90911615156004820152602481018590526001600160a01b039091169063879c0c5e9060440160206040518083038186803b158015610e3557600080fd5b505afa158015610e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6d91906152f3565b8015610f0157506021546040516303727eb960e01b81526004810185905260ff8085166024830152831660448201526001600160a01b03909116906303727eb99060640160206040518083038186803b158015610ec957600080fd5b505afa158015610edd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0191906152f3565b610f365760405162461bcd60e51b8152600401610c64906020808252600490820152634944313560e01b604082015260600190565b610f438989898989613024565b505050505050505050565b601d6020528260005260406000206020528160005260406000208181548110610f7657600080fd5b9060005260206000200160009250925050505481565b6001600160a01b038116610fe25760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610c64565b600154600160a01b900460ff161561104e5760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610c64565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6110cf6134ba565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016110bc565b6111256134ba565b60035460ff16151581151514156111395750565b6003805460ff191682151590811790915560ff161561115757426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5906020016110bc565b50565b61119b6134ba565b6000828152600e602052604090205460ff1680156111ce57506000828152600f602052604090205460ff16151581151514155b6111d757600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527f5c90f67f3547cb9c3f1b7612610d878aa4f00e88a643d2c6b658c1f9005fdcda91015b60405180910390a15050565b6023546001600160a01b031633148061125457506025546001600160a01b031633145b6112705760405162461bcd60e51b8152600401610c6490615bfe565b61127c84848484613534565b50505050565b60035461010090046001600160a01b031633146112b15760405162461bcd60e51b8152600401610c6490615c1c565b815160005b83518110156113b05760008482815181106112e157634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906112fc9190615643565b805160009081526013602052604090819020546023549151630ceda8e960e41b81526001600160a01b039182166004820181905293945091169063ceda8e909060240160206040518083038186803b15801561135757600080fd5b505afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f9190615327565b6113999085615d11565b9350505080806113a890615daf565b9150506112b6565b5060005b835181101561145a5760008482815181106113df57634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906113fa9190615643565b80516000908152600d602052604090205490915060ff16158015611436575080516000908152601360205260409020546001600160a01b031615155b1561144757611447868286866135a7565b508061145281615daf565b9150506113b4565b5050505050565b6114696134ba565b6000828152600e602052604090205460ff161515811515141561148b57600080fd5b6000828152600e6020908152604091829020805460ff19168415159081179091558251858152918201527f0a7daa18eab3013f94989c4e384004cab457b607ce1e975b8de79c4da52da9549101611225565b6114e56134ba565b816024541415806114f857508060275414155b61150157600080fd5b6024829055602781905560408051838152602081018390527ff34353d7947a2688f99ba2ee1f5848e1dd757ae5ea05d5736a24fd6b6a9adb6f9101611225565b60035461010090046001600160a01b031633146115705760405162461bcd60e51b8152600401610c6490615c1c565b60005b81518110156116b257600082828151811061159e57634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906115b9919061555f565b80516000908152600c602052604090205490915060ff1680156115f4575080516000908152601360205260409020546001600160a01b031615155b1561169f5760235481516000908152600b602081815260408084205486518552601383528185205487518652938352818520548552600f9092528084205490516329bfb6cd60e01b81526001600160a01b03958616956329bfb6cd9561166c958c958a959094919093169260ff1691906004016159dc565b600060405180830381600087803b15801561168657600080fd5b505af115801561169a573d6000803e3d6000fd5b505050505b50806116aa81615daf565b915050611573565b505050565b6116bf6134ba565b60008281526011602052604090205460ff16151581151514156116e157600080fd5b600082815260116020908152604091829020805460ff19168415159081179091558251858152918201527fbff84c147d533b99d8802295ac70c53aa7d9ac4e520dcd0200d2f434c34b52a39101611225565b6000818152601360209081526040808320546001600160a01b03168352601590915281205460ff168061178a57506000828152601360209081526040808320546001600160a01b03168352601690915290205460ff165b92915050565b6117986134ba565b601280546001600160a01b038681166001600160a01b03199283168117909355601780548983169084168117909155600380548b84166101008102610100600160a81b03199092169190911790915560218054898516908616811790915560238054898616908716811790915560258054958916959096168517909555604080519283526020830193909352918101949094526060840152608083019190915260a08201527f655a82a8af9bfe0bd2346ce98700798d4f8aa7bcfc1cef62a911171bd8e479a79060c00160405180910390a1505050505050565b6008602052600090815260409020805460018201546002808401546003850180549495939482840b9463010000008404850b94600160301b90940490930b9291906118bc90615d74565b80601f01602080910402602001604051908101604052809291908181526020018280546118e890615d74565b80156119355780601f1061190a57610100808354040283529160200191611935565b820191906000526020600020905b81548152906001019060200180831161191857829003601f168201915b50505050509080600401805461194a90615d74565b80601f016020809104026020016040519081016040528092919081815260200182805461197690615d74565b80156119c35780601f10611998576101008083540402835291602001916119c3565b820191906000526020600020905b8154815290600101906020018083116119a657829003601f168201915b5050505050905087565b6001600160a01b038116600081815260146020818152604080842054808552600b835281852054838052918520549590945291905291905b9193909250565b600054610100900460ff16611a275760005460ff1615611a2b565b303b155b611a8e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c64565b600054610100900460ff16158015611ab0576000805461ffff19166101011790555b611ab988610f8c565b60005b8751811015611b2b576001600e60008a8481518110611aeb57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611b2390615daf565b915050611abc565b5060005b8551811015611b9e576001600f6000888481518110611b5e57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611b9690615daf565b915050611b2f565b5060005b8351811015611c1157600160106000868481518110611bd157634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611c0990615daf565b915050611ba2565b5060005b8251811015611c8457600160116000858481518110611c4457634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611c7c90615daf565b915050611c15565b50601280546001600160a01b038089166001600160a01b03199283161790925560178054878416921691909117905588166000908152600460205260409020805460ff191660011790558015611ce0576000805461ff00191690555b5050505050505050565b611cf26134ba565b60008281526010602052604090205460ff1615158115151415611d1457600080fd5b600082815260106020908152604091829020805460ff19168415159081179091558251858152918201527f463b22afe346e0b505997c71b3cb5c2a507adb0214a645f6aede655b186917179101611225565b6001546001600160a01b03163314611dde5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610c64565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60005b8151811015611eb157611e9f828281518110611e9257634e487b7160e01b600052603260045260246000fd5b6020026020010151612e96565b80611ea981615daf565b915050611e66565b5050565b6000818152601360205260409020546001600160a01b03161580611f1e57506000818152601360209081526040808320546001600160a01b03168352601690915290205460ff168015611f1e57506000818152601360205260409020546001600160a01b031615155b611f505760405162461bcd60e51b815260206004820152600360248201526249443160e81b6044820152606401610c64565b6000818152600c602052604090205460ff16611f945760405162461bcd60e51b815260206004820152600360248201526224a21960e91b6044820152606401610c64565b60175460408051634b40849760e01b8152905183926001600160a01b0316916303aac5d5918391634b408497916004808301926020929190829003018186803b158015611fe057600080fd5b505afa158015611ff4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120189190615327565b6040518263ffffffff1660e01b815260040161203691815260200190565b60206040518083038186803b15801561204e57600080fd5b505afa158015612062573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120869190615327565b146120b95760405162461bcd60e51b815260206004820152600360248201526249443360e81b6044820152606401610c64565b611190816001613952565b60035461010090046001600160a01b031633146120f35760405162461bcd60e51b8152600401610c6490615c1c565b601254604051633d97451560e21b8152600481018490526000916001600160a01b03169063f65d14549060240160206040518083038186803b15801561213857600080fd5b505afa15801561214c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217091906152f3565b61217b57600061217e565b60035b6000848152600f602052604081205460ff92831693509091166121b7576121a6826001615d11565b85516121b29190615d29565b6121ba565b84515b8551909150156121e9576000838152601a602090815260408083208784529091529020805460ff191660011790555b60005b855181101561286957600086828151811061221757634e487b7160e01b600052603260045260246000fd5b6020026020010151806020019051810190612232919061548d565b80516000908152600c602052604090205490915060ff161580156122dd575060215460a082015160c08301516040516397dc205d60e01b81526001600160a01b03909316926397dc205d9261228b929091600401615bbb565b60206040518083038186803b1580156122a357600080fd5b505afa1580156122b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122db91906152f3565b155b80156122ec5750428160200151115b1561230f5780516122fe908688613d0a565b61230a88828886613d55565b612856565b80516000908152600c602052604090205460ff16156128565760006123378260000151612b85565b60215460a08085015190830151604051637fabe16b60e01b81529394506001600160a01b0390921692637fabe16b926123739291600401615bbb565b60206040518083038186803b15801561238b57600080fd5b505afa15801561239f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c391906152f3565b1580612456575060215460c08084015190830151604051637fabe16b60e01b81526001600160a01b0390931692637fabe16b92612404929091600401615bbb565b60206040518083038186803b15801561241c57600080fd5b505afa158015612430573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245491906152f3565b155b156125825781516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff16156124b95786600714156124be5781516124a0906000614022565b81516124ad908789613d0a565b6124b989838987613d55565b612854565b81516000908152601360205260409020546124e3906001600160a01b031660016140a7565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e926125289291169060019060040161587c565b600060405180830381600087803b15801561254257600080fd5b505af1158015612556573d6000803e3d6000fd5b505083516000908152601360205260408120546124b993506001600160a01b0316915060019080613534565b806020015182602001511461285457815161259e908789613d0a565b42826020015111156126e3576012548251600090815260136020908152604091829020549085015191516327ad762d60e21b81526001600160a01b039182166004820152602481019290925290911690639eb5d8b490604401600060405180830381600087803b15801561261157600080fd5b505af1158015612625573d6000803e3d6000fd5b5050835160009081526008602090815260409182902086518155818701516001820155918601516002808401805460608a015160808b0151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a086015180518795509293506126be9260038501929190910190614cc7565b5060c082015180516126da916004840191602090910190614cc7565b50905050612854565b81516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff16801561271c5750428160200151115b15612854578151600090815260136020526040902054612746906001600160a01b031660016140a7565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e9261278b9291169060019060040161587c565b600060405180830381600087803b1580156127a557600080fd5b505af11580156127b9573d6000803e3d6000fd5b505083516000908152601360205260408120546127e593506001600160a01b0316915060019080613534565b8151600090815260136020908152604091829020548451848301518387015185516001600160a01b039094168452938301919091529281019290925260608201527fb71601cabce6b66d1ceb87bb549207b61c7c27e3efd188cae1e0d39f7feedfd79060800160405180910390a15b505b508061286181615daf565b9150506121ec565b50505050505050565b6000828152601d602090815260408083208484528252918290208054835181840281018401909452808452606093928301828280156128d057602002820191906000526020600020905b8154815260200190600101908083116128bc575b5050505050905092915050565b60005b8151811015611eb15761291982828151811061290c57634e487b7160e01b600052603260045260246000fd5b6020026020010151611eb5565b8061292381615daf565b9150506128e0565b6129336134ba565b6001600160a01b0382161580159061296a57506001600160a01b03821660009081526004602052604090205460ff16151581151514155b61297357600080fd5b6001600160a01b03821660009081526004602052604090819020805460ff1916831515179055517f58d7a3ccc34541e162fcfc87b84be7b78c34d1e1e7f15de6e4dd67d0fe70aecd90611225908490849061587c565b3360009081526004602052604090205460ff166129f85760405162461bcd60e51b8152600401610c6490615be0565b6000818152600c602052604090205460ff16612a3f5760405162461bcd60e51b8152600401610c649060208082526004908201526324a2191960e11b604082015260600190565b6000908152600c60209081526040808320805460ff19908116909155600d90925290912080549091169055565b612a746134ba565b6001600160a01b038116612abc5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610c64565b600154600160a81b900460ff1615612b0c5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610c64565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016110bc565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c0810191909152600082815260086020908152604091829020825160e0810184528154815260018201549281019290925260028082015480820b820b820b9484019490945263010000008404810b810b810b6060840152600160301b909304830b830b90920b608082015260038201805491929160a084019190612c3c90615d74565b80601f0160208091040260200160405190810160405280929190818152602001828054612c6890615d74565b8015612cb55780601f10612c8a57610100808354040283529160200191612cb5565b820191906000526020600020905b815481529060010190602001808311612c9857829003601f168201915b50505050508152602001600482018054612cce90615d74565b80601f0160208091040260200160405190810160405280929190818152602001828054612cfa90615d74565b8015612d475780601f10612d1c57610100808354040283529160200191612d47565b820191906000526020600020905b815481529060010190602001808311612d2a57829003601f168201915b5050505050815250509050919050565b602354604051636c35b77560e01b81526001600160a01b0383811660048301526000928392911690636c35b7759060240160206040518083038186803b158015612da057600080fd5b505afa158015612db4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd89190614f4f565b6001600160a01b0316141592915050565b612df16134ba565b600082815260266020908152604091829020805460ff19168415159081179091558251858152918201527fc513a9633586b17da42f91779680c8eaf029d7e1752bb3e4b43ae26cd05849299101611225565b6001600160a01b0381166000908152601c602052604090205460609060ff16612e7457612e6f826141c2565b61178a565b6001600160a01b03821660009081526014602052604090205461178a90614347565b612e9f81611733565b15612ed25760405162461bcd60e51b815260206004820152600360248201526212510d60ea1b6044820152606401610c64565b6000818152600d602052604090205460ff16612f165760405162461bcd60e51b815260206004820152600360248201526249443560e81b6044820152606401610c64565b611190816000614379565b6023546001600160a01b0316331480612f4457506025546001600160a01b031633145b612f605760405162461bcd60e51b8152600401610c6490615bfe565b611eb182826140a7565b3360009081526004602052604090205460ff16612f995760405162461bcd60e51b8152600401610c6490615be0565b6001600160a01b03821660009081526014602052604090205415801590612fe557506001600160a01b0382166000908152601460209081526040808320548352600c90915290205460ff165b61301a5760405162461bcd60e51b8152600401610c64906020808252600490820152630494432360e41b604082015260600190565b611eb18282614784565b80156131975783156130615760405162461bcd60e51b8152600401610c64906020808252600490820152634944313760e01b604082015260600190565b6023546001600160a01b03868116600090815260146020908152604080832054808452600b8352818420548452600f9092529182902054915163048e4dcb60e11b81526004810191909152841515602482015260ff9091161515604482015291169063091c9b969060640160206040518083038186803b1580156130e457600080fd5b505afa1580156130f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061311c91906152f3565b61312557600080fd5b6023546001600160a01b0386811660009081526014602052604090819020549051639971441b60e01b81526004810191909152911690639971441b90602401600060405180830381600087803b15801561317e57600080fd5b505af1158015613192573d6000803e3d6000fd5b505050505b6131a28560006140a7565b60235460405162d2b13f60e11b81526001600160a01b03909116906301a5627e906131d490889060009060040161587c565b600060405180830381600087803b1580156131ee57600080fd5b505af1158015613202573d6000803e3d6000fd5b50505050613214856000806000613534565b6001600160a01b0385166000908152601460209081526040808320548352600b8252808320548352600f90915290205461326590869086908690869060ff1661325e57600b614813565b6008614813565b6040805160a0810182526001600160a01b0387166000908152601460209081528382205480845260ff8089168386015287811685870152908352600b8252848320548352600f9091529290205490916060830191166132c557600b6132c8565b60085b60ff9081168252600060209283018190526001600160a01b03891681526014835260408082208054835260098086528284208751815587870151600191820180548a8701516060808d015160809d8e0151958c1661ffff1990941693909317610100928c1683021767ffffffffffff0000191662010000938c169390930267ffffffffff000000191692909217630100000064ffffffffff95861602179092559454808852600b8a5286882054948a5286882087518281529a8b019590955295890195909552825493880193909352015480851696860196909652600886901c841660a0860152601086901c90931660c085015260189490941c90911660e0830152918101919091527f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73906101200160405180910390a18361345a576001600160a01b038516600081815260146020908152604091829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc910160405180910390a161145a565b6001600160a01b0385166000818152601460209081526040918290205482519384529083015281018590527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e444906060015b60405180910390a15050505050565b6000546201000090046001600160a01b031633146135325760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610c64565b565b60255460405163509e2f3360e01b81526001600160a01b0386811660048301528515156024830152841515604483015283151560648301529091169063509e2f3390608401600060405180830381600087803b15801561359357600080fd5b505af1158015611ce0573d6000803e3d6000fd5b60006135b68460000151612b85565b90506135d8846060015160ff9081166000908152601060205260409020541690565b806136075750606084015160ff9081166000908152601160205260409020541680156136075750428160200151105b15613837578351600090815260096020908152604080832087518082558389015160019283018054858c015160608d015160808e015164ffffffffff1663010000000267ffffffffff0000001960ff92831662010000021667ffffffffffff0000199383166101000261ffff1990951692909616919091179290921716929092179190911790558452600d835292819020805460ff191690931790925585516017548351638f0ac45360e01b815293517f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73948a948994938b936001600160a01b0390911692638f0ac453926004808301939192829003018186803b15801561370e57600080fd5b505afa158015613722573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137469190615327565b604080519586526020808701959095528581019390935281516060808701919091529382015160ff90811660808088019190915293830151811660a08701529382015190931660c0850152015164ffffffffff1660e08301526101008201526101200160405180910390a1602454821061382557601754845160405163602726b560e11b81526001600160a01b039092169163c04e4d6a916137ee9160040190815260200190565b600060405180830381600087803b15801561380857600080fd5b505af115801561381c573d6000803e3d6000fd5b5050505061145a565b8351613832906001614379565b61145a565b606084015160ff908116600090815260116020526040902054168015613861575042816020015110155b1561145a5783516000908152601360208181526040808420546001600160a01b039081168552601e8352818520805460ff191660019081179091558951865293909252909220546138b39216906140a7565b60235484516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e926138f89291169060019060040161587c565b600060405180830381600087803b15801561391257600080fd5b505af1158015613926573d6000803e3d6000fd5b5050855160009081526013602052604081205461145a93506001600160a01b0316915060019080613534565b600061395d83612b85565b90504281602001511115613c7c576000838152600b602052604081205461398390614a08565b60125460a084015160c08501516040519394506000936001600160a01b0390931692634cde32ce9289926139b99260200161583d565b60408051601f1981840301815291815260208881015160008c8152600b8352838120548152600f9092529181205460ff166139f55760036139f8565b60025b886000806040518963ffffffff1660e01b8152600401613a1f989796959493929190615973565b602060405180830381600087803b158015613a3957600080fd5b505af1158015613a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a719190614f4f565b8351600090815260136020908152604080832080546001600160a01b0319166001600160a01b0386811691821790925588518186526014855283862055601c90935292819020805460ff1916600117905560235487519151630e76f6e760e11b8152600481019290925260248201929092529293501690631cededce90604401600060405180830381600087803b158015613b0b57600080fd5b505af1158015613b1f573d6000803e3d6000fd5b505050508060288460a00151604051613b389190615821565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b03199093169290921790915560c08401518291602891613b7b91615821565b90815260405190819003602001902080546001600160a01b03929092166001600160a01b03199092169190911790558315613c3a57601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613c0057600080fd5b505af1158015613c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c389190615327565b505b82517f889e2060e46779287c2fcbf489c195ef20f5b44a74e3dcb58d491ae073c1370f9082908585613c6b83614347565b6040516134ab959493929190615897565b81156116b257601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613cd257600080fd5b505af1158015613ce6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127c9190615327565b600083815260208052604090205482146116b2576000908152601d60209081526040808320848452825280832080546001810182559084528284200185905593825280529190912055565b602754835160009081526008602090815260409182902086518155818701516001820155918601516002808401805460608a015160808b0151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a0860151805193851093879392613dee926003850192910190614cc7565b5060c08201518051613e0a916004840191602090910190614cc7565b505084516000908152600b602052604090208490555080613e98576017548451602086015160405163e9c962eb60e01b815260048101929092526024820152604481018590526001600160a01b039091169063e9c962eb90606401600060405180830381600087803b158015613e7f57600080fd5b505af1158015613e93573d6000803e3d6000fd5b505050505b83516000908152600c602052604090819020805460ff1916600117905560235485518287015160608801516080890151945163312025df60e21b81526004810193909352600291820b6024840152810b60448301529290920b60648301526001600160a01b03169063c480977c90608401600060405180830381600087803b158015613f2357600080fd5b505af1158015613f37573d6000803e3d6000fd5b505050507faba5c0e34b9b54828db4e0ac6b951ca282a0b171289eebf93353c296f9e826138584866000015187601760009054906101000a90046001600160a01b03166001600160a01b031663afff5a646040518163ffffffff1660e01b815260040160206040518083038186803b158015613fb257600080fd5b505afa158015613fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fea9190615327565b8951613ff590614347565b60405161400796959493929190615b17565b60405180910390a1801561145a57835161145a906000613952565b600082815260136020526040812054614049916001600160a01b0390911690808080614813565b801561405757614057614a6c565b6000828152601360209081526040918290205482516001600160a01b0390911681529081018490527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc9101611225565b6012546040516333dfec9960e21b81526001600160a01b03848116600483015283151592169063cf7fb2649060240160206040518083038186803b1580156140ee57600080fd5b505afa158015614102573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061412691906152f3565b151514611eb157601254604051637f8c2d6160e01b81526001600160a01b0390911690637f8c2d619061415f908590859060040161587c565b600060405180830381600087803b15801561417957600080fd5b505af115801561418d573d6000803e3d6000fd5b505050507f2b8992e59f9813c2f92be2374e9bdd5384146ff8f719b038fbaf7d3dbfa78fde828260405161122592919061587c565b60235460405163d28231bd60e01b81526001600160a01b038381166004830152606092169063d28231bd9060240160206040518083038186803b15801561420857600080fd5b505afa15801561421c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061424091906152f3565b6142c55760255460405163db0d457960e01b81526001600160a01b0384811660048301529091169063db0d45799060240160006040518083038186803b15801561428957600080fd5b505afa15801561429d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e6f9190810190615251565b60235460405163db0d457960e01b81526001600160a01b0384811660048301529091169063db0d4579906024015b60006040518083038186803b15801561430b57600080fd5b505afa15801561431f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261178a9190810190615251565b602354604051634d6759b760e11b8152600481018390526060916001600160a01b031690639aceb36e906024016142f3565b6000828152600960209081526040808320815160a0810183528154815260019091015460ff80821694830194909452610100810484169282019290925262010000820490921660608301526301000000900464ffffffffff166080820152906143e184612b85565b9050614403826060015160ff9081166000908152601060205260409020541690565b15614749576023548251600090815260136020526040908190205490516336c0d85560e01b81526001600160a01b0391821660048201529116906336c0d8559060240160206040518083038186803b15801561445e57600080fd5b505afa158015614472573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061449691906152f3565b1561455b5781516000908152601360205260408120546144c1916001600160a01b03909116906140a7565b602354825160009081526013602052604080822054905162d2b13f60e11b81526001600160a01b03938416936301a5627e93614503939091169160040161587c565b600060405180830381600087803b15801561451d57600080fd5b505af1158015614531573d6000803e3d6000fd5b5050835160009081526013602052604081205461455b93506001600160a01b031691508080613534565b600080600061456985614af4565b92509250925060038314801561459c575084516000908152600b60209081526040808320548352600f90915290205460ff165b156146015784516000908152600b60209081526040808320548352602690915290205460ff16156145f45784516000908152601360205260409020546145ef906001600160a01b03168484848a15614b65565b614741565b84516145ef908715614022565b6012548551600090815260136020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b15801561465757600080fd5b505afa15801561466b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061468f91906152f3565b61473457845160009081526013602052604090205460608601516146c2916001600160a01b031690859085908590614813565b856146cf576146cf614a6c565b845160009081526013602090815260409182902054875183516001600160a01b039092168252918101919091529081018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449060600160405180910390a1614741565b8561474157614741614a6c565b50505061127c565b606082015160ff9081166000908152601160205260409020541680156147725750428160200151105b1561127c57815161127c908415614022565b61478e82826140a7565b6023546001600160a01b038381166000818152601460205260409081902054905163032bc38360e21b8152600481019190915260248101919091528315156044820152911690630caf0e0c90606401600060405180830381600087803b1580156147f757600080fd5b505af115801561480b573d6000803e3d6000fd5b505050505050565b60125460405163b91f5e3560e01b81526001600160a01b038781166004830152602482018790529091169063b91f5e3590604401600060405180830381600087803b15801561486157600080fd5b505af1158015614875573d6000803e3d6000fd5b5050505060c98160ff1614156148f3576023546040516303e810fd60e61b81526001600160a01b039091169063fa043f40906148bc908890600090819081906004016158f0565b600060405180830381600087803b1580156148d657600080fd5b505af11580156148ea573d6000803e3d6000fd5b505050506149c4565b6023546040516303e810fd60e61b81526001600160a01b039091169063fa043f40906149299088908890889088906004016158f0565b600060405180830381600087803b15801561494357600080fd5b505af1158015614957573d6000803e3d6000fd5b5050505060008414156149c4576025546040516326ddf9ff60e11b81526001600160a01b03878116600483015290911690634dbbf3fe90602401600060405180830381600087803b1580156149ab57600080fd5b505af11580156149bf573d6000803e3d6000fd5b505050505b5050506001600160a01b039190911660009081526016602090815260408083208054941560ff19958616811790915560159092529091208054911591909216179055565b6040805160018082528183019092526060916000919060208083019080368337019050509050614a3a83612328615d11565b81600081518110614a5b57634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b601760009054906101000a90046001600160a01b03166001600160a01b03166377d078d76040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614abc57600080fd5b505af1158015614ad0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111909190615327565b6000806000836040015160ff16846020015160ff161415614b25575050506020810151604082015160039190611a05565b836040015160ff16846020015160ff1611614b4b57600284602001518560400151614b58565b6001846020015185604001515b9250925092509193909250565b60125460405163b91f5e3560e01b81526001600160a01b038781166004830152600060248301529091169063b91f5e3590604401600060405180830381600087803b158015614bb357600080fd5b505af1158015614bc7573d6000803e3d6000fd5b50506023546040516303e810fd60e61b81526001600160a01b03909116925063fa043f409150614c019088908890889088906004016158f0565b600060405180830381600087803b158015614c1b57600080fd5b505af1158015614c2f573d6000803e3d6000fd5b5050506001600160a01b0386166000908152601660209081526040808320805460ff19908116909155601590925290912080549091166001179055508015614c7957614c79614a6c565b6001600160a01b038516600081815260146020908152604091829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc91016134ab565b828054614cd390615d74565b90600052602060002090601f016020900481019282614cf55760008555614d3b565b82601f10614d0e57805160ff1916838001178555614d3b565b82800160010185558215614d3b579182015b82811115614d3b578251825591602001919060010190614d20565b50614d47929150614d4b565b5090565b5b80821115614d475760008155600101614d4c565b6000614d73614d6e84615cea565b615c97565b9050828152838383011115614d8757600080fd5b828260208301376000602084830101529392505050565b8035614da981615df6565b919050565b600082601f830112614dbe578081fd5b81356020614dce614d6e83615cc7565b80838252828201915082860187848660051b8901011115614ded578586fd5b855b85811015614e405781356001600160401b03811115614e0c578788fd5b8801603f81018a13614e1c578788fd5b614e2d8a8783013560408401614d60565b8552509284019290840190600101614def565b5090979650505050505050565b600082601f830112614e5d578081fd5b81356020614e6d614d6e83615cc7565b80838252828201915082860187848660051b8901011115614e8c578586fd5b855b85811015614e4057813584529284019290840190600101614e8e565b8051600181900b8114614da957600080fd5b8051600281900b8114614da957600080fd5b600082601f830112614ede578081fd5b8151614eec614d6e82615cea565b818152846020838601011115614f00578283fd5b614f11826020830160208701615d48565b949350505050565b805162ffffff81168114614da957600080fd5b600060208284031215614f3d578081fd5b8135614f4881615df6565b9392505050565b600060208284031215614f60578081fd5b8151614f4881615df6565b600080600080600080600060e0888a031215614f85578283fd5b614f8e88614d9e565b965060208801356001600160401b0380821115614fa9578485fd5b614fb58b838c01614e4d565b9750614fc360408b01614d9e565b965060608a0135915080821115614fd8578485fd5b614fe48b838c01614e4d565b9550614ff260808b01614d9e565b945060a08a0135915080821115615007578384fd5b6150138b838c01614e4d565b935060c08a0135915080821115615028578283fd5b506150358a828b01614e4d565b91505092959891949750929550565b60008060408385031215615056578182fd5b823561506181615df6565b9150602083013561507181615e0b565b809150509250929050565b60008060008060808587031215615091578182fd5b843561509c81615df6565b935060208501356150ac81615e0b565b925060408501356150bc81615e0b565b915060608501356150cc81615e0b565b939692955090935050565b60008060008060008060c087890312156150ef578384fd5b86356150fa81615df6565b9550602087013561510a81615df6565b9450604087013561511a81615df6565b9350606087013561512a81615df6565b9250608087013561513a81615df6565b915060a087013561514a81615df6565b809150509295509295509295565b600080600080600060a0868803121561516f578283fd5b853561517a81615df6565b945060208601359350604086013561519181615e19565b925060608601356151a181615e19565b915060808601356151b181615e0b565b809150509295509295909350565b600060208083850312156151d1578182fd5b82356001600160401b038111156151e6578283fd5b8301601f810185136151f6578283fd5b8035615204614d6e82615cc7565b80828252848201915084840188868560051b8701011115615223578687fd5b8694505b83851015615245578035835260019490940193918501918501615227565b50979650505050505050565b60006020808385031215615263578182fd5b82516001600160401b03811115615278578283fd5b8301601f81018513615288578283fd5b8051615296614d6e82615cc7565b80828252848201915084840188868560051b87010111156152b5578687fd5b8694505b838510156152455780518352600194909401939185019185016152b9565b6000602082840312156152e8578081fd5b8135614f4881615e0b565b600060208284031215615304578081fd5b8151614f4881615e0b565b600060208284031215615320578081fd5b5035919050565b600060208284031215615338578081fd5b5051919050565b60008060408385031215615351578182fd5b82359150602083013561507181615df6565b60008060408385031215615375578182fd5b8235915060208301356001600160401b03811115615391578182fd5b61539d85828601614dae565b9150509250929050565b6000806000606084860312156153bb578081fd5b8335925060208401356001600160401b038111156153d7578182fd5b6153e386828701614dae565b925050604084013590509250925092565b60008060008060808587031215615409578182fd5b8435935060208501356001600160401b03811115615425578283fd5b61543187828801614dae565b949794965050505060408301359260600135919050565b600060208284031215615459578081fd5b81356001600160401b0381111561546e578182fd5b8201601f8101841361547e578182fd5b614f1184823560208401614d60565b60006020828403121561549e578081fd5b81516001600160401b03808211156154b4578283fd5b9083019060e082860312156154c7578283fd5b6154cf615c4c565b82518152602083015160208201526154e960408401614ebc565b60408201526154fa60608401614ebc565b606082015261550b60808401614ebc565b608082015260a083015182811115615521578485fd5b61552d87828601614ece565b60a08301525060c083015182811115615544578485fd5b61555087828601614ece565b60c08301525095945050505050565b60006101808284031215615571578081fd5b615579615c74565b8251815261558960208401614ebc565b602082015261559a60408401614ebc565b60408201526155ab60608401614ebc565b60608201526155bc60808401614eaa565b60808201526155cd60a08401614ebc565b60a08201526155de60c08401614eaa565b60c08201526155ef60e08401614ebc565b60e0820152610100615602818501614f19565b90820152610120615614848201614ebc565b90820152610140615626848201614f19565b90820152610160615638848201614ebc565b908201529392505050565b600060a08284031215615654578081fd5b60405160a081018181106001600160401b038211171561567657615676615de0565b60405282518152602083015161568b81615e19565b6020820152604083015161569e81615e19565b604082015260608301516156b181615e19565b6060820152608083015164ffffffffff811681146156cd578283fd5b60808201529392505050565b600080604083850312156156eb578182fd5b82359150602083013561507181615e0b565b6000806040838503121561570f578182fd5b50508035926020909101359150565b600080600060608486031215615732578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b838110156157785781518752958201959082019060010161575c565b509495945050505050565b6000815180845261579b816020860160208601615d48565b601f01601f19169290920160200192915050565b8051825260208101516020830152604081015160020b6040830152606081015160020b6060830152608081015160020b6080830152600060a082015160e060a08501526157ff60e0850182615783565b905060c083015184820360c08601526158188282615783565b95945050505050565b60008251615833818460208701615d48565b9190910192915050565b6000835161584f818460208801615d48565b630103b39960e51b9083019081528351615870816004840160208801615d48565b01600401949350505050565b6001600160a01b039290921682521515602082015260400190565b60018060a01b038616815284602082015260a0604082015260006158be60a08301866157af565b82810360608401526158d08186615749565b905082810360808401526158e48185615749565b98975050505050505050565b6001600160a01b03949094168452602084019290925260ff908116604084015216606082015260800190565b6020808252825182820181905260009190848201906040850190845b8181101561595457835183529284019291840191600101615938565b50909695505050505050565b602081526000614f486020830184615749565b60006101008a835280602084015261598d8184018b615783565b905088604084015287606084015260ff8716608084015282810360a08401526159b68187615749565b94151560c084015250506001600160a01b039190911660e0909101529695505050505050565b600061022082019050878252865160208301526020870151615a03604084018260020b9052565b506040870151615a18606084018260020b9052565b506060870151615a2d608084018260020b9052565b506080870151615a4260a084018260010b9052565b5060a0870151615a5760c084018260020b9052565b5060c0870151615a6c60e084018260010b9052565b5060e0870151610100615a838185018360020b9052565b8801519050610120615a9b8482018362ffffff169052565b8801519050610140615ab18482018360020b9052565b8801519050610160615ac98482018362ffffff169052565b8801519050615ade61018084018260020b9052565b50856101a0830152615afc6101c08301866001600160a01b03169052565b9215156101e082015290151561020090910152949350505050565b86815285602082015284604082015260c060608201526000615b3c60c08301866157af565b84608084015282810360a0840152615b548185615749565b9998505050505050505050565b8781528660208201528560020b60408201528460020b60608201528360020b608082015260e060a08201526000615b9b60e0830185615783565b82810360c0840152615bad8185615783565b9a9950505050505050505050565b604081526000615bce6040830185615783565b82810360208401526158188185615783565b6020808252600490820152630494431360e41b604082015260600190565b6020808252600490820152630928862760e31b604082015260600190565b60208082526003908201526249443960e81b604082015260600190565b602081526000614f4860208301846157af565b60405160e081016001600160401b0381118282101715615c6e57615c6e615de0565b60405290565b60405161018081016001600160401b0381118282101715615c6e57615c6e615de0565b604051601f8201601f191681016001600160401b0381118282101715615cbf57615cbf615de0565b604052919050565b60006001600160401b03821115615ce057615ce0615de0565b5060051b60200190565b60006001600160401b03821115615d0357615d03615de0565b50601f01601f191660200190565b60008219821115615d2457615d24615dca565b500190565b6000816000190483118215151615615d4357615d43615dca565b500290565b60005b83811015615d63578181015183820152602001615d4b565b8381111561127c5750506000910152565b600181811c90821680615d8857607f821691505b60208210811415615da957634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615dc357615dc3615dca565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461119057600080fd5b801515811461119057600080fd5b60ff8116811461119057600080fdfea2646970667358221220636b7ab264d646a3870c3863b1cbe80ce3fa56ec1427589d5b016af97907fa7a64736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106104545760003560e01c806370aadcc411610241578063c13937361161013b578063e3f4c7c9116100c3578063ed5e00eb11610087578063ed5e00eb14610b85578063f89c6f1814610b98578063fa59104f14610bc1578063fceb01f214610be4578063feee9ca314610bf757600080fd5b8063e3f4c7c914610ae8578063e48ef05c14610afb578063e59aff4b14610b2f578063e7015ab214610b42578063e87a6b8514610b6257600080fd5b8063c72eccbf1161010a578063c72eccbf14610a80578063d8a4b40c14610a89578063db0d457914610a9c578063dec72d6314610abc578063e2ec13fc14610adf57600080fd5b8063c139373614610a27578063c3b83f5f14610a3a578063c48e62f114610a4d578063c4c2e6f614610a6d57600080fd5b806391b4ded9116101c9578063ad6b22ce1161018d578063ad6b22ce1461098f578063ae71dcdf146109a2578063af4cbdfc146109aa578063bc93233f146109f1578063be27f89d14610a0457600080fd5b806391b4ded914610938578063a3b08bce14610941578063a400a89114610949578063a50267a51461095c578063ac2c957c1461097c57600080fd5b80638067cd53116102105780638067cd53146108b7578063861de52c146108ca5780638c4e8cb5146108e95780638da5cb5b1461090c5780638ec2c5a61461092557600080fd5b806370aadcc41461085457806376d423db1461087457806379ba5097146108975780637df8b8021461089f57600080fd5b806331ef892111610352578063557db448116102da5780635d7fb8e21161029e5780635d7fb8e2146107d5578063627e7b42146107e8578063630e2c35146107fb57806367674b141461080e57806369a5492e1461083157600080fd5b8063557db4481461072e57806356e4194d146107545780635849e50b146107825780635b9fbe07146107a55780635c975abb146107c857600080fd5b806346cd86221161032157806346cd8622146106bf578063489f4b97146106d25780634cf5d715146106e55780634eac3e931461070857806353a47bb71461071b57600080fd5b806331ef89211461066e5780633d975d4e146106815780633ec70ca514610694578063459c0bd0146106b757600080fd5b806316c38b3c116103e05780632b7ac3f3116103a45780632b7ac3f3146106255780632f73199d146106385780632fff70201461064b578063300a02981461065357806331dca3841461065b57600080fd5b806316c38b3c146105c05780631afed5cc146105d35780632082af14146105dc5780632830aeb0146105ef5780632a4a3e7c1461060257600080fd5b80630b5cde46116104275780630b5cde46146104cc57806310063fdc1461054e57806313251f5e1461057957806313af40351461059a5780631627540c146105ad57600080fd5b80630259f5fd1461045957806304dc46d01461046e57806306c933d814610481578063099177e9146104b9575b600080fd5b61046c610467366004615044565b610c25565b005b61046c61047c36600461533f565b610c98565b6104a461048f366004614f2c565b60046020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61046c6104c7366004615158565b610cf1565b6105176104da36600461530f565b6009602052600090815260409020805460019091015460ff80821691610100810482169162010000820416906301000000900464ffffffffff1685565b6040805195865260ff948516602087015292841692850192909252909116606083015264ffffffffff16608082015260a0016104b0565b601254610561906001600160a01b031681565b6040516001600160a01b0390911681526020016104b0565b61058c61058736600461571e565b610f4e565b6040519081526020016104b0565b61046c6105a8366004614f2c565b610f8c565b61046c6105bb366004614f2c565b6110c7565b61046c6105ce3660046152d7565b61111d565b61058c61232881565b61046c6105ea3660046156d9565b611193565b61046c6105fd36600461507c565b611231565b6104a4610610366004614f2c565b601e6020526000908152604090205460ff1681565b602154610561906001600160a01b031681565b61046c6106463660046153a7565b611282565b61058c600181565b61058c600281565b61046c6106693660046156d9565b611461565b61046c61067c3660046156fd565b6114dd565b61046c61068f366004615363565b611541565b6104a46106a236600461530f565b600d6020526000908152604090205460ff1681565b61058c600381565b61046c6106cd3660046156d9565b6116b7565b6104a46106e036600461530f565b611733565b6104a46106f336600461530f565b600f6020526000908152604090205460ff1681565b61046c6107163660046150d7565b611790565b600154610561906001600160a01b031681565b61074161073c36600461530f565b611872565b6040516104b09796959493929190615b61565b610767610762366004614f2c565b6119cd565b604080519384526020840192909252908201526060016104b0565b6104a461079036600461530f565b60266020526000908152604090205460ff1681565b6104a46107b3366004614f2c565b60156020526000908152604090205460ff1681565b6003546104a49060ff1681565b602554610561906001600160a01b031681565b61046c6107f6366004614f6b565b611a0c565b61046c6108093660046156d9565b611cea565b6104a461081c36600461530f565b600c6020526000908152604090205460ff1681565b6104a461083f36600461530f565b600e6020526000908152604090205460ff1681565b61058c61086236600461530f565b600b6020526000908152604090205481565b61058c61088236600461530f565b60009081526008602052604090206001015490565b61046c611d66565b6003546105619061010090046001600160a01b031681565b61046c6108c53660046151bf565b611e63565b61058c6108d836600461530f565b602080526000908152604090205481565b6104a46108f7366004614f2c565b601c6020526000908152604090205460ff1681565b600054610561906201000090046001600160a01b031681565b61046c61093336600461530f565b611eb5565b61058c60025481565b61058c60c981565b61046c6109573660046153f4565b6120c4565b61096f61096a3660046156fd565b612872565b6040516104b0919061591c565b61046c61098a3660046151bf565b6128dd565b602354610561906001600160a01b031681565b61058c600081565b6109db6109b836600461530f565b6000908152600960205260409020600101546301000000900464ffffffffff1690565b60405164ffffffffff90911681526020016104b0565b61046c6109ff366004615044565b61292b565b6104a4610a1236600461530f565b6000908152600f602052604090205460ff1690565b61046c610a3536600461530f565b6129c9565b61046c610a48366004614f2c565b612a6c565b610a60610a5b36600461530f565b612b85565b6040516104b09190615c39565b6104a4610a7b366004614f2c565b612d57565b61058c60275481565b61046c610a973660046156d9565b612de9565b610aaf610aaa366004614f2c565b612e43565b6040516104b09190615960565b6104a4610aca366004614f2c565b60166020526000908152604090205460ff1681565b61058c60245481565b601754610561906001600160a01b031681565b610561610b09366004615448565b80516020818301810180516028825292820191909301209152546001600160a01b031681565b61046c610b3d36600461530f565b612e96565b61058c610b50366004614f2c565b60146020526000908152604090205481565b6104a4610b7036600461530f565b60106020526000908152604090205460ff1681565b61046c610b93366004615044565b612f21565b610561610ba636600461530f565b6013602052600090815260409020546001600160a01b031681565b6104a4610bcf36600461530f565b60116020526000908152604090205460ff1681565b61046c610bf2366004615044565b612f6a565b6104a4610c053660046156fd565b601a60209081526000928352604080842090915290825290205460ff1681565b6023546001600160a01b0316331480610c4857506025546001600160a01b031633145b610c6d5760405162461bcd60e51b8152600401610c6490615bfe565b60405180910390fd5b6001600160a01b03919091166000908152601e60205260409020805460ff1916911515919091179055565b6023546001600160a01b0316331480610cbb57506025546001600160a01b031633145b610cd75760405162461bcd60e51b8152600401610c6490615bfe565b6001600160a01b0316600090815260146020526040902055565b3360009081526004602052604090205460ff16610d205760405162461bcd60e51b8152600401610c6490615be0565b6001600160a01b038516600090815260146020526040902054848484610d4584611733565b15610d7b5760405162461bcd60e51b8152600401610c64906020808252600490820152634944313360e01b604082015260600190565b6000848152601360205260409020546001600160a01b0316610dc85760405162461bcd60e51b8152600401610c649060208082526004908201526312510c4d60e21b604082015260600190565b6021546000858152600b60209081526040808320548352600f909152908190205490516343ce062f60e11b815260ff90911615156004820152602481018590526001600160a01b039091169063879c0c5e9060440160206040518083038186803b158015610e3557600080fd5b505afa158015610e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6d91906152f3565b8015610f0157506021546040516303727eb960e01b81526004810185905260ff8085166024830152831660448201526001600160a01b03909116906303727eb99060640160206040518083038186803b158015610ec957600080fd5b505afa158015610edd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0191906152f3565b610f365760405162461bcd60e51b8152600401610c64906020808252600490820152634944313560e01b604082015260600190565b610f438989898989613024565b505050505050505050565b601d6020528260005260406000206020528160005260406000208181548110610f7657600080fd5b9060005260206000200160009250925050505481565b6001600160a01b038116610fe25760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610c64565b600154600160a01b900460ff161561104e5760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610c64565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6110cf6134ba565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016110bc565b6111256134ba565b60035460ff16151581151514156111395750565b6003805460ff191682151590811790915560ff161561115757426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5906020016110bc565b50565b61119b6134ba565b6000828152600e602052604090205460ff1680156111ce57506000828152600f602052604090205460ff16151581151514155b6111d757600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527f5c90f67f3547cb9c3f1b7612610d878aa4f00e88a643d2c6b658c1f9005fdcda91015b60405180910390a15050565b6023546001600160a01b031633148061125457506025546001600160a01b031633145b6112705760405162461bcd60e51b8152600401610c6490615bfe565b61127c84848484613534565b50505050565b60035461010090046001600160a01b031633146112b15760405162461bcd60e51b8152600401610c6490615c1c565b815160005b83518110156113b05760008482815181106112e157634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906112fc9190615643565b805160009081526013602052604090819020546023549151630ceda8e960e41b81526001600160a01b039182166004820181905293945091169063ceda8e909060240160206040518083038186803b15801561135757600080fd5b505afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f9190615327565b6113999085615d11565b9350505080806113a890615daf565b9150506112b6565b5060005b835181101561145a5760008482815181106113df57634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906113fa9190615643565b80516000908152600d602052604090205490915060ff16158015611436575080516000908152601360205260409020546001600160a01b031615155b1561144757611447868286866135a7565b508061145281615daf565b9150506113b4565b5050505050565b6114696134ba565b6000828152600e602052604090205460ff161515811515141561148b57600080fd5b6000828152600e6020908152604091829020805460ff19168415159081179091558251858152918201527f0a7daa18eab3013f94989c4e384004cab457b607ce1e975b8de79c4da52da9549101611225565b6114e56134ba565b816024541415806114f857508060275414155b61150157600080fd5b6024829055602781905560408051838152602081018390527ff34353d7947a2688f99ba2ee1f5848e1dd757ae5ea05d5736a24fd6b6a9adb6f9101611225565b60035461010090046001600160a01b031633146115705760405162461bcd60e51b8152600401610c6490615c1c565b60005b81518110156116b257600082828151811061159e57634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906115b9919061555f565b80516000908152600c602052604090205490915060ff1680156115f4575080516000908152601360205260409020546001600160a01b031615155b1561169f5760235481516000908152600b602081815260408084205486518552601383528185205487518652938352818520548552600f9092528084205490516329bfb6cd60e01b81526001600160a01b03958616956329bfb6cd9561166c958c958a959094919093169260ff1691906004016159dc565b600060405180830381600087803b15801561168657600080fd5b505af115801561169a573d6000803e3d6000fd5b505050505b50806116aa81615daf565b915050611573565b505050565b6116bf6134ba565b60008281526011602052604090205460ff16151581151514156116e157600080fd5b600082815260116020908152604091829020805460ff19168415159081179091558251858152918201527fbff84c147d533b99d8802295ac70c53aa7d9ac4e520dcd0200d2f434c34b52a39101611225565b6000818152601360209081526040808320546001600160a01b03168352601590915281205460ff168061178a57506000828152601360209081526040808320546001600160a01b03168352601690915290205460ff165b92915050565b6117986134ba565b601280546001600160a01b038681166001600160a01b03199283168117909355601780548983169084168117909155600380548b84166101008102610100600160a81b03199092169190911790915560218054898516908616811790915560238054898616908716811790915560258054958916959096168517909555604080519283526020830193909352918101949094526060840152608083019190915260a08201527f655a82a8af9bfe0bd2346ce98700798d4f8aa7bcfc1cef62a911171bd8e479a79060c00160405180910390a1505050505050565b6008602052600090815260409020805460018201546002808401546003850180549495939482840b9463010000008404850b94600160301b90940490930b9291906118bc90615d74565b80601f01602080910402602001604051908101604052809291908181526020018280546118e890615d74565b80156119355780601f1061190a57610100808354040283529160200191611935565b820191906000526020600020905b81548152906001019060200180831161191857829003601f168201915b50505050509080600401805461194a90615d74565b80601f016020809104026020016040519081016040528092919081815260200182805461197690615d74565b80156119c35780601f10611998576101008083540402835291602001916119c3565b820191906000526020600020905b8154815290600101906020018083116119a657829003601f168201915b5050505050905087565b6001600160a01b038116600081815260146020818152604080842054808552600b835281852054838052918520549590945291905291905b9193909250565b600054610100900460ff16611a275760005460ff1615611a2b565b303b155b611a8e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c64565b600054610100900460ff16158015611ab0576000805461ffff19166101011790555b611ab988610f8c565b60005b8751811015611b2b576001600e60008a8481518110611aeb57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611b2390615daf565b915050611abc565b5060005b8551811015611b9e576001600f6000888481518110611b5e57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611b9690615daf565b915050611b2f565b5060005b8351811015611c1157600160106000868481518110611bd157634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611c0990615daf565b915050611ba2565b5060005b8251811015611c8457600160116000858481518110611c4457634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611c7c90615daf565b915050611c15565b50601280546001600160a01b038089166001600160a01b03199283161790925560178054878416921691909117905588166000908152600460205260409020805460ff191660011790558015611ce0576000805461ff00191690555b5050505050505050565b611cf26134ba565b60008281526010602052604090205460ff1615158115151415611d1457600080fd5b600082815260106020908152604091829020805460ff19168415159081179091558251858152918201527f463b22afe346e0b505997c71b3cb5c2a507adb0214a645f6aede655b186917179101611225565b6001546001600160a01b03163314611dde5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610c64565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60005b8151811015611eb157611e9f828281518110611e9257634e487b7160e01b600052603260045260246000fd5b6020026020010151612e96565b80611ea981615daf565b915050611e66565b5050565b6000818152601360205260409020546001600160a01b03161580611f1e57506000818152601360209081526040808320546001600160a01b03168352601690915290205460ff168015611f1e57506000818152601360205260409020546001600160a01b031615155b611f505760405162461bcd60e51b815260206004820152600360248201526249443160e81b6044820152606401610c64565b6000818152600c602052604090205460ff16611f945760405162461bcd60e51b815260206004820152600360248201526224a21960e91b6044820152606401610c64565b60175460408051634b40849760e01b8152905183926001600160a01b0316916303aac5d5918391634b408497916004808301926020929190829003018186803b158015611fe057600080fd5b505afa158015611ff4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120189190615327565b6040518263ffffffff1660e01b815260040161203691815260200190565b60206040518083038186803b15801561204e57600080fd5b505afa158015612062573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120869190615327565b146120b95760405162461bcd60e51b815260206004820152600360248201526249443360e81b6044820152606401610c64565b611190816001613952565b60035461010090046001600160a01b031633146120f35760405162461bcd60e51b8152600401610c6490615c1c565b601254604051633d97451560e21b8152600481018490526000916001600160a01b03169063f65d14549060240160206040518083038186803b15801561213857600080fd5b505afa15801561214c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217091906152f3565b61217b57600061217e565b60035b6000848152600f602052604081205460ff92831693509091166121b7576121a6826001615d11565b85516121b29190615d29565b6121ba565b84515b8551909150156121e9576000838152601a602090815260408083208784529091529020805460ff191660011790555b60005b855181101561286957600086828151811061221757634e487b7160e01b600052603260045260246000fd5b6020026020010151806020019051810190612232919061548d565b80516000908152600c602052604090205490915060ff161580156122dd575060215460a082015160c08301516040516397dc205d60e01b81526001600160a01b03909316926397dc205d9261228b929091600401615bbb565b60206040518083038186803b1580156122a357600080fd5b505afa1580156122b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122db91906152f3565b155b80156122ec5750428160200151115b1561230f5780516122fe908688613d0a565b61230a88828886613d55565b612856565b80516000908152600c602052604090205460ff16156128565760006123378260000151612b85565b60215460a08085015190830151604051637fabe16b60e01b81529394506001600160a01b0390921692637fabe16b926123739291600401615bbb565b60206040518083038186803b15801561238b57600080fd5b505afa15801561239f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c391906152f3565b1580612456575060215460c08084015190830151604051637fabe16b60e01b81526001600160a01b0390931692637fabe16b92612404929091600401615bbb565b60206040518083038186803b15801561241c57600080fd5b505afa158015612430573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245491906152f3565b155b156125825781516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff16156124b95786600714156124be5781516124a0906000614022565b81516124ad908789613d0a565b6124b989838987613d55565b612854565b81516000908152601360205260409020546124e3906001600160a01b031660016140a7565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e926125289291169060019060040161587c565b600060405180830381600087803b15801561254257600080fd5b505af1158015612556573d6000803e3d6000fd5b505083516000908152601360205260408120546124b993506001600160a01b0316915060019080613534565b806020015182602001511461285457815161259e908789613d0a565b42826020015111156126e3576012548251600090815260136020908152604091829020549085015191516327ad762d60e21b81526001600160a01b039182166004820152602481019290925290911690639eb5d8b490604401600060405180830381600087803b15801561261157600080fd5b505af1158015612625573d6000803e3d6000fd5b5050835160009081526008602090815260409182902086518155818701516001820155918601516002808401805460608a015160808b0151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a086015180518795509293506126be9260038501929190910190614cc7565b5060c082015180516126da916004840191602090910190614cc7565b50905050612854565b81516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff16801561271c5750428160200151115b15612854578151600090815260136020526040902054612746906001600160a01b031660016140a7565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e9261278b9291169060019060040161587c565b600060405180830381600087803b1580156127a557600080fd5b505af11580156127b9573d6000803e3d6000fd5b505083516000908152601360205260408120546127e593506001600160a01b0316915060019080613534565b8151600090815260136020908152604091829020548451848301518387015185516001600160a01b039094168452938301919091529281019290925260608201527fb71601cabce6b66d1ceb87bb549207b61c7c27e3efd188cae1e0d39f7feedfd79060800160405180910390a15b505b508061286181615daf565b9150506121ec565b50505050505050565b6000828152601d602090815260408083208484528252918290208054835181840281018401909452808452606093928301828280156128d057602002820191906000526020600020905b8154815260200190600101908083116128bc575b5050505050905092915050565b60005b8151811015611eb15761291982828151811061290c57634e487b7160e01b600052603260045260246000fd5b6020026020010151611eb5565b8061292381615daf565b9150506128e0565b6129336134ba565b6001600160a01b0382161580159061296a57506001600160a01b03821660009081526004602052604090205460ff16151581151514155b61297357600080fd5b6001600160a01b03821660009081526004602052604090819020805460ff1916831515179055517f58d7a3ccc34541e162fcfc87b84be7b78c34d1e1e7f15de6e4dd67d0fe70aecd90611225908490849061587c565b3360009081526004602052604090205460ff166129f85760405162461bcd60e51b8152600401610c6490615be0565b6000818152600c602052604090205460ff16612a3f5760405162461bcd60e51b8152600401610c649060208082526004908201526324a2191960e11b604082015260600190565b6000908152600c60209081526040808320805460ff19908116909155600d90925290912080549091169055565b612a746134ba565b6001600160a01b038116612abc5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610c64565b600154600160a81b900460ff1615612b0c5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610c64565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016110bc565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c0810191909152600082815260086020908152604091829020825160e0810184528154815260018201549281019290925260028082015480820b820b820b9484019490945263010000008404810b810b810b6060840152600160301b909304830b830b90920b608082015260038201805491929160a084019190612c3c90615d74565b80601f0160208091040260200160405190810160405280929190818152602001828054612c6890615d74565b8015612cb55780601f10612c8a57610100808354040283529160200191612cb5565b820191906000526020600020905b815481529060010190602001808311612c9857829003601f168201915b50505050508152602001600482018054612cce90615d74565b80601f0160208091040260200160405190810160405280929190818152602001828054612cfa90615d74565b8015612d475780601f10612d1c57610100808354040283529160200191612d47565b820191906000526020600020905b815481529060010190602001808311612d2a57829003601f168201915b5050505050815250509050919050565b602354604051636c35b77560e01b81526001600160a01b0383811660048301526000928392911690636c35b7759060240160206040518083038186803b158015612da057600080fd5b505afa158015612db4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd89190614f4f565b6001600160a01b0316141592915050565b612df16134ba565b600082815260266020908152604091829020805460ff19168415159081179091558251858152918201527fc513a9633586b17da42f91779680c8eaf029d7e1752bb3e4b43ae26cd05849299101611225565b6001600160a01b0381166000908152601c602052604090205460609060ff16612e7457612e6f826141c2565b61178a565b6001600160a01b03821660009081526014602052604090205461178a90614347565b612e9f81611733565b15612ed25760405162461bcd60e51b815260206004820152600360248201526212510d60ea1b6044820152606401610c64565b6000818152600d602052604090205460ff16612f165760405162461bcd60e51b815260206004820152600360248201526249443560e81b6044820152606401610c64565b611190816000614379565b6023546001600160a01b0316331480612f4457506025546001600160a01b031633145b612f605760405162461bcd60e51b8152600401610c6490615bfe565b611eb182826140a7565b3360009081526004602052604090205460ff16612f995760405162461bcd60e51b8152600401610c6490615be0565b6001600160a01b03821660009081526014602052604090205415801590612fe557506001600160a01b0382166000908152601460209081526040808320548352600c90915290205460ff165b61301a5760405162461bcd60e51b8152600401610c64906020808252600490820152630494432360e41b604082015260600190565b611eb18282614784565b80156131975783156130615760405162461bcd60e51b8152600401610c64906020808252600490820152634944313760e01b604082015260600190565b6023546001600160a01b03868116600090815260146020908152604080832054808452600b8352818420548452600f9092529182902054915163048e4dcb60e11b81526004810191909152841515602482015260ff9091161515604482015291169063091c9b969060640160206040518083038186803b1580156130e457600080fd5b505afa1580156130f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061311c91906152f3565b61312557600080fd5b6023546001600160a01b0386811660009081526014602052604090819020549051639971441b60e01b81526004810191909152911690639971441b90602401600060405180830381600087803b15801561317e57600080fd5b505af1158015613192573d6000803e3d6000fd5b505050505b6131a28560006140a7565b60235460405162d2b13f60e11b81526001600160a01b03909116906301a5627e906131d490889060009060040161587c565b600060405180830381600087803b1580156131ee57600080fd5b505af1158015613202573d6000803e3d6000fd5b50505050613214856000806000613534565b6001600160a01b0385166000908152601460209081526040808320548352600b8252808320548352600f90915290205461326590869086908690869060ff1661325e57600b614813565b6008614813565b6040805160a0810182526001600160a01b0387166000908152601460209081528382205480845260ff8089168386015287811685870152908352600b8252848320548352600f9091529290205490916060830191166132c557600b6132c8565b60085b60ff9081168252600060209283018190526001600160a01b03891681526014835260408082208054835260098086528284208751815587870151600191820180548a8701516060808d015160809d8e0151958c1661ffff1990941693909317610100928c1683021767ffffffffffff0000191662010000938c169390930267ffffffffff000000191692909217630100000064ffffffffff95861602179092559454808852600b8a5286882054948a5286882087518281529a8b019590955295890195909552825493880193909352015480851696860196909652600886901c841660a0860152601086901c90931660c085015260189490941c90911660e0830152918101919091527f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73906101200160405180910390a18361345a576001600160a01b038516600081815260146020908152604091829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc910160405180910390a161145a565b6001600160a01b0385166000818152601460209081526040918290205482519384529083015281018590527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e444906060015b60405180910390a15050505050565b6000546201000090046001600160a01b031633146135325760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610c64565b565b60255460405163509e2f3360e01b81526001600160a01b0386811660048301528515156024830152841515604483015283151560648301529091169063509e2f3390608401600060405180830381600087803b15801561359357600080fd5b505af1158015611ce0573d6000803e3d6000fd5b60006135b68460000151612b85565b90506135d8846060015160ff9081166000908152601060205260409020541690565b806136075750606084015160ff9081166000908152601160205260409020541680156136075750428160200151105b15613837578351600090815260096020908152604080832087518082558389015160019283018054858c015160608d015160808e015164ffffffffff1663010000000267ffffffffff0000001960ff92831662010000021667ffffffffffff0000199383166101000261ffff1990951692909616919091179290921716929092179190911790558452600d835292819020805460ff191690931790925585516017548351638f0ac45360e01b815293517f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73948a948994938b936001600160a01b0390911692638f0ac453926004808301939192829003018186803b15801561370e57600080fd5b505afa158015613722573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137469190615327565b604080519586526020808701959095528581019390935281516060808701919091529382015160ff90811660808088019190915293830151811660a08701529382015190931660c0850152015164ffffffffff1660e08301526101008201526101200160405180910390a1602454821061382557601754845160405163602726b560e11b81526001600160a01b039092169163c04e4d6a916137ee9160040190815260200190565b600060405180830381600087803b15801561380857600080fd5b505af115801561381c573d6000803e3d6000fd5b5050505061145a565b8351613832906001614379565b61145a565b606084015160ff908116600090815260116020526040902054168015613861575042816020015110155b1561145a5783516000908152601360208181526040808420546001600160a01b039081168552601e8352818520805460ff191660019081179091558951865293909252909220546138b39216906140a7565b60235484516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e926138f89291169060019060040161587c565b600060405180830381600087803b15801561391257600080fd5b505af1158015613926573d6000803e3d6000fd5b5050855160009081526013602052604081205461145a93506001600160a01b0316915060019080613534565b600061395d83612b85565b90504281602001511115613c7c576000838152600b602052604081205461398390614a08565b60125460a084015160c08501516040519394506000936001600160a01b0390931692634cde32ce9289926139b99260200161583d565b60408051601f1981840301815291815260208881015160008c8152600b8352838120548152600f9092529181205460ff166139f55760036139f8565b60025b886000806040518963ffffffff1660e01b8152600401613a1f989796959493929190615973565b602060405180830381600087803b158015613a3957600080fd5b505af1158015613a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a719190614f4f565b8351600090815260136020908152604080832080546001600160a01b0319166001600160a01b0386811691821790925588518186526014855283862055601c90935292819020805460ff1916600117905560235487519151630e76f6e760e11b8152600481019290925260248201929092529293501690631cededce90604401600060405180830381600087803b158015613b0b57600080fd5b505af1158015613b1f573d6000803e3d6000fd5b505050508060288460a00151604051613b389190615821565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b03199093169290921790915560c08401518291602891613b7b91615821565b90815260405190819003602001902080546001600160a01b03929092166001600160a01b03199092169190911790558315613c3a57601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613c0057600080fd5b505af1158015613c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c389190615327565b505b82517f889e2060e46779287c2fcbf489c195ef20f5b44a74e3dcb58d491ae073c1370f9082908585613c6b83614347565b6040516134ab959493929190615897565b81156116b257601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613cd257600080fd5b505af1158015613ce6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127c9190615327565b600083815260208052604090205482146116b2576000908152601d60209081526040808320848452825280832080546001810182559084528284200185905593825280529190912055565b602754835160009081526008602090815260409182902086518155818701516001820155918601516002808401805460608a015160808b0151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a0860151805193851093879392613dee926003850192910190614cc7565b5060c08201518051613e0a916004840191602090910190614cc7565b505084516000908152600b602052604090208490555080613e98576017548451602086015160405163e9c962eb60e01b815260048101929092526024820152604481018590526001600160a01b039091169063e9c962eb90606401600060405180830381600087803b158015613e7f57600080fd5b505af1158015613e93573d6000803e3d6000fd5b505050505b83516000908152600c602052604090819020805460ff1916600117905560235485518287015160608801516080890151945163312025df60e21b81526004810193909352600291820b6024840152810b60448301529290920b60648301526001600160a01b03169063c480977c90608401600060405180830381600087803b158015613f2357600080fd5b505af1158015613f37573d6000803e3d6000fd5b505050507faba5c0e34b9b54828db4e0ac6b951ca282a0b171289eebf93353c296f9e826138584866000015187601760009054906101000a90046001600160a01b03166001600160a01b031663afff5a646040518163ffffffff1660e01b815260040160206040518083038186803b158015613fb257600080fd5b505afa158015613fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fea9190615327565b8951613ff590614347565b60405161400796959493929190615b17565b60405180910390a1801561145a57835161145a906000613952565b600082815260136020526040812054614049916001600160a01b0390911690808080614813565b801561405757614057614a6c565b6000828152601360209081526040918290205482516001600160a01b0390911681529081018490527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc9101611225565b6012546040516333dfec9960e21b81526001600160a01b03848116600483015283151592169063cf7fb2649060240160206040518083038186803b1580156140ee57600080fd5b505afa158015614102573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061412691906152f3565b151514611eb157601254604051637f8c2d6160e01b81526001600160a01b0390911690637f8c2d619061415f908590859060040161587c565b600060405180830381600087803b15801561417957600080fd5b505af115801561418d573d6000803e3d6000fd5b505050507f2b8992e59f9813c2f92be2374e9bdd5384146ff8f719b038fbaf7d3dbfa78fde828260405161122592919061587c565b60235460405163d28231bd60e01b81526001600160a01b038381166004830152606092169063d28231bd9060240160206040518083038186803b15801561420857600080fd5b505afa15801561421c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061424091906152f3565b6142c55760255460405163db0d457960e01b81526001600160a01b0384811660048301529091169063db0d45799060240160006040518083038186803b15801561428957600080fd5b505afa15801561429d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e6f9190810190615251565b60235460405163db0d457960e01b81526001600160a01b0384811660048301529091169063db0d4579906024015b60006040518083038186803b15801561430b57600080fd5b505afa15801561431f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261178a9190810190615251565b602354604051634d6759b760e11b8152600481018390526060916001600160a01b031690639aceb36e906024016142f3565b6000828152600960209081526040808320815160a0810183528154815260019091015460ff80821694830194909452610100810484169282019290925262010000820490921660608301526301000000900464ffffffffff166080820152906143e184612b85565b9050614403826060015160ff9081166000908152601060205260409020541690565b15614749576023548251600090815260136020526040908190205490516336c0d85560e01b81526001600160a01b0391821660048201529116906336c0d8559060240160206040518083038186803b15801561445e57600080fd5b505afa158015614472573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061449691906152f3565b1561455b5781516000908152601360205260408120546144c1916001600160a01b03909116906140a7565b602354825160009081526013602052604080822054905162d2b13f60e11b81526001600160a01b03938416936301a5627e93614503939091169160040161587c565b600060405180830381600087803b15801561451d57600080fd5b505af1158015614531573d6000803e3d6000fd5b5050835160009081526013602052604081205461455b93506001600160a01b031691508080613534565b600080600061456985614af4565b92509250925060038314801561459c575084516000908152600b60209081526040808320548352600f90915290205460ff165b156146015784516000908152600b60209081526040808320548352602690915290205460ff16156145f45784516000908152601360205260409020546145ef906001600160a01b03168484848a15614b65565b614741565b84516145ef908715614022565b6012548551600090815260136020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b15801561465757600080fd5b505afa15801561466b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061468f91906152f3565b61473457845160009081526013602052604090205460608601516146c2916001600160a01b031690859085908590614813565b856146cf576146cf614a6c565b845160009081526013602090815260409182902054875183516001600160a01b039092168252918101919091529081018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449060600160405180910390a1614741565b8561474157614741614a6c565b50505061127c565b606082015160ff9081166000908152601160205260409020541680156147725750428160200151105b1561127c57815161127c908415614022565b61478e82826140a7565b6023546001600160a01b038381166000818152601460205260409081902054905163032bc38360e21b8152600481019190915260248101919091528315156044820152911690630caf0e0c90606401600060405180830381600087803b1580156147f757600080fd5b505af115801561480b573d6000803e3d6000fd5b505050505050565b60125460405163b91f5e3560e01b81526001600160a01b038781166004830152602482018790529091169063b91f5e3590604401600060405180830381600087803b15801561486157600080fd5b505af1158015614875573d6000803e3d6000fd5b5050505060c98160ff1614156148f3576023546040516303e810fd60e61b81526001600160a01b039091169063fa043f40906148bc908890600090819081906004016158f0565b600060405180830381600087803b1580156148d657600080fd5b505af11580156148ea573d6000803e3d6000fd5b505050506149c4565b6023546040516303e810fd60e61b81526001600160a01b039091169063fa043f40906149299088908890889088906004016158f0565b600060405180830381600087803b15801561494357600080fd5b505af1158015614957573d6000803e3d6000fd5b5050505060008414156149c4576025546040516326ddf9ff60e11b81526001600160a01b03878116600483015290911690634dbbf3fe90602401600060405180830381600087803b1580156149ab57600080fd5b505af11580156149bf573d6000803e3d6000fd5b505050505b5050506001600160a01b039190911660009081526016602090815260408083208054941560ff19958616811790915560159092529091208054911591909216179055565b6040805160018082528183019092526060916000919060208083019080368337019050509050614a3a83612328615d11565b81600081518110614a5b57634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b601760009054906101000a90046001600160a01b03166001600160a01b03166377d078d76040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614abc57600080fd5b505af1158015614ad0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111909190615327565b6000806000836040015160ff16846020015160ff161415614b25575050506020810151604082015160039190611a05565b836040015160ff16846020015160ff1611614b4b57600284602001518560400151614b58565b6001846020015185604001515b9250925092509193909250565b60125460405163b91f5e3560e01b81526001600160a01b038781166004830152600060248301529091169063b91f5e3590604401600060405180830381600087803b158015614bb357600080fd5b505af1158015614bc7573d6000803e3d6000fd5b50506023546040516303e810fd60e61b81526001600160a01b03909116925063fa043f409150614c019088908890889088906004016158f0565b600060405180830381600087803b158015614c1b57600080fd5b505af1158015614c2f573d6000803e3d6000fd5b5050506001600160a01b0386166000908152601660209081526040808320805460ff19908116909155601590925290912080549091166001179055508015614c7957614c79614a6c565b6001600160a01b038516600081815260146020908152604091829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc91016134ab565b828054614cd390615d74565b90600052602060002090601f016020900481019282614cf55760008555614d3b565b82601f10614d0e57805160ff1916838001178555614d3b565b82800160010185558215614d3b579182015b82811115614d3b578251825591602001919060010190614d20565b50614d47929150614d4b565b5090565b5b80821115614d475760008155600101614d4c565b6000614d73614d6e84615cea565b615c97565b9050828152838383011115614d8757600080fd5b828260208301376000602084830101529392505050565b8035614da981615df6565b919050565b600082601f830112614dbe578081fd5b81356020614dce614d6e83615cc7565b80838252828201915082860187848660051b8901011115614ded578586fd5b855b85811015614e405781356001600160401b03811115614e0c578788fd5b8801603f81018a13614e1c578788fd5b614e2d8a8783013560408401614d60565b8552509284019290840190600101614def565b5090979650505050505050565b600082601f830112614e5d578081fd5b81356020614e6d614d6e83615cc7565b80838252828201915082860187848660051b8901011115614e8c578586fd5b855b85811015614e4057813584529284019290840190600101614e8e565b8051600181900b8114614da957600080fd5b8051600281900b8114614da957600080fd5b600082601f830112614ede578081fd5b8151614eec614d6e82615cea565b818152846020838601011115614f00578283fd5b614f11826020830160208701615d48565b949350505050565b805162ffffff81168114614da957600080fd5b600060208284031215614f3d578081fd5b8135614f4881615df6565b9392505050565b600060208284031215614f60578081fd5b8151614f4881615df6565b600080600080600080600060e0888a031215614f85578283fd5b614f8e88614d9e565b965060208801356001600160401b0380821115614fa9578485fd5b614fb58b838c01614e4d565b9750614fc360408b01614d9e565b965060608a0135915080821115614fd8578485fd5b614fe48b838c01614e4d565b9550614ff260808b01614d9e565b945060a08a0135915080821115615007578384fd5b6150138b838c01614e4d565b935060c08a0135915080821115615028578283fd5b506150358a828b01614e4d565b91505092959891949750929550565b60008060408385031215615056578182fd5b823561506181615df6565b9150602083013561507181615e0b565b809150509250929050565b60008060008060808587031215615091578182fd5b843561509c81615df6565b935060208501356150ac81615e0b565b925060408501356150bc81615e0b565b915060608501356150cc81615e0b565b939692955090935050565b60008060008060008060c087890312156150ef578384fd5b86356150fa81615df6565b9550602087013561510a81615df6565b9450604087013561511a81615df6565b9350606087013561512a81615df6565b9250608087013561513a81615df6565b915060a087013561514a81615df6565b809150509295509295509295565b600080600080600060a0868803121561516f578283fd5b853561517a81615df6565b945060208601359350604086013561519181615e19565b925060608601356151a181615e19565b915060808601356151b181615e0b565b809150509295509295909350565b600060208083850312156151d1578182fd5b82356001600160401b038111156151e6578283fd5b8301601f810185136151f6578283fd5b8035615204614d6e82615cc7565b80828252848201915084840188868560051b8701011115615223578687fd5b8694505b83851015615245578035835260019490940193918501918501615227565b50979650505050505050565b60006020808385031215615263578182fd5b82516001600160401b03811115615278578283fd5b8301601f81018513615288578283fd5b8051615296614d6e82615cc7565b80828252848201915084840188868560051b87010111156152b5578687fd5b8694505b838510156152455780518352600194909401939185019185016152b9565b6000602082840312156152e8578081fd5b8135614f4881615e0b565b600060208284031215615304578081fd5b8151614f4881615e0b565b600060208284031215615320578081fd5b5035919050565b600060208284031215615338578081fd5b5051919050565b60008060408385031215615351578182fd5b82359150602083013561507181615df6565b60008060408385031215615375578182fd5b8235915060208301356001600160401b03811115615391578182fd5b61539d85828601614dae565b9150509250929050565b6000806000606084860312156153bb578081fd5b8335925060208401356001600160401b038111156153d7578182fd5b6153e386828701614dae565b925050604084013590509250925092565b60008060008060808587031215615409578182fd5b8435935060208501356001600160401b03811115615425578283fd5b61543187828801614dae565b949794965050505060408301359260600135919050565b600060208284031215615459578081fd5b81356001600160401b0381111561546e578182fd5b8201601f8101841361547e578182fd5b614f1184823560208401614d60565b60006020828403121561549e578081fd5b81516001600160401b03808211156154b4578283fd5b9083019060e082860312156154c7578283fd5b6154cf615c4c565b82518152602083015160208201526154e960408401614ebc565b60408201526154fa60608401614ebc565b606082015261550b60808401614ebc565b608082015260a083015182811115615521578485fd5b61552d87828601614ece565b60a08301525060c083015182811115615544578485fd5b61555087828601614ece565b60c08301525095945050505050565b60006101808284031215615571578081fd5b615579615c74565b8251815261558960208401614ebc565b602082015261559a60408401614ebc565b60408201526155ab60608401614ebc565b60608201526155bc60808401614eaa565b60808201526155cd60a08401614ebc565b60a08201526155de60c08401614eaa565b60c08201526155ef60e08401614ebc565b60e0820152610100615602818501614f19565b90820152610120615614848201614ebc565b90820152610140615626848201614f19565b90820152610160615638848201614ebc565b908201529392505050565b600060a08284031215615654578081fd5b60405160a081018181106001600160401b038211171561567657615676615de0565b60405282518152602083015161568b81615e19565b6020820152604083015161569e81615e19565b604082015260608301516156b181615e19565b6060820152608083015164ffffffffff811681146156cd578283fd5b60808201529392505050565b600080604083850312156156eb578182fd5b82359150602083013561507181615e0b565b6000806040838503121561570f578182fd5b50508035926020909101359150565b600080600060608486031215615732578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b838110156157785781518752958201959082019060010161575c565b509495945050505050565b6000815180845261579b816020860160208601615d48565b601f01601f19169290920160200192915050565b8051825260208101516020830152604081015160020b6040830152606081015160020b6060830152608081015160020b6080830152600060a082015160e060a08501526157ff60e0850182615783565b905060c083015184820360c08601526158188282615783565b95945050505050565b60008251615833818460208701615d48565b9190910192915050565b6000835161584f818460208801615d48565b630103b39960e51b9083019081528351615870816004840160208801615d48565b01600401949350505050565b6001600160a01b039290921682521515602082015260400190565b60018060a01b038616815284602082015260a0604082015260006158be60a08301866157af565b82810360608401526158d08186615749565b905082810360808401526158e48185615749565b98975050505050505050565b6001600160a01b03949094168452602084019290925260ff908116604084015216606082015260800190565b6020808252825182820181905260009190848201906040850190845b8181101561595457835183529284019291840191600101615938565b50909695505050505050565b602081526000614f486020830184615749565b60006101008a835280602084015261598d8184018b615783565b905088604084015287606084015260ff8716608084015282810360a08401526159b68187615749565b94151560c084015250506001600160a01b039190911660e0909101529695505050505050565b600061022082019050878252865160208301526020870151615a03604084018260020b9052565b506040870151615a18606084018260020b9052565b506060870151615a2d608084018260020b9052565b506080870151615a4260a084018260010b9052565b5060a0870151615a5760c084018260020b9052565b5060c0870151615a6c60e084018260010b9052565b5060e0870151610100615a838185018360020b9052565b8801519050610120615a9b8482018362ffffff169052565b8801519050610140615ab18482018360020b9052565b8801519050610160615ac98482018362ffffff169052565b8801519050615ade61018084018260020b9052565b50856101a0830152615afc6101c08301866001600160a01b03169052565b9215156101e082015290151561020090910152949350505050565b86815285602082015284604082015260c060608201526000615b3c60c08301866157af565b84608084015282810360a0840152615b548185615749565b9998505050505050505050565b8781528660208201528560020b60408201528460020b60608201528360020b608082015260e060a08201526000615b9b60e0830185615783565b82810360c0840152615bad8185615783565b9a9950505050505050505050565b604081526000615bce6040830185615783565b82810360208401526158188185615783565b6020808252600490820152630494431360e41b604082015260600190565b6020808252600490820152630928862760e31b604082015260600190565b60208082526003908201526249443960e81b604082015260600190565b602081526000614f4860208301846157af565b60405160e081016001600160401b0381118282101715615c6e57615c6e615de0565b60405290565b60405161018081016001600160401b0381118282101715615c6e57615c6e615de0565b604051601f8201601f191681016001600160401b0381118282101715615cbf57615cbf615de0565b604052919050565b60006001600160401b03821115615ce057615ce0615de0565b5060051b60200190565b60006001600160401b03821115615d0357615d03615de0565b50601f01601f191660200190565b60008219821115615d2457615d24615dca565b500190565b6000816000190483118215151615615d4357615d43615dca565b500290565b60005b83811015615d63578181015183820152602001615d4b565b8381111561127c5750506000910152565b600181811c90821680615d8857607f821691505b60208210811415615da957634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615dc357615dc3615dca565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461119057600080fd5b801515811461119057600080fd5b60ff8116811461119057600080fdfea2646970667358221220636b7ab264d646a3870c3863b1cbe80ce3fa56ec1427589d5b016af97907fa7a64736f6c63430008040033

Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading