Contract 0x5daa90f5343d7abcdb1190d1455f3308a8248841

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

Contract Overview

Balance:
Txn Hash Method
Block
From
To
Value
0x198c1881854fdafdbb4b36508a1b3a43033059c7afbbc20ba38b5fa23e80d7ed0x60806040181822342023-12-05 16:08:56221 days 2 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  Create: GamesOddsObtainer0 ETH0.0000546964960.00001
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GamesOddsObtainer

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 17 : GamesOddsObtainer.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";
import "@openzeppelin/contracts-4.4.1/utils/Strings.sol";

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

// interface
import "../../interfaces/ISportPositionalMarketManager.sol";
import "../../interfaces/ITherundownConsumerVerifier.sol";
import "../../interfaces/ITherundownConsumer.sol";
import "../../interfaces/IGamesOddsObtainer.sol";

/// @title Contract, which works on odds obtain
/// @author gruja
contract GamesOddsObtainer is Initializable, ProxyOwned, ProxyPausable {
    /* ========== CONSTANTS =========== */
    uint public constant MIN_TAG_NUMBER = 9000;
    uint public constant TAG_NUMBER_SPREAD = 10001;
    uint public constant TAG_NUMBER_TOTAL = 10002;
    uint public constant CANCELLED = 0;
    uint public constant HOME_WIN = 1;
    uint public constant AWAY_WIN = 2;

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

    ITherundownConsumer public consumer;
    ITherundownConsumerVerifier public verifier;
    ISportPositionalMarketManager public sportsManager;

    // game properties
    mapping(bytes32 => IGamesOddsObtainer.GameOdds) public gameOdds;
    mapping(bytes32 => IGamesOddsObtainer.GameOdds) public backupOdds;
    mapping(address => bool) public invalidOdds;
    mapping(bytes32 => uint) public oddsLastPulledForGame;
    mapping(address => bytes32) public gameIdPerChildMarket;
    mapping(uint => bool) public doesSportSupportSpreadAndTotal;

    // market props
    mapping(address => mapping(uint => address)) public mainMarketChildMarketIndex;
    mapping(address => uint) public numberOfChildMarkets;
    mapping(address => mapping(int16 => address)) public mainMarketSpreadChildMarket;
    mapping(address => mapping(uint24 => address)) public mainMarketTotalChildMarket;
    mapping(address => address) public childMarketMainMarket;
    mapping(address => int16) public childMarketSread;
    mapping(address => uint24) public childMarketTotal;
    mapping(address => address) public currentActiveTotalChildMarket;
    mapping(address => address) public currentActiveSpreadChildMarket;
    mapping(address => bool) public isSpreadChildMarket;
    mapping(address => bool) public childMarketCreated;
    mapping(address => bool) public normalizedOddsForMarketFulfilled;
    mapping(address => uint[]) public normalizedOddsForMarket;
    address public oddsReceiver;
    mapping(address => uint) public playersReportTimestamp;
    uint public waitTimePlayersReport;

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

    function initialize(
        address _owner,
        address _consumer,
        address _verifier,
        address _sportsManager,
        uint[] memory _supportedSportIds
    ) external initializer {
        setOwner(_owner);
        consumer = ITherundownConsumer(_consumer);
        verifier = ITherundownConsumerVerifier(_verifier);
        sportsManager = ISportPositionalMarketManager(_sportsManager);

        for (uint i; i < _supportedSportIds.length; i++) {
            doesSportSupportSpreadAndTotal[_supportedSportIds[i]] = true;
        }
    }

    /* ========== OBTAINER MAIN FUNCTIONS ========== */

    /// @notice main function for odds obtaining
    /// @param requestId chainlnink request ID
    /// @param _game game odds struct see @ IGamesOddsObtainer.GameOdds
    function obtainOdds(
        bytes32 requestId,
        IGamesOddsObtainer.GameOdds memory _game,
        uint _sportId,
        address _main,
        bool _isTwoPositional,
        bool _playersReport
    ) external canUpdateOdds {
        bool _isMainMarketPaused = sportsManager.isMarketPaused(_main);
        if (_areOddsValid(_game, _isTwoPositional)) {
            uint[] memory currentNormalizedOdd = _getNormalizedOdds(_game.gameId);
            IGamesOddsObtainer.GameOdds memory currentOddsBeforeSave = gameOdds[_game.gameId];
            gameOdds[_game.gameId] = _game;
            oddsLastPulledForGame[_game.gameId] = block.timestamp;

            _setNormalizedOdds(_main, _game.gameId, true);
            if (doesSportSupportSpreadAndTotal[_sportId] || numberOfChildMarkets[_main] > 0) {
                _obtainTotalAndSpreadOdds(_game, _main);
            }
            bool _inThreshold = verifier.areOddsArrayInThreshold(
                _sportId,
                currentNormalizedOdd,
                normalizedOddsForMarket[_main],
                _isTwoPositional
            );
            // if was paused and paused by invalid odds unpause
            if (_isMainMarketPaused) {
                if (invalidOdds[_main] || consumer.isPausedByCanceledStatus(_main)) {
                    consumer.setPausedByCanceledStatus(_main, false);
                    if (!_inThreshold) {
                        invalidOdds[_main] = false;
                        backupOdds[_game.gameId] = currentOddsBeforeSave;
                        _pauseOrUnpauseMarkets(_game, _main, true, true);
                        emit OddsCircuitBreaker(_main, _game.gameId);
                    } else {
                        if (
                            playersReportTimestamp[_main] > 0 &&
                            block.timestamp - playersReportTimestamp[_main] < waitTimePlayersReport
                        ) {
                            _pauseOrUnpauseMarkets(_game, _main, true, true);
                        } else {
                            invalidOdds[_main] = false;
                            _pauseOrUnpauseMarkets(_game, _main, false, true);
                            playersReportTimestamp[_main] = 0;
                        }
                    }
                }
            } else if (
                //if market is not paused but odd are not in threshold, pause parket
                !_isMainMarketPaused && !_inThreshold
            ) {
                _pauseOrUnpauseMarkets(_game, _main, true, true);
                _pauseOrUnpausePlayerProps(_main, true, false, true);
                backupOdds[_game.gameId] = currentOddsBeforeSave;
                emit OddsCircuitBreaker(_main, _game.gameId);
            }
            emit GameOddsAdded(requestId, _game.gameId, _game, normalizedOddsForMarket[_main]);
        } else {
            if (!_isMainMarketPaused) {
                invalidOdds[_main] = true;
                if (_playersReport) {
                    playersReportTimestamp[_main] = block.timestamp;
                }
                _pauseOrUnpauseMarkets(_game, _main, true, true);
                _pauseOrUnpausePlayerProps(_main, true, true, false);
            }

            emit InvalidOddsForMarket(requestId, _main, _game.gameId, _game);
        }
    }

    /// @notice set first odds on creation
    /// @param _gameId game id
    /// @param _homeOdds home odds for a game
    /// @param _awayOdds away odds for a game
    /// @param _drawOdds draw odds for a game
    function setFirstOdds(
        bytes32 _gameId,
        int24 _homeOdds,
        int24 _awayOdds,
        int24 _drawOdds
    ) external onlyConsumer {
        gameOdds[_gameId] = IGamesOddsObtainer.GameOdds(_gameId, _homeOdds, _awayOdds, _drawOdds, 0, 0, 0, 0, 0, 0, 0, 0);
        oddsLastPulledForGame[_gameId] = block.timestamp;
    }

    /// @notice set first odds on creation market
    /// @param _gameId game id
    /// @param _market market
    function setFirstNormalizedOdds(bytes32 _gameId, address _market) external onlyConsumer {
        _setNormalizedOdds(_market, _gameId, true);
    }

    /// @notice set backup odds to be main odds
    /// @param _gameId game id which is using backup odds
    function setBackupOddsAsMainOddsForGame(bytes32 _gameId) external onlyConsumer {
        gameOdds[_gameId] = backupOdds[_gameId];
        address _main = _getMarketPerGameId(_gameId);
        _setNormalizedOdds(_main, _gameId, true);
        emit GameOddsAdded(
            _gameId, // // no req. from CL (manual cancel) so just put gameID
            _gameId,
            gameOdds[_gameId],
            normalizedOddsForMarket[_main]
        );
    }

    /// @notice pause/unpause all child markets
    /// @param _main parent market for which we are pause/unpause child markets
    /// @param _flag pause -> true, unpause -> false
    function pauseUnpauseChildMarkets(address _main, bool _flag) external onlyConsumer {
        // number of childs more then 0
        for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
            _pauseOrUnpauseSingleMarket(mainMarketChildMarketIndex[_main][i], _flag);
        }
    }

    /// @notice pause/unpause current active child markets
    /// @param _gameId game id for spread and totals checking
    /// @param _main parent market for which we are pause/unpause child markets
    /// @param _flag pause -> true, unpause -> false
    function pauseUnpauseCurrentActiveChildMarket(
        bytes32 _gameId,
        address _main,
        bool _flag
    ) external onlyConsumer {
        _pauseOrUnpauseMarkets(gameOdds[_gameId], _main, _flag, true);
    }

    function setChildMarketGameId(bytes32 gameId, address market) external onlyManager {
        consumer.setGameIdPerChildMarket(gameId, market);
    }

    /// @notice resolve all child markets
    /// @param _main parent market for which we are resolving
    /// @param _outcome poitions thet is winning (homw, away, cancel)
    /// @param _homeScore points that home team score
    /// @param _awayScore points that away team score
    function resolveChildMarkets(
        address _main,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore
    ) external onlyConsumer {
        for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
            address child = mainMarketChildMarketIndex[_main][i];
            if (_outcome == CANCELLED) {
                sportsManager.resolveMarket(child, _outcome);
            } else if (isSpreadChildMarket[child]) {
                _resolveMarketSpread(child, uint16(_homeScore), uint16(_awayScore));
            } else {
                _resolveMarketTotal(child, uint24(_homeScore), uint24(_awayScore));
            }
        }
    }

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

    /// @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) external view returns (uint[] memory) {
        return _getNormalizedOdds(_gameId);
    }

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

    /// @notice function which retrievers all markert addresses for given parent market
    /// @param _parent parent market
    /// @return address[] child addresses
    function getAllChildMarketsFromParent(address _parent) external view returns (address[] memory) {
        address[] memory allMarkets = new address[](numberOfChildMarkets[_parent]);
        for (uint i = 0; i < numberOfChildMarkets[_parent]; i++) {
            allMarkets[i] = mainMarketChildMarketIndex[_parent][i];
        }
        return allMarkets;
    }

    /// @notice function which retrievers all markert addresses for given parent market
    /// @param _parent parent market
    /// @return totalsMarket totals child address
    /// @return spreadsMarket spread child address
    function getActiveChildMarketsFromParent(address _parent)
        external
        view
        returns (address totalsMarket, address spreadsMarket)
    {
        totalsMarket = currentActiveTotalChildMarket[_parent];
        spreadsMarket = currentActiveSpreadChildMarket[_parent];
    }

    /// @notice are odds valid or not
    /// @param _gameId game id for which game is looking
    /// @param _useBackup see if looking at backupOdds
    /// @return bool true/false (valid or not)
    function areOddsValid(
        bytes32 _gameId,
        bool _useBackup,
        bool _isTwoPositional
    ) external view returns (bool) {
        return
            _useBackup
                ? _areOddsValid(backupOdds[_gameId], _isTwoPositional)
                : _areOddsValid(gameOdds[_gameId], _isTwoPositional);
    }

    /// @notice view function which returns odds
    /// @param _gameId game id
    /// @return spreadHome points difference between home and away
    /// @return spreadAway  points difference between home and away
    /// @return totalOver  points total in a game over limit
    /// @return totalUnder  points total in game under limit
    function getLinesForGame(bytes32 _gameId)
        public
        view
        returns (
            int16,
            int16,
            uint24,
            uint24
        )
    {
        return (
            gameOdds[_gameId].spreadHome,
            gameOdds[_gameId].spreadAway,
            gameOdds[_gameId].totalOver,
            gameOdds[_gameId].totalUnder
        );
    }

    /// @notice view function which returns odds
    /// @param _gameId game id
    /// @return homeOdds moneyline odd in a two decimal places
    /// @return awayOdds moneyline odd in a two decimal places
    /// @return drawOdds moneyline odd in a two decimal places
    /// @return spreadHomeOdds moneyline odd in a two decimal places
    /// @return spreadAwayOdds moneyline odd in a two decimal places
    /// @return totalOverOdds moneyline odd in a two decimal places
    /// @return totalUnderOdds moneyline odd in a two decimal places
    function getOddsForGame(bytes32 _gameId)
        public
        view
        returns (
            int24,
            int24,
            int24,
            int24,
            int24,
            int24,
            int24
        )
    {
        return (
            gameOdds[_gameId].homeOdds,
            gameOdds[_gameId].awayOdds,
            gameOdds[_gameId].drawOdds,
            gameOdds[_gameId].spreadHomeOdds,
            gameOdds[_gameId].spreadAwayOdds,
            gameOdds[_gameId].totalOverOdds,
            gameOdds[_gameId].totalUnderOdds
        );
    }

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

    function _getNormalizedOdds(bytes32 _gameId) internal view returns (uint[] memory) {
        address _market = _getMarketPerGameId(_gameId);
        return
            normalizedOddsForMarketFulfilled[_market]
                ? normalizedOddsForMarket[_market]
                : _getNormalizedOddsFromGameOddsStruct(_gameId);
    }

    function _getNormalizedChildOdds(address _market) internal view returns (uint[] memory) {
        return
            normalizedOddsForMarketFulfilled[_market]
                ? normalizedOddsForMarket[_market]
                : _getNormalizedChildOddsFromGameOddsStruct(_market);
    }

    function _getNormalizedOddsFromGameOddsStruct(bytes32 _gameId) internal view returns (uint[] memory) {
        int[] memory odds = new int[](3);
        odds[0] = gameOdds[_gameId].homeOdds;
        odds[1] = gameOdds[_gameId].awayOdds;
        odds[2] = gameOdds[_gameId].drawOdds;
        return verifier.calculateAndNormalizeOdds(odds);
    }

    function _getNormalizedChildOddsFromGameOddsStruct(address _market) internal view returns (uint[] memory) {
        bytes32 gameId = gameIdPerChildMarket[_market];
        int[] memory odds = new int[](2);
        odds[0] = isSpreadChildMarket[_market] ? gameOdds[gameId].spreadHomeOdds : gameOdds[gameId].totalOverOdds;
        odds[1] = isSpreadChildMarket[_market] ? gameOdds[gameId].spreadAwayOdds : gameOdds[gameId].totalUnderOdds;
        return verifier.calculateAndNormalizeOdds(odds);
    }

    function _areOddsValid(IGamesOddsObtainer.GameOdds memory _game, bool _isTwoPositional) internal view returns (bool) {
        return verifier.areOddsValid(_isTwoPositional, _game.homeOdds, _game.awayOdds, _game.drawOdds);
    }

    function _obtainTotalAndSpreadOdds(IGamesOddsObtainer.GameOdds memory _game, address _main) internal {
        if (_areTotalOddsValid(_game)) {
            _obtainSpreadTotal(_game, _main, false);
            emit GamedOddsAddedChild(
                _game.gameId,
                currentActiveTotalChildMarket[_main],
                _game,
                _getNormalizedChildOdds(currentActiveTotalChildMarket[_main]),
                TAG_NUMBER_TOTAL
            );
        } else {
            _pauseTotalSpreadMarkets(_game, false);
        }
        if (_areSpreadOddsValid(_game)) {
            _obtainSpreadTotal(_game, _main, true);
            emit GamedOddsAddedChild(
                _game.gameId,
                currentActiveSpreadChildMarket[_main],
                _game,
                _getNormalizedChildOdds(currentActiveSpreadChildMarket[_main]),
                TAG_NUMBER_SPREAD
            );
        } else {
            _pauseTotalSpreadMarkets(_game, true);
        }
    }

    function _areTotalOddsValid(IGamesOddsObtainer.GameOdds memory _game) internal view returns (bool) {
        return verifier.areTotalOddsValid(_game.totalOver, _game.totalOverOdds, _game.totalUnder, _game.totalUnderOdds);
    }

    function _areSpreadOddsValid(IGamesOddsObtainer.GameOdds memory _game) internal view returns (bool) {
        return verifier.areSpreadOddsValid(_game.spreadHome, _game.spreadHomeOdds, _game.spreadAway, _game.spreadAwayOdds);
    }

    function _obtainSpreadTotal(
        IGamesOddsObtainer.GameOdds memory _game,
        address _main,
        bool _isSpread
    ) internal {
        bool isNewMarket = numberOfChildMarkets[_main] == 0;

        address currentActiveChildMarket = _isSpread
            ? currentActiveSpreadChildMarket[_main]
            : currentActiveTotalChildMarket[_main];

        address currentMarket = _isSpread
            ? mainMarketSpreadChildMarket[_main][_game.spreadHome]
            : mainMarketTotalChildMarket[_main][_game.totalOver];

        if (isNewMarket || currentMarket == address(0)) {
            address newMarket = _createMarketSpreadTotalMarket(
                _game.gameId,
                _main,
                _isSpread,
                _game.spreadHome,
                _game.totalOver
            );

            _setCurrentChildMarkets(_main, newMarket, _isSpread);

            if (currentActiveChildMarket != address(0)) {
                _pauseOrUnpauseSingleMarket(currentActiveChildMarket, true);
            }
            _setNormalizedOdds(newMarket, _game.gameId, false);
        } else if (currentMarket != currentActiveChildMarket) {
            _pauseOrUnpauseSingleMarket(currentMarket, false);
            _pauseOrUnpauseSingleMarket(currentActiveChildMarket, true);
            _setCurrentChildMarkets(_main, currentMarket, _isSpread);
            _setNormalizedOdds(currentMarket, _game.gameId, false);
        } else {
            _pauseOrUnpauseSingleMarket(currentActiveChildMarket, false);
            _setNormalizedOdds(currentActiveChildMarket, _game.gameId, false);
        }
    }

    function _pauseOrUnpauseSingleMarket(address _market, bool _pause) internal {
        consumer.pauseOrUnpauseMarket(_market, _pause);
    }

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

    function _setNormalizedOdds(
        address _market,
        bytes32 _gameId,
        bool _isParent
    ) internal {
        normalizedOddsForMarket[_market] = _isParent
            ? _getNormalizedOddsFromGameOddsStruct(_gameId)
            : _getNormalizedChildOddsFromGameOddsStruct(_market);
        normalizedOddsForMarketFulfilled[_market] = true;
    }

    function _createMarketSpreadTotalMarket(
        bytes32 _gameId,
        address _mainMarket,
        bool _isSpread,
        int16 _spreadHome,
        uint24 _totalOver
    ) internal returns (address _childMarket) {
        // create
        uint[] memory tags = _calculateTags(consumer.sportsIdPerGame(_gameId), _isSpread);
        sportsManager.createMarket(
            _gameId,
            _append(_gameId, _isSpread, _spreadHome, _totalOver), // gameLabel
            consumer.getGameCreatedById(_gameId).startTime, //maturity
            0, //initialMint
            2, // always two positions for spread/total
            tags, //tags
            true, // is child
            _mainMarket
        );

        _childMarket = sportsManager.getActiveMarketAddress(sportsManager.numActiveMarkets() - 1);

        // adding child markets
        _setChildMarkets(_gameId, _mainMarket, _childMarket, _isSpread, _spreadHome, _totalOver, tags[1]);
    }

    function _calculateTags(uint _sportsId, bool _isSpread) internal pure returns (uint[] memory) {
        uint[] memory result = new uint[](2);
        result[0] = MIN_TAG_NUMBER + _sportsId;
        result[1] = _isSpread ? TAG_NUMBER_SPREAD : TAG_NUMBER_TOTAL;
        return result;
    }

    function _append(
        bytes32 _gameId,
        bool _isSpread,
        int16 _spreadHome,
        uint24 _totalOver
    ) internal view returns (string memory) {
        string memory teamVsTeam = string(
            abi.encodePacked(
                consumer.getGameCreatedById(_gameId).homeTeam,
                " vs ",
                consumer.getGameCreatedById(_gameId).awayTeam
            )
        );
        if (_isSpread) {
            return string(abi.encodePacked(teamVsTeam, "(", _parseSpread(_spreadHome), ")"));
        } else {
            return string(abi.encodePacked(teamVsTeam, " - ", Strings.toString(_totalOver)));
        }
    }

    function _parseSpread(int16 _spreadHome) internal pure returns (string memory) {
        return
            _spreadHome > 0
                ? Strings.toString(uint16(_spreadHome))
                : string(abi.encodePacked("-", Strings.toString(uint16(_spreadHome * (-1)))));
    }

    function _pauseOrUnpauseMarkets(
        IGamesOddsObtainer.GameOdds memory _game,
        address _main,
        bool _flag,
        bool _unpauseMain
    ) internal {
        if (_unpauseMain) {
            _pauseOrUnpauseSingleMarket(_main, _flag);
        }

        if (numberOfChildMarkets[_main] > 0) {
            if (_flag) {
                for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
                    _pauseOrUnpauseSingleMarket(mainMarketChildMarketIndex[_main][i], _flag);
                }
            } else {
                if (_areTotalOddsValid(_game)) {
                    address totalChildMarket = mainMarketTotalChildMarket[_main][_game.totalOver];
                    if (totalChildMarket == address(0)) {
                        address newMarket = _createMarketSpreadTotalMarket(
                            _game.gameId,
                            _main,
                            false,
                            _game.spreadHome,
                            _game.totalOver
                        );
                        _setCurrentChildMarkets(_main, newMarket, false);
                    } else {
                        _pauseOrUnpauseSingleMarket(totalChildMarket, _flag);
                        _setCurrentChildMarkets(_main, totalChildMarket, false);
                    }
                }
                if (_areSpreadOddsValid(_game)) {
                    address spreadChildMarket = mainMarketSpreadChildMarket[_main][_game.spreadHome];
                    if (spreadChildMarket == address(0)) {
                        address newMarket = _createMarketSpreadTotalMarket(
                            _game.gameId,
                            _main,
                            true,
                            _game.spreadHome,
                            _game.totalOver
                        );
                        _setCurrentChildMarkets(_main, newMarket, true);
                    } else {
                        _pauseOrUnpauseSingleMarket(spreadChildMarket, _flag);
                        _setCurrentChildMarkets(_main, spreadChildMarket, true);
                    }
                }
            }
        }
    }

    function _pauseTotalSpreadMarkets(IGamesOddsObtainer.GameOdds memory _game, bool _isSpread) internal {
        address _main = _getMarketPerGameId(_game.gameId);
        // in number of childs more then 0
        if (numberOfChildMarkets[_main] > 0) {
            for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
                address _child = mainMarketChildMarketIndex[_main][i];
                if (isSpreadChildMarket[_child] == _isSpread) {
                    _pauseOrUnpauseSingleMarket(_child, true);
                }
            }
        }
    }

    function _getMarketPerGameId(bytes32 _gameId) internal view returns (address) {
        return consumer.marketPerGameId(_gameId);
    }

    function _setCurrentChildMarkets(
        address _main,
        address _child,
        bool _isSpread
    ) internal {
        if (_isSpread) {
            currentActiveSpreadChildMarket[_main] = _child;
        } else {
            currentActiveTotalChildMarket[_main] = _child;
        }
    }

    function _setChildMarkets(
        bytes32 _gameId,
        address _main,
        address _child,
        bool _isSpread,
        int16 _spreadHome,
        uint24 _totalOver,
        uint _type
    ) internal {
        consumer.setGameIdPerChildMarket(_gameId, _child);
        gameIdPerChildMarket[_child] = _gameId;
        childMarketCreated[_child] = true;
        // adding child markets
        childMarketMainMarket[_child] = _main;
        mainMarketChildMarketIndex[_main][numberOfChildMarkets[_main]] = _child;
        numberOfChildMarkets[_main] = numberOfChildMarkets[_main] + 1;
        if (_isSpread) {
            mainMarketSpreadChildMarket[_main][_spreadHome] = _child;
            childMarketSread[_child] = _spreadHome;
            currentActiveSpreadChildMarket[_main] = _child;
            isSpreadChildMarket[_child] = true;
            emit CreateChildSpreadSportsMarket(_main, _child, _gameId, _spreadHome, _getNormalizedChildOdds(_child), _type);
        } else {
            mainMarketTotalChildMarket[_main][_totalOver] = _child;
            childMarketTotal[_child] = _totalOver;
            currentActiveTotalChildMarket[_main] = _child;
            emit CreateChildTotalSportsMarket(_main, _child, _gameId, _totalOver, _getNormalizedChildOdds(_child), _type);
        }
    }

    function _resolveMarketTotal(
        address _child,
        uint24 _homeScore,
        uint24 _awayScore
    ) internal {
        uint24 totalLine = childMarketTotal[_child];

        uint outcome = (_homeScore + _awayScore) * 100 > totalLine ? HOME_WIN : (_homeScore + _awayScore) * 100 < totalLine
            ? AWAY_WIN
            : CANCELLED;

        sportsManager.resolveMarket(_child, outcome);
        emit ResolveChildMarket(_child, outcome, childMarketMainMarket[_child], _homeScore, _awayScore);
    }

    function _resolveMarketSpread(
        address _child,
        uint16 _homeScore,
        uint16 _awayScore
    ) internal {
        int16 homeScoreWithSpread = int16(_homeScore) * 100 + childMarketSread[_child];
        int16 newAwayScore = int16(_awayScore) * 100;

        uint outcome = homeScoreWithSpread > newAwayScore ? HOME_WIN : homeScoreWithSpread < newAwayScore
            ? AWAY_WIN
            : CANCELLED;
        sportsManager.resolveMarket(_child, outcome);
        emit ResolveChildMarket(_child, outcome, childMarketMainMarket[_child], uint24(_homeScore), uint24(_awayScore));
    }

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

    /// @notice sets consumer, verifier, manager address
    /// @param _consumer consumer address
    /// @param _verifier verifier address
    /// @param _sportsManager sport manager address
    function setContracts(
        address _consumer,
        address _verifier,
        address _sportsManager,
        address _receiver
    ) external onlyOwner {
        consumer = ITherundownConsumer(_consumer);
        verifier = ITherundownConsumerVerifier(_verifier);
        sportsManager = ISportPositionalMarketManager(_sportsManager);
        oddsReceiver = _receiver;

        emit NewContractAddresses(_consumer, _verifier, _sportsManager, _receiver);
    }

    /// @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 setSupportedSportForTotalAndSpread(uint _sportId, bool _isSupported) external onlyOwner {
        doesSportSupportSpreadAndTotal[_sportId] = _isSupported;
        emit SupportedSportForTotalAndSpreadAdded(_sportId, _isSupported);
    }

    /// @notice sets wait time for unpausing markets
    /// @param _waitTime time in seconds
    function setWaitTime(uint _waitTime) external onlyOwner {
        waitTimePlayersReport = _waitTime;
        emit NewWaitTime(_waitTime);
    }

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

    modifier canUpdateOdds() {
        require(msg.sender == address(consumer) || msg.sender == oddsReceiver, "Invalid sender");
        _;
    }

    modifier onlyConsumer() {
        require(msg.sender == address(consumer), "Only consumer");
        _;
    }

    modifier onlyManager() {
        require(msg.sender == address(sportsManager), "Only manager");
        _;
    }

    /* ========== EVENTS ========== */

    event GameOddsAdded(bytes32 _requestId, bytes32 _id, IGamesOddsObtainer.GameOdds _game, uint[] _normalizedOdds);
    event GamedOddsAddedChild(
        bytes32 _id,
        address _market,
        IGamesOddsObtainer.GameOdds _game,
        uint[] _normalizedChildOdds,
        uint _type
    );
    event InvalidOddsForMarket(bytes32 _requestId, address _marketAddress, bytes32 _id, IGamesOddsObtainer.GameOdds _game);
    event OddsCircuitBreaker(address _marketAddress, bytes32 _id);
    event NewContractAddresses(address _consumer, address _verifier, address _sportsManager, address _receiver);
    event CreateChildSpreadSportsMarket(
        address _main,
        address _child,
        bytes32 _id,
        int16 _spread,
        uint[] _normalizedOdds,
        uint _type
    );
    event CreateChildTotalSportsMarket(
        address _main,
        address _child,
        bytes32 _id,
        uint24 _total,
        uint[] _normalizedOdds,
        uint _type
    );
    event SupportedSportForTotalAndSpreadAdded(uint _sportId, bool _isSupported);
    event ResolveChildMarket(address _child, uint _outcome, address _main, uint24 _homeScore, uint24 _awayScore);
    event NewWaitTime(uint _waitTime);
}

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

pragma solidity ^0.8.0;

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

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

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

    bool private _paused;

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

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

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

File 4 of 17 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

    modifier onlyOwner {
        _onlyOwner();
        _;
    }

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

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

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

pragma solidity ^0.8.0;

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

// Clone of syntetix contract without constructor

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

    

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

        // Set our paused state.
        paused = _paused;

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

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

    event PauseChanged(bool isPaused);

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

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

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

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

    function marketCreationEnabled() external view returns (bool);

    function totalDeposited() external view returns (uint);

    function numActiveMarkets() external view returns (uint);

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

    function numMaturedMarkets() external view returns (uint);

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

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

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

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

    function isDoubleChanceSupported() external view returns (bool);

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

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

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

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

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

    function expiryDuration() external view returns (uint);

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

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

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

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

    function setMarketPaused(address _market, bool _paused) external;

    function updateDatesForMarket(address _market, uint256 _newStartTime) external;

    function resolveMarket(address market, uint outcome) external;

    function expireMarkets(address[] calldata market) external;

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

    // view functions
    function supportedSport(uint _sportId) external view returns (bool);

    function gameOnADate(bytes32 _gameId) external view returns (uint);

    function isGameResolvedOrCanceled(bytes32 _gameId) external view returns (bool);

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

    function getGamesPerDatePerSport(uint _sportId, uint _date) external view returns (bytes32[] memory);

    function getGamePropsForOdds(address _market)
        external
        view
        returns (
            uint,
            uint,
            bytes32
        );

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

    function getGameCreatedById(bytes32 _gameId) external view returns (GameCreate memory);

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

    function gameFulfilledCreated(bytes32 _gameId) external view returns (bool);

    function playerProps() external view returns (address);

    function oddsObtainer() external view returns (address);

    // write functions
    function fulfillGamesCreated(
        bytes32 _requestId,
        bytes[] memory _games,
        uint _sportsId,
        uint _date
    ) external;

    function fulfillGamesResolved(
        bytes32 _requestId,
        bytes[] memory _games,
        uint _sportsId
    ) external;

    function fulfillGamesOdds(bytes32 _requestId, bytes[] memory _games) external;

    function setPausedByCanceledStatus(address _market, bool _flag) external;

    function setGameIdPerChildMarket(bytes32 _gameId, address _child) external;

    function pauseOrUnpauseMarket(address _market, bool _pause) external;

    function pauseOrUnpauseMarketForPlayerProps(
        address _market,
        bool _pause,
        bool _invalidOdds,
        bool _circuitBreakerMain
    ) external;

    function setChildMarkets(
        bytes32 _gameId,
        address _main,
        address _child,
        bool _isSpread,
        int16 _spreadHome,
        uint24 _totalOver
    ) external;

    function resolveMarketManually(
        address _market,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore,
        bool _usebackupOdds
    ) external;

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

    function sportsIdPerGame(bytes32 _gameId) external view returns (uint);

    function getGameStartTime(bytes32 _gameId) external view returns (uint256);

    function getLastUpdatedFromGameResolve(bytes32 _gameId) external view returns (uint40);

    function marketPerGameId(bytes32 _gameId) external view returns (address);

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

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

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

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

    function isSportOnADate(uint _date, uint _sportId) external view returns (bool);

    function isSportTwoPositionsSport(uint _sportsId) external view returns (bool);

    function marketForTeamName(string memory _teamName) external view returns (address);
}

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

pragma solidity ^0.8.0;

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

    // view

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // executable

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

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

    function setFirstNormalizedOdds(bytes32 _gameId, address _market) external;

    function setBackupOddsAsMainOddsForGame(bytes32 _gameId) external;

    function pauseUnpauseChildMarkets(address _main, bool _flag) external;

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    function getGameId() external view returns (bytes32);

    function deposited() external view returns (uint);

    function optionsCount() external view returns (uint);

    function creator() external view returns (address);

    function resolved() external view returns (bool);

    function cancelled() external view returns (bool);

    function paused() external view returns (bool);

    function phase() external view returns (Phase);

    function canResolve() external view returns (bool);

    function result() external view returns (Side);

    function isChild() external view returns (bool);

    function optionsInitialized() external view returns (bool);

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

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

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

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

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

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

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

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

    function isDoubleChance() external view returns (bool);

    function parentMarket() external view returns (ISportPositionalMarket);

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

    function setPaused(bool _paused) external;

    function updateDates(uint256 _maturity, uint256 _expiry) external;

    function mint(uint value) external;

    function exerciseOptions() external;

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

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

pragma solidity >=0.5.16;

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

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

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

    function capitalRequirement() external view returns (uint);

    function marketCreationEnabled() external view returns (bool);

    function onlyAMMMintingAndBurning() external view returns (bool);

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

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

    function totalDeposited() external view returns (uint);

    function numActiveMarkets() external view returns (uint);

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

    function numMaturedMarkets() external view returns (uint);

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

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

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

    function getThalesAMM() external view returns (address);

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

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

    function resolveMarket(address market) external;

    function expireMarkets(address[] calldata market) external;

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

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

pragma solidity >=0.5.16;

import "./IPositionalMarket.sol";

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

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

    function getTotalSupply() external view returns (uint);

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

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

pragma solidity >=0.5.16;

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

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

    function removeAggregator(bytes32 currencyKey) external;

    // Views

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

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

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

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

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

pragma solidity >=0.5.16;

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

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

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

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

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

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

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

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

    function deposited() external view returns (uint);

    function creator() external view returns (address);

    function resolved() external view returns (bool);

    function phase() external view returns (Phase);

    function oraclePrice() external view returns (uint);

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

    function canResolve() external view returns (bool);

    function result() external view returns (Side);

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

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

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

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

    function mint(uint value) external;

    function exerciseOptions() external returns (uint);

    function burnOptions(uint amount) external;

    function burnOptionsMaximum() external;
}

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

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"address","name":"_child","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"int16","name":"_spread","type":"int16"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"CreateChildSpreadSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"address","name":"_child","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"uint24","name":"_total","type":"uint24"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"CreateChildTotalSportsMarket","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"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"indexed":false,"internalType":"struct IGamesOddsObtainer.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":"_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_market","type":"address"},{"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"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"indexed":false,"internalType":"struct IGamesOddsObtainer.GameOdds","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedChildOdds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"GamedOddsAddedChild","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"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"indexed":false,"internalType":"struct IGamesOddsObtainer.GameOdds","name":"_game","type":"tuple"}],"name":"InvalidOddsForMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_consumer","type":"address"},{"indexed":false,"internalType":"address","name":"_verifier","type":"address"},{"indexed":false,"internalType":"address","name":"_sportsManager","type":"address"},{"indexed":false,"internalType":"address","name":"_receiver","type":"address"}],"name":"NewContractAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_waitTime","type":"uint256"}],"name":"NewWaitTime","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":"_child","type":"address"},{"indexed":false,"internalType":"uint256","name":"_outcome","type":"uint256"},{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"uint24","name":"_homeScore","type":"uint24"},{"indexed":false,"internalType":"uint24","name":"_awayScore","type":"uint24"}],"name":"ResolveChildMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"SupportedSportForTotalAndSpreadAdded","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":"TAG_NUMBER_SPREAD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TAG_NUMBER_TOTAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"bool","name":"_useBackup","type":"bool"},{"internalType":"bool","name":"_isTwoPositional","type":"bool"}],"name":"areOddsValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketMainMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketSread","outputs":[{"internalType":"int16","name":"","type":"int16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketTotal","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"consumer","outputs":[{"internalType":"contract ITherundownConsumer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"currentActiveSpreadChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"currentActiveTotalChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"doesSportSupportSpreadAndTotal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gameIdPerChildMarket","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"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_parent","type":"address"}],"name":"getActiveChildMarketsFromParent","outputs":[{"internalType":"address","name":"totalsMarket","type":"address"},{"internalType":"address","name":"spreadsMarket","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_parent","type":"address"}],"name":"getAllChildMarketsFromParent","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getLinesForGame","outputs":[{"internalType":"int16","name":"","type":"int16"},{"internalType":"int16","name":"","type":"int16"},{"internalType":"uint24","name":"","type":"uint24"},{"internalType":"uint24","name":"","type":"uint24"}],"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":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getOddsForGame","outputs":[{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_consumer","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"address","name":"_sportsManager","type":"address"},{"internalType":"uint256[]","name":"_supportedSportIds","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":"","type":"address"}],"name":"isSpreadChildMarket","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"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mainMarketChildMarketIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int16","name":"","type":"int16"}],"name":"mainMarketSpreadChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint24","name":"","type":"uint24"}],"name":"mainMarketTotalChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"normalizedOddsForMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"normalizedOddsForMarketFulfilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numberOfChildMarkets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","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"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"internalType":"struct IGamesOddsObtainer.GameOdds","name":"_game","type":"tuple"},{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"address","name":"_main","type":"address"},{"internalType":"bool","name":"_isTwoPositional","type":"bool"},{"internalType":"bool","name":"_playersReport","type":"bool"}],"name":"obtainOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"oddsLastPulledForGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oddsReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_main","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"pauseUnpauseChildMarkets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"address","name":"_main","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"pauseUnpauseCurrentActiveChildMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"playersReportTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_main","type":"address"},{"internalType":"uint256","name":"_outcome","type":"uint256"},{"internalType":"uint8","name":"_homeScore","type":"uint8"},{"internalType":"uint8","name":"_awayScore","type":"uint8"}],"name":"resolveChildMarkets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"setBackupOddsAsMainOddsForGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"address","name":"market","type":"address"}],"name":"setChildMarketGameId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_consumer","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"address","name":"_sportsManager","type":"address"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"setContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"address","name":"_market","type":"address"}],"name":"setFirstNormalizedOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"int24","name":"_homeOdds","type":"int24"},{"internalType":"int24","name":"_awayOdds","type":"int24"},{"internalType":"int24","name":"_drawOdds","type":"int24"}],"name":"setFirstOdds","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":"uint256","name":"_sportId","type":"uint256"},{"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"setSupportedSportForTotalAndSpread","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_waitTime","type":"uint256"}],"name":"setWaitTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sportsManager","outputs":[{"internalType":"contract ISportPositionalMarketManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"transferOwnershipAtInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract ITherundownConsumerVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"waitTimePlayersReport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b506157ab80620000216000396000f3fe608060405234801561001057600080fd5b50600436106103995760003560e01c806360b4df85116101e9578063b0275fa01161010f578063c480977c116100ad578063db0d45791161007c578063db0d457914610bec578063df351aaf14610bff578063e38f273814610c12578063fa043f4014610c2557600080fd5b8063c480977c14610b83578063cc5cea2714610b96578063ceda8e9014610ba9578063d28231bd14610bc957600080fd5b8063b4fd7296116100e9578063b4fd729614610b1c578063b613d8ee14610b34578063bf989b6e14610b5d578063c3b83f5f14610b7057600080fd5b8063b0275fa014610a52578063b09bd9e314610a72578063b103feb014610b0957600080fd5b806393f4452e116101875780639aceb36e116101565780639aceb36e146109fe578063a12695ca14610a1e578063a4f096e814610a41578063ae71dcdf14610a4a57600080fd5b806393f4452e1461089f57806393ff69d7146109a95780639971441b146109e25780639a196e33146109f557600080fd5b80638d220d99116101c35780638d220d99146107ea5780638da5cb5b1461082057806391b4ded914610839578063937a314f1461084257600080fd5b806360b4df85146107115780636c35b775146107b957806379ba5097146107e257600080fd5b80632da3f9ce116102ce578063447b1d581161026c578063574ef5d91161023b578063574ef5d9146106845780635a2f7731146106a75780635c975abb146106d05780635d134bc2146106dd57600080fd5b8063447b1d58146105fd5780634adf7219146106315780635034c5881461065157806353a47bb71461067157600080fd5b806332b566a9116102a857806332b566a91461052f578063366c16a5146105b157806336c0d855146105d15780633ea921ae146105f457600080fd5b80632da3f9ce1461050c5780632fff70201461051f578063300a02981461052757600080fd5b806316c38b3c1161033b5780631e864c3b116103155780631e864c3b1461049f578063263737e2146104b257806329bfb6cd146104e65780632b7ac3f3146104f957600080fd5b806316c38b3c146104625780631afed5cc146104755780631cededce1461048c57600080fd5b806310063fdc1161037757806310063fdc146103ee57806313af40351461041957806314bdaa891461042c5780631627540c1461044f57600080fd5b806301a5627e1461039e578063091c9b96146103b35780630caf0e0c146103db575b600080fd5b6103b16103ac36600461493e565b610c38565b005b6103c66103c1366004614b96565b610cda565b60405190151581526020015b60405180910390f35b6103b16103e9366004614b55565b610eda565b600554610401906001600160a01b031681565b6040516001600160a01b0390911681526020016103d2565b6103b16104273660046147c6565b611003565b6103c661043a3660046147c6565b60176020526000908152604090205460ff1681565b6103b161045d3660046147c6565b61113e565b6103b1610470366004614ae1565b611194565b61047e61232881565b6040519081526020016103d2565b6103b161049a366004614b31565b61120a565b601954610401906001600160a01b031681565b6104016104c03660046149aa565b600f6020908152600092835260408084209091529082529020546001600160a01b031681565b6103b16104f4366004614c03565b611249565b600454610401906001600160a01b031681565b6103b161051a366004614859565b611f47565b61047e600181565b61047e600281565b61057f61053d366004614b19565b6000908152600660205260409020600190810154600160481b8104820b92600160701b820490920b9162ffffff600160981b8304811692600160c81b90041690565b60408051600195860b81529390940b602084015262ffffff9182169383019390935290911660608201526080016103d2565b6105c46105bf3660046147c6565b6120d0565b6040516103d29190615158565b6103c66105df3660046147c6565b60086020526000908152604090205460ff1681565b61047e61271181565b61040161060b3660046149d5565b600c6020908152600092835260408084209091529082529020546001600160a01b031681565b61047e61063f3660046147c6565b600a6020526000908152604090205481565b61047e61065f366004614b19565b60096020526000908152604090205481565b600154610401906001600160a01b031681565b6103c6610692366004614b19565b600b6020526000908152604090205460ff1681565b6104016106b53660046147c6565b6014602052600090815260409020546001600160a01b031681565b6003546103c69060ff1681565b6104016106eb366004614976565b600e6020908152600092835260408084209091529082529020546001600160a01b031681565b61077661071f366004614b19565b600090815260066020526040902060010154600281810b9263010000008304820b92600160301b8104830b92600160581b8204810b92600160801b8304820b92600160b01b8104830b92600160e01b909104900b90565b60408051600298890b815296880b602088015294870b9486019490945291850b6060850152840b6080840152830b60a083015290910b60c082015260e0016103d2565b6104016107c73660046147c6565b6010602052600090815260409020546001600160a01b031681565b6103b16121dd565b61080d6107f83660046147c6565b60116020526000908152604090205460010b81565b60405160019190910b81526020016103d2565b600054610401906201000090046001600160a01b031681565b61047e60025481565b61087f6108503660046147c6565b6001600160a01b0390811660009081526013602090815260408083205460149092529091205490821692911690565b604080516001600160a01b039384168152929091166020830152016103d2565b6109366108ad366004614b19565b600660205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b604080519c8d5260029b8c0b60208e0152998b0b998c019990995296890b60608b0152600195860b60808b015293880b60a08a01529190930b60c088015291850b60e087015262ffffff918216610100870152840b61012086015216610140840152900b610160820152610180016103d2565b6109ce6109b73660046147c6565b60126020526000908152604090205462ffffff1681565b60405162ffffff90911681526020016103d2565b6103b16109f0366004614b19565b6122da565b61047e601b5481565b610a11610a0c366004614b19565b612567565b6040516103d291906151dd565b6103c6610a2c3660046147c6565b60156020526000908152604090205460ff1681565b61047e61271281565b61047e600081565b61047e610a603660046147c6565b601a6020526000908152604090205481565b610936610a80366004614b19565b600760205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b61047e610b173660046149d5565b612578565b6003546104019061010090046001600160a01b031681565b610401610b423660046147c6565b6013602052600090815260409020546001600160a01b031681565b6103b1610b6b3660046147fe565b6125a9565b6103b1610b7e3660046147c6565b61265b565b6103b1610b91366004614bbc565b612774565b6103b1610ba4366004614e34565b612a12565b61047e610bb73660046147c6565b600d6020526000908152604090205481565b6103c6610bd73660046147c6565b60166020526000908152604090205460ff1681565b610a11610bfa3660046147c6565b612a6c565b6103b1610c0d366004614b19565b612a77565b6103b1610c20366004614b31565b612ab4565b6103b1610c33366004614a00565b612b65565b60035461010090046001600160a01b03163314610c705760405162461bcd60e51b8152600401610c679061543e565b60405180910390fd5b60005b6001600160a01b0383166000908152600d6020526040902054811015610cd5576001600160a01b038084166000908152600c60209081526040808320858452909152902054610cc3911683612caf565b80610ccd816156d2565b915050610c73565b505050565b600082610ddc5760008481526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610dd79083612cef565b610ed2565b60008481526007602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610ed29083612cef565b949350505050565b60035461010090046001600160a01b03163314610f095760405162461bcd60e51b8152600401610c679061543e565b60008381526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b820b60c0820152600160801b8404830b830b830b60e082015262ffffff600160981b85048116610100830152600160b01b8504840b840b840b610120830152600160c81b850416610140820152600160e01b909304820b820b90910b610160830152610cd5919084908490612da0565b6001600160a01b0381166110595760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610c67565b600154600160a01b900460ff16156110c55760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610c67565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b611146612f5c565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001611133565b61119c612f5c565b60035460ff16151581151514156111b05750565b6003805460ff191682151590811790915560ff16156111ce57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001611133565b50565b60035461010090046001600160a01b031633146112395760405162461bcd60e51b8152600401610c679061543e565b61124581836001612fd6565b5050565b60035461010090046001600160a01b031633148061127157506019546001600160a01b031633145b6112ae5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610c67565b6005546040516333dfec9960e21b81526001600160a01b038581166004830152600092169063cf7fb2649060240160206040518083038186803b1580156112f457600080fd5b505afa158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132c9190614afd565b90506113388684612cef565b15611e9a57600061134c8760000151613046565b90506000600660008960000151815260200190815260200160002060405180610180016040529081600082015481526020016001820160009054906101000a900460020b60020b60020b81526020016001820160039054906101000a900460020b60020b60020b81526020016001820160069054906101000a900460020b60020b60020b81526020016001820160099054906101000a900460010b60010b60010b815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a900460010b60010b60010b81526020016001820160109054906101000a900460020b60020b60020b81526020016001820160139054906101000a900462ffffff1662ffffff1662ffffff1681526020016001820160169054906101000a900460020b60020b60020b81526020016001820160199054906101000a900462ffffff1662ffffff1662ffffff16815260200160018201601c9054906101000a900460020b60020b60020b81525050905087600660008a6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008a600001518152602001908152602001600020819055506116cd8689600001516001612fd6565b6000878152600b602052604090205460ff168061170157506001600160a01b0386166000908152600d602052604090205415155b156117105761171088876130ee565b600480546001600160a01b03888116600090815260186020526040808220905163217d323560e11b8152919492909316926342fa646a92611759928d92899290918d9101615465565b60206040518083038186803b15801561177157600080fd5b505afa158015611785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a99190614afd565b90508315611be6576001600160a01b03871660009081526008602052604090205460ff16806118565750600354604051630a928f9f60e21b81526001600160a01b03898116600483015261010090920490911690632a4a3e7c9060240160206040518083038186803b15801561181e57600080fd5b505afa158015611832573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118569190614afd565b15611b9457600354604051630259f5fd60e01b81526001600160a01b0389811660048301526000602483015261010090920490911690630259f5fd90604401600060405180830381600087803b1580156118af57600080fd5b505af11580156118c3573d6000803e3d6000fd5b5050505080611b3857600060086000896001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff02191690831515021790555081600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff160217905550905050611aee8988600180612da0565b8851604080516001600160a01b038a16815260208101929092527fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a910160405180910390a1611e3c565b6001600160a01b0387166000908152601a602052604090205415801590611b825750601b546001600160a01b0388166000908152601a6020526040902054611b80904261568f565b105b15611b9957611b948988600180612da0565b611e3c565b6001600160a01b0387166000908152600860205260408120805460ff19169055611bc8908a9089906001612da0565b6001600160a01b0387166000908152601a6020526040812055611e3c565b83158015611bf2575080155b15611e3c57611c048988600180612da0565b611c1387600160006001613201565b81600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff1602179055509050507fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a878a60000151604051611e339291906001600160a01b03929092168252602082015260400190565b60405180910390a15b88516001600160a01b0388166000908152601860205260409081902090517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe92611e8a928e928e919061526f565b60405180910390a1505050611f3e565b80611eff576001600160a01b0384166000908152600860205260409020805460ff191660011790558115611ee4576001600160a01b0384166000908152601a602052604090204290555b611ef18685600180612da0565b611eff846001806000613201565b85516040517f420dbf4677c8331a5938fcc5890c5ae453dd3344f80f9a669d6adb2fea7de3d091611f35918a9188918b906151f0565b60405180910390a15b50505050505050565b600054610100900460ff16611f625760005460ff1615611f66565b303b155b611fc95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c67565b600054610100900460ff16158015611feb576000805461ffff19166101011790555b611ff486611003565b600380546001600160a01b0380881661010002610100600160a81b031990921691909117909155600480548683166001600160a01b031991821617909155600580549286169290911691909117905560005b82518110156120b5576001600b600085848151811061207557634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff02191690831515021790555080806120ad906156d2565b915050612046565b5080156120c8576000805461ff00191690555b505050505050565b6001600160a01b0381166000908152600d60205260408120546060919067ffffffffffffffff81111561211357634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561213c578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600d60205260409020548110156121d6576001600160a01b038085166000908152600c6020908152604080832085845290915290205483519116908390839081106121ac57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0390921660209283029190910190910152806121ce816156d2565b915050612142565b5092915050565b6001546001600160a01b031633146122555760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610c67565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60035461010090046001600160a01b031633146123095760405162461bcd60e51b8152600401610c679061543e565b60008181526007602090815260408083206006909252822081548155600191820180549183018054600293840b840b62ffffff90811662ffffff198316811784558454630100000090819004870b870b83160265ffffffffffff1990931617919091178083558354600160301b90819004860b860b83160268ffffff000000000000198216811784558454600160481b90819004880b880b61ffff9081169091026affff000000000000000000199092166affffffffff0000000000001990931692909217178084558454600160581b90819004870b870b84160262ffffff60581b198216811785558554600160701b90819004890b90980b90921690960261ffff60701b1990911664ffffffffff60581b1990961695909517949094178082558254600160801b90819004850b850b86160262ffffff60801b198216811783558354600160981b9081900487160262ffffff60981b1990911665ffffffffffff60801b1990921691909117178082558254600160b01b90819004850b850b86160262ffffff60b01b198216811783558354600160c81b9081900487160262ffffff60c81b1990911665ffffffffffff60b01b1990921691909117178082559154600160e01b90819004840b90930b90931690910262ffffff60e01b199091161790556124f582613284565b905061250381836001612fd6565b60008281526006602090815260408083206001600160a01b038516845260189092529182902091517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe9261255b9286928392906152a8565b60405180910390a15050565b606061257282613046565b92915050565b6018602052816000526040600020818154811061259457600080fd5b90600052602060002001600091509150505481565b6125b1612f5c565b60038054610100600160a81b0319166101006001600160a01b0387811691820292909217909255600480546001600160a01b0319908116878416908117909255600580548216878516908117909155601980549092169386169384179091556040805194855260208501929092529083015260608201527fa2cad6ae2699ea86ba233a96ca0e57d895983eeed04f6bd0a770187c58b820dd9060800160405180910390a150505050565b612663612f5c565b6001600160a01b0381166126ab5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610c67565b600154600160a81b900460ff16156126fb5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610c67565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101611133565b60035461010090046001600160a01b031633146127a35760405162461bcd60e51b8152600401610c679061543e565b6040518061018001604052808581526020018460020b81526020018360020b81526020018260020b8152602001600060010b8152602001600060020b8152602001600060010b8152602001600060020b8152602001600062ffffff168152602001600060020b8152602001600062ffffff168152602001600060020b815250600660008681526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008681526020019081526020016000208190555050505050565b612a1a612f5c565b6000828152600b6020908152604091829020805460ff19168415159081179091558251858152918201527f388428bda48903bbd0180b2e70447674064e582855a643dd2df349c85b0683f6910161255b565b606061257282613306565b612a7f612f5c565b601b8190556040518181527fcf94ac0e8dccd8a891f16d217c94137033687f7fcffbfa4cfc4e16d85a52320790602001611133565b6005546001600160a01b03163314612afd5760405162461bcd60e51b815260206004820152600c60248201526b27b7363c9036b0b730b3b2b960a11b6044820152606401610c67565b600354604051624dc46d60e41b8152600481018490526001600160a01b038381166024830152610100909204909116906304dc46d0906044015b600060405180830381600087803b158015612b5157600080fd5b505af11580156120c8573d6000803e3d6000fd5b60035461010090046001600160a01b03163314612b945760405162461bcd60e51b8152600401610c679061543e565b60005b6001600160a01b0385166000908152600d6020526040902054811015612ca8576001600160a01b038086166000908152600c602090815260408083208584529091529020541684612c4d5760055460405163b91f5e3560e01b81526001600160a01b038381166004830152602482018890529091169063b91f5e3590604401600060405180830381600087803b158015612c3057600080fd5b505af1158015612c44573d6000803e3d6000fd5b50505050612c95565b6001600160a01b03811660009081526015602052604090205460ff1615612c8457612c7f818560ff168560ff166133a0565b612c95565b612c95818560ff168560ff166134e2565b5080612ca0816156d2565b915050612b97565b5050505050565b60035460405163ed5e00eb60e01b81526001600160a01b03848116600483015283151560248301526101009092049091169063ed5e00eb90604401612b37565b60048054602084015160408086015160608701519151631578f73160e31b815286151595810195909552600292830b6024860152820b6044850152900b60648301526000916001600160a01b039091169063abc7b9889060840160206040518083038186803b158015612d6157600080fd5b505afa158015612d75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d999190614afd565b9392505050565b8015612db057612db08383612caf565b6001600160a01b0383166000908152600d602052604090205415612f56578115612e3f5760005b6001600160a01b0384166000908152600d6020526040902054811015612e39576001600160a01b038085166000908152600c60209081526040808320858452909152902054612e27911684612caf565b80612e31816156d2565b915050612dd7565b50612f56565b612e4884613622565b15612ecb576001600160a01b038084166000908152600f6020908152604080832061010089015162ffffff1684529091529020541680612eb3576000612e9f866000015186600089608001518a61010001516136d9565b9050612ead858260006139cf565b50612ec9565b612ebd8184612caf565b612ec9848260006139cf565b505b612ed484613a33565b15612f56576001600160a01b038084166000908152600e602090815260408083206080890151600190810b900b84529091529020541680612f40576000612f2c866000015186600189608001518a61010001516136d9565b9050612f3a858260016139cf565b50612ca8565b612f4a8184612caf565b612ca8848260016139cf565b50505050565b6000546201000090046001600160a01b03163314612fd45760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610c67565b565b80612fe957612fe483613a98565b612ff2565b612ff282613c78565b6001600160a01b0384166000908152601860209081526040909120825161301f939192919091019061469d565b5050506001600160a01b03166000908152601760205260409020805460ff19166001179055565b6060600061305383613284565b6001600160a01b03811660009081526017602052604090205490915060ff166130845761307f83613c78565b612d99565b6001600160a01b038116600090815260186020908152604091829020805483518184028101840190945280845290918301828280156130e257602002820191906000526020600020905b8154815260200190600101908083116130ce575b50505050509392505050565b6130f782613622565b156131735761310882826000613e0d565b81516001600160a01b038083166000908152601360205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c9291168461315282613306565b612712604051613166959493929190615224565b60405180910390a161317e565b61317e826000613fb6565b61318782613a33565b156131f65761319882826001613e0d565b81516001600160a01b038083166000908152601460205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c929116846131e282613306565b61271160405161255b959493929190615224565b611245826001613fb6565b6003546040516302830aeb60e41b81526001600160a01b03868116600483015285151560248301528415156044830152831515606483015261010090920490911690632830aeb090608401600060405180830381600087803b15801561326657600080fd5b505af115801561327a573d6000803e3d6000fd5b5050505050505050565b600354604051631f138de360e31b81526004810183905260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b1580156132ce57600080fd5b505afa1580156132e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257291906147e2565b6001600160a01b03811660009081526017602052604090205460609060ff166133375761333282613a98565b612572565b6001600160a01b0382166000908152601860209081526040918290208054835181840281018401909452808452909183018282801561339557602002820191906000526020600020905b815481526020019060010190808311613381575b505050505092915050565b6001600160a01b03831660009081526011602052604081205460010b6133c78460646155dd565b6133d19190615546565b905060006133e08360646155dd565b905060008160010b8360010b1361340c578160010b8360010b1261340557600061340f565b600261340f565b60015b60055460405163b91f5e3560e01b81526001600160a01b0389811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b15801561345f57600080fd5b505af1158015613473573d6000803e3d6000fd5b5050506001600160a01b03808816600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b693506134d2928a92869291169061ffff808c1691908b1690615120565b60405180910390a1505050505050565b6001600160a01b03831660009081526012602052604081205462ffffff16908161350c848661558a565b613517906064615664565b62ffffff16116135545762ffffff8216613531848661558a565b61353c906064615664565b62ffffff161061354d576000613557565b6002613557565b60015b60055460405163b91f5e3560e01b81526001600160a01b0388811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b1580156135a757600080fd5b505af11580156135bb573d6000803e3d6000fd5b5050506001600160a01b03808716600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b69350613613928992869291169089908990615120565b60405180910390a15050505050565b60048054610100830151610120840151610140850151610160860151604051634e3a53b760e11b815262ffffff94851696810196909652600292830b6024870152921660448501520b60648301526000916001600160a01b0390911690639c74a76e906084015b60206040518083038186803b1580156136a157600080fd5b505afa1580156136b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125729190614afd565b600354604051631c2ab73160e21b81526004810187905260009182916137679161010090046001600160a01b0316906370aadcc49060240160206040518083038186803b15801561372957600080fd5b505afa15801561373d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137619190614e1c565b86614069565b6005549091506001600160a01b0316634cde32ce886137888189898961410b565b60035460405163c48e62f160e01b8152600481018d90526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b1580156137d057600080fd5b505afa1580156137e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261380c9190810190614d49565b60200151600060028760018e6040518963ffffffff1660e01b815260040161383b9897969594939291906153b9565b602060405180830381600087803b15801561385557600080fd5b505af1158015613869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061388d91906147e2565b5060055460408051622610c560e41b815290516001600160a01b039092169163dd5adfa39160019184916302610c50916004808301926020929190829003018186803b1580156138dc57600080fd5b505afa1580156138f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139149190614e1c565b61391e919061568f565b6040518263ffffffff1660e01b815260040161393c91815260200190565b60206040518083038186803b15801561395457600080fd5b505afa158015613968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061398c91906147e2565b91506139c5878784888888876001815181106139b857634e487b7160e01b600052603260045260246000fd5b602002602001015161429b565b5095945050505050565b8015613a0457506001600160a01b03918216600090815260146020526040902080546001600160a01b03191691909216179055565b506001600160a01b03918216600090815260136020526040902080546001600160a01b03191691909216179055565b60048054608083015160a084015160c085015160e0860151604051630df2ba2560e41b8152600194850b96810196909652600292830b6024870152920b60448501520b60648301526000916001600160a01b039091169063df2ba25090608401613689565b6001600160a01b0381166000908152600a602052604080822054815160028082526060828101909452929391928160200160208202803683375050506001600160a01b03851660009081526015602052604090205490915060ff16613b1857600082815260066020526040902060010154600160b01b900460020b613b35565b600082815260066020526040902060010154600160581b900460020b5b60020b81600081518110613b5957634e487b7160e01b600052603260045260246000fd5b6020908102919091018101919091526001600160a01b03851660009081526015909152604090205460ff16613ba957600082815260066020526040902060010154600160e01b900460020b613bc6565b600082815260066020526040902060010154600160801b900460020b5b60020b81600181518110613bea57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d97491613c24918591016151a5565b60006040518083038186803b158015613c3c57600080fd5b505afa158015613c50573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed29190810190614a4e565b60408051600380825260808201909252606091600091906020820184803683375050506000848152600660205260408120600101548251929350600290810b900b91839190613cd757634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160039054906101000a900460020b60020b81600181518110613d2b57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160069054906101000a900460020b60020b81600281518110613d7f57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d97491613db9918591016151a5565b60006040518083038186803b158015613dd157600080fd5b505afa158015613de5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d999190810190614a4e565b6001600160a01b0382166000908152600d6020526040812054159082613e4d576001600160a01b0380851660009081526013602052604090205416613e69565b6001600160a01b03808516600090815260146020526040902054165b9050600083613ea7576001600160a01b038086166000908152600f602090815260408083206101008b015162ffffff16845290915290205416613ed9565b6001600160a01b038086166000908152600e6020908152604080832060808b0151600190810b900b8452909152902054165b90508280613eee57506001600160a01b038116155b15613f4c576000613f0f876000015187878a608001518b61010001516136d9565b9050613f1c8682876139cf565b6001600160a01b03831615613f3657613f36836001612caf565b613f468188600001516000612fd6565b506120c8565b816001600160a01b0316816001600160a01b031614613f9b57613f70816000612caf565b613f7b826001612caf565b613f868582866139cf565b613f968187600001516000612fd6565b6120c8565b613fa6826000612caf565b6120c88287600001516000612fd6565b6000613fc58360000151613284565b6001600160a01b0381166000908152600d602052604090205490915015610cd55760005b6001600160a01b0382166000908152600d6020526040902054811015612f56576001600160a01b038083166000908152600c6020908152604080832085845282528083205490931680835260159091529190205460ff161515841515141561405657614056816001612caf565b5080614061816156d2565b915050613fe9565b6040805160028082526060808301845292600092919060208301908036833701905050905061409a846123286155b1565b816000815181106140bb57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050826140d4576127126140d8565b6127115b816001815181106140f957634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b60035460405163c48e62f160e01b8152600481018690526060916000916101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b15801561415957600080fd5b505afa15801561416d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526141959190810190614d49565b60a0015160035460405163c48e62f160e01b8152600481018990526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b1580156141e157600080fd5b505afa1580156141f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261421d9190810190614d49565b60c0015160405160200161423292919061502a565b6040516020818303038152906040529050841561427b578061425385614531565b604051602001614264929190614fa2565b604051602081830303815290604052915050610ed2565b8061428a8462ffffff16614583565b604051602001614264929190614fec565b600354604051624dc46d60e41b8152600481018990526001600160a01b038781166024830152610100909204909116906304dc46d090604401600060405180830381600087803b1580156142ee57600080fd5b505af1158015614302573d6000803e3d6000fd5b5050506001600160a01b038087166000818152600a602090815260408083208d905560168252808320805460ff19166001908117909155601083528184208054968e166001600160a01b03199788168117909155808552600c8452828520600d80865284872080548852918652938620805490981690961790965594909252525461438e9250906155b1565b6001600160a01b0387166000908152600d60205260409020558315614485576001600160a01b038681166000818152600e60209081526040808320600189810b80820b865291845282852080546001600160a01b0319908116988e1698891790915587865260118552838620805461ffff191661ffff90941693909317909255948452601483528184208054909116861790559382526015905291909120805460ff191690911790557f41525405a5e10a7f61a75ce8fb247811dadc00a10ad9bd82d09ddab453a686d38686898661446583613306565b8660405161447896959493929190615092565b60405180910390a1611f3e565b6001600160a01b038087166000818152600f6020908152604080832062ffffff88168085529083528184208054968c166001600160a01b0319978816811790915580855260128452828520805462ffffff19169092179091559383526013909152902080549092161790557f2fb9c2a6ac1646a705c03b0657053182a32ea93c368b719a84e352ab42dcb8f88686898561451e83613306565b86604051611f35969594939291906150e2565b606060008260010b1361457a5761455661454d836000196155dd565b61ffff16614583565b6040516020016145669190615069565b604051602081830303815290604052612572565b6125728261ffff165b6060816145a75750506040805180820190915260018152600360fc1b602082015290565b8160005b81156145d157806145bb816156d2565b91506145ca9050600a836155c9565b91506145ab565b60008167ffffffffffffffff8111156145fa57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614624576020820181803683370190505b5090505b8415610ed25761463960018361568f565b9150614646600a866156ed565b6146519060306155b1565b60f81b81838151811061467457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350614696600a866155c9565b9450614628565b8280548282559060005260206000209081019282156146d8579160200282015b828111156146d85782518255916020019190600101906146bd565b506146e49291506146e8565b5090565b5b808211156146e457600081556001016146e9565b803561470881615743565b919050565b803561470881615758565b8035600181900b811461470857600080fd5b803561470881615766565b805161470881615766565b600082601f830112614750578081fd5b815167ffffffffffffffff81111561476a5761476a61572d565b61477d601f8201601f19166020016154f1565b818152846020838601011115614791578283fd5b610ed28260208301602087016156a6565b803562ffffff8116811461470857600080fd5b803560ff8116811461470857600080fd5b6000602082840312156147d7578081fd5b8135612d9981615743565b6000602082840312156147f3578081fd5b8151612d9981615743565b60008060008060808587031215614813578283fd5b843561481e81615743565b9350602085013561482e81615743565b9250604085013561483e81615743565b9150606085013561484e81615743565b939692955090935050565b600080600080600060a08688031215614870578283fd5b853561487b81615743565b945060208681013561488c81615743565b9450604087013561489c81615743565b935060608701356148ac81615743565b9250608087013567ffffffffffffffff8111156148c7578283fd5b8701601f810189136148d7578283fd5b80356148ea6148e582615522565b6154f1565b8082825284820191508484018c868560051b8701011115614909578687fd5b8694505b8385101561492b57803583526001949094019391850191850161490d565b5080955050505050509295509295909350565b60008060408385031215614950578182fd5b823561495b81615743565b9150602083013561496b81615758565b809150509250929050565b60008060408385031215614988578182fd5b823561499381615743565b91506149a160208401614718565b90509250929050565b600080604083850312156149bc578182fd5b82356149c781615743565b91506149a1602084016147a2565b600080604083850312156149e7578182fd5b82356149f281615743565b946020939093013593505050565b60008060008060808587031215614a15578182fd5b8435614a2081615743565b935060208501359250614a35604086016147b5565b9150614a43606086016147b5565b905092959194509250565b60006020808385031215614a60578182fd5b825167ffffffffffffffff811115614a76578283fd5b8301601f81018513614a86578283fd5b8051614a946148e582615522565b80828252848201915084840188868560051b8701011115614ab3578687fd5b8694505b83851015614ad5578051835260019490940193918501918501614ab7565b50979650505050505050565b600060208284031215614af2578081fd5b8135612d9981615758565b600060208284031215614b0e578081fd5b8151612d9981615758565b600060208284031215614b2a578081fd5b5035919050565b60008060408385031215614b43578182fd5b82359150602083013561496b81615743565b600080600060608486031215614b69578081fd5b833592506020840135614b7b81615743565b91506040840135614b8b81615758565b809150509250925092565b600080600060608486031215614baa578081fd5b833592506020840135614b7b81615758565b60008060008060808587031215614bd1578182fd5b843593506020850135614be381615766565b92506040850135614bf381615766565b9150606085013561484e81615766565b600080600080600080868803610220811215614c1d578485fd5b8735965061018080601f1983011215614c34578586fd5b614c3c6154a4565b915060208901358252614c5160408a0161472a565b6020830152614c6260608a0161472a565b6040830152614c7360808a0161472a565b6060830152614c8460a08a01614718565b6080830152614c9560c08a0161472a565b60a0830152614ca660e08a01614718565b60c0830152610100614cb9818b0161472a565b60e0840152610120614ccc818c016147a2565b828501526101409150614ce0828c0161472a565b90840152610160614cf28b82016147a2565b82850152614d01838c0161472a565b9084015250909550506101a08701359350614d1f6101c088016146fd565b9250614d2e6101e0880161470d565b9150614d3d610200880161470d565b90509295509295509295565b600060208284031215614d5a578081fd5b815167ffffffffffffffff80821115614d71578283fd5b9083019060e08286031215614d84578283fd5b614d8c6154ce565b8251815260208301516020820152614da660408401614735565b6040820152614db760608401614735565b6060820152614dc860808401614735565b608082015260a083015182811115614dde578485fd5b614dea87828601614740565b60a08301525060c083015182811115614e01578485fd5b614e0d87828601614740565b60c08301525095945050505050565b600060208284031215614e2d578081fd5b5051919050565b60008060408385031215614e46578182fd5b82359150602083013561496b81615758565b6000815180845260208085019450808401835b83811015614e8757815187529582019590820190600101614e6b565b509495945050505050565b6000815480845260208085019450838352808320835b83811015614e8757815487529582019560019182019101614ea8565b805182526020810151614edc602084018260020b9052565b506040810151614ef1604084018260020b9052565b506060810151614f06606084018260020b9052565b506080810151614f1b608084018260010b9052565b5060a0810151614f3060a084018260020b9052565b5060c0810151614f4560c084018260010b9052565b5060e0810151614f5a60e084018260020b9052565b506101008181015162ffffff169083015261012080820151600281900b8285015250506101408181015162ffffff169083015261016080820151600281900b82850152612f56565b60008351614fb48184602088016156a6565b600560fb1b9083019081528351614fd28160018401602088016156a6565b602960f81b60019290910191820152600201949350505050565b60008351614ffe8184602088016156a6565b6201016960ed1b908301908152835161501e8160038401602088016156a6565b01600301949350505050565b6000835161503c8184602088016156a6565b630103b39960e51b908301908152835161505d8160048401602088016156a6565b01600401949350505050565b602d60f81b8152600082516150858160018501602087016156a6565b9190910160010192915050565b6001600160a01b0387811682528616602082015260408101859052600184900b606082015260c0608082018190526000906150cf90830185614e58565b90508260a0830152979650505050505050565b6001600160a01b038781168252861660208201526040810185905262ffffff8416606082015260c0608082018190526000906150cf90830185614e58565b6001600160a01b039586168152602081019490945291909316604083015262ffffff9283166060830152909116608082015260a00190565b6020808252825182820181905260009190848201906040850190845b818110156151995783516001600160a01b031683529284019291840191600101615174565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015615199578351835292840192918401916001016151c1565b602081526000612d996020830184614e58565b8481526001600160a01b0384166020820152604081018390526101e0810161521b6060830184614ec4565b95945050505050565b8581526001600160a01b038516602082015260006102006152486040840187614ec4565b806101c084015261525b81840186614e58565b915050826101e08301529695505050505050565b60006101e086835285602084015261528a6040840186614ec4565b806101c084015261529d81840185614e92565b979650505050505050565b60006101e086835285602084015284546040840152600185015460026152d56060860183830b60020b9052565b6152e9608086018360181c830b60020b9052565b6152fd60a086018360301c830b60020b9052565b61531260c086018360481c60010b60010b9052565b61532660e086018360581c830b60020b9052565b61533c61010086018360701c60010b60010b9052565b61535161012086018360801c830b60020b9052565b62ffffff609883901c811661014087015261537761016087018460b01c840b60020b9052565b61538e6101808701828560c81c1662ffffff169052565b506153a46101a086018360e01c830b60020b9052565b5050806101c084015261529d81840185614e92565b60006101008a83528060208401528951808285015261012091506153e38183860160208e016156a6565b604084018a90526060840189905260808401889052601f01601f19168301838103820160a085015261541782820188614e58565b95151560c08501525050506001600160a01b039190911660e0909101529695505050505050565b6020808252600d908201526c27b7363c9031b7b739bab6b2b960991b604082015260600190565b84815260806020820152600061547e6080830186614e58565b82810360408401526154908186614e92565b915050821515606083015295945050505050565b604051610180810167ffffffffffffffff811182821017156154c8576154c861572d565b60405290565b60405160e0810167ffffffffffffffff811182821017156154c8576154c861572d565b604051601f8201601f1916810167ffffffffffffffff8111828210171561551a5761551a61572d565b604052919050565b600067ffffffffffffffff82111561553c5761553c61572d565b5060051b60200190565b60008160010b8360010b82821282617fff0382138115161561556a5761556a615701565b82617fff1903821281161561558157615581615701565b50019392505050565b600062ffffff8083168185168083038211156155a8576155a8615701565b01949350505050565b600082198211156155c4576155c4615701565b500190565b6000826155d8576155d8615717565b500490565b60008160010b8360010b617fff8382138484138383048511828216161561560657615606615701565b617fff198685128281168783058712161561562357615623615701565b87871292508582058712848416161561563e5761563e615701565b8585058712818416161561565457615654615701565b5050509290910295945050505050565b600062ffffff8083168185168183048111821515161561568657615686615701565b02949350505050565b6000828210156156a1576156a1615701565b500390565b60005b838110156156c15781810151838201526020016156a9565b83811115612f565750506000910152565b60006000198214156156e6576156e6615701565b5060010190565b6000826156fc576156fc615717565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461120757600080fd5b801515811461120757600080fd5b8060020b811461120757600080fdfea2646970667358221220e81c52a8caf81f76b3e96a9dc9dce00f9672ccaa01e6eeff17b7370259427a2364736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103995760003560e01c806360b4df85116101e9578063b0275fa01161010f578063c480977c116100ad578063db0d45791161007c578063db0d457914610bec578063df351aaf14610bff578063e38f273814610c12578063fa043f4014610c2557600080fd5b8063c480977c14610b83578063cc5cea2714610b96578063ceda8e9014610ba9578063d28231bd14610bc957600080fd5b8063b4fd7296116100e9578063b4fd729614610b1c578063b613d8ee14610b34578063bf989b6e14610b5d578063c3b83f5f14610b7057600080fd5b8063b0275fa014610a52578063b09bd9e314610a72578063b103feb014610b0957600080fd5b806393f4452e116101875780639aceb36e116101565780639aceb36e146109fe578063a12695ca14610a1e578063a4f096e814610a41578063ae71dcdf14610a4a57600080fd5b806393f4452e1461089f57806393ff69d7146109a95780639971441b146109e25780639a196e33146109f557600080fd5b80638d220d99116101c35780638d220d99146107ea5780638da5cb5b1461082057806391b4ded914610839578063937a314f1461084257600080fd5b806360b4df85146107115780636c35b775146107b957806379ba5097146107e257600080fd5b80632da3f9ce116102ce578063447b1d581161026c578063574ef5d91161023b578063574ef5d9146106845780635a2f7731146106a75780635c975abb146106d05780635d134bc2146106dd57600080fd5b8063447b1d58146105fd5780634adf7219146106315780635034c5881461065157806353a47bb71461067157600080fd5b806332b566a9116102a857806332b566a91461052f578063366c16a5146105b157806336c0d855146105d15780633ea921ae146105f457600080fd5b80632da3f9ce1461050c5780632fff70201461051f578063300a02981461052757600080fd5b806316c38b3c1161033b5780631e864c3b116103155780631e864c3b1461049f578063263737e2146104b257806329bfb6cd146104e65780632b7ac3f3146104f957600080fd5b806316c38b3c146104625780631afed5cc146104755780631cededce1461048c57600080fd5b806310063fdc1161037757806310063fdc146103ee57806313af40351461041957806314bdaa891461042c5780631627540c1461044f57600080fd5b806301a5627e1461039e578063091c9b96146103b35780630caf0e0c146103db575b600080fd5b6103b16103ac36600461493e565b610c38565b005b6103c66103c1366004614b96565b610cda565b60405190151581526020015b60405180910390f35b6103b16103e9366004614b55565b610eda565b600554610401906001600160a01b031681565b6040516001600160a01b0390911681526020016103d2565b6103b16104273660046147c6565b611003565b6103c661043a3660046147c6565b60176020526000908152604090205460ff1681565b6103b161045d3660046147c6565b61113e565b6103b1610470366004614ae1565b611194565b61047e61232881565b6040519081526020016103d2565b6103b161049a366004614b31565b61120a565b601954610401906001600160a01b031681565b6104016104c03660046149aa565b600f6020908152600092835260408084209091529082529020546001600160a01b031681565b6103b16104f4366004614c03565b611249565b600454610401906001600160a01b031681565b6103b161051a366004614859565b611f47565b61047e600181565b61047e600281565b61057f61053d366004614b19565b6000908152600660205260409020600190810154600160481b8104820b92600160701b820490920b9162ffffff600160981b8304811692600160c81b90041690565b60408051600195860b81529390940b602084015262ffffff9182169383019390935290911660608201526080016103d2565b6105c46105bf3660046147c6565b6120d0565b6040516103d29190615158565b6103c66105df3660046147c6565b60086020526000908152604090205460ff1681565b61047e61271181565b61040161060b3660046149d5565b600c6020908152600092835260408084209091529082529020546001600160a01b031681565b61047e61063f3660046147c6565b600a6020526000908152604090205481565b61047e61065f366004614b19565b60096020526000908152604090205481565b600154610401906001600160a01b031681565b6103c6610692366004614b19565b600b6020526000908152604090205460ff1681565b6104016106b53660046147c6565b6014602052600090815260409020546001600160a01b031681565b6003546103c69060ff1681565b6104016106eb366004614976565b600e6020908152600092835260408084209091529082529020546001600160a01b031681565b61077661071f366004614b19565b600090815260066020526040902060010154600281810b9263010000008304820b92600160301b8104830b92600160581b8204810b92600160801b8304820b92600160b01b8104830b92600160e01b909104900b90565b60408051600298890b815296880b602088015294870b9486019490945291850b6060850152840b6080840152830b60a083015290910b60c082015260e0016103d2565b6104016107c73660046147c6565b6010602052600090815260409020546001600160a01b031681565b6103b16121dd565b61080d6107f83660046147c6565b60116020526000908152604090205460010b81565b60405160019190910b81526020016103d2565b600054610401906201000090046001600160a01b031681565b61047e60025481565b61087f6108503660046147c6565b6001600160a01b0390811660009081526013602090815260408083205460149092529091205490821692911690565b604080516001600160a01b039384168152929091166020830152016103d2565b6109366108ad366004614b19565b600660205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b604080519c8d5260029b8c0b60208e0152998b0b998c019990995296890b60608b0152600195860b60808b015293880b60a08a01529190930b60c088015291850b60e087015262ffffff918216610100870152840b61012086015216610140840152900b610160820152610180016103d2565b6109ce6109b73660046147c6565b60126020526000908152604090205462ffffff1681565b60405162ffffff90911681526020016103d2565b6103b16109f0366004614b19565b6122da565b61047e601b5481565b610a11610a0c366004614b19565b612567565b6040516103d291906151dd565b6103c6610a2c3660046147c6565b60156020526000908152604090205460ff1681565b61047e61271281565b61047e600081565b61047e610a603660046147c6565b601a6020526000908152604090205481565b610936610a80366004614b19565b600760205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b61047e610b173660046149d5565b612578565b6003546104019061010090046001600160a01b031681565b610401610b423660046147c6565b6013602052600090815260409020546001600160a01b031681565b6103b1610b6b3660046147fe565b6125a9565b6103b1610b7e3660046147c6565b61265b565b6103b1610b91366004614bbc565b612774565b6103b1610ba4366004614e34565b612a12565b61047e610bb73660046147c6565b600d6020526000908152604090205481565b6103c6610bd73660046147c6565b60166020526000908152604090205460ff1681565b610a11610bfa3660046147c6565b612a6c565b6103b1610c0d366004614b19565b612a77565b6103b1610c20366004614b31565b612ab4565b6103b1610c33366004614a00565b612b65565b60035461010090046001600160a01b03163314610c705760405162461bcd60e51b8152600401610c679061543e565b60405180910390fd5b60005b6001600160a01b0383166000908152600d6020526040902054811015610cd5576001600160a01b038084166000908152600c60209081526040808320858452909152902054610cc3911683612caf565b80610ccd816156d2565b915050610c73565b505050565b600082610ddc5760008481526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610dd79083612cef565b610ed2565b60008481526007602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610ed29083612cef565b949350505050565b60035461010090046001600160a01b03163314610f095760405162461bcd60e51b8152600401610c679061543e565b60008381526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b820b60c0820152600160801b8404830b830b830b60e082015262ffffff600160981b85048116610100830152600160b01b8504840b840b840b610120830152600160c81b850416610140820152600160e01b909304820b820b90910b610160830152610cd5919084908490612da0565b6001600160a01b0381166110595760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610c67565b600154600160a01b900460ff16156110c55760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610c67565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b611146612f5c565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001611133565b61119c612f5c565b60035460ff16151581151514156111b05750565b6003805460ff191682151590811790915560ff16156111ce57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001611133565b50565b60035461010090046001600160a01b031633146112395760405162461bcd60e51b8152600401610c679061543e565b61124581836001612fd6565b5050565b60035461010090046001600160a01b031633148061127157506019546001600160a01b031633145b6112ae5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610c67565b6005546040516333dfec9960e21b81526001600160a01b038581166004830152600092169063cf7fb2649060240160206040518083038186803b1580156112f457600080fd5b505afa158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132c9190614afd565b90506113388684612cef565b15611e9a57600061134c8760000151613046565b90506000600660008960000151815260200190815260200160002060405180610180016040529081600082015481526020016001820160009054906101000a900460020b60020b60020b81526020016001820160039054906101000a900460020b60020b60020b81526020016001820160069054906101000a900460020b60020b60020b81526020016001820160099054906101000a900460010b60010b60010b815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a900460010b60010b60010b81526020016001820160109054906101000a900460020b60020b60020b81526020016001820160139054906101000a900462ffffff1662ffffff1662ffffff1681526020016001820160169054906101000a900460020b60020b60020b81526020016001820160199054906101000a900462ffffff1662ffffff1662ffffff16815260200160018201601c9054906101000a900460020b60020b60020b81525050905087600660008a6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008a600001518152602001908152602001600020819055506116cd8689600001516001612fd6565b6000878152600b602052604090205460ff168061170157506001600160a01b0386166000908152600d602052604090205415155b156117105761171088876130ee565b600480546001600160a01b03888116600090815260186020526040808220905163217d323560e11b8152919492909316926342fa646a92611759928d92899290918d9101615465565b60206040518083038186803b15801561177157600080fd5b505afa158015611785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a99190614afd565b90508315611be6576001600160a01b03871660009081526008602052604090205460ff16806118565750600354604051630a928f9f60e21b81526001600160a01b03898116600483015261010090920490911690632a4a3e7c9060240160206040518083038186803b15801561181e57600080fd5b505afa158015611832573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118569190614afd565b15611b9457600354604051630259f5fd60e01b81526001600160a01b0389811660048301526000602483015261010090920490911690630259f5fd90604401600060405180830381600087803b1580156118af57600080fd5b505af11580156118c3573d6000803e3d6000fd5b5050505080611b3857600060086000896001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff02191690831515021790555081600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff160217905550905050611aee8988600180612da0565b8851604080516001600160a01b038a16815260208101929092527fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a910160405180910390a1611e3c565b6001600160a01b0387166000908152601a602052604090205415801590611b825750601b546001600160a01b0388166000908152601a6020526040902054611b80904261568f565b105b15611b9957611b948988600180612da0565b611e3c565b6001600160a01b0387166000908152600860205260408120805460ff19169055611bc8908a9089906001612da0565b6001600160a01b0387166000908152601a6020526040812055611e3c565b83158015611bf2575080155b15611e3c57611c048988600180612da0565b611c1387600160006001613201565b81600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff1602179055509050507fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a878a60000151604051611e339291906001600160a01b03929092168252602082015260400190565b60405180910390a15b88516001600160a01b0388166000908152601860205260409081902090517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe92611e8a928e928e919061526f565b60405180910390a1505050611f3e565b80611eff576001600160a01b0384166000908152600860205260409020805460ff191660011790558115611ee4576001600160a01b0384166000908152601a602052604090204290555b611ef18685600180612da0565b611eff846001806000613201565b85516040517f420dbf4677c8331a5938fcc5890c5ae453dd3344f80f9a669d6adb2fea7de3d091611f35918a9188918b906151f0565b60405180910390a15b50505050505050565b600054610100900460ff16611f625760005460ff1615611f66565b303b155b611fc95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c67565b600054610100900460ff16158015611feb576000805461ffff19166101011790555b611ff486611003565b600380546001600160a01b0380881661010002610100600160a81b031990921691909117909155600480548683166001600160a01b031991821617909155600580549286169290911691909117905560005b82518110156120b5576001600b600085848151811061207557634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff02191690831515021790555080806120ad906156d2565b915050612046565b5080156120c8576000805461ff00191690555b505050505050565b6001600160a01b0381166000908152600d60205260408120546060919067ffffffffffffffff81111561211357634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561213c578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600d60205260409020548110156121d6576001600160a01b038085166000908152600c6020908152604080832085845290915290205483519116908390839081106121ac57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0390921660209283029190910190910152806121ce816156d2565b915050612142565b5092915050565b6001546001600160a01b031633146122555760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610c67565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60035461010090046001600160a01b031633146123095760405162461bcd60e51b8152600401610c679061543e565b60008181526007602090815260408083206006909252822081548155600191820180549183018054600293840b840b62ffffff90811662ffffff198316811784558454630100000090819004870b870b83160265ffffffffffff1990931617919091178083558354600160301b90819004860b860b83160268ffffff000000000000198216811784558454600160481b90819004880b880b61ffff9081169091026affff000000000000000000199092166affffffffff0000000000001990931692909217178084558454600160581b90819004870b870b84160262ffffff60581b198216811785558554600160701b90819004890b90980b90921690960261ffff60701b1990911664ffffffffff60581b1990961695909517949094178082558254600160801b90819004850b850b86160262ffffff60801b198216811783558354600160981b9081900487160262ffffff60981b1990911665ffffffffffff60801b1990921691909117178082558254600160b01b90819004850b850b86160262ffffff60b01b198216811783558354600160c81b9081900487160262ffffff60c81b1990911665ffffffffffff60b01b1990921691909117178082559154600160e01b90819004840b90930b90931690910262ffffff60e01b199091161790556124f582613284565b905061250381836001612fd6565b60008281526006602090815260408083206001600160a01b038516845260189092529182902091517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe9261255b9286928392906152a8565b60405180910390a15050565b606061257282613046565b92915050565b6018602052816000526040600020818154811061259457600080fd5b90600052602060002001600091509150505481565b6125b1612f5c565b60038054610100600160a81b0319166101006001600160a01b0387811691820292909217909255600480546001600160a01b0319908116878416908117909255600580548216878516908117909155601980549092169386169384179091556040805194855260208501929092529083015260608201527fa2cad6ae2699ea86ba233a96ca0e57d895983eeed04f6bd0a770187c58b820dd9060800160405180910390a150505050565b612663612f5c565b6001600160a01b0381166126ab5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610c67565b600154600160a81b900460ff16156126fb5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610c67565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101611133565b60035461010090046001600160a01b031633146127a35760405162461bcd60e51b8152600401610c679061543e565b6040518061018001604052808581526020018460020b81526020018360020b81526020018260020b8152602001600060010b8152602001600060020b8152602001600060010b8152602001600060020b8152602001600062ffffff168152602001600060020b8152602001600062ffffff168152602001600060020b815250600660008681526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008681526020019081526020016000208190555050505050565b612a1a612f5c565b6000828152600b6020908152604091829020805460ff19168415159081179091558251858152918201527f388428bda48903bbd0180b2e70447674064e582855a643dd2df349c85b0683f6910161255b565b606061257282613306565b612a7f612f5c565b601b8190556040518181527fcf94ac0e8dccd8a891f16d217c94137033687f7fcffbfa4cfc4e16d85a52320790602001611133565b6005546001600160a01b03163314612afd5760405162461bcd60e51b815260206004820152600c60248201526b27b7363c9036b0b730b3b2b960a11b6044820152606401610c67565b600354604051624dc46d60e41b8152600481018490526001600160a01b038381166024830152610100909204909116906304dc46d0906044015b600060405180830381600087803b158015612b5157600080fd5b505af11580156120c8573d6000803e3d6000fd5b60035461010090046001600160a01b03163314612b945760405162461bcd60e51b8152600401610c679061543e565b60005b6001600160a01b0385166000908152600d6020526040902054811015612ca8576001600160a01b038086166000908152600c602090815260408083208584529091529020541684612c4d5760055460405163b91f5e3560e01b81526001600160a01b038381166004830152602482018890529091169063b91f5e3590604401600060405180830381600087803b158015612c3057600080fd5b505af1158015612c44573d6000803e3d6000fd5b50505050612c95565b6001600160a01b03811660009081526015602052604090205460ff1615612c8457612c7f818560ff168560ff166133a0565b612c95565b612c95818560ff168560ff166134e2565b5080612ca0816156d2565b915050612b97565b5050505050565b60035460405163ed5e00eb60e01b81526001600160a01b03848116600483015283151560248301526101009092049091169063ed5e00eb90604401612b37565b60048054602084015160408086015160608701519151631578f73160e31b815286151595810195909552600292830b6024860152820b6044850152900b60648301526000916001600160a01b039091169063abc7b9889060840160206040518083038186803b158015612d6157600080fd5b505afa158015612d75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d999190614afd565b9392505050565b8015612db057612db08383612caf565b6001600160a01b0383166000908152600d602052604090205415612f56578115612e3f5760005b6001600160a01b0384166000908152600d6020526040902054811015612e39576001600160a01b038085166000908152600c60209081526040808320858452909152902054612e27911684612caf565b80612e31816156d2565b915050612dd7565b50612f56565b612e4884613622565b15612ecb576001600160a01b038084166000908152600f6020908152604080832061010089015162ffffff1684529091529020541680612eb3576000612e9f866000015186600089608001518a61010001516136d9565b9050612ead858260006139cf565b50612ec9565b612ebd8184612caf565b612ec9848260006139cf565b505b612ed484613a33565b15612f56576001600160a01b038084166000908152600e602090815260408083206080890151600190810b900b84529091529020541680612f40576000612f2c866000015186600189608001518a61010001516136d9565b9050612f3a858260016139cf565b50612ca8565b612f4a8184612caf565b612ca8848260016139cf565b50505050565b6000546201000090046001600160a01b03163314612fd45760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610c67565b565b80612fe957612fe483613a98565b612ff2565b612ff282613c78565b6001600160a01b0384166000908152601860209081526040909120825161301f939192919091019061469d565b5050506001600160a01b03166000908152601760205260409020805460ff19166001179055565b6060600061305383613284565b6001600160a01b03811660009081526017602052604090205490915060ff166130845761307f83613c78565b612d99565b6001600160a01b038116600090815260186020908152604091829020805483518184028101840190945280845290918301828280156130e257602002820191906000526020600020905b8154815260200190600101908083116130ce575b50505050509392505050565b6130f782613622565b156131735761310882826000613e0d565b81516001600160a01b038083166000908152601360205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c9291168461315282613306565b612712604051613166959493929190615224565b60405180910390a161317e565b61317e826000613fb6565b61318782613a33565b156131f65761319882826001613e0d565b81516001600160a01b038083166000908152601460205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c929116846131e282613306565b61271160405161255b959493929190615224565b611245826001613fb6565b6003546040516302830aeb60e41b81526001600160a01b03868116600483015285151560248301528415156044830152831515606483015261010090920490911690632830aeb090608401600060405180830381600087803b15801561326657600080fd5b505af115801561327a573d6000803e3d6000fd5b5050505050505050565b600354604051631f138de360e31b81526004810183905260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b1580156132ce57600080fd5b505afa1580156132e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257291906147e2565b6001600160a01b03811660009081526017602052604090205460609060ff166133375761333282613a98565b612572565b6001600160a01b0382166000908152601860209081526040918290208054835181840281018401909452808452909183018282801561339557602002820191906000526020600020905b815481526020019060010190808311613381575b505050505092915050565b6001600160a01b03831660009081526011602052604081205460010b6133c78460646155dd565b6133d19190615546565b905060006133e08360646155dd565b905060008160010b8360010b1361340c578160010b8360010b1261340557600061340f565b600261340f565b60015b60055460405163b91f5e3560e01b81526001600160a01b0389811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b15801561345f57600080fd5b505af1158015613473573d6000803e3d6000fd5b5050506001600160a01b03808816600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b693506134d2928a92869291169061ffff808c1691908b1690615120565b60405180910390a1505050505050565b6001600160a01b03831660009081526012602052604081205462ffffff16908161350c848661558a565b613517906064615664565b62ffffff16116135545762ffffff8216613531848661558a565b61353c906064615664565b62ffffff161061354d576000613557565b6002613557565b60015b60055460405163b91f5e3560e01b81526001600160a01b0388811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b1580156135a757600080fd5b505af11580156135bb573d6000803e3d6000fd5b5050506001600160a01b03808716600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b69350613613928992869291169089908990615120565b60405180910390a15050505050565b60048054610100830151610120840151610140850151610160860151604051634e3a53b760e11b815262ffffff94851696810196909652600292830b6024870152921660448501520b60648301526000916001600160a01b0390911690639c74a76e906084015b60206040518083038186803b1580156136a157600080fd5b505afa1580156136b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125729190614afd565b600354604051631c2ab73160e21b81526004810187905260009182916137679161010090046001600160a01b0316906370aadcc49060240160206040518083038186803b15801561372957600080fd5b505afa15801561373d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137619190614e1c565b86614069565b6005549091506001600160a01b0316634cde32ce886137888189898961410b565b60035460405163c48e62f160e01b8152600481018d90526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b1580156137d057600080fd5b505afa1580156137e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261380c9190810190614d49565b60200151600060028760018e6040518963ffffffff1660e01b815260040161383b9897969594939291906153b9565b602060405180830381600087803b15801561385557600080fd5b505af1158015613869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061388d91906147e2565b5060055460408051622610c560e41b815290516001600160a01b039092169163dd5adfa39160019184916302610c50916004808301926020929190829003018186803b1580156138dc57600080fd5b505afa1580156138f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139149190614e1c565b61391e919061568f565b6040518263ffffffff1660e01b815260040161393c91815260200190565b60206040518083038186803b15801561395457600080fd5b505afa158015613968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061398c91906147e2565b91506139c5878784888888876001815181106139b857634e487b7160e01b600052603260045260246000fd5b602002602001015161429b565b5095945050505050565b8015613a0457506001600160a01b03918216600090815260146020526040902080546001600160a01b03191691909216179055565b506001600160a01b03918216600090815260136020526040902080546001600160a01b03191691909216179055565b60048054608083015160a084015160c085015160e0860151604051630df2ba2560e41b8152600194850b96810196909652600292830b6024870152920b60448501520b60648301526000916001600160a01b039091169063df2ba25090608401613689565b6001600160a01b0381166000908152600a602052604080822054815160028082526060828101909452929391928160200160208202803683375050506001600160a01b03851660009081526015602052604090205490915060ff16613b1857600082815260066020526040902060010154600160b01b900460020b613b35565b600082815260066020526040902060010154600160581b900460020b5b60020b81600081518110613b5957634e487b7160e01b600052603260045260246000fd5b6020908102919091018101919091526001600160a01b03851660009081526015909152604090205460ff16613ba957600082815260066020526040902060010154600160e01b900460020b613bc6565b600082815260066020526040902060010154600160801b900460020b5b60020b81600181518110613bea57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d97491613c24918591016151a5565b60006040518083038186803b158015613c3c57600080fd5b505afa158015613c50573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed29190810190614a4e565b60408051600380825260808201909252606091600091906020820184803683375050506000848152600660205260408120600101548251929350600290810b900b91839190613cd757634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160039054906101000a900460020b60020b81600181518110613d2b57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160069054906101000a900460020b60020b81600281518110613d7f57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d97491613db9918591016151a5565b60006040518083038186803b158015613dd157600080fd5b505afa158015613de5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d999190810190614a4e565b6001600160a01b0382166000908152600d6020526040812054159082613e4d576001600160a01b0380851660009081526013602052604090205416613e69565b6001600160a01b03808516600090815260146020526040902054165b9050600083613ea7576001600160a01b038086166000908152600f602090815260408083206101008b015162ffffff16845290915290205416613ed9565b6001600160a01b038086166000908152600e6020908152604080832060808b0151600190810b900b8452909152902054165b90508280613eee57506001600160a01b038116155b15613f4c576000613f0f876000015187878a608001518b61010001516136d9565b9050613f1c8682876139cf565b6001600160a01b03831615613f3657613f36836001612caf565b613f468188600001516000612fd6565b506120c8565b816001600160a01b0316816001600160a01b031614613f9b57613f70816000612caf565b613f7b826001612caf565b613f868582866139cf565b613f968187600001516000612fd6565b6120c8565b613fa6826000612caf565b6120c88287600001516000612fd6565b6000613fc58360000151613284565b6001600160a01b0381166000908152600d602052604090205490915015610cd55760005b6001600160a01b0382166000908152600d6020526040902054811015612f56576001600160a01b038083166000908152600c6020908152604080832085845282528083205490931680835260159091529190205460ff161515841515141561405657614056816001612caf565b5080614061816156d2565b915050613fe9565b6040805160028082526060808301845292600092919060208301908036833701905050905061409a846123286155b1565b816000815181106140bb57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050826140d4576127126140d8565b6127115b816001815181106140f957634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b60035460405163c48e62f160e01b8152600481018690526060916000916101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b15801561415957600080fd5b505afa15801561416d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526141959190810190614d49565b60a0015160035460405163c48e62f160e01b8152600481018990526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b1580156141e157600080fd5b505afa1580156141f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261421d9190810190614d49565b60c0015160405160200161423292919061502a565b6040516020818303038152906040529050841561427b578061425385614531565b604051602001614264929190614fa2565b604051602081830303815290604052915050610ed2565b8061428a8462ffffff16614583565b604051602001614264929190614fec565b600354604051624dc46d60e41b8152600481018990526001600160a01b038781166024830152610100909204909116906304dc46d090604401600060405180830381600087803b1580156142ee57600080fd5b505af1158015614302573d6000803e3d6000fd5b5050506001600160a01b038087166000818152600a602090815260408083208d905560168252808320805460ff19166001908117909155601083528184208054968e166001600160a01b03199788168117909155808552600c8452828520600d80865284872080548852918652938620805490981690961790965594909252525461438e9250906155b1565b6001600160a01b0387166000908152600d60205260409020558315614485576001600160a01b038681166000818152600e60209081526040808320600189810b80820b865291845282852080546001600160a01b0319908116988e1698891790915587865260118552838620805461ffff191661ffff90941693909317909255948452601483528184208054909116861790559382526015905291909120805460ff191690911790557f41525405a5e10a7f61a75ce8fb247811dadc00a10ad9bd82d09ddab453a686d38686898661446583613306565b8660405161447896959493929190615092565b60405180910390a1611f3e565b6001600160a01b038087166000818152600f6020908152604080832062ffffff88168085529083528184208054968c166001600160a01b0319978816811790915580855260128452828520805462ffffff19169092179091559383526013909152902080549092161790557f2fb9c2a6ac1646a705c03b0657053182a32ea93c368b719a84e352ab42dcb8f88686898561451e83613306565b86604051611f35969594939291906150e2565b606060008260010b1361457a5761455661454d836000196155dd565b61ffff16614583565b6040516020016145669190615069565b604051602081830303815290604052612572565b6125728261ffff165b6060816145a75750506040805180820190915260018152600360fc1b602082015290565b8160005b81156145d157806145bb816156d2565b91506145ca9050600a836155c9565b91506145ab565b60008167ffffffffffffffff8111156145fa57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614624576020820181803683370190505b5090505b8415610ed25761463960018361568f565b9150614646600a866156ed565b6146519060306155b1565b60f81b81838151811061467457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350614696600a866155c9565b9450614628565b8280548282559060005260206000209081019282156146d8579160200282015b828111156146d85782518255916020019190600101906146bd565b506146e49291506146e8565b5090565b5b808211156146e457600081556001016146e9565b803561470881615743565b919050565b803561470881615758565b8035600181900b811461470857600080fd5b803561470881615766565b805161470881615766565b600082601f830112614750578081fd5b815167ffffffffffffffff81111561476a5761476a61572d565b61477d601f8201601f19166020016154f1565b818152846020838601011115614791578283fd5b610ed28260208301602087016156a6565b803562ffffff8116811461470857600080fd5b803560ff8116811461470857600080fd5b6000602082840312156147d7578081fd5b8135612d9981615743565b6000602082840312156147f3578081fd5b8151612d9981615743565b60008060008060808587031215614813578283fd5b843561481e81615743565b9350602085013561482e81615743565b9250604085013561483e81615743565b9150606085013561484e81615743565b939692955090935050565b600080600080600060a08688031215614870578283fd5b853561487b81615743565b945060208681013561488c81615743565b9450604087013561489c81615743565b935060608701356148ac81615743565b9250608087013567ffffffffffffffff8111156148c7578283fd5b8701601f810189136148d7578283fd5b80356148ea6148e582615522565b6154f1565b8082825284820191508484018c868560051b8701011115614909578687fd5b8694505b8385101561492b57803583526001949094019391850191850161490d565b5080955050505050509295509295909350565b60008060408385031215614950578182fd5b823561495b81615743565b9150602083013561496b81615758565b809150509250929050565b60008060408385031215614988578182fd5b823561499381615743565b91506149a160208401614718565b90509250929050565b600080604083850312156149bc578182fd5b82356149c781615743565b91506149a1602084016147a2565b600080604083850312156149e7578182fd5b82356149f281615743565b946020939093013593505050565b60008060008060808587031215614a15578182fd5b8435614a2081615743565b935060208501359250614a35604086016147b5565b9150614a43606086016147b5565b905092959194509250565b60006020808385031215614a60578182fd5b825167ffffffffffffffff811115614a76578283fd5b8301601f81018513614a86578283fd5b8051614a946148e582615522565b80828252848201915084840188868560051b8701011115614ab3578687fd5b8694505b83851015614ad5578051835260019490940193918501918501614ab7565b50979650505050505050565b600060208284031215614af2578081fd5b8135612d9981615758565b600060208284031215614b0e578081fd5b8151612d9981615758565b600060208284031215614b2a578081fd5b5035919050565b60008060408385031215614b43578182fd5b82359150602083013561496b81615743565b600080600060608486031215614b69578081fd5b833592506020840135614b7b81615743565b91506040840135614b8b81615758565b809150509250925092565b600080600060608486031215614baa578081fd5b833592506020840135614b7b81615758565b60008060008060808587031215614bd1578182fd5b843593506020850135614be381615766565b92506040850135614bf381615766565b9150606085013561484e81615766565b600080600080600080868803610220811215614c1d578485fd5b8735965061018080601f1983011215614c34578586fd5b614c3c6154a4565b915060208901358252614c5160408a0161472a565b6020830152614c6260608a0161472a565b6040830152614c7360808a0161472a565b6060830152614c8460a08a01614718565b6080830152614c9560c08a0161472a565b60a0830152614ca660e08a01614718565b60c0830152610100614cb9818b0161472a565b60e0840152610120614ccc818c016147a2565b828501526101409150614ce0828c0161472a565b90840152610160614cf28b82016147a2565b82850152614d01838c0161472a565b9084015250909550506101a08701359350614d1f6101c088016146fd565b9250614d2e6101e0880161470d565b9150614d3d610200880161470d565b90509295509295509295565b600060208284031215614d5a578081fd5b815167ffffffffffffffff80821115614d71578283fd5b9083019060e08286031215614d84578283fd5b614d8c6154ce565b8251815260208301516020820152614da660408401614735565b6040820152614db760608401614735565b6060820152614dc860808401614735565b608082015260a083015182811115614dde578485fd5b614dea87828601614740565b60a08301525060c083015182811115614e01578485fd5b614e0d87828601614740565b60c08301525095945050505050565b600060208284031215614e2d578081fd5b5051919050565b60008060408385031215614e46578182fd5b82359150602083013561496b81615758565b6000815180845260208085019450808401835b83811015614e8757815187529582019590820190600101614e6b565b509495945050505050565b6000815480845260208085019450838352808320835b83811015614e8757815487529582019560019182019101614ea8565b805182526020810151614edc602084018260020b9052565b506040810151614ef1604084018260020b9052565b506060810151614f06606084018260020b9052565b506080810151614f1b608084018260010b9052565b5060a0810151614f3060a084018260020b9052565b5060c0810151614f4560c084018260010b9052565b5060e0810151614f5a60e084018260020b9052565b506101008181015162ffffff169083015261012080820151600281900b8285015250506101408181015162ffffff169083015261016080820151600281900b82850152612f56565b60008351614fb48184602088016156a6565b600560fb1b9083019081528351614fd28160018401602088016156a6565b602960f81b60019290910191820152600201949350505050565b60008351614ffe8184602088016156a6565b6201016960ed1b908301908152835161501e8160038401602088016156a6565b01600301949350505050565b6000835161503c8184602088016156a6565b630103b39960e51b908301908152835161505d8160048401602088016156a6565b01600401949350505050565b602d60f81b8152600082516150858160018501602087016156a6565b9190910160010192915050565b6001600160a01b0387811682528616602082015260408101859052600184900b606082015260c0608082018190526000906150cf90830185614e58565b90508260a0830152979650505050505050565b6001600160a01b038781168252861660208201526040810185905262ffffff8416606082015260c0608082018190526000906150cf90830185614e58565b6001600160a01b039586168152602081019490945291909316604083015262ffffff9283166060830152909116608082015260a00190565b6020808252825182820181905260009190848201906040850190845b818110156151995783516001600160a01b031683529284019291840191600101615174565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015615199578351835292840192918401916001016151c1565b602081526000612d996020830184614e58565b8481526001600160a01b0384166020820152604081018390526101e0810161521b6060830184614ec4565b95945050505050565b8581526001600160a01b038516602082015260006102006152486040840187614ec4565b806101c084015261525b81840186614e58565b915050826101e08301529695505050505050565b60006101e086835285602084015261528a6040840186614ec4565b806101c084015261529d81840185614e92565b979650505050505050565b60006101e086835285602084015284546040840152600185015460026152d56060860183830b60020b9052565b6152e9608086018360181c830b60020b9052565b6152fd60a086018360301c830b60020b9052565b61531260c086018360481c60010b60010b9052565b61532660e086018360581c830b60020b9052565b61533c61010086018360701c60010b60010b9052565b61535161012086018360801c830b60020b9052565b62ffffff609883901c811661014087015261537761016087018460b01c840b60020b9052565b61538e6101808701828560c81c1662ffffff169052565b506153a46101a086018360e01c830b60020b9052565b5050806101c084015261529d81840185614e92565b60006101008a83528060208401528951808285015261012091506153e38183860160208e016156a6565b604084018a90526060840189905260808401889052601f01601f19168301838103820160a085015261541782820188614e58565b95151560c08501525050506001600160a01b039190911660e0909101529695505050505050565b6020808252600d908201526c27b7363c9031b7b739bab6b2b960991b604082015260600190565b84815260806020820152600061547e6080830186614e58565b82810360408401526154908186614e92565b915050821515606083015295945050505050565b604051610180810167ffffffffffffffff811182821017156154c8576154c861572d565b60405290565b60405160e0810167ffffffffffffffff811182821017156154c8576154c861572d565b604051601f8201601f1916810167ffffffffffffffff8111828210171561551a5761551a61572d565b604052919050565b600067ffffffffffffffff82111561553c5761553c61572d565b5060051b60200190565b60008160010b8360010b82821282617fff0382138115161561556a5761556a615701565b82617fff1903821281161561558157615581615701565b50019392505050565b600062ffffff8083168185168083038211156155a8576155a8615701565b01949350505050565b600082198211156155c4576155c4615701565b500190565b6000826155d8576155d8615717565b500490565b60008160010b8360010b617fff8382138484138383048511828216161561560657615606615701565b617fff198685128281168783058712161561562357615623615701565b87871292508582058712848416161561563e5761563e615701565b8585058712818416161561565457615654615701565b5050509290910295945050505050565b600062ffffff8083168185168183048111821515161561568657615686615701565b02949350505050565b6000828210156156a1576156a1615701565b500390565b60005b838110156156c15781810151838201526020016156a9565b83811115612f565750506000910152565b60006000198214156156e6576156e6615701565b5060010190565b6000826156fc576156fc615717565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461120757600080fd5b801515811461120757600080fd5b8060020b811461120757600080fdfea2646970667358221220e81c52a8caf81f76b3e96a9dc9dce00f9672ccaa01e6eeff17b7370259427a2364736f6c63430008040033

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