Contract 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da68611

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

Contract Overview

Balance:
Txn Hash Method
Block
From
To
Value
0xa388a11229da93d01b4da3044abbe0c3d1cf84d5b037d01268286b9103adcffd0x60806040117911992023-07-10 17:34:26340 days 7 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  Create: TherundownConsumer0 ETH0.0018519465390.00001
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 12 hrs ago 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce1 0x7ab3bab7d5db61cb6fb1f2a7ce216d7b1da686110 ETH
[ Download CSV Export 
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 16 : 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";

/// @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[]) public requestIdGamesCreated; // deprecated see Wrapper
    mapping(bytes32 => bytes[]) public requestIdGamesResolved; // deprecated see Wrapper
    mapping(bytes32 => bytes[]) public requestIdGamesOdds; // deprecated see Wrapper

    // Maps <GameId, Game>
    mapping(bytes32 => GameCreate) public gameCreated;
    mapping(bytes32 => GameResolve) public gameResolved;
    mapping(bytes32 => GameOdds) public 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) public oddsLastPulledForGame; // deprecated see GamesOddsObtainer
    mapping(uint => bytes32[]) public gamesPerDate; // deprecated use gamesPerDatePerSport
    mapping(uint => mapping(uint => bool)) public isSportOnADate;
    mapping(address => bool) public invalidOdds; // deprecated see GamesOddsObtainer
    mapping(address => bool) public marketCreated;
    mapping(uint => mapping(uint => bytes32[])) public gamesPerDatePerSport;
    mapping(address => bool) public isPausedByCanceledStatus;
    mapping(address => bool) public canMarketBeUpdated; // deprecated
    mapping(bytes32 => uint) public gameOnADate;

    ITherundownConsumerVerifier public verifier;
    mapping(bytes32 => GameOdds) public backupOdds; // deprecated see GamesOddsObtainer
    IGamesOddsObtainer public oddsObtainer;
    uint public maxNumberOfMarketsToResolve;

    /* ========== 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 {
        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);
            }
            // old game UFC checking fighters
            else if (gameFulfilledCreated[gameForProcessing.gameId]) {
                GameCreate memory currentGameValues = getGameCreatedById(gameForProcessing.gameId);

                // if name of fighter (away or home) is 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);
                        } else {
                            _pauseOrUnpauseMarket(marketPerGameId[gameForProcessing.gameId], true);
                            oddsObtainer.pauseUnpauseChildMarkets(marketPerGameId[gameForProcessing.gameId], true);
                        }
                    }
                    // 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;
                        queues.updateGameStartDate(gameForProcessing.gameId, gameForProcessing.startTime);
                    } 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);
                            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]);
            }
        }
    }

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

    /// @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 onlyObtainer {
        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 onlyObtainer {
        _pauseOrUnpauseMarket(_market, _pause);
    }

    /// @notice setting gameid per market
    /// @param _gameId game id
    /// @param _child child market address
    function setGameIdPerChildMarket(bytes32 _gameId, address _child) external onlyObtainer {
        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 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 if game is resolved
    /// @param _gameId game id for which game is looking
    /// @return bool is game resolved true/false
    function isGameInResolvedStatus(bytes32 _gameId) public view returns (bool) {
        return _isGameStatusResolved(gameResolved[_gameId]);
    }

    /// @notice view function which returns normalized odds up to 100 (Example: 50-40-10)
    /// @param _gameId game id for which game is looking
    /// @return uint[] odds array normalized
    function getNormalizedOdds(bytes32 _gameId) public view returns (uint[] memory) {
        return oddsObtainer.getNormalizedOdds(_gameId);
    }

    /// @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) public view returns (uint[] memory) {
        return marketCreated[_market] ? getNormalizedOdds(gameIdPerMarket[_market]) : getNormalizedChildOdds(_market);
    }

    /// @notice view function which returns normalized odds up to 100 (Example: 50-40-10)
    /// @param _market market
    /// @return uint[] odds array normalized
    function getNormalizedChildOdds(address _market) public view returns (uint[] memory) {
        return oddsObtainer.getNormalizedChildOdds(_market);
    }

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

    function _createGameFulfill(
        bytes32 requestId,
        GameCreate memory _game,
        uint _sportId
    ) internal {
        gameCreated[_game.gameId] = _game;
        sportsIdPerGame[_game.gameId] = _sportId;
        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(),
            oddsObtainer.getNormalizedOdds(_game.gameId)
        );
    }

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

    function _createMarket(bytes32 _gameId) 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
                isSportTwoPositionsSport(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));

            queues.dequeueGamesCreated();

            emit CreateSportsMarket(address(market), game.gameId, game, tags, oddsObtainer.getNormalizedOdds(game.gameId));
        } else {
            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);
            }

            (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]]) {
                _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));
            oddsObtainer.setBackupOddsAsMainOddsForGame(gameIdPerMarket[_market]);
        }

        _pauseOrUnpauseMarket(_market, false);
        oddsObtainer.pauseUnpauseChildMarkets(_market, false);
        _setMarketCancelOrResolved(
            _market,
            _outcome,
            _homeScore,
            _awayScore,
            isSportTwoPositionsSport(sportsIdPerGame[gameIdPerMarket[_market]]) ? 8 : 11
        );
        gameResolved[gameIdPerMarket[_market]] = GameResolve(
            gameIdPerMarket[_market],
            _homeScore,
            _awayScore,
            isSportTwoPositionsSport(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 _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);
        }
        marketCanceled[_market] = _outcome == CANCELLED;
        marketResolved[_market] = _outcome != CANCELLED;
    }

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

    /* ========== 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 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 setNewMaxNumberOfMarketsToResolve(uint _maxNumberOfMarketsToResolve) external onlyOwner {
        require(maxNumberOfMarketsToResolve != _maxNumberOfMarketsToResolve);
        maxNumberOfMarketsToResolve = _maxNumberOfMarketsToResolve;
        emit NewMaxNumberOfMarketsToResolve(_maxNumberOfMarketsToResolve);
    }

    /// @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
    ) external onlyOwner {
        sportsManager = ISportPositionalMarketManager(_sportsManager);
        queues = _queues;
        wrapperAddress = _wrapperAddress;
        verifier = ITherundownConsumerVerifier(_verifier);
        oddsObtainer = IGamesOddsObtainer(_oddsObtainer);

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

    /// @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 onlyObtainer() {
        require(msg.sender == address(oddsObtainer), "ID16");
        _;
    }

    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(isSportTwoPositionsSport(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 GameOddsAdded(bytes32 _requestId, bytes32 _id, GameOdds _game, uint[] _normalizedOdds); // deprecated see GamesOddsObtainer
    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 InvalidOddsForMarket(bytes32 _requestId, address _marketAddress, bytes32 _id, GameOdds _game); // deprecated see GamesOddsObtainer
    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 NewSportsMarketManager(address _sportsManager); // deprecated
    event NewWrapperAddress(address _wrapperAddress); // deprecated
    event NewQueueAddress(GamesQueue _queues); // deprecated
    event NewSportContracts(
        address _wrapperAddress,
        GamesQueue _queues,
        address _sportsManager,
        address _verifier,
        address _oddsObtainer
    );
    event AddedIntoWhitelist(address _whitelistAddress, bool _flag);
    event OddsCircuitBreaker(address _marketAddress, bytes32 _id); // deprecated see GamesOddsObtainer
    event NewMaxNumberOfMarketsToResolve(uint _maxNumber);
    event GameTimeMovedAhead(address _market, bytes32 _gameId, uint _oldStartTime, uint _newStartTime);
}

File 2 of 16 : 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 16 : 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 16 : 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 16 : 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 16 : 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) public 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;
        gameStartPerGameId[data] = startTime;

        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 update a game start date
    /// @param _gameId gameId which start date is updated
    /// @param _date date
    function updateGameStartDate(bytes32 _gameId, uint _date) public canExecuteFunction {
        require(_date > block.timestamp, "Date must be in future");
        require(gameStartPerGameId[_gameId] != 0, "Game not existing");
        gameStartPerGameId[_gameId] = _date;
        emit NewStartDateOnGame(_gameId, _date);
    }

    /// @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);
    event NewStartDateOnGame(bytes32 _gameId, uint _date);
}

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

File 8 of 16 : 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 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 getStringIDsFromBytesArrayIDs(bytes32[] memory _ids) external view returns (string[] memory);
}

File 9 of 16 : 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) external view returns (bool);

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

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

    function getNormalizedChildOdds(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 currentActiveTotalChildMarket(address _main) external view returns (address);

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

    function isSpreadChildMarket(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
    ) 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 16 : 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 initialMint() external view returns (uint);

    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 tags(uint idx) external view returns (uint);

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

    function getParentMarketPositions() external view returns (IPosition position1, IPosition 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 16 : 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 12 of 16 : 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 13 of 16 : 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 14 of 16 : 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 15 of 16 : 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 16 of 16 : 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":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"}],"indexed":false,"internalType":"struct TherundownConsumer.GameOdds","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"}],"name":"GameOddsAdded","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":"bytes32","name":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"}],"indexed":false,"internalType":"struct TherundownConsumer.GameOdds","name":"_game","type":"tuple"}],"name":"InvalidOddsForMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_maxNumber","type":"uint256"}],"name":"NewMaxNumberOfMarketsToResolve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract GamesQueue","name":"_queues","type":"address"}],"name":"NewQueueAddress","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"}],"name":"NewSportContracts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sportsManager","type":"address"}],"name":"NewSportsMarketManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_wrapperAddress","type":"address"}],"name":"NewWrapperAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"OddsCircuitBreaker","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":"bytes32","name":"","type":"bytes32"}],"name":"backupOdds","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"canMarketBeUpdated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"gameOdds","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"}],"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"}],"name":"gamesPerDate","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"address","name":"_market","type":"address"}],"name":"getNormalizedChildOdds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getNormalizedOdds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":"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":"","type":"address"}],"name":"invalidOdds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"isGameInResolvedStatus","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":"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":"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":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"oddsLastPulledForGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"_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":"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":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdGamesCreated","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdGamesOdds","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdGamesResolved","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","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":"_maxNumberOfMarketsToResolve","type":"uint256"}],"name":"setNewMaxNumberOfMarketsToResolve","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"}],"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"}]

608060405234801561001057600080fd5b506159d180620000216000396000f3fe608060405234801561001057600080fd5b506004361061048b5760003560e01c806379ba509711610262578063be27f89d11610151578063e2ec13fc116100ce578063ed5e00eb11610092578063ed5e00eb14610c6d578063efccb47a14610c80578063f89c6f1814610c93578063fa59104f14610cbc578063fceb01f214610cdf578063feee9ca314610cf257600080fd5b8063e2ec13fc14610bfb578063e3f4c7c914610c04578063e59aff4b14610c17578063e7015ab214610c2a578063e87a6b8514610c4a57600080fd5b8063c48e62f111610115578063c48e62f114610b7f578063c4c2e6f614610b9f578063cb9ae26414610bb2578063db0d457914610bc5578063dec72d6314610bd857600080fd5b8063be27f89d14610b00578063c139373614610b23578063c39718a814610b36578063c3b83f5f14610b59578063c475e0b314610b6c57600080fd5b80639aceb36e116101df578063ad6b22ce116101a3578063ad6b22ce14610a7e578063ae71dcdf14610a91578063b0686d8814610a99578063b09bd9e314610aac578063bc93233f14610aed57600080fd5b80639aceb36e14610a1d578063a3b08bce14610a30578063a400a89114610a38578063a50267a514610a4b578063ac2c957c14610a6b57600080fd5b80638da5cb5b116102265780638da5cb5b1461095d5780638ec2c5a61461097657806391b4ded91461098957806393f4452e1461099257806396583661146109fd57600080fd5b806379ba5097146108e85780637df8b802146108f05780638067cd5314610908578063861de52c1461091b5780638c4e8cb51461093a57600080fd5b80633d975d4e1161037e57806356e4194d116102fb578063630e2c35116102bf578063630e2c351461084c57806367674b141461085f57806369a5492e1461088257806370aadcc4146108a557806376d423db146108c557600080fd5b806356e4194d146107c85780635b9fbe07146107f65780635c975abb14610819578063621da70314610826578063627e7b421461083957600080fd5b8063489f4b9711610342578063489f4b97146107395780634cf5d7151461074c5780635034c5881461076f57806353a47bb71461078f578063557db448146107a257600080fd5b80633d975d4e146106c85780633ec70ca5146106db578063436d765a146106fe578063459c0bd01461071e57806346cd86221461072657600080fd5b806316c38b3c1161040c5780632f73199d116103d05780632f73199d1461066f5780632fff702014610682578063300a02981461068a57806331dca3841461069257806336c0d855146106a557600080fd5b806316c38b3c1461060a5780631afed5cc1461061d5780632082af14146106265780632a4a3e7c146106395780632b7ac3f31461065c57600080fd5b80630b5cde46116104535780630b5cde461461052457806310063fdc146105a657806313251f5e146105d157806313af4035146105e45780631627540c146105f757600080fd5b80630259f5fd1461049057806304dc46d0146104a557806306c933d8146104b8578063097c9e0f146104f0578063099177e914610511575b600080fd5b6104a361049e366004614cf3565b610d20565b005b6104a36104b3366004614f74565b610d7e565b6104db6104c6366004614bdb565b60046020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6105036104fe36600461507d565b610dc2565b6040519081526020016104e7565b6104a361051f366004614d9b565b610df3565b61056f610532366004614f44565b6009602052600090815260409020805460019091015460ff80821691610100810482169162010000820416906301000000900464ffffffffff1685565b6040805195865260ff948516602087015292841692850192909252909116606083015264ffffffffff16608082015260a0016104e7565b6012546105b9906001600160a01b031681565b6040516001600160a01b0390911681526020016104e7565b6105036105df36600461530e565b611055565b6104a36105f2366004614bdb565b611093565b6104a3610605366004614bdb565b6111ce565b6104a3610618366004614f0c565b611224565b61050361232881565b6104a36106343660046152ea565b61129a565b6104db610647366004614bdb565b601e6020526000908152604090205460ff1681565b6021546105b9906001600160a01b031681565b6104a361067d366004614fdc565b611338565b610503600181565b610503600281565b6104a36106a03660046152ea565b611517565b6104db6106b3366004614bdb565b601b6020526000908152604090205460ff1681565b6104a36106d6366004614f98565b611593565b6104db6106e9366004614f44565b600d6020526000908152604090205460ff1681565b61071161070c36600461507d565b6116da565b6040516104e7919061573a565b610503600381565b6104a36107343660046152ea565b611793565b6104db610747366004614f44565b61180f565b6104db61075a366004614f44565b600f6020526000908152604090205460ff1681565b61050361077d366004614f44565b60186020526000908152604090205481565b6001546105b9906001600160a01b031681565b6107b56107b0366004614f44565b61186c565b6040516104e797969594939291906156e0565b6107db6107d6366004614bdb565b6119c7565b604080519384526020840192909252908201526060016104e7565b6104db610804366004614bdb565b60156020526000908152604090205460ff1681565b6003546104db9060ff1681565b6104db610834366004614f44565b611a06565b6104a3610847366004614c1a565b611a74565b6104a361085a3660046152ea565b611d52565b6104db61086d366004614f44565b600c6020526000908152604090205460ff1681565b6104db610890366004614f44565b600e6020526000908152604090205460ff1681565b6105036108b3366004614f44565b600b6020526000908152604090205481565b6105036108d3366004614f44565b60009081526008602052604090206001015490565b6104a3611dce565b6003546105b99061010090046001600160a01b031681565b6104a3610916366004614df4565b611ecb565b610503610929366004614f44565b602080526000908152604090205481565b6104db610948366004614bdb565b601c6020526000908152604090205460ff1681565b6000546105b9906201000090046001600160a01b031681565b6104a3610984366004614f44565b611f1d565b61050360025481565b6109d36109a0366004614f44565b600a6020526000908152604090208054600190910154600281810b9163010000008104820b91600160301b909104900b84565b60408051948552600293840b602086015291830b91840191909152900b60608201526080016104e7565b610a10610a0b366004614bdb565b61212a565b6040516104e79190615508565b610a10610a2b366004614f44565b6121ad565b61050360c981565b6104a3610a46366004615029565b6121df565b610a5e610a5936600461507d565b6128a6565b6040516104e791906154c4565b6104a3610a79366004614df4565b612911565b6023546105b9906001600160a01b031681565b610503600081565b6104a3610aa7366004614d2b565b61295f565b6109d3610aba366004614f44565b60226020526000908152604090208054600190910154600281810b9163010000008104820b91600160301b909104900b84565b6104a3610afb366004614cf3565b612a2d565b6104db610b0e366004614f44565b6000908152600f602052604090205460ff1690565b6104a3610b31366004614f44565b612acb565b6104db610b44366004614bdb565b601f6020526000908152604090205460ff1681565b6104a3610b67366004614bdb565b612b6e565b610711610b7a36600461507d565b612c87565b610b92610b8d366004614f44565b612ca3565b6040516104e791906157cb565b6104db610bad366004614bdb565b612e75565b6104a3610bc0366004614f44565b612f07565b610a10610bd3366004614bdb565b612f53565b6104db610be6366004614bdb565b60166020526000908152604090205460ff1681565b61050360245481565b6017546105b9906001600160a01b031681565b6104a3610c25366004614f44565b612fa6565b610503610c38366004614bdb565b60146020526000908152604090205481565b6104db610c58366004614f44565b60106020526000908152604090205460ff1681565b6104a3610c7b366004614cf3565b613031565b610711610c8e36600461507d565b613065565b6105b9610ca1366004614f44565b6013602052600090815260409020546001600160a01b031681565b6104db610cca366004614f44565b60116020526000908152604090205460ff1681565b6104a3610ced366004614cf3565b613081565b6104db610d0036600461507d565b601a60209081526000928352604080842090915290825290205460ff1681565b6023546001600160a01b03163314610d535760405162461bcd60e51b8152600401610d4a90615790565b60405180910390fd5b6001600160a01b03919091166000908152601e60205260409020805460ff1916911515919091179055565b6023546001600160a01b03163314610da85760405162461bcd60e51b8152600401610d4a90615790565b6001600160a01b0316600090815260146020526040902055565b60196020528160005260406000208181548110610dde57600080fd5b90600052602060002001600091509150505481565b3360009081526004602052604090205460ff16610e225760405162461bcd60e51b8152600401610d4a90615772565b6001600160a01b038516600090815260146020526040902054848484610e478461180f565b15610e7d5760405162461bcd60e51b8152600401610d4a906020808252600490820152634944313360e01b604082015260600190565b6000848152601360205260409020546001600160a01b0316610eca5760405162461bcd60e51b8152600401610d4a9060208082526004908201526312510c4d60e21b604082015260600190565b6021546000858152600b60209081526040808320548352600f9091529020546001600160a01b039091169063879c0c5e9060ff166040516001600160e01b031960e084901b16815290151560048201526024810186905260440160206040518083038186803b158015610f3c57600080fd5b505afa158015610f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f749190614f28565b801561100857506021546040516303727eb960e01b81526004810185905260ff8085166024830152831660448201526001600160a01b03909116906303727eb99060640160206040518083038186803b158015610fd057600080fd5b505afa158015610fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110089190614f28565b61103d5760405162461bcd60e51b8152600401610d4a906020808252600490820152634944313560e01b604082015260600190565b61104a898989898961313b565b505050505050505050565b601d602052826000526040600020602052816000526040600020818154811061107d57600080fd5b9060005260206000200160009250925050505481565b6001600160a01b0381166110e95760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610d4a565b600154600160a01b900460ff16156111555760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610d4a565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6111d6613594565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016111c3565b61122c613594565b60035460ff16151581151514156112405750565b6003805460ff191682151590811790915560ff161561125e57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5906020016111c3565b50565b6112a2613594565b6000828152600e602052604090205460ff1680156112d557506000828152600f602052604090205460ff16151581151514155b6112de57600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527f5c90f67f3547cb9c3f1b7612610d878aa4f00e88a643d2c6b658c1f9005fdcda91015b60405180910390a15050565b60035461010090046001600160a01b031633146113675760405162461bcd60e51b8152600401610d4a906157ae565b815160005b835181101561146657600084828151811061139757634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906113b29190615254565b805160009081526013602052604090819020546023549151630ceda8e960e41b81526001600160a01b039182166004820181905293945091169063ceda8e909060240160206040518083038186803b15801561140d57600080fd5b505afa158015611421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114459190614f5c565b61144f90856158a3565b93505050808061145e90615922565b91505061136c565b5060005b835181101561151057600084828151811061149557634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906114b09190615254565b80516000908152600d602052604090205490915060ff161580156114ec575080516000908152601360205260409020546001600160a01b031615155b156114fd576114fd8682868661360e565b508061150881615922565b91505061146a565b5050505050565b61151f613594565b6000828152600e602052604090205460ff161515811515141561154157600080fd5b6000828152600e6020908152604091829020805460ff19168415159081179091558251858152918201527f0a7daa18eab3013f94989c4e384004cab457b607ce1e975b8de79c4da52da954910161132c565b60035461010090046001600160a01b031633146115c25760405162461bcd60e51b8152600401610d4a906157ae565b60005b81518110156116d55760008282815181106115f057634e487b7160e01b600052603260045260246000fd5b602002602001015180602001905181019061160b9190615170565b80516000908152600c602052604090205490915060ff168015611646575080516000908152601360205260409020546001600160a01b031615155b156116c25760235481516000908152600b60205260409081902054905163988a130960e01b81526001600160a01b039092169163988a13099161168f9188918691600401615584565b600060405180830381600087803b1580156116a957600080fd5b505af11580156116bd573d6000803e3d6000fd5b505050505b50806116cd81615922565b9150506115c5565b505050565b600660205281600052604060002081815481106116f657600080fd5b90600052602060002001600091509150508054611712906158e7565b80601f016020809104026020016040519081016040528092919081815260200182805461173e906158e7565b801561178b5780601f106117605761010080835404028352916020019161178b565b820191906000526020600020905b81548152906001019060200180831161176e57829003601f168201915b505050505081565b61179b613594565b60008281526011602052604090205460ff16151581151514156117bd57600080fd5b600082815260116020908152604091829020805460ff19168415159081179091558251858152918201527fbff84c147d533b99d8802295ac70c53aa7d9ac4e520dcd0200d2f434c34b52a3910161132c565b6000818152601360209081526040808320546001600160a01b03168352601590915281205460ff168061186657506000828152601360209081526040808320546001600160a01b03168352601690915290205460ff165b92915050565b6008602052600090815260409020805460018201546002808401546003850180549495939482840b9463010000008404850b94600160301b90940490930b9291906118b6906158e7565b80601f01602080910402602001604051908101604052809291908181526020018280546118e2906158e7565b801561192f5780601f106119045761010080835404028352916020019161192f565b820191906000526020600020905b81548152906001019060200180831161191257829003601f168201915b505050505090806004018054611944906158e7565b80601f0160208091040260200160405190810160405280929190818152602001828054611970906158e7565b80156119bd5780601f10611992576101008083540402835291602001916119bd565b820191906000526020600020905b8154815290600101906020018083116119a057829003601f168201915b5050505050905087565b6001600160a01b038116600081815260146020818152604080842054808552600b835281852054838052918520549590945291905291905b9193909250565b6000818152600960209081526040808320815160a0810183528154815260019091015460ff808216838601526101008204811683850152620100008204811660608401819052630100000090920464ffffffffff166080909301929092528452601090925282205416611866565b600054610100900460ff16611a8f5760005460ff1615611a93565b303b155b611af65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d4a565b600054610100900460ff16158015611b18576000805461ffff19166101011790555b611b2188611093565b60005b8751811015611b93576001600e60008a8481518110611b5357634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611b8b90615922565b915050611b24565b5060005b8551811015611c06576001600f6000888481518110611bc657634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611bfe90615922565b915050611b97565b5060005b8351811015611c7957600160106000868481518110611c3957634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611c7190615922565b915050611c0a565b5060005b8251811015611cec57600160116000858481518110611cac57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611ce490615922565b915050611c7d565b50601280546001600160a01b038089166001600160a01b03199283161790925560178054878416921691909117905588166000908152600460205260409020805460ff191660011790558015611d48576000805461ff00191690555b5050505050505050565b611d5a613594565b60008281526010602052604090205460ff1615158115151415611d7c57600080fd5b600082815260106020908152604091829020805460ff19168415159081179091558251858152918201527f463b22afe346e0b505997c71b3cb5c2a507adb0214a645f6aede655b18691717910161132c565b6001546001600160a01b03163314611e465760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610d4a565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60005b8151811015611f1957611f07828281518110611efa57634e487b7160e01b600052603260045260246000fd5b6020026020010151612fa6565b80611f1181615922565b915050611ece565b5050565b6000818152601360205260409020546001600160a01b03161580611f8657506000818152601360209081526040808320546001600160a01b03168352601690915290205460ff168015611f8657506000818152601360205260409020546001600160a01b031615155b611fb85760405162461bcd60e51b815260206004820152600360248201526249443160e81b6044820152606401610d4a565b6000818152600c602052604090205460ff16611ffc5760405162461bcd60e51b815260206004820152600360248201526224a21960e91b6044820152606401610d4a565b60175460408051634b40849760e01b8152905183926001600160a01b0316916303aac5d5918391634b408497916004808301926020929190829003018186803b15801561204857600080fd5b505afa15801561205c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120809190614f5c565b6040518263ffffffff1660e01b815260040161209e91815260200190565b60206040518083038186803b1580156120b657600080fd5b505afa1580156120ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ee9190614f5c565b146121215760405162461bcd60e51b815260206004820152600360248201526249443360e81b6044820152606401610d4a565b6112978161398d565b602354604051639658366160e01b81526001600160a01b03838116600483015260609216906396583661906024015b60006040518083038186803b15801561217157600080fd5b505afa158015612185573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118669190810190614e86565b602354604051634d6759b760e11b8152600481018390526060916001600160a01b031690639aceb36e90602401612159565b60035461010090046001600160a01b0316331461220e5760405162461bcd60e51b8152600401610d4a906157ae565b82511561223a576000818152601a602090815260408083208584529091529020805460ff191660011790555b60005b835181101561151057600084828151811061226857634e487b7160e01b600052603260045260246000fd5b6020026020010151806020019051810190612283919061509e565b80516000908152600c602052604090205490915060ff1615801561232e575060215460a082015160c08301516040516397dc205d60e01b81526001600160a01b03909316926397dc205d926122dc92909160040161574d565b60206040518083038186803b1580156122f457600080fd5b505afa158015612308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232c9190614f28565b155b801561233d5750428160200151115b1561235f57805161234f908486613d3a565b61235a868286613d85565b612893565b80516000908152600c602052604090205460ff16156128935760006123878260000151612ca3565b60215460a08085015190830151604051637fabe16b60e01b81529394506001600160a01b0390921692637fabe16b926123c3929160040161574d565b60206040518083038186803b1580156123db57600080fd5b505afa1580156123ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124139190614f28565b15806124a6575060215460c08084015190830151604051637fabe16b60e01b81526001600160a01b0390931692637fabe16b9261245492909160040161574d565b60206040518083038186803b15801561246c57600080fd5b505afa158015612480573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a49190614f28565b155b156125ae5781516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff161561250857846007141561250d5781516124f09060006140b9565b81516124fd908587613d3a565b612508878387613d85565b612891565b8151600090815260136020526040902054612532906001600160a01b0316600161413e565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e9261257792911690600190600401615450565b600060405180830381600087803b15801561259157600080fd5b505af11580156125a5573d6000803e3d6000fd5b50505050612891565b80602001518260200151146128915781516125ca908587613d3a565b4282602001511115612747576012548251600090815260136020908152604091829020549085015191516327ad762d60e21b81526001600160a01b039182166004820152602481019290925290911690639eb5d8b490604401600060405180830381600087803b15801561263d57600080fd5b505af1158015612651573d6000803e3d6000fd5b5050835160009081526008602090815260409182902086518155818701516001820155918601516002808401805460608a015160808b0151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a086015180518795509293506126ea926003850192919091019061498a565b5060c0820151805161270691600484019160209091019061498a565b505060175483516020850151604051630464f33160e31b8152600481019290925260248201526001600160a01b039091169150632327998890604401612577565b81516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff1680156127805750428160200151115b156128915781516000908152601360205260409020546127aa906001600160a01b0316600161413e565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e926127ef92911690600190600401615450565b600060405180830381600087803b15801561280957600080fd5b505af115801561281d573d6000803e3d6000fd5b50508351600090815260136020908152604091829020548651868301518389015185516001600160a01b039094168452938301919091529281019290925260608201527fb71601cabce6b66d1ceb87bb549207b61c7c27e3efd188cae1e0d39f7feedfd79250608001905060405180910390a15b505b508061289e81615922565b91505061223d565b6000828152601d6020908152604080832084845282529182902080548351818402810184019094528084526060939283018282801561290457602002820191906000526020600020905b8154815260200190600101908083116128f0575b5050505050905092915050565b60005b8151811015611f195761294d82828151811061294057634e487b7160e01b600052603260045260246000fd5b6020026020010151611f1d565b8061295781615922565b915050612914565b612967613594565b601280546001600160a01b038581166001600160a01b03199283168117909355601780548883169084168117909155600380548a84166101008102610100600160a81b0319909216919091179091556021805488851690861681179091556023805494881694909516841790945560408051918252602082019290925290810193909352606083019190915260808201527f2719351fde6efd8f8541e7d0c0219124dd63d0fe319bc118a1b85b8803e4effe9060a0015b60405180910390a15050505050565b612a35613594565b6001600160a01b03821615801590612a6c57506001600160a01b03821660009081526004602052604090205460ff16151581151514155b612a7557600080fd5b6001600160a01b03821660009081526004602052604090819020805460ff1916831515179055517f58d7a3ccc34541e162fcfc87b84be7b78c34d1e1e7f15de6e4dd67d0fe70aecd9061132c9084908490615450565b3360009081526004602052604090205460ff16612afa5760405162461bcd60e51b8152600401610d4a90615772565b6000818152600c602052604090205460ff16612b415760405162461bcd60e51b8152600401610d4a9060208082526004908201526324a2191960e11b604082015260600190565b6000908152600c60209081526040808320805460ff19908116909155600d90925290912080549091169055565b612b76613594565b6001600160a01b038116612bbe5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610d4a565b600154600160a81b900460ff1615612c0e5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610d4a565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016111c3565b600560205281600052604060002081815481106116f657600080fd5b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c0810191909152600082815260086020908152604091829020825160e0810184528154815260018201549281019290925260028082015480820b820b820b9484019490945263010000008404810b810b810b6060840152600160301b909304830b830b90920b608082015260038201805491929160a084019190612d5a906158e7565b80601f0160208091040260200160405190810160405280929190818152602001828054612d86906158e7565b8015612dd35780601f10612da857610100808354040283529160200191612dd3565b820191906000526020600020905b815481529060010190602001808311612db657829003601f168201915b50505050508152602001600482018054612dec906158e7565b80601f0160208091040260200160405190810160405280929190818152602001828054612e18906158e7565b8015612e655780601f10612e3a57610100808354040283529160200191612e65565b820191906000526020600020905b815481529060010190602001808311612e4857829003601f168201915b5050505050815250509050919050565b602354604051636c35b77560e01b81526001600160a01b0383811660048301526000928392911690636c35b7759060240160206040518083038186803b158015612ebe57600080fd5b505afa158015612ed2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef69190614bfe565b6001600160a01b0316141592915050565b612f0f613594565b806024541415612f1e57600080fd5b60248190556040518181527f9e07ff05aae276b1721af92dd4740303ffd42aaa4e57ac204b0781a5b46e2606906020016111c3565b6001600160a01b0381166000908152601c602052604090205460609060ff16612f8457612f7f8261212a565b611866565b6001600160a01b038216600090815260146020526040902054611866906121ad565b612faf8161180f565b15612fe25760405162461bcd60e51b815260206004820152600360248201526212510d60ea1b6044820152606401610d4a565b6000818152600d602052604090205460ff166130265760405162461bcd60e51b815260206004820152600360248201526249443560e81b6044820152606401610d4a565b611297816000614259565b6023546001600160a01b0316331461305b5760405162461bcd60e51b8152600401610d4a90615790565b611f19828261413e565b600760205281600052604060002081815481106116f657600080fd5b3360009081526004602052604090205460ff166130b05760405162461bcd60e51b8152600401610d4a90615772565b6001600160a01b038216600090815260146020526040902054158015906130fc57506001600160a01b0382166000908152601460209081526040808320548352600c90915290205460ff165b6131315760405162461bcd60e51b8152600401610d4a906020808252600490820152630494432360e41b604082015260600190565b611f1982826145f7565b801561328a5783156131785760405162461bcd60e51b8152600401610d4a906020808252600490820152634944313760e01b604082015260600190565b6023546001600160a01b03868116600090815260146020526040908190205490516304763b0360e31b8152600481019190915283151560248201529116906323b1d8189060440160206040518083038186803b1580156131d757600080fd5b505afa1580156131eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320f9190614f28565b61321857600080fd5b6023546001600160a01b0386811660009081526014602052604090819020549051639971441b60e01b81526004810191909152911690639971441b90602401600060405180830381600087803b15801561327157600080fd5b505af1158015613285573d6000803e3d6000fd5b505050505b61329585600061413e565b60235460405162d2b13f60e11b81526001600160a01b03909116906301a5627e906132c7908890600090600401615450565b600060405180830381600087803b1580156132e157600080fd5b505af11580156132f5573d6000803e3d6000fd5b505050506001600160a01b0385166000908152601460209081526040808320548352600b8252808320548352600f90915290205461334a90869086908690869060ff1661334357600b614686565b6008614686565b6040805160a0810182526001600160a01b0387166000908152601460209081528382205480845260ff8881168386015287811685870152908352600b8252848320548352600f9091529290205490916060830191166133aa57600b6133ad565b60085b60ff9081168252600060209283018190526001600160a01b03891681526014835260408082208054835260098086528284208751815587870151600191820180548a8701516060808d015160809d8e0151958c1661ffff1990941693909317610100928c1683021767ffffffffffff0000191662010000938c169390930267ffffffffff000000191692909217630100000064ffffffffff95861602179092559454808852600b8a5286882054948a5286882087518281529a8b019590955295890195909552825493880193909352015480851696860196909652600886901c841660a0860152601086901c90931660c085015260189490941c90911660e0830152918101919091527f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73906101200160405180910390a18361353f576001600160a01b038516600081815260146020908152604091829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc910160405180910390a1611510565b6001600160a01b0385166000818152601460209081526040918290205482519384529083015281018590527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e44490606001612a1e565b6000546201000090046001600160a01b0316331461360c5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610d4a565b565b600061361d8460000151612ca3565b905061363f846060015160ff9081166000908152601060205260409020541690565b8061366e5750606084015160ff90811660009081526011602052604090205416801561366e5750428160200151105b1561389e578351600090815260096020908152604080832087518082558389015160019283018054858c015160608d015160808e015164ffffffffff1663010000000267ffffffffff0000001960ff92831662010000021667ffffffffffff0000199383166101000261ffff1990951692909616919091179290921716929092179190911790558452600d835292819020805460ff191690931790925585516017548351638f0ac45360e01b815293517f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73948a948994938b936001600160a01b0390911692638f0ac453926004808301939192829003018186803b15801561377557600080fd5b505afa158015613789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ad9190614f5c565b604080519586526020808701959095528581019390935281516060808701919091529382015160ff90811660808088019190915293830151811660a08701529382015190931660c0850152015164ffffffffff1660e08301526101008201526101200160405180910390a1602454821061388c57601754845160405163602726b560e11b81526001600160a01b039092169163c04e4d6a916138559160040190815260200190565b600060405180830381600087803b15801561386f57600080fd5b505af1158015613883573d6000803e3d6000fd5b50505050611510565b8351613899906001614259565b611510565b606084015160ff9081166000908152601160205260409020541680156138c8575042816020015110155b156115105783516000908152601360208181526040808420546001600160a01b039081168552601e8352818520805460ff1916600190811790915589518652939092529092205461391a92169061413e565b60235484516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e9261395f92911690600190600401615450565b600060405180830381600087803b15801561397957600080fd5b505af115801561104a573d6000803e3d6000fd5b600061399882612ca3565b90504281602001511115613cb2576000828152600b60205260408120546139be9061482d565b60125460a084015160c08501516040519394506000936001600160a01b0390931692634cde32ce9288926139f492602001615411565b60408051808303601f1901815291815260208881015160008b8152600b8352838120548152600f9092529181205460ff16613a30576003613a33565b60025b886000806040518963ffffffff1660e01b8152600401613a5a98979695949392919061551b565b602060405180830381600087803b158015613a7457600080fd5b505af1158015613a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aac9190614bfe565b8351600090815260136020908152604080832080546001600160a01b0319166001600160a01b0386811691821790925588518186526014855283862055601c90935292819020805460ff1916600117905560235487519151630e76f6e760e11b8152600481019290925260248201929092529293501690631cededce90604401600060405180830381600087803b158015613b4657600080fd5b505af1158015613b5a573d6000803e3d6000fd5b50505050601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613bae57600080fd5b505af1158015613bc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613be69190614f5c565b508251602354604051634d6759b760e11b8152600481018390527f889e2060e46779287c2fcbf489c195ef20f5b44a74e3dcb58d491ae073c1370f9284929091879187916001600160a01b0390911690639aceb36e9060240160006040518083038186803b158015613c5757600080fd5b505afa158015613c6b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613c939190810190614e86565b604051613ca495949392919061546b565b60405180910390a150505050565b601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613d0257600080fd5b505af1158015613d16573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d59190614f5c565b600083815260208052604090205482146116d5576000908152601d60209081526040808320848452825280832080546001810182559084528284200185905593825280529190912055565b815160009081526008602090815260409182902084518155818501516001820155918401516002808401805460608801516080890151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a08401518051859392613e1792600385019291019061498a565b5060c08201518051613e3391600484019160209091019061498a565b505082516000908152600b6020908152604091829020849055601754855191860151925163e9c962eb60e01b815260048101929092526024820192909252604481018490526001600160a01b03909116915063e9c962eb90606401600060405180830381600087803b158015613ea857600080fd5b505af1158015613ebc573d6000803e3d6000fd5b505083516000908152600c602052604090819020805460ff1916600117905560235485518287015160608801516080890151945163312025df60e21b81526004810193909352600291820b6024840152810b60448301529290920b60648301526001600160a01b0316925063c480977c9150608401600060405180830381600087803b158015613f4b57600080fd5b505af1158015613f5f573d6000803e3d6000fd5b505050507faba5c0e34b9b54828db4e0ac6b951ca282a0b171289eebf93353c296f9e826138382846000015185601760009054906101000a90046001600160a01b03166001600160a01b031663afff5a646040518163ffffffff1660e01b815260040160206040518083038186803b158015613fda57600080fd5b505afa158015613fee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140129190614f5c565b6023548851604051634d6759b760e11b81526001600160a01b0390921691639aceb36e916140469160040190815260200190565b60006040518083038186803b15801561405e57600080fd5b505afa158015614072573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261409a9190810190614e86565b6040516140ac96959493929190615696565b60405180910390a1505050565b6000828152601360205260408120546140e0916001600160a01b0390911690808080614686565b80156140ee576140ee614891565b6000828152601360209081526040918290205482516001600160a01b0390911681529081018490527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc910161132c565b6012546040516333dfec9960e21b81526001600160a01b03848116600483015283151592169063cf7fb2649060240160206040518083038186803b15801561418557600080fd5b505afa158015614199573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141bd9190614f28565b151514611f1957601254604051637f8c2d6160e01b81526001600160a01b0390911690637f8c2d61906141f69085908590600401615450565b600060405180830381600087803b15801561421057600080fd5b505af1158015614224573d6000803e3d6000fd5b505050507f2b8992e59f9813c2f92be2374e9bdd5384146ff8f719b038fbaf7d3dbfa78fde828260405161132c929190615450565b6000828152600960209081526040808320815160a0810183528154815260019091015460ff80821694830194909452610100810484169282019290925262010000820490921660608301526301000000900464ffffffffff166080820152906142c184612ca3565b90506142e3826060015160ff9081166000908152601060205260409020541690565b156145b6576023548251600090815260136020526040908190205490516336c0d85560e01b81526001600160a01b0391821660048201529116906336c0d8559060240160206040518083038186803b15801561433e57600080fd5b505afa158015614352573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143769190614f28565b156144165781516000908152601360205260408120546143a1916001600160a01b039091169061413e565b602354825160009081526013602052604080822054905162d2b13f60e11b81526001600160a01b03938416936301a5627e936143e39390911691600401615450565b600060405180830381600087803b1580156143fd57600080fd5b505af1158015614411573d6000803e3d6000fd5b505050505b600080600061442485614919565b925092509250600383148015614457575084516000908152600b60209081526040808320548352600f90915290205460ff165b1561446e5784516144699087156140b9565b6145ae565b6012548551600090815260136020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b1580156144c457600080fd5b505afa1580156144d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144fc9190614f28565b6145a1578451600090815260136020526040902054606086015161452f916001600160a01b031690859085908590614686565b8561453c5761453c614891565b845160009081526013602090815260409182902054875183516001600160a01b039092168252918101919091529081018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449060600160405180910390a16145ae565b856145ae576145ae614891565b5050506145f1565b606082015160ff9081166000908152601160205260409020541680156145df5750428160200151105b156145f15781516145f19084156140b9565b50505050565b614601828261413e565b6023546001600160a01b038381166000818152601460205260409081902054905163032bc38360e21b8152600481019190915260248101919091528315156044820152911690630caf0e0c90606401600060405180830381600087803b15801561466a57600080fd5b505af115801561467e573d6000803e3d6000fd5b505050505050565b60125460405163b91f5e3560e01b81526001600160a01b038781166004830152602482018790529091169063b91f5e3590604401600060405180830381600087803b1580156146d457600080fd5b505af11580156146e8573d6000803e3d6000fd5b5050505060c98160ff161415614771576023546040516303e810fd60e61b81526001600160a01b0387811660048301526000602483018190526044830181905260648301529091169063fa043f4090608401600060405180830381600087803b15801561475457600080fd5b505af1158015614768573d6000803e3d6000fd5b505050506147e9565b6023546040516303e810fd60e61b81526001600160a01b0387811660048301526024820187905260ff8087166044840152851660648301529091169063fa043f4090608401600060405180830381600087803b1580156147d057600080fd5b505af11580156147e4573d6000803e3d6000fd5b505050505b5050506001600160a01b039190911660009081526016602090815260408083208054941560ff19958616811790915560159092529091208054911591909216179055565b604080516001808252818301909252606091600091906020808301908036833701905050905061485f836123286158a3565b8160008151811061488057634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b601760009054906101000a90046001600160a01b03166001600160a01b03166377d078d76040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156148e157600080fd5b505af11580156148f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112979190614f5c565b6000806000836040015160ff16846020015160ff16141561494a5750505060208101516040820151600391906119ff565b836040015160ff16846020015160ff16116149705760028460200151856040015161497d565b6001846020015185604001515b9250925092509193909250565b828054614996906158e7565b90600052602060002090601f0160209004810192826149b857600085556149fe565b82601f106149d157805160ff19168380011785556149fe565b828001600101855582156149fe579182015b828111156149fe5782518255916020019190600101906149e3565b50614a0a929150614a0e565b5090565b5b80821115614a0a5760008155600101614a0f565b8035614a2e81615969565b919050565b600082601f830112614a43578081fd5b81356020614a58614a5383615859565b615829565b80838252828201915082860187848660051b8901011115614a77578586fd5b855b85811015614aef5781356001600160401b03811115614a96578788fd5b8801603f81018a13614aa6578788fd5b858101356040614ab8614a538361587c565b8281528c82848601011115614acb578a8bfd5b828285018a83013791820188018a9052508552509284019290840190600101614a79565b5090979650505050505050565b600082601f830112614b0c578081fd5b81356020614b1c614a5383615859565b80838252828201915082860187848660051b8901011115614b3b578586fd5b855b85811015614aef57813584529284019290840190600101614b3d565b8051600181900b8114614a2e57600080fd5b8051600281900b8114614a2e57600080fd5b600082601f830112614b8d578081fd5b8151614b9b614a538261587c565b818152846020838601011115614baf578283fd5b614bc08260208301602087016158bb565b949350505050565b805162ffffff81168114614a2e57600080fd5b600060208284031215614bec578081fd5b8135614bf781615969565b9392505050565b600060208284031215614c0f578081fd5b8151614bf781615969565b600080600080600080600060e0888a031215614c34578283fd5b614c3d88614a23565b965060208801356001600160401b0380821115614c58578485fd5b614c648b838c01614afc565b9750614c7260408b01614a23565b965060608a0135915080821115614c87578485fd5b614c938b838c01614afc565b9550614ca160808b01614a23565b945060a08a0135915080821115614cb6578384fd5b614cc28b838c01614afc565b935060c08a0135915080821115614cd7578283fd5b50614ce48a828b01614afc565b91505092959891949750929550565b60008060408385031215614d05578182fd5b8235614d1081615969565b91506020830135614d208161597e565b809150509250929050565b600080600080600060a08688031215614d42578283fd5b8535614d4d81615969565b94506020860135614d5d81615969565b93506040860135614d6d81615969565b92506060860135614d7d81615969565b91506080860135614d8d81615969565b809150509295509295909350565b600080600080600060a08688031215614db2578283fd5b8535614dbd81615969565b9450602086013593506040860135614dd48161598c565b92506060860135614de48161598c565b91506080860135614d8d8161597e565b60006020808385031215614e06578182fd5b82356001600160401b03811115614e1b578283fd5b8301601f81018513614e2b578283fd5b8035614e39614a5382615859565b80828252848201915084840188868560051b8701011115614e58578687fd5b8694505b83851015614e7a578035835260019490940193918501918501614e5c565b50979650505050505050565b60006020808385031215614e98578182fd5b82516001600160401b03811115614ead578283fd5b8301601f81018513614ebd578283fd5b8051614ecb614a5382615859565b80828252848201915084840188868560051b8701011115614eea578687fd5b8694505b83851015614e7a578051835260019490940193918501918501614eee565b600060208284031215614f1d578081fd5b8135614bf78161597e565b600060208284031215614f39578081fd5b8151614bf78161597e565b600060208284031215614f55578081fd5b5035919050565b600060208284031215614f6d578081fd5b5051919050565b60008060408385031215614f86578182fd5b823591506020830135614d2081615969565b60008060408385031215614faa578182fd5b8235915060208301356001600160401b03811115614fc6578182fd5b614fd285828601614a33565b9150509250929050565b600080600060608486031215614ff0578081fd5b8335925060208401356001600160401b0381111561500c578182fd5b61501886828701614a33565b925050604084013590509250925092565b6000806000806080858703121561503e578182fd5b8435935060208501356001600160401b0381111561505a578283fd5b61506687828801614a33565b949794965050505060408301359260600135919050565b6000806040838503121561508f578182fd5b50508035926020909101359150565b6000602082840312156150af578081fd5b81516001600160401b03808211156150c5578283fd5b9083019060e082860312156150d8578283fd5b6150e06157de565b82518152602083015160208201526150fa60408401614b6b565b604082015261510b60608401614b6b565b606082015261511c60808401614b6b565b608082015260a083015182811115615132578485fd5b61513e87828601614b7d565b60a08301525060c083015182811115615155578485fd5b61516187828601614b7d565b60c08301525095945050505050565b60006101808284031215615182578081fd5b61518a615806565b8251815261519a60208401614b6b565b60208201526151ab60408401614b6b565b60408201526151bc60608401614b6b565b60608201526151cd60808401614b59565b60808201526151de60a08401614b6b565b60a08201526151ef60c08401614b59565b60c082015261520060e08401614b6b565b60e0820152610100615213818501614bc8565b90820152610120615225848201614b6b565b90820152610140615237848201614bc8565b90820152610160615249848201614b6b565b908201529392505050565b600060a08284031215615265578081fd5b60405160a081018181106001600160401b038211171561528757615287615953565b60405282518152602083015161529c8161598c565b602082015260408301516152af8161598c565b604082015260608301516152c28161598c565b6060820152608083015164ffffffffff811681146152de578283fd5b60808201529392505050565b600080604083850312156152fc578182fd5b823591506020830135614d208161597e565b600080600060608486031215615322578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b838110156153685781518752958201959082019060010161534c565b509495945050505050565b6000815180845261538b8160208601602086016158bb565b601f01601f19169290920160200192915050565b8051825260208101516020830152604081015160020b6040830152606081015160020b6060830152608081015160020b6080830152600060a082015160e060a08501526153ef60e0850182615373565b905060c083015184820360c08601526154088282615373565b95945050505050565b600083516154238184602088016158bb565b630103b39960e51b90830190815283516154448160048401602088016158bb565b01600401949350505050565b6001600160a01b039290921682521515602082015260400190565b60018060a01b038616815284602082015260a06040820152600061549260a083018661539f565b82810360608401526154a48186615339565b905082810360808401526154b88185615339565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b818110156154fc578351835292840192918401916001016154e0565b50909695505050505050565b602081526000614bf76020830184615339565b60006101008a83528060208401526155358184018b615373565b905088604084015287606084015260ff8716608084015282810360a084015261555e8187615339565b94151560c084015250506001600160a01b039190911660e0909101529695505050505050565b60006101c0820190508482528351602083015260208401516155ab604084018260020b9052565b5060408401516155c0606084018260020b9052565b5060608401516155d5608084018260020b9052565b5060808401516155ea60a084018260010b9052565b5060a08401516155ff60c084018260020b9052565b5060c084015161561460e084018260010b9052565b5060e084015161010061562b8185018360020b9052565b85015190506101206156438482018362ffffff169052565b85015190506101406156598482018360020b9052565b85015190506101606156718482018362ffffff169052565b850151905061568661018084018260020b9052565b50826101a0830152949350505050565b86815285602082015284604082015260c0606082015260006156bb60c083018661539f565b84608084015282810360a08401526156d38185615339565b9998505050505050505050565b8781528660208201528560020b60408201528460020b60608201528360020b608082015260e060a0820152600061571a60e0830185615373565b82810360c084015261572c8185615373565b9a9950505050505050505050565b602081526000614bf76020830184615373565b6040815260006157606040830185615373565b82810360208401526154088185615373565b6020808252600490820152630494431360e41b604082015260600190565b60208082526004908201526324a2189b60e11b604082015260600190565b60208082526003908201526249443960e81b604082015260600190565b602081526000614bf7602083018461539f565b60405160e081016001600160401b038111828210171561580057615800615953565b60405290565b60405161018081016001600160401b038111828210171561580057615800615953565b604051601f8201601f191681016001600160401b038111828210171561585157615851615953565b604052919050565b60006001600160401b0382111561587257615872615953565b5060051b60200190565b60006001600160401b0382111561589557615895615953565b50601f01601f191660200190565b600082198211156158b6576158b661593d565b500190565b60005b838110156158d65781810151838201526020016158be565b838111156145f15750506000910152565b600181811c908216806158fb57607f821691505b6020821081141561591c57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156159365761593661593d565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461129757600080fd5b801515811461129757600080fd5b60ff8116811461129757600080fdfea2646970667358221220f23db72512c781603bb68930f9838814bf43d7888fc195670c9400438e6a3ced64736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061048b5760003560e01c806379ba509711610262578063be27f89d11610151578063e2ec13fc116100ce578063ed5e00eb11610092578063ed5e00eb14610c6d578063efccb47a14610c80578063f89c6f1814610c93578063fa59104f14610cbc578063fceb01f214610cdf578063feee9ca314610cf257600080fd5b8063e2ec13fc14610bfb578063e3f4c7c914610c04578063e59aff4b14610c17578063e7015ab214610c2a578063e87a6b8514610c4a57600080fd5b8063c48e62f111610115578063c48e62f114610b7f578063c4c2e6f614610b9f578063cb9ae26414610bb2578063db0d457914610bc5578063dec72d6314610bd857600080fd5b8063be27f89d14610b00578063c139373614610b23578063c39718a814610b36578063c3b83f5f14610b59578063c475e0b314610b6c57600080fd5b80639aceb36e116101df578063ad6b22ce116101a3578063ad6b22ce14610a7e578063ae71dcdf14610a91578063b0686d8814610a99578063b09bd9e314610aac578063bc93233f14610aed57600080fd5b80639aceb36e14610a1d578063a3b08bce14610a30578063a400a89114610a38578063a50267a514610a4b578063ac2c957c14610a6b57600080fd5b80638da5cb5b116102265780638da5cb5b1461095d5780638ec2c5a61461097657806391b4ded91461098957806393f4452e1461099257806396583661146109fd57600080fd5b806379ba5097146108e85780637df8b802146108f05780638067cd5314610908578063861de52c1461091b5780638c4e8cb51461093a57600080fd5b80633d975d4e1161037e57806356e4194d116102fb578063630e2c35116102bf578063630e2c351461084c57806367674b141461085f57806369a5492e1461088257806370aadcc4146108a557806376d423db146108c557600080fd5b806356e4194d146107c85780635b9fbe07146107f65780635c975abb14610819578063621da70314610826578063627e7b421461083957600080fd5b8063489f4b9711610342578063489f4b97146107395780634cf5d7151461074c5780635034c5881461076f57806353a47bb71461078f578063557db448146107a257600080fd5b80633d975d4e146106c85780633ec70ca5146106db578063436d765a146106fe578063459c0bd01461071e57806346cd86221461072657600080fd5b806316c38b3c1161040c5780632f73199d116103d05780632f73199d1461066f5780632fff702014610682578063300a02981461068a57806331dca3841461069257806336c0d855146106a557600080fd5b806316c38b3c1461060a5780631afed5cc1461061d5780632082af14146106265780632a4a3e7c146106395780632b7ac3f31461065c57600080fd5b80630b5cde46116104535780630b5cde461461052457806310063fdc146105a657806313251f5e146105d157806313af4035146105e45780631627540c146105f757600080fd5b80630259f5fd1461049057806304dc46d0146104a557806306c933d8146104b8578063097c9e0f146104f0578063099177e914610511575b600080fd5b6104a361049e366004614cf3565b610d20565b005b6104a36104b3366004614f74565b610d7e565b6104db6104c6366004614bdb565b60046020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6105036104fe36600461507d565b610dc2565b6040519081526020016104e7565b6104a361051f366004614d9b565b610df3565b61056f610532366004614f44565b6009602052600090815260409020805460019091015460ff80821691610100810482169162010000820416906301000000900464ffffffffff1685565b6040805195865260ff948516602087015292841692850192909252909116606083015264ffffffffff16608082015260a0016104e7565b6012546105b9906001600160a01b031681565b6040516001600160a01b0390911681526020016104e7565b6105036105df36600461530e565b611055565b6104a36105f2366004614bdb565b611093565b6104a3610605366004614bdb565b6111ce565b6104a3610618366004614f0c565b611224565b61050361232881565b6104a36106343660046152ea565b61129a565b6104db610647366004614bdb565b601e6020526000908152604090205460ff1681565b6021546105b9906001600160a01b031681565b6104a361067d366004614fdc565b611338565b610503600181565b610503600281565b6104a36106a03660046152ea565b611517565b6104db6106b3366004614bdb565b601b6020526000908152604090205460ff1681565b6104a36106d6366004614f98565b611593565b6104db6106e9366004614f44565b600d6020526000908152604090205460ff1681565b61071161070c36600461507d565b6116da565b6040516104e7919061573a565b610503600381565b6104a36107343660046152ea565b611793565b6104db610747366004614f44565b61180f565b6104db61075a366004614f44565b600f6020526000908152604090205460ff1681565b61050361077d366004614f44565b60186020526000908152604090205481565b6001546105b9906001600160a01b031681565b6107b56107b0366004614f44565b61186c565b6040516104e797969594939291906156e0565b6107db6107d6366004614bdb565b6119c7565b604080519384526020840192909252908201526060016104e7565b6104db610804366004614bdb565b60156020526000908152604090205460ff1681565b6003546104db9060ff1681565b6104db610834366004614f44565b611a06565b6104a3610847366004614c1a565b611a74565b6104a361085a3660046152ea565b611d52565b6104db61086d366004614f44565b600c6020526000908152604090205460ff1681565b6104db610890366004614f44565b600e6020526000908152604090205460ff1681565b6105036108b3366004614f44565b600b6020526000908152604090205481565b6105036108d3366004614f44565b60009081526008602052604090206001015490565b6104a3611dce565b6003546105b99061010090046001600160a01b031681565b6104a3610916366004614df4565b611ecb565b610503610929366004614f44565b602080526000908152604090205481565b6104db610948366004614bdb565b601c6020526000908152604090205460ff1681565b6000546105b9906201000090046001600160a01b031681565b6104a3610984366004614f44565b611f1d565b61050360025481565b6109d36109a0366004614f44565b600a6020526000908152604090208054600190910154600281810b9163010000008104820b91600160301b909104900b84565b60408051948552600293840b602086015291830b91840191909152900b60608201526080016104e7565b610a10610a0b366004614bdb565b61212a565b6040516104e79190615508565b610a10610a2b366004614f44565b6121ad565b61050360c981565b6104a3610a46366004615029565b6121df565b610a5e610a5936600461507d565b6128a6565b6040516104e791906154c4565b6104a3610a79366004614df4565b612911565b6023546105b9906001600160a01b031681565b610503600081565b6104a3610aa7366004614d2b565b61295f565b6109d3610aba366004614f44565b60226020526000908152604090208054600190910154600281810b9163010000008104820b91600160301b909104900b84565b6104a3610afb366004614cf3565b612a2d565b6104db610b0e366004614f44565b6000908152600f602052604090205460ff1690565b6104a3610b31366004614f44565b612acb565b6104db610b44366004614bdb565b601f6020526000908152604090205460ff1681565b6104a3610b67366004614bdb565b612b6e565b610711610b7a36600461507d565b612c87565b610b92610b8d366004614f44565b612ca3565b6040516104e791906157cb565b6104db610bad366004614bdb565b612e75565b6104a3610bc0366004614f44565b612f07565b610a10610bd3366004614bdb565b612f53565b6104db610be6366004614bdb565b60166020526000908152604090205460ff1681565b61050360245481565b6017546105b9906001600160a01b031681565b6104a3610c25366004614f44565b612fa6565b610503610c38366004614bdb565b60146020526000908152604090205481565b6104db610c58366004614f44565b60106020526000908152604090205460ff1681565b6104a3610c7b366004614cf3565b613031565b610711610c8e36600461507d565b613065565b6105b9610ca1366004614f44565b6013602052600090815260409020546001600160a01b031681565b6104db610cca366004614f44565b60116020526000908152604090205460ff1681565b6104a3610ced366004614cf3565b613081565b6104db610d0036600461507d565b601a60209081526000928352604080842090915290825290205460ff1681565b6023546001600160a01b03163314610d535760405162461bcd60e51b8152600401610d4a90615790565b60405180910390fd5b6001600160a01b03919091166000908152601e60205260409020805460ff1916911515919091179055565b6023546001600160a01b03163314610da85760405162461bcd60e51b8152600401610d4a90615790565b6001600160a01b0316600090815260146020526040902055565b60196020528160005260406000208181548110610dde57600080fd5b90600052602060002001600091509150505481565b3360009081526004602052604090205460ff16610e225760405162461bcd60e51b8152600401610d4a90615772565b6001600160a01b038516600090815260146020526040902054848484610e478461180f565b15610e7d5760405162461bcd60e51b8152600401610d4a906020808252600490820152634944313360e01b604082015260600190565b6000848152601360205260409020546001600160a01b0316610eca5760405162461bcd60e51b8152600401610d4a9060208082526004908201526312510c4d60e21b604082015260600190565b6021546000858152600b60209081526040808320548352600f9091529020546001600160a01b039091169063879c0c5e9060ff166040516001600160e01b031960e084901b16815290151560048201526024810186905260440160206040518083038186803b158015610f3c57600080fd5b505afa158015610f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f749190614f28565b801561100857506021546040516303727eb960e01b81526004810185905260ff8085166024830152831660448201526001600160a01b03909116906303727eb99060640160206040518083038186803b158015610fd057600080fd5b505afa158015610fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110089190614f28565b61103d5760405162461bcd60e51b8152600401610d4a906020808252600490820152634944313560e01b604082015260600190565b61104a898989898961313b565b505050505050505050565b601d602052826000526040600020602052816000526040600020818154811061107d57600080fd5b9060005260206000200160009250925050505481565b6001600160a01b0381166110e95760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610d4a565b600154600160a01b900460ff16156111555760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610d4a565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6111d6613594565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016111c3565b61122c613594565b60035460ff16151581151514156112405750565b6003805460ff191682151590811790915560ff161561125e57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5906020016111c3565b50565b6112a2613594565b6000828152600e602052604090205460ff1680156112d557506000828152600f602052604090205460ff16151581151514155b6112de57600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527f5c90f67f3547cb9c3f1b7612610d878aa4f00e88a643d2c6b658c1f9005fdcda91015b60405180910390a15050565b60035461010090046001600160a01b031633146113675760405162461bcd60e51b8152600401610d4a906157ae565b815160005b835181101561146657600084828151811061139757634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906113b29190615254565b805160009081526013602052604090819020546023549151630ceda8e960e41b81526001600160a01b039182166004820181905293945091169063ceda8e909060240160206040518083038186803b15801561140d57600080fd5b505afa158015611421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114459190614f5c565b61144f90856158a3565b93505050808061145e90615922565b91505061136c565b5060005b835181101561151057600084828151811061149557634e487b7160e01b600052603260045260246000fd5b60200260200101518060200190518101906114b09190615254565b80516000908152600d602052604090205490915060ff161580156114ec575080516000908152601360205260409020546001600160a01b031615155b156114fd576114fd8682868661360e565b508061150881615922565b91505061146a565b5050505050565b61151f613594565b6000828152600e602052604090205460ff161515811515141561154157600080fd5b6000828152600e6020908152604091829020805460ff19168415159081179091558251858152918201527f0a7daa18eab3013f94989c4e384004cab457b607ce1e975b8de79c4da52da954910161132c565b60035461010090046001600160a01b031633146115c25760405162461bcd60e51b8152600401610d4a906157ae565b60005b81518110156116d55760008282815181106115f057634e487b7160e01b600052603260045260246000fd5b602002602001015180602001905181019061160b9190615170565b80516000908152600c602052604090205490915060ff168015611646575080516000908152601360205260409020546001600160a01b031615155b156116c25760235481516000908152600b60205260409081902054905163988a130960e01b81526001600160a01b039092169163988a13099161168f9188918691600401615584565b600060405180830381600087803b1580156116a957600080fd5b505af11580156116bd573d6000803e3d6000fd5b505050505b50806116cd81615922565b9150506115c5565b505050565b600660205281600052604060002081815481106116f657600080fd5b90600052602060002001600091509150508054611712906158e7565b80601f016020809104026020016040519081016040528092919081815260200182805461173e906158e7565b801561178b5780601f106117605761010080835404028352916020019161178b565b820191906000526020600020905b81548152906001019060200180831161176e57829003601f168201915b505050505081565b61179b613594565b60008281526011602052604090205460ff16151581151514156117bd57600080fd5b600082815260116020908152604091829020805460ff19168415159081179091558251858152918201527fbff84c147d533b99d8802295ac70c53aa7d9ac4e520dcd0200d2f434c34b52a3910161132c565b6000818152601360209081526040808320546001600160a01b03168352601590915281205460ff168061186657506000828152601360209081526040808320546001600160a01b03168352601690915290205460ff165b92915050565b6008602052600090815260409020805460018201546002808401546003850180549495939482840b9463010000008404850b94600160301b90940490930b9291906118b6906158e7565b80601f01602080910402602001604051908101604052809291908181526020018280546118e2906158e7565b801561192f5780601f106119045761010080835404028352916020019161192f565b820191906000526020600020905b81548152906001019060200180831161191257829003601f168201915b505050505090806004018054611944906158e7565b80601f0160208091040260200160405190810160405280929190818152602001828054611970906158e7565b80156119bd5780601f10611992576101008083540402835291602001916119bd565b820191906000526020600020905b8154815290600101906020018083116119a057829003601f168201915b5050505050905087565b6001600160a01b038116600081815260146020818152604080842054808552600b835281852054838052918520549590945291905291905b9193909250565b6000818152600960209081526040808320815160a0810183528154815260019091015460ff808216838601526101008204811683850152620100008204811660608401819052630100000090920464ffffffffff166080909301929092528452601090925282205416611866565b600054610100900460ff16611a8f5760005460ff1615611a93565b303b155b611af65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d4a565b600054610100900460ff16158015611b18576000805461ffff19166101011790555b611b2188611093565b60005b8751811015611b93576001600e60008a8481518110611b5357634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611b8b90615922565b915050611b24565b5060005b8551811015611c06576001600f6000888481518110611bc657634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611bfe90615922565b915050611b97565b5060005b8351811015611c7957600160106000868481518110611c3957634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611c7190615922565b915050611c0a565b5060005b8251811015611cec57600160116000858481518110611cac57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611ce490615922565b915050611c7d565b50601280546001600160a01b038089166001600160a01b03199283161790925560178054878416921691909117905588166000908152600460205260409020805460ff191660011790558015611d48576000805461ff00191690555b5050505050505050565b611d5a613594565b60008281526010602052604090205460ff1615158115151415611d7c57600080fd5b600082815260106020908152604091829020805460ff19168415159081179091558251858152918201527f463b22afe346e0b505997c71b3cb5c2a507adb0214a645f6aede655b18691717910161132c565b6001546001600160a01b03163314611e465760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610d4a565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60005b8151811015611f1957611f07828281518110611efa57634e487b7160e01b600052603260045260246000fd5b6020026020010151612fa6565b80611f1181615922565b915050611ece565b5050565b6000818152601360205260409020546001600160a01b03161580611f8657506000818152601360209081526040808320546001600160a01b03168352601690915290205460ff168015611f8657506000818152601360205260409020546001600160a01b031615155b611fb85760405162461bcd60e51b815260206004820152600360248201526249443160e81b6044820152606401610d4a565b6000818152600c602052604090205460ff16611ffc5760405162461bcd60e51b815260206004820152600360248201526224a21960e91b6044820152606401610d4a565b60175460408051634b40849760e01b8152905183926001600160a01b0316916303aac5d5918391634b408497916004808301926020929190829003018186803b15801561204857600080fd5b505afa15801561205c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120809190614f5c565b6040518263ffffffff1660e01b815260040161209e91815260200190565b60206040518083038186803b1580156120b657600080fd5b505afa1580156120ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ee9190614f5c565b146121215760405162461bcd60e51b815260206004820152600360248201526249443360e81b6044820152606401610d4a565b6112978161398d565b602354604051639658366160e01b81526001600160a01b03838116600483015260609216906396583661906024015b60006040518083038186803b15801561217157600080fd5b505afa158015612185573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118669190810190614e86565b602354604051634d6759b760e11b8152600481018390526060916001600160a01b031690639aceb36e90602401612159565b60035461010090046001600160a01b0316331461220e5760405162461bcd60e51b8152600401610d4a906157ae565b82511561223a576000818152601a602090815260408083208584529091529020805460ff191660011790555b60005b835181101561151057600084828151811061226857634e487b7160e01b600052603260045260246000fd5b6020026020010151806020019051810190612283919061509e565b80516000908152600c602052604090205490915060ff1615801561232e575060215460a082015160c08301516040516397dc205d60e01b81526001600160a01b03909316926397dc205d926122dc92909160040161574d565b60206040518083038186803b1580156122f457600080fd5b505afa158015612308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232c9190614f28565b155b801561233d5750428160200151115b1561235f57805161234f908486613d3a565b61235a868286613d85565b612893565b80516000908152600c602052604090205460ff16156128935760006123878260000151612ca3565b60215460a08085015190830151604051637fabe16b60e01b81529394506001600160a01b0390921692637fabe16b926123c3929160040161574d565b60206040518083038186803b1580156123db57600080fd5b505afa1580156123ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124139190614f28565b15806124a6575060215460c08084015190830151604051637fabe16b60e01b81526001600160a01b0390931692637fabe16b9261245492909160040161574d565b60206040518083038186803b15801561246c57600080fd5b505afa158015612480573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a49190614f28565b155b156125ae5781516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff161561250857846007141561250d5781516124f09060006140b9565b81516124fd908587613d3a565b612508878387613d85565b612891565b8151600090815260136020526040902054612532906001600160a01b0316600161413e565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e9261257792911690600190600401615450565b600060405180830381600087803b15801561259157600080fd5b505af11580156125a5573d6000803e3d6000fd5b50505050612891565b80602001518260200151146128915781516125ca908587613d3a565b4282602001511115612747576012548251600090815260136020908152604091829020549085015191516327ad762d60e21b81526001600160a01b039182166004820152602481019290925290911690639eb5d8b490604401600060405180830381600087803b15801561263d57600080fd5b505af1158015612651573d6000803e3d6000fd5b5050835160009081526008602090815260409182902086518155818701516001820155918601516002808401805460608a015160808b0151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a086015180518795509293506126ea926003850192919091019061498a565b5060c0820151805161270691600484019160209091019061498a565b505060175483516020850151604051630464f33160e31b8152600481019290925260248201526001600160a01b039091169150632327998890604401612577565b81516000908152601360209081526040808320546001600160a01b03168352601c90915290205460ff1680156127805750428160200151115b156128915781516000908152601360205260409020546127aa906001600160a01b0316600161413e565b60235482516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e926127ef92911690600190600401615450565b600060405180830381600087803b15801561280957600080fd5b505af115801561281d573d6000803e3d6000fd5b50508351600090815260136020908152604091829020548651868301518389015185516001600160a01b039094168452938301919091529281019290925260608201527fb71601cabce6b66d1ceb87bb549207b61c7c27e3efd188cae1e0d39f7feedfd79250608001905060405180910390a15b505b508061289e81615922565b91505061223d565b6000828152601d6020908152604080832084845282529182902080548351818402810184019094528084526060939283018282801561290457602002820191906000526020600020905b8154815260200190600101908083116128f0575b5050505050905092915050565b60005b8151811015611f195761294d82828151811061294057634e487b7160e01b600052603260045260246000fd5b6020026020010151611f1d565b8061295781615922565b915050612914565b612967613594565b601280546001600160a01b038581166001600160a01b03199283168117909355601780548883169084168117909155600380548a84166101008102610100600160a81b0319909216919091179091556021805488851690861681179091556023805494881694909516841790945560408051918252602082019290925290810193909352606083019190915260808201527f2719351fde6efd8f8541e7d0c0219124dd63d0fe319bc118a1b85b8803e4effe9060a0015b60405180910390a15050505050565b612a35613594565b6001600160a01b03821615801590612a6c57506001600160a01b03821660009081526004602052604090205460ff16151581151514155b612a7557600080fd5b6001600160a01b03821660009081526004602052604090819020805460ff1916831515179055517f58d7a3ccc34541e162fcfc87b84be7b78c34d1e1e7f15de6e4dd67d0fe70aecd9061132c9084908490615450565b3360009081526004602052604090205460ff16612afa5760405162461bcd60e51b8152600401610d4a90615772565b6000818152600c602052604090205460ff16612b415760405162461bcd60e51b8152600401610d4a9060208082526004908201526324a2191960e11b604082015260600190565b6000908152600c60209081526040808320805460ff19908116909155600d90925290912080549091169055565b612b76613594565b6001600160a01b038116612bbe5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610d4a565b600154600160a81b900460ff1615612c0e5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610d4a565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016111c3565b600560205281600052604060002081815481106116f657600080fd5b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c0810191909152600082815260086020908152604091829020825160e0810184528154815260018201549281019290925260028082015480820b820b820b9484019490945263010000008404810b810b810b6060840152600160301b909304830b830b90920b608082015260038201805491929160a084019190612d5a906158e7565b80601f0160208091040260200160405190810160405280929190818152602001828054612d86906158e7565b8015612dd35780601f10612da857610100808354040283529160200191612dd3565b820191906000526020600020905b815481529060010190602001808311612db657829003601f168201915b50505050508152602001600482018054612dec906158e7565b80601f0160208091040260200160405190810160405280929190818152602001828054612e18906158e7565b8015612e655780601f10612e3a57610100808354040283529160200191612e65565b820191906000526020600020905b815481529060010190602001808311612e4857829003601f168201915b5050505050815250509050919050565b602354604051636c35b77560e01b81526001600160a01b0383811660048301526000928392911690636c35b7759060240160206040518083038186803b158015612ebe57600080fd5b505afa158015612ed2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef69190614bfe565b6001600160a01b0316141592915050565b612f0f613594565b806024541415612f1e57600080fd5b60248190556040518181527f9e07ff05aae276b1721af92dd4740303ffd42aaa4e57ac204b0781a5b46e2606906020016111c3565b6001600160a01b0381166000908152601c602052604090205460609060ff16612f8457612f7f8261212a565b611866565b6001600160a01b038216600090815260146020526040902054611866906121ad565b612faf8161180f565b15612fe25760405162461bcd60e51b815260206004820152600360248201526212510d60ea1b6044820152606401610d4a565b6000818152600d602052604090205460ff166130265760405162461bcd60e51b815260206004820152600360248201526249443560e81b6044820152606401610d4a565b611297816000614259565b6023546001600160a01b0316331461305b5760405162461bcd60e51b8152600401610d4a90615790565b611f19828261413e565b600760205281600052604060002081815481106116f657600080fd5b3360009081526004602052604090205460ff166130b05760405162461bcd60e51b8152600401610d4a90615772565b6001600160a01b038216600090815260146020526040902054158015906130fc57506001600160a01b0382166000908152601460209081526040808320548352600c90915290205460ff165b6131315760405162461bcd60e51b8152600401610d4a906020808252600490820152630494432360e41b604082015260600190565b611f1982826145f7565b801561328a5783156131785760405162461bcd60e51b8152600401610d4a906020808252600490820152634944313760e01b604082015260600190565b6023546001600160a01b03868116600090815260146020526040908190205490516304763b0360e31b8152600481019190915283151560248201529116906323b1d8189060440160206040518083038186803b1580156131d757600080fd5b505afa1580156131eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320f9190614f28565b61321857600080fd5b6023546001600160a01b0386811660009081526014602052604090819020549051639971441b60e01b81526004810191909152911690639971441b90602401600060405180830381600087803b15801561327157600080fd5b505af1158015613285573d6000803e3d6000fd5b505050505b61329585600061413e565b60235460405162d2b13f60e11b81526001600160a01b03909116906301a5627e906132c7908890600090600401615450565b600060405180830381600087803b1580156132e157600080fd5b505af11580156132f5573d6000803e3d6000fd5b505050506001600160a01b0385166000908152601460209081526040808320548352600b8252808320548352600f90915290205461334a90869086908690869060ff1661334357600b614686565b6008614686565b6040805160a0810182526001600160a01b0387166000908152601460209081528382205480845260ff8881168386015287811685870152908352600b8252848320548352600f9091529290205490916060830191166133aa57600b6133ad565b60085b60ff9081168252600060209283018190526001600160a01b03891681526014835260408082208054835260098086528284208751815587870151600191820180548a8701516060808d015160809d8e0151958c1661ffff1990941693909317610100928c1683021767ffffffffffff0000191662010000938c169390930267ffffffffff000000191692909217630100000064ffffffffff95861602179092559454808852600b8a5286882054948a5286882087518281529a8b019590955295890195909552825493880193909352015480851696860196909652600886901c841660a0860152601086901c90931660c085015260189490941c90911660e0830152918101919091527f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73906101200160405180910390a18361353f576001600160a01b038516600081815260146020908152604091829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc910160405180910390a1611510565b6001600160a01b0385166000818152601460209081526040918290205482519384529083015281018590527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e44490606001612a1e565b6000546201000090046001600160a01b0316331461360c5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610d4a565b565b600061361d8460000151612ca3565b905061363f846060015160ff9081166000908152601060205260409020541690565b8061366e5750606084015160ff90811660009081526011602052604090205416801561366e5750428160200151105b1561389e578351600090815260096020908152604080832087518082558389015160019283018054858c015160608d015160808e015164ffffffffff1663010000000267ffffffffff0000001960ff92831662010000021667ffffffffffff0000199383166101000261ffff1990951692909616919091179290921716929092179190911790558452600d835292819020805460ff191690931790925585516017548351638f0ac45360e01b815293517f9b6a2889290ea187763cae1d385adecd9295e6c5e49527154213bbfa4e1aba73948a948994938b936001600160a01b0390911692638f0ac453926004808301939192829003018186803b15801561377557600080fd5b505afa158015613789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ad9190614f5c565b604080519586526020808701959095528581019390935281516060808701919091529382015160ff90811660808088019190915293830151811660a08701529382015190931660c0850152015164ffffffffff1660e08301526101008201526101200160405180910390a1602454821061388c57601754845160405163602726b560e11b81526001600160a01b039092169163c04e4d6a916138559160040190815260200190565b600060405180830381600087803b15801561386f57600080fd5b505af1158015613883573d6000803e3d6000fd5b50505050611510565b8351613899906001614259565b611510565b606084015160ff9081166000908152601160205260409020541680156138c8575042816020015110155b156115105783516000908152601360208181526040808420546001600160a01b039081168552601e8352818520805460ff1916600190811790915589518652939092529092205461391a92169061413e565b60235484516000908152601360205260409081902054905162d2b13f60e11b81526001600160a01b03928316926301a5627e9261395f92911690600190600401615450565b600060405180830381600087803b15801561397957600080fd5b505af115801561104a573d6000803e3d6000fd5b600061399882612ca3565b90504281602001511115613cb2576000828152600b60205260408120546139be9061482d565b60125460a084015160c08501516040519394506000936001600160a01b0390931692634cde32ce9288926139f492602001615411565b60408051808303601f1901815291815260208881015160008b8152600b8352838120548152600f9092529181205460ff16613a30576003613a33565b60025b886000806040518963ffffffff1660e01b8152600401613a5a98979695949392919061551b565b602060405180830381600087803b158015613a7457600080fd5b505af1158015613a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aac9190614bfe565b8351600090815260136020908152604080832080546001600160a01b0319166001600160a01b0386811691821790925588518186526014855283862055601c90935292819020805460ff1916600117905560235487519151630e76f6e760e11b8152600481019290925260248201929092529293501690631cededce90604401600060405180830381600087803b158015613b4657600080fd5b505af1158015613b5a573d6000803e3d6000fd5b50505050601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613bae57600080fd5b505af1158015613bc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613be69190614f5c565b508251602354604051634d6759b760e11b8152600481018390527f889e2060e46779287c2fcbf489c195ef20f5b44a74e3dcb58d491ae073c1370f9284929091879187916001600160a01b0390911690639aceb36e9060240160006040518083038186803b158015613c5757600080fd5b505afa158015613c6b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613c939190810190614e86565b604051613ca495949392919061546b565b60405180910390a150505050565b601760009054906101000a90046001600160a01b03166001600160a01b03166389daf7eb6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613d0257600080fd5b505af1158015613d16573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d59190614f5c565b600083815260208052604090205482146116d5576000908152601d60209081526040808320848452825280832080546001810182559084528284200185905593825280529190912055565b815160009081526008602090815260409182902084518155818501516001820155918401516002808401805460608801516080890151840b62ffffff908116600160301b0268ffffff0000000000001992860b821663010000000265ffffffffffff199094169690950b1694909417179290921617905560a08401518051859392613e1792600385019291019061498a565b5060c08201518051613e3391600484019160209091019061498a565b505082516000908152600b6020908152604091829020849055601754855191860151925163e9c962eb60e01b815260048101929092526024820192909252604481018490526001600160a01b03909116915063e9c962eb90606401600060405180830381600087803b158015613ea857600080fd5b505af1158015613ebc573d6000803e3d6000fd5b505083516000908152600c602052604090819020805460ff1916600117905560235485518287015160608801516080890151945163312025df60e21b81526004810193909352600291820b6024840152810b60448301529290920b60648301526001600160a01b0316925063c480977c9150608401600060405180830381600087803b158015613f4b57600080fd5b505af1158015613f5f573d6000803e3d6000fd5b505050507faba5c0e34b9b54828db4e0ac6b951ca282a0b171289eebf93353c296f9e826138382846000015185601760009054906101000a90046001600160a01b03166001600160a01b031663afff5a646040518163ffffffff1660e01b815260040160206040518083038186803b158015613fda57600080fd5b505afa158015613fee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140129190614f5c565b6023548851604051634d6759b760e11b81526001600160a01b0390921691639aceb36e916140469160040190815260200190565b60006040518083038186803b15801561405e57600080fd5b505afa158015614072573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261409a9190810190614e86565b6040516140ac96959493929190615696565b60405180910390a1505050565b6000828152601360205260408120546140e0916001600160a01b0390911690808080614686565b80156140ee576140ee614891565b6000828152601360209081526040918290205482516001600160a01b0390911681529081018490527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc910161132c565b6012546040516333dfec9960e21b81526001600160a01b03848116600483015283151592169063cf7fb2649060240160206040518083038186803b15801561418557600080fd5b505afa158015614199573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141bd9190614f28565b151514611f1957601254604051637f8c2d6160e01b81526001600160a01b0390911690637f8c2d61906141f69085908590600401615450565b600060405180830381600087803b15801561421057600080fd5b505af1158015614224573d6000803e3d6000fd5b505050507f2b8992e59f9813c2f92be2374e9bdd5384146ff8f719b038fbaf7d3dbfa78fde828260405161132c929190615450565b6000828152600960209081526040808320815160a0810183528154815260019091015460ff80821694830194909452610100810484169282019290925262010000820490921660608301526301000000900464ffffffffff166080820152906142c184612ca3565b90506142e3826060015160ff9081166000908152601060205260409020541690565b156145b6576023548251600090815260136020526040908190205490516336c0d85560e01b81526001600160a01b0391821660048201529116906336c0d8559060240160206040518083038186803b15801561433e57600080fd5b505afa158015614352573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143769190614f28565b156144165781516000908152601360205260408120546143a1916001600160a01b039091169061413e565b602354825160009081526013602052604080822054905162d2b13f60e11b81526001600160a01b03938416936301a5627e936143e39390911691600401615450565b600060405180830381600087803b1580156143fd57600080fd5b505af1158015614411573d6000803e3d6000fd5b505050505b600080600061442485614919565b925092509250600383148015614457575084516000908152600b60209081526040808320548352600f90915290205460ff165b1561446e5784516144699087156140b9565b6145ae565b6012548551600090815260136020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b1580156144c457600080fd5b505afa1580156144d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144fc9190614f28565b6145a1578451600090815260136020526040902054606086015161452f916001600160a01b031690859085908590614686565b8561453c5761453c614891565b845160009081526013602090815260409182902054875183516001600160a01b039092168252918101919091529081018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449060600160405180910390a16145ae565b856145ae576145ae614891565b5050506145f1565b606082015160ff9081166000908152601160205260409020541680156145df5750428160200151105b156145f15781516145f19084156140b9565b50505050565b614601828261413e565b6023546001600160a01b038381166000818152601460205260409081902054905163032bc38360e21b8152600481019190915260248101919091528315156044820152911690630caf0e0c90606401600060405180830381600087803b15801561466a57600080fd5b505af115801561467e573d6000803e3d6000fd5b505050505050565b60125460405163b91f5e3560e01b81526001600160a01b038781166004830152602482018790529091169063b91f5e3590604401600060405180830381600087803b1580156146d457600080fd5b505af11580156146e8573d6000803e3d6000fd5b5050505060c98160ff161415614771576023546040516303e810fd60e61b81526001600160a01b0387811660048301526000602483018190526044830181905260648301529091169063fa043f4090608401600060405180830381600087803b15801561475457600080fd5b505af1158015614768573d6000803e3d6000fd5b505050506147e9565b6023546040516303e810fd60e61b81526001600160a01b0387811660048301526024820187905260ff8087166044840152851660648301529091169063fa043f4090608401600060405180830381600087803b1580156147d057600080fd5b505af11580156147e4573d6000803e3d6000fd5b505050505b5050506001600160a01b039190911660009081526016602090815260408083208054941560ff19958616811790915560159092529091208054911591909216179055565b604080516001808252818301909252606091600091906020808301908036833701905050905061485f836123286158a3565b8160008151811061488057634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b601760009054906101000a90046001600160a01b03166001600160a01b03166377d078d76040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156148e157600080fd5b505af11580156148f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112979190614f5c565b6000806000836040015160ff16846020015160ff16141561494a5750505060208101516040820151600391906119ff565b836040015160ff16846020015160ff16116149705760028460200151856040015161497d565b6001846020015185604001515b9250925092509193909250565b828054614996906158e7565b90600052602060002090601f0160209004810192826149b857600085556149fe565b82601f106149d157805160ff19168380011785556149fe565b828001600101855582156149fe579182015b828111156149fe5782518255916020019190600101906149e3565b50614a0a929150614a0e565b5090565b5b80821115614a0a5760008155600101614a0f565b8035614a2e81615969565b919050565b600082601f830112614a43578081fd5b81356020614a58614a5383615859565b615829565b80838252828201915082860187848660051b8901011115614a77578586fd5b855b85811015614aef5781356001600160401b03811115614a96578788fd5b8801603f81018a13614aa6578788fd5b858101356040614ab8614a538361587c565b8281528c82848601011115614acb578a8bfd5b828285018a83013791820188018a9052508552509284019290840190600101614a79565b5090979650505050505050565b600082601f830112614b0c578081fd5b81356020614b1c614a5383615859565b80838252828201915082860187848660051b8901011115614b3b578586fd5b855b85811015614aef57813584529284019290840190600101614b3d565b8051600181900b8114614a2e57600080fd5b8051600281900b8114614a2e57600080fd5b600082601f830112614b8d578081fd5b8151614b9b614a538261587c565b818152846020838601011115614baf578283fd5b614bc08260208301602087016158bb565b949350505050565b805162ffffff81168114614a2e57600080fd5b600060208284031215614bec578081fd5b8135614bf781615969565b9392505050565b600060208284031215614c0f578081fd5b8151614bf781615969565b600080600080600080600060e0888a031215614c34578283fd5b614c3d88614a23565b965060208801356001600160401b0380821115614c58578485fd5b614c648b838c01614afc565b9750614c7260408b01614a23565b965060608a0135915080821115614c87578485fd5b614c938b838c01614afc565b9550614ca160808b01614a23565b945060a08a0135915080821115614cb6578384fd5b614cc28b838c01614afc565b935060c08a0135915080821115614cd7578283fd5b50614ce48a828b01614afc565b91505092959891949750929550565b60008060408385031215614d05578182fd5b8235614d1081615969565b91506020830135614d208161597e565b809150509250929050565b600080600080600060a08688031215614d42578283fd5b8535614d4d81615969565b94506020860135614d5d81615969565b93506040860135614d6d81615969565b92506060860135614d7d81615969565b91506080860135614d8d81615969565b809150509295509295909350565b600080600080600060a08688031215614db2578283fd5b8535614dbd81615969565b9450602086013593506040860135614dd48161598c565b92506060860135614de48161598c565b91506080860135614d8d8161597e565b60006020808385031215614e06578182fd5b82356001600160401b03811115614e1b578283fd5b8301601f81018513614e2b578283fd5b8035614e39614a5382615859565b80828252848201915084840188868560051b8701011115614e58578687fd5b8694505b83851015614e7a578035835260019490940193918501918501614e5c565b50979650505050505050565b60006020808385031215614e98578182fd5b82516001600160401b03811115614ead578283fd5b8301601f81018513614ebd578283fd5b8051614ecb614a5382615859565b80828252848201915084840188868560051b8701011115614eea578687fd5b8694505b83851015614e7a578051835260019490940193918501918501614eee565b600060208284031215614f1d578081fd5b8135614bf78161597e565b600060208284031215614f39578081fd5b8151614bf78161597e565b600060208284031215614f55578081fd5b5035919050565b600060208284031215614f6d578081fd5b5051919050565b60008060408385031215614f86578182fd5b823591506020830135614d2081615969565b60008060408385031215614faa578182fd5b8235915060208301356001600160401b03811115614fc6578182fd5b614fd285828601614a33565b9150509250929050565b600080600060608486031215614ff0578081fd5b8335925060208401356001600160401b0381111561500c578182fd5b61501886828701614a33565b925050604084013590509250925092565b6000806000806080858703121561503e578182fd5b8435935060208501356001600160401b0381111561505a578283fd5b61506687828801614a33565b949794965050505060408301359260600135919050565b6000806040838503121561508f578182fd5b50508035926020909101359150565b6000602082840312156150af578081fd5b81516001600160401b03808211156150c5578283fd5b9083019060e082860312156150d8578283fd5b6150e06157de565b82518152602083015160208201526150fa60408401614b6b565b604082015261510b60608401614b6b565b606082015261511c60808401614b6b565b608082015260a083015182811115615132578485fd5b61513e87828601614b7d565b60a08301525060c083015182811115615155578485fd5b61516187828601614b7d565b60c08301525095945050505050565b60006101808284031215615182578081fd5b61518a615806565b8251815261519a60208401614b6b565b60208201526151ab60408401614b6b565b60408201526151bc60608401614b6b565b60608201526151cd60808401614b59565b60808201526151de60a08401614b6b565b60a08201526151ef60c08401614b59565b60c082015261520060e08401614b6b565b60e0820152610100615213818501614bc8565b90820152610120615225848201614b6b565b90820152610140615237848201614bc8565b90820152610160615249848201614b6b565b908201529392505050565b600060a08284031215615265578081fd5b60405160a081018181106001600160401b038211171561528757615287615953565b60405282518152602083015161529c8161598c565b602082015260408301516152af8161598c565b604082015260608301516152c28161598c565b6060820152608083015164ffffffffff811681146152de578283fd5b60808201529392505050565b600080604083850312156152fc578182fd5b823591506020830135614d208161597e565b600080600060608486031215615322578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b838110156153685781518752958201959082019060010161534c565b509495945050505050565b6000815180845261538b8160208601602086016158bb565b601f01601f19169290920160200192915050565b8051825260208101516020830152604081015160020b6040830152606081015160020b6060830152608081015160020b6080830152600060a082015160e060a08501526153ef60e0850182615373565b905060c083015184820360c08601526154088282615373565b95945050505050565b600083516154238184602088016158bb565b630103b39960e51b90830190815283516154448160048401602088016158bb565b01600401949350505050565b6001600160a01b039290921682521515602082015260400190565b60018060a01b038616815284602082015260a06040820152600061549260a083018661539f565b82810360608401526154a48186615339565b905082810360808401526154b88185615339565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b818110156154fc578351835292840192918401916001016154e0565b50909695505050505050565b602081526000614bf76020830184615339565b60006101008a83528060208401526155358184018b615373565b905088604084015287606084015260ff8716608084015282810360a084015261555e8187615339565b94151560c084015250506001600160a01b039190911660e0909101529695505050505050565b60006101c0820190508482528351602083015260208401516155ab604084018260020b9052565b5060408401516155c0606084018260020b9052565b5060608401516155d5608084018260020b9052565b5060808401516155ea60a084018260010b9052565b5060a08401516155ff60c084018260020b9052565b5060c084015161561460e084018260010b9052565b5060e084015161010061562b8185018360020b9052565b85015190506101206156438482018362ffffff169052565b85015190506101406156598482018360020b9052565b85015190506101606156718482018362ffffff169052565b850151905061568661018084018260020b9052565b50826101a0830152949350505050565b86815285602082015284604082015260c0606082015260006156bb60c083018661539f565b84608084015282810360a08401526156d38185615339565b9998505050505050505050565b8781528660208201528560020b60408201528460020b60608201528360020b608082015260e060a0820152600061571a60e0830185615373565b82810360c084015261572c8185615373565b9a9950505050505050505050565b602081526000614bf76020830184615373565b6040815260006157606040830185615373565b82810360208401526154088185615373565b6020808252600490820152630494431360e41b604082015260600190565b60208082526004908201526324a2189b60e11b604082015260600190565b60208082526003908201526249443960e81b604082015260600190565b602081526000614bf7602083018461539f565b60405160e081016001600160401b038111828210171561580057615800615953565b60405290565b60405161018081016001600160401b038111828210171561580057615800615953565b604051601f8201601f191681016001600160401b038111828210171561585157615851615953565b604052919050565b60006001600160401b0382111561587257615872615953565b5060051b60200190565b60006001600160401b0382111561589557615895615953565b50601f01601f191660200190565b600082198211156158b6576158b661593d565b500190565b60005b838110156158d65781810151838201526020016158be565b838111156145f15750506000910152565b600181811c908216806158fb57607f821691505b6020821081141561591c57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156159365761593661593d565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461129757600080fd5b801515811461129757600080fd5b60ff8116811461129757600080fdfea2646970667358221220f23db72512c781603bb68930f9838814bf43d7888fc195670c9400438e6a3ced64736f6c63430008040033

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