Contract 0x487Ea0597Ab2e6fb198B2b04f7aceb127627b3C4

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

Contract Overview

Balance:
Txn Hash Method
Block
From
To
Value
0xd3f47132e61c43e608408a9b302bed5812efd256bcfce0977604372710ca6aa80x60806040184323992023-12-11 11:07:46130 days 16 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  Create: GamesPlayerProps0 ETH0.0000000464150.00001
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GamesPlayerProps

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 17 : GamesPlayerProps.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/IGamesPlayerProps.sol";
import "../../interfaces/ISportPositionalMarket.sol";

/// @title Contract, which works on player props
/// @author gruja
contract GamesPlayerProps is Initializable, ProxyOwned, ProxyPausable {
    /* ========== CONSTANTS =========== */
    uint public constant MIN_TAG_NUMBER = 9000;
    uint public constant TAG_NUMBER_PLAYERS = 10010;
    uint public constant TAG_NUMBER_PLAYER_PROPS = 11000;
    uint public constant CANCELLED = 0;
    uint public constant HOME_WIN = 1;
    uint public constant AWAY_WIN = 2;
    uint public constant CANCELLED_STATUS = 255;

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

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

    // game properties
    mapping(bytes32 => mapping(bytes32 => mapping(uint8 => IGamesPlayerProps.PlayerProps))) public playerProp;
    mapping(uint => bool) public doesSportSupportPlayerProps;
    mapping(address => bytes32) public gameIdPerChildMarket;
    mapping(address => bytes32) public playerIdPerChildMarket;
    mapping(address => uint8) public optionIdPerChildMarket;

    // market props
    mapping(address => mapping(uint => address)) public mainMarketChildMarketIndex;
    mapping(address => bool) public mainMarketPausedPlayerProps;
    mapping(address => uint) public numberOfChildMarkets;
    mapping(address => mapping(bytes32 => mapping(uint8 => mapping(uint => address))))
        public mainMarketChildMarketPerPlayerAndOptionIndex;
    mapping(address => mapping(bytes32 => mapping(uint8 => uint))) public numberOfChildMarketsPerPlayerAndOption;
    mapping(address => mapping(bytes32 => mapping(uint8 => mapping(uint16 => address))))
        public mainMarketPlayerOptionLineChildMarket;
    mapping(address => address) public childMarketMainMarket;
    mapping(address => mapping(bytes32 => mapping(uint8 => address))) public currentActiveChildMarketPerPlayerAndOption;
    mapping(address => uint[]) public normalizedOddsForMarket;
    mapping(address => bool) public normalizedOddsForMarketFulfilled;
    mapping(address => bool) public childMarketCreated;
    mapping(address => uint16) public childMarketLine;
    mapping(bytes32 => mapping(bytes32 => mapping(uint8 => bool))) public invalidOddsForPlayerProps;
    mapping(bytes32 => mapping(bytes32 => mapping(uint8 => bool))) public createFulfilledForPlayerProps;
    mapping(bytes32 => mapping(bytes32 => mapping(uint8 => bool))) public resolveFulfilledForPlayerProps;
    mapping(address => bool) public pausedByInvalidOddsOnMain;
    mapping(address => bool) public pausedByCircuitBreakerOnMain;
    mapping(address => bool) public playerPropsAddedForMain;

    mapping(bytes32 => bytes32[]) public playersInAGame;
    mapping(bytes32 => mapping(bytes32 => bool)) public playersInAGameFulfilled;
    mapping(bytes32 => mapping(bytes32 => uint8[])) public allOptionsPerPlayer;
    mapping(bytes32 => mapping(bytes32 => mapping(uint8 => IGamesPlayerProps.PlayerPropsResolver)))
        public resolvedPlayerProps;
    mapping(address => bool) public childMarketResolved;
    mapping(bytes32 => address) public currentMainMarketForPlayer;

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

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

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

    /* ========== PLAYER PROPS MAIN FUNCTIONS ========== */

    /// @notice main function for player props
    /// @param _player player props struct see @ IGamesPlayerProps.PlayerProps
    /// @param _sportId sport id
    function obtainPlayerProps(IGamesPlayerProps.PlayerProps memory _player, uint _sportId) external canExecute {
        address _main = consumer.marketPerGameId(_player.gameId);
        // if main is created and not paused and also sport support player props
        if (_main != address(0) && doesSportSupportPlayerProps[_sportId]) {
            if (_areOddsAndLinesValidForPlayer(_player)) {
                if (
                    invalidOddsForPlayerProps[_player.gameId][_player.playerId][_player.option] ||
                    pausedByInvalidOddsOnMain[_main] ||
                    pausedByCircuitBreakerOnMain[_main]
                ) {
                    invalidOddsForPlayerProps[_player.gameId][_player.playerId][_player.option] = false;
                    pausedByInvalidOddsOnMain[_main] = false;
                    pausedByCircuitBreakerOnMain[_main] = false;
                }
                playerProp[_player.gameId][_player.playerId][_player.option] = _player;
                address playerPropsMarket = _obtainPlayerProps(_player, _main);
                mainMarketPausedPlayerProps[_main] = false;
                playerPropsAddedForMain[_main] = true;

                if (!playersInAGameFulfilled[_player.gameId][_player.playerId]) {
                    playersInAGameFulfilled[_player.gameId][_player.playerId] = true;
                    playersInAGame[_player.gameId].push(_player.playerId);
                }

                if (!createFulfilledForPlayerProps[_player.gameId][_player.playerId][_player.option]) {
                    createFulfilledForPlayerProps[_player.gameId][_player.playerId][_player.option] = true;
                    allOptionsPerPlayer[_player.gameId][_player.playerId].push(_player.option);
                }

                emit PlayerPropsAdded(
                    _player.gameId,
                    _player.playerId,
                    _player.option,
                    normalizedOddsForMarket[playerPropsMarket]
                );
            } else {
                invalidOddsForPlayerProps[_player.gameId][_player.playerId][_player.option] = true;
                _pauseMarketsForPlayerPropsForOption(_player, true);

                emit InvalidOddsForMarket(_main, _player.gameId, _player.playerId, _player.option);
            }
        }
    }

    /// @notice resolve playerProp
    /// @param _result object for resolve
    function resolvePlayerProps(IGamesPlayerProps.PlayerPropsResolver memory _result) external canExecute {
        // get main market
        address _main = consumer.marketPerGameId(_result.gameId);
        //number of childs per option
        uint numberOfChildsPerOptions = numberOfChildMarketsPerPlayerAndOption[_main][_result.playerId][_result.option];
        // if it is resolved skip it
        if (!resolveFulfilledForPlayerProps[_result.gameId][_result.playerId][_result.option]) {
            // resolve
            for (uint j = 0; j < numberOfChildsPerOptions; j++) {
                address child = mainMarketChildMarketPerPlayerAndOptionIndex[_main][_result.playerId][_result.option][j];
                if (!childMarketResolved[child]) {
                    if (invalidOddsForPlayerProps[_result.gameId][_result.playerId][_result.option]) {
                        consumer.pauseOrUnpauseMarket(child, false);
                    }
                    if (_result.statusId == CANCELLED_STATUS) {
                        _resolveMarket(child, uint16(CANCELLED), CANCELLED);
                    } else {
                        _resolveMarketForPlayer(child, _result.score);
                    }
                    childMarketResolved[child] = true;
                }
            }
            resolvedPlayerProps[_result.gameId][_result.playerId][_result.option] = _result;
            resolveFulfilledForPlayerProps[_result.gameId][_result.playerId][_result.option] = true;
        }
    }

    /// @notice cancel playerProp
    /// @param _market market for cancelation
    function cancelMarketFromManager(address _market) external onlyManager {
        address parent = childMarketMainMarket[_market];
        bytes32 gameId = gameIdPerChildMarket[_market];
        bytes32 playerId = playerIdPerChildMarket[_market];
        uint8 option = optionIdPerChildMarket[_market];
        uint numberOfChildsPerOptions = numberOfChildMarketsPerPlayerAndOption[parent][playerId][option];
        if (!childMarketResolved[_market]) {
            _resolveMarket(_market, uint16(CANCELLED), CANCELLED);
            if (numberOfChildsPerOptions < 2) {
                resolveFulfilledForPlayerProps[gameId][playerId][option] = true;
            } else {
                bool flagResolved = true;
                for (uint j = 0; j < numberOfChildsPerOptions; j++) {
                    address child = mainMarketChildMarketPerPlayerAndOptionIndex[parent][playerId][option][j];
                    if (!childMarketResolved[child] && child != _market) {
                        flagResolved = false;
                        break;
                    }
                }
                if (flagResolved) {
                    resolveFulfilledForPlayerProps[gameId][playerId][option] = true;
                }
            }
            childMarketResolved[_market] = true;
        }
    }

    /// @notice pause/unpause all markets for game
    /// @param _main parent market for which we are pause/unpause child markets
    /// @param _flag pause -> true, unpause -> false
    /// @param _invalidOddsMain are paused by invalid odds on main
    /// @param _circuitBreakerOnMain are paused by circuit breaker on main
    function pauseAllPlayerPropsMarketForMain(
        address _main,
        bool _flag,
        bool _invalidOddsMain,
        bool _circuitBreakerOnMain
    ) external onlyConsumer {
        if (playerPropsAddedForMain[_main]) {
            mainMarketPausedPlayerProps[_main] = _flag;
            pausedByInvalidOddsOnMain[_main] = _invalidOddsMain;
            pausedByCircuitBreakerOnMain[_main] = _circuitBreakerOnMain;
            _pauseAllPlayerPropsMarket(_main, _flag);
        }
    }

    /// @notice pause/unpause current active child markets
    /// @param _main parent market for which we are pause/unpause child markets
    function cancelPlayerPropsMarketForMain(address _main) external onlyConsumer {
        _cancelPlayerPropsMarket(_main);
    }

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

    function _areOddsAndLinesValidForPlayer(IGamesPlayerProps.PlayerProps memory _player) internal view returns (bool) {
        return verifier.areOddsAndLinesValidForPlayer(_player.line, _player.overOdds, _player.underOdds);
    }

    function _obtainPlayerProps(IGamesPlayerProps.PlayerProps memory _player, address _main) internal returns (address) {
        bool isNewMarket = numberOfChildMarkets[_main] == 0;
        address currentActiveChildMarket = currentActiveChildMarketPerPlayerAndOption[_main][_player.playerId][
            _player.option
        ];
        address currentMarket = mainMarketPlayerOptionLineChildMarket[_main][_player.playerId][_player.option][_player.line];

        if (isNewMarket || currentMarket == address(0)) {
            address newMarket = _createMarketForPlayerProps(_player, _main);

            currentActiveChildMarketPerPlayerAndOption[_main][_player.playerId][_player.option] = newMarket;

            if (currentActiveChildMarket != address(0)) {
                consumer.pauseOrUnpauseMarket(currentActiveChildMarket, true);
            }
            _setNormalizedOdds(newMarket, _player.gameId, _player.playerId, _player.option);
            return newMarket;
        } else if (currentMarket != currentActiveChildMarket) {
            consumer.pauseOrUnpauseMarket(currentMarket, false);
            consumer.pauseOrUnpauseMarket(currentActiveChildMarket, true);
            currentActiveChildMarketPerPlayerAndOption[_main][_player.playerId][_player.option] = currentMarket;
            _setNormalizedOdds(currentMarket, _player.gameId, _player.playerId, _player.option);
            return currentMarket;
        } else {
            consumer.pauseOrUnpauseMarket(currentActiveChildMarket, false);
            _setNormalizedOdds(currentActiveChildMarket, _player.gameId, _player.playerId, _player.option);
            return currentActiveChildMarket;
        }
    }

    function _pauseMarketsForPlayerPropsForOption(IGamesPlayerProps.PlayerProps memory _player, bool _flag)
        internal
        returns (bool)
    {
        // get main market
        address _main = consumer.marketPerGameId(_player.gameId);
        //number of childs per option
        uint numberOfChildsPerOptions = numberOfChildMarketsPerPlayerAndOption[_main][_player.playerId][_player.option];
        // pause all per option
        for (uint j = 0; j < numberOfChildsPerOptions; j++) {
            address child = mainMarketChildMarketPerPlayerAndOptionIndex[_main][_player.playerId][_player.option][j];
            _pauseOrUnpauseMarket(child, _flag);
        }
    }

    function _pauseAllPlayerPropsMarket(address _main, bool _flag) internal {
        for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
            consumer.pauseOrUnpauseMarket(mainMarketChildMarketIndex[_main][i], _flag);
        }
    }

    function _cancelPlayerPropsMarket(address _main) internal {
        for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
            if (!childMarketResolved[mainMarketChildMarketIndex[_main][i]]) {
                sportsManager.resolveMarket(mainMarketChildMarketIndex[_main][i], CANCELLED);
            }
        }
    }

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

    function _setNormalizedOdds(
        address _market,
        bytes32 _gameId,
        bytes32 _playerId,
        uint8 _option
    ) internal {
        normalizedOddsForMarket[_market] = _getNormalizedOddsForPlayerProps(_gameId, _playerId, _option);
        normalizedOddsForMarketFulfilled[_market] = true;
    }

    function _createMarketForPlayerProps(IGamesPlayerProps.PlayerProps memory _player, address _mainMarket)
        internal
        returns (address _playerMarket)
    {
        // create
        uint[] memory tags = _calculateTags(consumer.sportsIdPerGame(_player.gameId), _player.option);
        sportsManager.createMarket(
            _player.gameId,
            _append(_player), // gameLabel
            consumer.getGameCreatedById(_player.gameId).startTime, //maturity
            0, //initialMint
            2, // always two positions for player props
            tags, //tags
            true, // is child
            _mainMarket
        );

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

        // adding child markets
        _setChildMarkets(
            _player.gameId,
            _mainMarket,
            _playerMarket,
            _player.line,
            _player.playerId,
            _player.playerName,
            _player.option,
            tags[2]
        );
    }

    function _append(IGamesPlayerProps.PlayerProps memory _player) internal pure returns (string memory) {
        return
            string(
                abi.encodePacked(
                    _player.playerName,
                    " - ",
                    Strings.toString(_player.option),
                    " - ",
                    Strings.toString(_player.line)
                )
            );
    }

    function _calculateTags(uint _sportsId, uint8 _option) internal pure returns (uint[] memory) {
        uint[] memory result = new uint[](3);
        result[0] = MIN_TAG_NUMBER + _sportsId;
        result[1] = TAG_NUMBER_PLAYERS;
        result[2] = TAG_NUMBER_PLAYER_PROPS + _option;
        return result;
    }

    function _setChildMarkets(
        bytes32 _gameId,
        address _main,
        address _child,
        uint16 _line,
        bytes32 _playerId,
        string memory _playerName,
        uint8 _option,
        uint _type
    ) internal {
        consumer.setGameIdPerChildMarket(_gameId, _child);
        gameIdPerChildMarket[_child] = _gameId;
        playerIdPerChildMarket[_child] = _playerId;
        currentMainMarketForPlayer[_playerId] = _main;
        optionIdPerChildMarket[_child] = _option;
        childMarketCreated[_child] = true;
        childMarketMainMarket[_child] = _main;
        mainMarketChildMarketIndex[_main][numberOfChildMarkets[_main]] = _child;
        numberOfChildMarkets[_main] += 1;
        mainMarketPlayerOptionLineChildMarket[_main][_playerId][_option][_line] = _child;
        childMarketLine[_child] = _line;
        currentActiveChildMarketPerPlayerAndOption[_main][_playerId][_option] = _child;
        mainMarketChildMarketPerPlayerAndOptionIndex[_main][_playerId][_option][
            numberOfChildMarketsPerPlayerAndOption[_main][_playerId][_option]
        ] = _child;
        numberOfChildMarketsPerPlayerAndOption[_main][_playerId][_option] += 1;
        emit CreatePlayerPropsMarket(
            _main,
            _child,
            _gameId,
            _playerId,
            _playerName,
            _line,
            _option,
            _getNormalizedChildOdds(_child),
            _type
        );
    }

    function _resolveMarketForPlayer(address _child, uint16 _score) internal {
        uint16 line = childMarketLine[_child];

        uint outcome = _score * 100 > line ? HOME_WIN : _score * 100 < line ? AWAY_WIN : CANCELLED;

        _resolveMarket(_child, _score, outcome);
    }

    function _resolveMarket(
        address _child,
        uint16 _score,
        uint _outcome
    ) internal {
        sportsManager.resolveMarket(_child, _outcome);
        emit ResolveChildMarket(_child, _outcome, childMarketMainMarket[_child], _score);
    }

    function _getNormalizedOddsForPlayerProps(
        bytes32 _gameId,
        bytes32 _playerId,
        uint8 _option
    ) internal view returns (uint[] memory) {
        int[] memory odds = new int[](2);
        odds[0] = playerProp[_gameId][_playerId][_option].overOdds;
        odds[1] = playerProp[_gameId][_playerId][_option].underOdds;
        return verifier.calculateAndNormalizeOdds(odds);
    }

    function _getNormalizedChildOddsFromGameOddsStruct(address _market) internal view returns (uint[] memory) {
        return
            _getNormalizedOddsForPlayerProps(
                gameIdPerChildMarket[_market],
                playerIdPerChildMarket[_market],
                optionIdPerChildMarket[_market]
            );
    }

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

    function _getAllChildMarketsForParentPlayerOption(
        address _parent,
        bytes32 _player,
        uint8 _option
    ) internal view returns (address[] memory _children) {
        uint num = numberOfChildMarketsPerPlayerAndOption[_parent][_player][_option];
        _children = new address[](num);

        for (uint j = 0; j < num; j++) {
            address child = mainMarketChildMarketPerPlayerAndOptionIndex[_parent][_player][_option][j];
            _children[j] = child;
        }
    }

    function _getValidMainMarket(address mainMarket) internal view returns (address toReturn) {
        if (mainMarket != address(0)) {
            (uint maturity, ) = ISportPositionalMarket(mainMarket).times();
            if (maturity >= block.timestamp && !ISportPositionalMarket(mainMarket).resolved()) {
                toReturn = mainMarket;
            }
        }
    }

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

    /// @notice view function which returns props data for given child market
    /// @param _market market
    function getPlayerPropsDataForMarket(address _market)
        external
        view
        returns (
            address,
            bytes32,
            bytes32,
            uint8
        )
    {
        return (
            childMarketMainMarket[_market],
            gameIdPerChildMarket[_market],
            playerIdPerChildMarket[_market],
            optionIdPerChildMarket[_market]
        );
    }

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

    function getPlayerPropForOption(
        bytes32 _gameId,
        bytes32 _playerId,
        uint8 _option
    )
        external
        view
        returns (
            uint16,
            int24,
            int24,
            bool
        )
    {
        IGamesPlayerProps.PlayerProps memory currentProp = playerProp[_gameId][_playerId][_option];
        return (
            currentProp.line,
            currentProp.overOdds,
            currentProp.underOdds,
            invalidOddsForPlayerProps[_gameId][_playerId][_option]
        );
    }

    function getAllOptionsWithPlayersForGameId(bytes32 _gameId)
        external
        view
        returns (
            bytes32[] memory _playerIds,
            uint8[] memory _options,
            bool[] memory _isResolved,
            bool[] memory _hasMintsOnChildren
        )
    {
        // get main market
        address _main = consumer.marketPerGameId(_gameId);

        uint256 totalCombinations = 0;

        for (uint256 i = 0; i < playersInAGame[_gameId].length; i++) {
            bytes32 playerId = playersInAGame[_gameId][i];
            totalCombinations += allOptionsPerPlayer[_gameId][playerId].length;
        }

        _playerIds = new bytes32[](totalCombinations);
        _options = new uint8[](totalCombinations);
        _isResolved = new bool[](totalCombinations);
        _hasMintsOnChildren = new bool[](totalCombinations);

        uint256 index = 0;
        for (uint256 i = 0; i < playersInAGame[_gameId].length; i++) {
            bytes32 playerId = playersInAGame[_gameId][i];
            uint8[] memory playerOptions = allOptionsPerPlayer[_gameId][playerId];

            for (uint256 j = 0; j < playerOptions.length; j++) {
                uint8 optionId = playerOptions[j];

                if (createFulfilledForPlayerProps[_gameId][playerId][optionId]) {
                    _playerIds[index] = playerId;
                    _options[index] = optionId;
                    _isResolved[index] = resolveFulfilledForPlayerProps[_gameId][playerId][optionId];
                    address[] memory _childArraysPerOption = _getAllChildMarketsForParentPlayerOption(
                        _main,
                        playerId,
                        optionId
                    );

                    (bool[] memory _hasAnyMintsArray, , , ) = sportsManager.queryMintsAndMaturityStatusForPlayerProps(
                        _childArraysPerOption
                    );

                    _hasMintsOnChildren[index] = false;
                    for (uint256 m = 0; m < _childArraysPerOption.length; m++) {
                        if (_hasAnyMintsArray[m]) {
                            _hasMintsOnChildren[index] = true;
                            break;
                        }
                    }

                    index++;
                }
            }
        }
    }

    function getAllChildMarketsForParents(address[] memory _parents) external view returns (address[] memory _children) {
        uint totalChildren = 0;
        for (uint i = 0; i < _parents.length; i++) {
            totalChildren += numberOfChildMarkets[_parents[i]];
        }

        _children = new address[](totalChildren);
        uint index = 0;

        for (uint i = 0; i < _parents.length; i++) {
            uint num = numberOfChildMarkets[_parents[i]];
            for (uint j = 0; j < num; j++) {
                address child = mainMarketChildMarketIndex[_parents[i]][j];
                _children[index] = child;
                index++;
            }
        }
    }

    function getAllMainMarketsBasedOnPlayer(bytes32[] memory _playerIds, string[] memory _teamNames)
        external
        view
        returns (address[] memory _mainMarkets)
    {
        _mainMarkets = new address[](_playerIds.length);

        for (uint i = 0; i < _playerIds.length; i++) {
            address mainMarket = currentMainMarketForPlayer[_playerIds[i]];
            _mainMarkets[i] = _getValidMainMarket(mainMarket);

            if (_mainMarkets[i] == address(0)) {
                mainMarket = consumer.marketForTeamName(_teamNames[i]);
                _mainMarkets[i] = _getValidMainMarket(mainMarket);
            }
        }
    }

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

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

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

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

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

    modifier canExecute() {
        require(msg.sender == playerPropsReceiver, "Invalid sender");
        _;
    }

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

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

    /* ========== EVENTS ========== */
    event PlayerPropsAdded(bytes32 _gameId, bytes32 _playerId, uint8 _option, uint[] _normalizedOdds);
    event NewContractAddresses(address _consumer, address _verifier, address _sportsManager, address _receiver);
    event SupportedSportForPlayerPropsAdded(uint _sportId, bool _isSupported);
    event CreatePlayerPropsMarket(
        address _main,
        address _child,
        bytes32 _gameId,
        bytes32 _playerId,
        string _playerName,
        uint16 _line,
        uint8 _option,
        uint[] _normalizedOdds,
        uint _type
    );
    event ResolveChildMarket(address _child, uint _outcome, address _main, uint16 _score);
    event InvalidOddsForMarket(address _main, bytes32 _gameId, bytes32 _playerId, uint8 option);
}

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 : IGamesPlayerProps.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

    function resolvePlayerProps(PlayerPropsResolver memory _result) external;

    function cancelMarketFromManager(address _market) external;

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

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

    function cancelPlayerPropsMarketForMain(address _main) external;

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

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

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

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

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

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

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

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

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

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

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

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

File 11 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;

    function initializeOptions() external;
}

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity >=0.5.16;

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

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

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

    function capitalRequirement() external view returns (uint);

    function marketCreationEnabled() external view returns (bool);

    function onlyAMMMintingAndBurning() external view returns (bool);

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

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

    function totalDeposited() external view returns (uint);

    function numActiveMarkets() external view returns (uint);

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

    function numMaturedMarkets() external view returns (uint);

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

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

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

    function getThalesAMM() external view returns (address);

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

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

    function resolveMarket(address market) external;

    function expireMarkets(address[] calldata market) external;

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

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

pragma solidity >=0.5.16;

import "./IPositionalMarket.sol";

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

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

    function getTotalSupply() external view returns (uint);

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

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

pragma solidity >=0.5.16;

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

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

    function removeAggregator(bytes32 currencyKey) external;

    // Views

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

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

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

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

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

pragma solidity >=0.5.16;

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

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

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

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

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

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

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

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

    function deposited() external view returns (uint);

    function creator() external view returns (address);

    function resolved() external view returns (bool);

    function phase() external view returns (Phase);

    function oraclePrice() external view returns (uint);

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

    function canResolve() external view returns (bool);

    function result() external view returns (Side);

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

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

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

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

    function mint(uint value) external;

    function exerciseOptions() external returns (uint);

    function burnOptions(uint amount) external;

    function burnOptionsMaximum() external;
}

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

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"address","name":"_child","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_playerId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"_playerName","type":"string"},{"indexed":false,"internalType":"uint16","name":"_line","type":"uint16"},{"indexed":false,"internalType":"uint8","name":"_option","type":"uint8"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"CreatePlayerPropsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_playerId","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"option","type":"uint8"}],"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":"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":"bytes32","name":"_gameId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_playerId","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"_option","type":"uint8"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"}],"name":"PlayerPropsAdded","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":"uint16","name":"_score","type":"uint16"}],"name":"ResolveChildMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"SupportedSportForPlayerPropsAdded","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":"CANCELLED_STATUS","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_PLAYERS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TAG_NUMBER_PLAYER_PROPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"allOptionsPerPlayer","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"cancelMarketFromManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_main","type":"address"}],"name":"cancelPlayerPropsMarketForMain","outputs":[],"stateMutability":"nonpayable","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":"childMarketLine","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"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":"childMarketResolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"consumer","outputs":[{"internalType":"contract ITherundownConsumer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"createFulfilledForPlayerProps","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"currentActiveChildMarketPerPlayerAndOption","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"currentMainMarketForPlayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"doesSportSupportPlayerProps","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":"address[]","name":"_parents","type":"address[]"}],"name":"getAllChildMarketsForParents","outputs":[{"internalType":"address[]","name":"_children","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_playerIds","type":"bytes32[]"},{"internalType":"string[]","name":"_teamNames","type":"string[]"}],"name":"getAllMainMarketsBasedOnPlayer","outputs":[{"internalType":"address[]","name":"_mainMarkets","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getAllOptionsWithPlayersForGameId","outputs":[{"internalType":"bytes32[]","name":"_playerIds","type":"bytes32[]"},{"internalType":"uint8[]","name":"_options","type":"uint8[]"},{"internalType":"bool[]","name":"_isResolved","type":"bool[]"},{"internalType":"bool[]","name":"_hasMintsOnChildren","type":"bool[]"}],"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"},{"internalType":"bytes32","name":"_playerId","type":"bytes32"},{"internalType":"uint8","name":"_option","type":"uint8"}],"name":"getPlayerPropForOption","outputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"getPlayerPropsDataForMarket","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"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":"address","name":"_playerPropsReceiver","type":"address"},{"internalType":"uint256[]","name":"_supportedSportIds","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"invalidOddsForPlayerProps","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":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mainMarketChildMarketPerPlayerAndOptionIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mainMarketPausedPlayerProps","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"mainMarketPlayerOptionLineChildMarket","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":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"numberOfChildMarketsPerPlayerAndOption","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"bytes32","name":"playerId","type":"bytes32"},{"internalType":"uint8","name":"option","type":"uint8"},{"internalType":"string","name":"playerName","type":"string"},{"internalType":"uint16","name":"line","type":"uint16"},{"internalType":"int24","name":"overOdds","type":"int24"},{"internalType":"int24","name":"underOdds","type":"int24"}],"internalType":"struct IGamesPlayerProps.PlayerProps","name":"_player","type":"tuple"},{"internalType":"uint256","name":"_sportId","type":"uint256"}],"name":"obtainPlayerProps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"optionIdPerChildMarket","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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"},{"internalType":"bool","name":"_invalidOddsMain","type":"bool"},{"internalType":"bool","name":"_circuitBreakerOnMain","type":"bool"}],"name":"pauseAllPlayerPropsMarketForMain","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":"pausedByCircuitBreakerOnMain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pausedByInvalidOddsOnMain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"playerIdPerChildMarket","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"playerProp","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"bytes32","name":"playerId","type":"bytes32"},{"internalType":"uint8","name":"option","type":"uint8"},{"internalType":"string","name":"playerName","type":"string"},{"internalType":"uint16","name":"line","type":"uint16"},{"internalType":"int24","name":"overOdds","type":"int24"},{"internalType":"int24","name":"underOdds","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"playerPropsAddedForMain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"playerPropsReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"playersInAGame","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"playersInAGameFulfilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"resolveFulfilledForPlayerProps","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"bytes32","name":"playerId","type":"bytes32"},{"internalType":"uint8","name":"option","type":"uint8"},{"internalType":"uint16","name":"score","type":"uint16"},{"internalType":"uint8","name":"statusId","type":"uint8"}],"internalType":"struct IGamesPlayerProps.PlayerPropsResolver","name":"_result","type":"tuple"}],"name":"resolvePlayerProps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"resolvedPlayerProps","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"bytes32","name":"playerId","type":"bytes32"},{"internalType":"uint8","name":"option","type":"uint8"},{"internalType":"uint16","name":"score","type":"uint16"},{"internalType":"uint8","name":"statusId","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_consumer","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"address","name":"_sportsManager","type":"address"},{"internalType":"address","name":"_playerPropsReceiver","type":"address"}],"name":"setContracts","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":"setSupportedSportForPlayerPropsAdded","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"}]

608060405234801561001057600080fd5b506152fa806100206000396000f3fe608060405234801561001057600080fd5b50600436106103c55760003560e01c80636c35b775116101ff578063b103feb01161011a578063db0d4579116100ad578063faecc97a1161007c578063faecc97a14610b7b578063fbf1c75514610b84578063fd86b32d14610b97578063ffe1681414610bd157600080fd5b8063db0d457914610b1d578063dc8ad5cb14610b3d578063f05d098214610b60578063f1d56d9714610b7357600080fd5b8063c3b83f5f116100e9578063c3b83f5f14610a99578063ceda8e9014610aac578063d28231bd14610acc578063d93dbbcb14610aef57600080fd5b8063b103feb014610a38578063b4fd729614610a4b578063b811e28014610a63578063bf989b6e14610a8657600080fd5b80638a42af3f1161019257806391b4ded91161016157806391b4ded9146109e45780639740a60c146109ed578063a73a39d814610a10578063ae71dcdf14610a3057600080fd5b80638a42af3f146108e35780638bf502a8146109265780638d37d0b21461094c5780638da5cb5b146109cb57600080fd5b80637dec0dac116101ce5780637dec0dac146108495780637e17027f1461085c5780637e6e97ab1461089f578063879cf437146108b257600080fd5b80636c35b775146107dc57806379ba5097146108055780637b17f7971461080d5780637d018f0f1461082057600080fd5b8063300a0298116102ef5780634dbbf3fe116102825780635938541f116102515780635938541f146107895780635bac88b01461079c5780635c975abb146107af5780635c9ef4a5146107bc57600080fd5b80634dbbf3fe1461071c578063509e2f331461072f57806351aa86ed1461074257806353a47bb71461077657600080fd5b80633cbf9a73116102be5780633cbf9a7314610671578063420209c214610694578063447b1d58146106c85780634adf7219146106fc57600080fd5b8063300a02981461062a578063343d372f1461063257806336b74f621461063b5780633baff8f11461064e57600080fd5b806316c38b3c116103675780631c8db097116103365780631c8db097146105b55780632978b568146105ec5780632b7ac3f31461060f5780632fff70201461062257600080fd5b806316c38b3c14610543578063186b39f7146105565780631999b9dc1461057b5780631afed5cc1461059e57600080fd5b806313af4035116103a357806313af4035146104c557806314bdaa89146104da57806314cb6a711461050d5780631627540c1461053057600080fd5b806305c84a54146103ca5780630fd59f561461040f57806310063fdc1461049a575b600080fd5b6103dd6103d8366004614a14565b610c05565b6040805161ffff9095168552600293840b60208601529190920b90830152151560608201526080015b60405180910390f35b61046861041d366004614a14565b602160209081526000938452604080852082529284528284209052825290208054600182015460029092015490919060ff8082169161ffff6101008204169163010000009091041685565b60408051958652602086019490945260ff9283169385019390935261ffff16606084015216608082015260a001610406565b6005546104ad906001600160a01b031681565b6040516001600160a01b039091168152602001610406565b6104d86104d3366004614476565b610d77565b005b6104fd6104e8366004614476565b60156020526000908152604090205460ff1681565b6040519015158152602001610406565b6104fd61051b3660046149b0565b60086020526000908152604090205460ff1681565b6104d861053e366004614476565b610eb7565b6104d8610551366004614978565b610f0d565b6105696105643660046149e9565b610f83565b60405160ff9091168152602001610406565b61058e6105893660046149b0565b610fd2565b6040516104069493929190614e98565b6105a761232881565b604051908152602001610406565b6105d96105c3366004614476565b60176020526000908152604090205461ffff1681565b60405161ffff9091168152602001610406565b6104fd6105fa366004614476565b601c6020526000908152604090205460ff1681565b6004546104ad906001600160a01b031681565b6105a7600181565b6105a7600281565b6105a761271a81565b6006546104ad906001600160a01b031681565b6104fd61065c366004614476565b600d6020526000908152604090205460ff1681565b6104fd61067f366004614476565b60226020526000908152604090205460ff1681565b6104fd6106a2366004614a14565b601960209081526000938452604080852082529284528284209052825290205460ff1681565b6104ad6106d6366004614720565b600c6020908152600092835260408084209091529082529020546001600160a01b031681565b6105a761070a366004614476565b60096020526000908152604090205481565b6104d861072a366004614476565b6115bc565b6104d861073d366004614600565b611614565b6104fd610750366004614a14565b601860209081526000938452604080852082529284528284209052825290205460ff1681565b6001546104ad906001600160a01b031681565b6104d8610797366004614476565b6116e2565b6104d86107aa366004614b91565b6118e4565b6003546104fd9060ff1681565b6107cf6107ca36600461474b565b611e0c565b6040516104069190614e4b565b6104ad6107ea366004614476565b6012602052600090815260409020546001600160a01b031681565b6104d861202f565b6104d861081b366004614c71565b61212c565b6104ad61082e3660046149b0565b6023602052600090815260409020546001600160a01b031681565b6105a76108573660046149c8565b61218d565b6104ad61086a36600461468d565b60116020908152600094855260408086208252938552838520815291845282842090915282529020546001600160a01b031681565b6107cf6108ad36600461488d565b6121be565b6105a76108c0366004614650565b601060209081526000938452604080852082529284528284209052825290205481565b6104ad6108f13660046146db565b600f6020908152600094855260408086208252938552838520815291845282842090915282529020546001600160a01b031681565b610939610934366004614a14565b612414565b6040516104069796959493929190614fe9565b61099e61095a366004614476565b6001600160a01b039081166000908152601260209081526040808320546009835281842054600a845282852054600b90945291909320549290931693909160ff1690565b604080516001600160a01b03909516855260208501939093529183015260ff166060820152608001610406565b6000546104ad906201000090046001600160a01b031681565b6105a760025481565b6104fd6109fb366004614476565b601d6020526000908152604090205460ff1681565b6105a7610a1e366004614476565b600a6020526000908152604090205481565b6105a7600081565b6105a7610a46366004614720565b6124fd565b6003546104ad9061010090046001600160a01b031681565b6104fd610a71366004614476565b601b6020526000908152604090205460ff1681565b6104d8610a943660046144b5565b612519565b6104d8610aa7366004614476565b6125cb565b6105a7610aba366004614476565b600e6020526000908152604090205481565b6104fd610ada366004614476565b60166020526000908152604090205460ff1681565b6104fd610afd3660046149c8565b601f60209081526000928352604080842090915290825290205460ff1681565b610b30610b2b366004614476565b6126e4565b6040516104069190614f75565b610569610b4b366004614476565b600b6020526000908152604090205460ff1681565b6104d8610b6e366004614510565b6126f5565b6105a760ff81565b6105a7612af881565b6104d8610b92366004614b11565b61288b565b6104ad610ba5366004614650565b60136020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6104fd610bdf366004614a14565b601a60209081526000938452604080852082529284528284209052825290205460ff1681565b6000838152600760209081526040808320858452825280832060ff8086168552908352818420825160e081018452815481526001820154948101949094526002810154909116918301919091526003810180548493849384938493606084019190610c6f906151ec565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9b906151ec565b8015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b820191906000526020600020905b815481529060010190602001808311610ccb57829003601f168201915b50505091835250506004919091015461ffff8116602080840191909152620100008204600290810b810b810b604080860191909152600160281b909304810b810b900b606090930192909252608083015160a084015160c09094015160009c8d5260188452828d209b8d529a8352818c2060ff9a8b168d52909252909920549899909890961695945050505050565b6001600160a01b038116610dd25760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f7420626520300000000000000060448201526064015b60405180910390fd5b600154600160a01b900460ff1615610e3e5760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610dc9565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b610ebf612be1565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610eac565b610f15612be1565b60035460ff1615158115151415610f295750565b6003805460ff191682151590811790915560ff1615610f4757426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001610eac565b50565b602080528260005260406000206020528160005260406000208181548110610faa57600080fd5b906000526020600020906020918282040191900692509250509054906101000a900460ff1681565b600354604051631f138de360e31b81526004810183905260609182918291829160009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561102557600080fd5b505afa158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105d9190614499565b90506000805b6000888152601e60205260409020548110156110ec576000888152601e602052604081208054839081106110a757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548b835281805260408084208285529092529120549091506110d69084615153565b92505080806110e490615221565b915050611063565b50806001600160401b0381111561111357634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561113c578160200160208202803683370190505b509550806001600160401b0381111561116557634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561118e578160200160208202803683370190505b509450806001600160401b038111156111b757634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156111e0578160200160208202803683370190505b509350806001600160401b0381111561120957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611232578160200160208202803683370190505b5092506000805b6000898152601e60205260409020548110156115b1576000898152601e6020526040812080548390811061127d57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548c8352818052604080842082855283528084208054825181860281018601909352808352929550909290919083018282801561130457602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116112d55790505b5050505050905060005b815181101561159b57600082828151811061133957634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160008f8152601983526040808220888352845280822060ff80851684529452902054909250161561158857838c878151811061139157634e487b7160e01b600052603260045260246000fd5b602002602001018181525050808b87815181106113be57634e487b7160e01b600052603260045260246000fd5b60ff92831660209182029290920181019190915260008f8152601a825260408082208883528352808220858516835290925220548b519116908b908890811061141757634e487b7160e01b600052603260045260246000fd5b911515602092830291909101909101526000611434898684612c5b565b600554604051638d924e7360e01b81529192506000916001600160a01b0390911690638d924e739061146a908590600401614e4b565b60006040518083038186803b15801561148257600080fd5b505afa158015611496573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114be91908101906147e6565b505050905060008b89815181106114e557634e487b7160e01b600052603260045260246000fd5b9115156020928302919091019091015260005b82518110156115775781818151811061152157634e487b7160e01b600052603260045260246000fd5b6020026020010151156115655760018c8a8151811061155057634e487b7160e01b600052603260045260246000fd5b91151560209283029190910190910152611577565b8061156f81615221565b9150506114f8565b508761158281615221565b98505050505b508061159381615221565b91505061130e565b50505080806115a990615221565b915050611239565b505050509193509193565b60035461010090046001600160a01b0316331461160b5760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9031b7b739bab6b2b960991b6044820152606401610dc9565b610f8081612d7d565b60035461010090046001600160a01b031633146116635760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9031b7b739bab6b2b960991b6044820152606401610dc9565b6001600160a01b0384166000908152601d602052604090205460ff16156116dc576001600160a01b0384166000908152600d60209081526040808320805460ff1990811688151517909155601b835281842080548216871515179055601c90925290912080549091168215151790556116dc8484612e71565b50505050565b6005546001600160a01b0316331461172b5760405162461bcd60e51b815260206004820152600c60248201526b27b7363c9036b0b730b3b2b960a11b6044820152606401610dc9565b6001600160a01b038082166000818152601260209081526040808320546009835281842054600a845282852054600b8552838620549290971680865260108552838620888752855283862060ff93841680885290865284872054978752602290955292909420549195939491166118dc576117a886600080612f2e565b60028110156117e5576000848152601a60209081526040808320868452825280832060ff861684529091529020805460ff191660011790556118b8565b600160005b8281101561187f576001600160a01b038088166000908152600f60209081526040808320898452825280832060ff808a16855290835281842086855283528184205490941680845260229092529091205490911615801561185d5750886001600160a01b0316816001600160a01b031614155b1561186c57600092505061187f565b508061187781615221565b9150506117ea565b5080156118b6576000858152601a60209081526040808320878452825280832060ff871684529091529020805460ff191660011790555b505b6001600160a01b0386166000908152602260205260409020805460ff191660011790555b505050505050565b6006546001600160a01b0316331461192f5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610dc9565b6003548251604051631f138de360e31b8152600481019190915260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561197c57600080fd5b505afa158015611990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b49190614499565b90506001600160a01b038116158015906119dc575060008281526008602052604090205460ff165b15611e07576119ea83612ffb565b15611d62578251600090815260186020908152604080832082870151845282528083208187015160ff90811685529252909120541680611a4257506001600160a01b0381166000908152601b602052604090205460ff165b80611a6557506001600160a01b0381166000908152601c602052604090205460ff165b15611aca578251600090815260186020908152604080832082870151845282528083208187015160ff1684528252808320805460ff199081169091556001600160a01b0385168452601b8352818420805482169055601c909252909120805490911690555b8251600090815260076020908152604080832082870180518552908352818420828801805160ff9081168752918552929094208751815590516001820155905160028201805460ff1916919094161790925560608501518051869392611b37926003850192910190614187565b5060808201516004909101805460a084015160c090940151600290810b62ffffff908116600160281b0267ffffff0000000000199690920b16620100000264ffffffffff1990921661ffff9094169390931717929092161790556000611b9d84836130a3565b6001600160a01b0383166000908152600d60209081526040808320805460ff19908116909155601d83528184208054909116600117905587518352601f825280832088830151845290915290205490915060ff16611c435783516000908152601f6020908152604080832082880180518552908352818420805460ff1916600190811790915588518552601e845291842090518154928301825590845291909220909101555b8351600090815260196020908152604080832082880151845282528083208188015160ff908116855292529091205416611cfc578351600090815260196020908152604080832082880180518552908352818420828901805160ff9081168752918552838620805460ff191660019081179091558a51875285805284872093518752928552928520925183549283018455928552938390209281049092018054918416601f9093166101000a9283029290930219161790555b83516020808601516040808801516001600160a01b038616600090815260149094529281902090517fc61be96f161d85045cec8df9adaf89ad271f38b3ad65ffd65003c4af0eb1278494611d54949093929091614f88565b60405180910390a150505050565b8251600090815260186020908152604080832082870151845282528083208187015160ff1684529091529020805460ff19166001908117909155611da7908490613409565b50825160208085015160408087015181516001600160a01b03871681529384019490945282015260ff90911660608201527fb01bde7f1f22703d0c6d3f5cd2c574f64158d9ed6dd21cb3d83f08174898b978906080015b60405180910390a15b505050565b60606000805b8351811015611e8757600e6000858381518110611e3f57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482611e739190615153565b915080611e7f81615221565b915050611e12565b50806001600160401b03811115611eae57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611ed7578160200160208202803683370190505b5091506000805b8451811015612027576000600e6000878481518110611f0d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054905060005b81811015612012576000600c6000898681518110611f6957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600083815260200190815260200160002060009054906101000a90046001600160a01b0316905080878681518110611fd957634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015284611ffb81615221565b95505050808061200a90615221565b915050611f3b565b5050808061201f90615221565b915050611ede565b505050919050565b6001546001600160a01b031633146120a75760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610dc9565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b612134612be1565b600082815260086020908152604091829020805460ff19168415159081179091558251858152918201527f929eaf016075fe0cd58ebe9e1c169deb9e2591960438ff5a324740440a150db1910160405180910390a15050565b601e60205281600052604060002081815481106121a957600080fd5b90600052602060002001600091509150505481565b606082516001600160401b038111156121e757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612210578160200160208202803683370190505b50905060005b835181101561240d5760006023600086848151811061224557634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600020546001600160a01b031690506122748161352e565b83838151811061229457634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060006001600160a01b03168383815181106122df57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156123fa57600360019054906101000a90046001600160a01b03166001600160a01b031663e48ef05c85848151811061233a57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161235e919061509e565b60206040518083038186803b15801561237657600080fd5b505afa15801561238a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ae9190614499565b90506123b98161352e565b8383815181106123d957634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b0316815250505b508061240581615221565b915050612216565b5092915050565b600760209081526000938452604080852082529284528284209052825290208054600182015460028301546003840180549394929360ff9092169291612459906151ec565b80601f0160208091040260200160405190810160405280929190818152602001828054612485906151ec565b80156124d25780601f106124a7576101008083540402835291602001916124d2565b820191906000526020600020905b8154815290600101906020018083116124b557829003601f168201915b5050506004909301549192505061ffff811690620100008104600290810b91600160281b9004900b87565b601460205281600052604060002081815481106121a957600080fd5b612521612be1565b60038054610100600160a81b0319166101006001600160a01b0387811691820292909217909255600480546001600160a01b0319908116878416908117909255600580548216878516908117909155600680549092169386169384179091556040805194855260208501929092529083015260608201527fa2cad6ae2699ea86ba233a96ca0e57d895983eeed04f6bd0a770187c58b820dd9060800160405180910390a150505050565b6125d3612be1565b6001600160a01b03811661261b5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610dc9565b600154600160a81b900460ff161561266b5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610dc9565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101610eac565b60606126ef82613642565b92915050565b600054610100900460ff166127105760005460ff1615612714565b303b155b6127775760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610dc9565b600054610100900460ff16158015612799576000805461ffff19166101011790555b6127a287610d77565b60038054610100600160a81b0319166101006001600160a01b038981169190910291909117909155600480546001600160a01b0319908116888416179091556005805482168784161790556006805490911691851691909117905560005b825181101561286f5760016008600085848151811061282f57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550808061286790615221565b915050612800565b508015612882576000805461ff00191690555b50505050505050565b6006546001600160a01b031633146128d65760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610dc9565b6003548151604051631f138de360e31b8152600481019190915260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561292357600080fd5b505afa158015612937573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295b9190614499565b6001600160a01b038116600090815260106020908152604080832086830180518552908352818420878301805160ff90811687529185528386205489518752601a865284872093518752928552838620905182168652909352922054929350909116611e075760005b81811015612b28576001600160a01b038084166000908152600f6020908152604080832088830151845282528083208882015160ff9081168552908352818420868552835281842054909416808452602290925290912054909116612b15578451600090815260186020908152604080832082890151845282528083208189015160ff90811685529252909120541615612ac25760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90612a8f908490600090600401614e30565b600060405180830381600087803b158015612aa957600080fd5b505af1158015612abd573d6000803e3d6000fd5b505050505b60ff856080015160ff161415612ae357612ade81600080612f2e565b612af1565b612af18186606001516136dc565b6001600160a01b0381166000908152602260205260409020805460ff191660011790555b5080612b2081615221565b9150506129c4565b508251600090815260216020908152604080832082870180518552908352818420828801805160ff90811687529185528386208951808255845160018084019190915583516002909301805460608e015160808f0151881663010000000263ff0000001961ffff9092166101000262ffffff19909316968916969096179190911716939093179092558752601a86528487209351875292855283862090519091168552909252909120805460ff19169091179055505050565b6000546201000090046001600160a01b03163314612c595760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610dc9565b565b6001600160a01b0383166000908152601060209081526040808320858452825280832060ff85168452909152902054606090806001600160401b03811115612cb357634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612cdc578160200160208202803683370190505b50915060005b81811015612d74576001600160a01b038087166000908152600f60209081526040808320898452825280832060ff89168452825280832085845290915290205484519116908190859084908110612d4957634e487b7160e01b600052603260045260246000fd5b6001600160a01b03909216602092830291909101909101525080612d6c81615221565b915050612ce2565b50509392505050565b60005b6001600160a01b0382166000908152600e6020526040902054811015612e6d576001600160a01b038083166000908152600c60209081526040808320858452825280832054909316825260229052205460ff16612e5b576005546001600160a01b038381166000908152600c6020908152604080832086845290915280822054905163b91f5e3560e01b81529083166004820152602481019190915291169063b91f5e3590604401600060405180830381600087803b158015612e4257600080fd5b505af1158015612e56573d6000803e3d6000fd5b505050505b80612e6581615221565b915050612d80565b5050565b60005b6001600160a01b0383166000908152600e6020526040902054811015611e07576003546001600160a01b038481166000908152600c602090815260408083208684529091529081902054905163ed5e00eb60e01b815261010090930482169263ed5e00eb92612ee99216908690600401614e30565b600060405180830381600087803b158015612f0357600080fd5b505af1158015612f17573d6000803e3d6000fd5b505050508080612f2690615221565b915050612e74565b60055460405163b91f5e3560e01b81526001600160a01b038581166004830152602482018490529091169063b91f5e3590604401600060405180830381600087803b158015612f7c57600080fd5b505af1158015612f90573d6000803e3d6000fd5b505050506001600160a01b038381166000818152601260209081526040918290205482519384529083018590529092169181019190915261ffff831660608201527f7b72264d363f766973a07f09021df5169917b274b948b57fb5028ecc3cc9b5cd90608001611dfe565b60048054608083015160a084015160c0850151604051631743f79b60e21b815261ffff90931694830194909452600290810b60248301529290920b60448301526000916001600160a01b0390911690635d0fde6c9060640160206040518083038186803b15801561306b57600080fd5b505afa15801561307f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ef9190614994565b6001600160a01b038082166000818152600e60209081526040808320546013835281842088840180518652908452828520898401805160ff908116885291865284872054978752601186528487209251875291855283862091511685528352818420608089015161ffff168552909252822054919390159281169116828061313257506001600160a01b038116155b156132215760006131438787613746565b6001600160a01b0387811660009081526013602090815260408083208c830151845282528083208c82015160ff168452909152902080546001600160a01b0319168383161790559091508316156131fe5760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb906131cb908690600190600401614e30565b600060405180830381600087803b1580156131e557600080fd5b505af11580156131f9573d6000803e3d6000fd5b505050505b61321681886000015189602001518a60400151613a51565b93506126ef92505050565b816001600160a01b0316816001600160a01b0316146133755760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90613271908490600090600401614e30565b600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505060035460405163ed5e00eb60e01b81526101009091046001600160a01b0316925063ed5e00eb91506132da908590600190600401614e30565b600060405180830381600087803b1580156132f457600080fd5b505af1158015613308573d6000803e3d6000fd5b505050506001600160a01b0385811660009081526013602090815260408083208a8301805185529083528184208b8301805160ff1686529352922080546001600160a01b0319169385169390931790925587519051915161336b92849291613a51565b92506126ef915050565b60035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb906133ac908590600090600401614e30565b600060405180830381600087803b1580156133c657600080fd5b505af11580156133da573d6000803e3d6000fd5b505050506133f682876000015188602001518960400151613a51565b5091506126ef9050565b50505092915050565b6003548251604051631f138de360e31b8152600481019190915260009182916101009091046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561345957600080fd5b505afa15801561346d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134919190614499565b6001600160a01b038116600090815260106020908152604080832088830151845282528083208882015160ff1684529091528120549192505b81811015613400576001600160a01b038084166000908152600f602090815260408083208a830151845282528083208a82015160ff16845282528083208584529091529020541661351b8187613ab3565b508061352681615221565b9150506134ca565b60006001600160a01b0382161561363d576000826001600160a01b0316639e3b34bf6040518163ffffffff1660e01b8152600401604080518083038186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b19190614ca0565b5090504281101580156136325750826001600160a01b0316633f6fa6556040518163ffffffff1660e01b815260040160206040518083038186803b1580156135f857600080fd5b505afa15801561360c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136309190614994565b155b1561363b578291505b505b919050565b6001600160a01b03811660009081526015602052604090205460609060ff166136735761366e82613b17565b6126ef565b6001600160a01b038216600090815260146020908152604091829020805483518184028101840190945280845290918301828280156136d157602002820191906000526020600020905b8154815260200190600101908083116136bd575b505050505092915050565b6001600160a01b03821660009081526017602052604081205461ffff16908161370684606461517f565b61ffff16116137365761ffff821661371f84606461517f565b61ffff161061372f576000613739565b6002613739565b60015b90506116dc848483612f2e565b6003548251604051631c2ab73160e21b8152600481019190915260009182916137db9161010090046001600160a01b0316906370aadcc49060240160206040518083038186803b15801561379957600080fd5b505afa1580156137ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137d19190614c59565b8560400151613b54565b60055485519192506001600160a01b031690634cde32ce906137fc87613c24565b600354885160405163c48e62f160e01b815260048101919091526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b15801561384757600080fd5b505afa15801561385b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526138839190810190614a3f565b60200151600060028760018b6040518963ffffffff1660e01b81526004016138b2989796959493929190615038565b602060405180830381600087803b1580156138cc57600080fd5b505af11580156138e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139049190614499565b5060055460408051622610c560e41b815290516001600160a01b039092169163dd5adfa39160019184916302610c50916004808301926020929190829003018186803b15801561395357600080fd5b505afa158015613967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061398b9190614c59565b61399591906151a9565b6040518263ffffffff1660e01b81526004016139b391815260200190565b60206040518083038186803b1580156139cb57600080fd5b505afa1580156139df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a039190614499565b915061240d846000015184848760800151886020015189606001518a6040015188600281518110613a4457634e487b7160e01b600052603260045260246000fd5b6020026020010151613c74565b613a5c838383613eef565b6001600160a01b03851660009081526014602090815260409091208251613a89939192919091019061420b565b5050506001600160a01b039091166000908152601560205260409020805460ff1916600117905550565b60035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90613ae99085908590600401614e30565b600060405180830381600087803b158015613b0357600080fd5b505af11580156118dc573d6000803e3d6000fd5b6001600160a01b038116600090815260096020908152604080832054600a835281842054600b9093529220546060926126ef92909160ff16613eef565b6040805160038082526080820190925260609160009190602082018480368337019050509050613b8684612328615153565b81600081518110613ba757634e487b7160e01b600052603260045260246000fd5b60200260200101818152505061271a81600181518110613bd757634e487b7160e01b600052603260045260246000fd5b6020908102919091010152613bf160ff8416612af8615153565b81600281518110613c1257634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b60608160600151613c3b836040015160ff16614066565b613c4c846080015161ffff16614066565b604051602001613c5e93929190614d5a565b6040516020818303038152906040529050919050565b600354604051624dc46d60e41b8152600481018a90526001600160a01b038881166024830152610100909204909116906304dc46d090604401600060405180830381600087803b158015613cc757600080fd5b505af1158015613cdb573d6000803e3d6000fd5b505050506001600160a01b0386811660008181526009602090815260408083208d9055600a8252808320899055888352602382528083208054958d166001600160a01b03199687168117909155848452600b8352818420805460ff8a1660ff19918216179091556016845282852080549091166001908117909155601284528285208054881683179055818552600c8452828520600e808652848720805488529186529386208054909816909617909655835290528154613d9d908490615153565b90915550506001600160a01b038088166000818152601160209081526040808320898452825280832060ff881680855290835281842061ffff8c168086529084528285208054978e166001600160a01b0319988916811790915580865260178552838620805461ffff1916909217909155858552601384528285208b8652845282852082865284528285208054881682179055858552600f84528285208b865284528285208286528452828520958552601084528285208b865284528285208286528085528386208054875296855292852080549097161790955593825292909252805460019290613e90908490615153565b909155507fad561eb279f0551643e940bd69a05112c9f5e19962eae3312d6490409e19410e905087878a87878a88613ec786613642565b89604051613edd99989796959493929190614db6565b60405180910390a15050505050505050565b604080516002808252606080830184529260009291906020830190803683375050506000868152600760209081526040808320888452825280832060ff881684529091528120600401548251929350620100009004600290810b900b91839190613f6957634e487b7160e01b600052603260045260246000fd5b6020908102919091018101919091526000868152600782526040808220878352835280822060ff8716835290925220600401548151600160281b909104600290810b900b9082906001908110613fcf57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d9749161400991859101614f3d565b60006040518083038186803b15801561402157600080fd5b505afa158015614035573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261405d9190810190614946565b95945050505050565b60608161408a5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156140b4578061409e81615221565b91506140ad9050600a8361516b565b915061408e565b6000816001600160401b038111156140dc57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614106576020820181803683370190505b5090505b841561417f5761411b6001836151a9565b9150614128600a8661523c565b614133906030615153565b60f81b81838151811061415657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350614178600a8661516b565b945061410a565b949350505050565b828054614193906151ec565b90600052602060002090601f0160209004810192826141b557600085556141fb565b82601f106141ce57805160ff19168380011785556141fb565b828001600101855582156141fb579182015b828111156141fb5782518255916020019190600101906141e0565b50614207929150614245565b5090565b8280548282559060005260206000209081019282156141fb57916020028201828111156141fb5782518255916020019190600101906141e0565b5b808211156142075760008155600101614246565b600082601f83011261426a578081fd5b8151602061427f61427a83615109565b6150d9565b80838252828201915082860187848660051b890101111561429e578586fd5b855b858110156142c55781516142b3816152a7565b845292840192908401906001016142a0565b5090979650505050505050565b600082601f8301126142e2578081fd5b813560206142f261427a83615109565b80838252828201915082860187848660051b8901011115614311578586fd5b855b858110156142c55781356001600160401b03811115614330578788fd5b61433e8a87838c01016143c4565b8552509284019290840190600101614313565b600082601f830112614361578081fd5b8151602061437161427a83615109565b80838252828201915082860187848660051b8901011115614390578586fd5b855b858110156142c557815184529284019290840190600101614392565b803561363d816152b5565b805161363d816152b5565b600082601f8301126143d4578081fd5b81356143e261427a8261512c565b8181528460208386010111156143f6578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112614420578081fd5b815161442e61427a8261512c565b818152846020838601011115614442578283fd5b61417f8260208301602087016151c0565b803561ffff8116811461363d57600080fd5b803560ff8116811461363d57600080fd5b600060208284031215614487578081fd5b813561449281615292565b9392505050565b6000602082840312156144aa578081fd5b815161449281615292565b600080600080608085870312156144ca578283fd5b84356144d581615292565b935060208501356144e581615292565b925060408501356144f581615292565b9150606085013561450581615292565b939692955090935050565b60008060008060008060c08789031215614528578384fd5b863561453381615292565b955060208781013561454481615292565b9550604088013561455481615292565b9450606088013561456481615292565b9350608088013561457481615292565b925060a08801356001600160401b0381111561458e578283fd5b8801601f81018a1361459e578283fd5b80356145ac61427a82615109565b8082825284820191508484018d868560051b87010111156145cb578687fd5b8694505b838510156145ed5780358352600194909401939185019185016145cf565b5080955050505050509295509295509295565b60008060008060808587031215614615578182fd5b843561462081615292565b93506020850135614630816152a7565b92506040850135614640816152a7565b91506060850135614505816152a7565b600080600060608486031215614664578081fd5b833561466f81615292565b92506020840135915061468460408501614465565b90509250925092565b600080600080608085870312156146a2578182fd5b84356146ad81615292565b9350602085013592506146c260408601614465565b91506146d060608601614453565b905092959194509250565b600080600080608085870312156146f0578182fd5b84356146fb81615292565b93506020850135925061471060408601614465565b9396929550929360600135925050565b60008060408385031215614732578182fd5b823561473d81615292565b946020939093013593505050565b6000602080838503121561475d578182fd5b82356001600160401b03811115614772578283fd5b8301601f81018513614782578283fd5b803561479061427a82615109565b80828252848201915084840188868560051b87010111156147af578687fd5b8694505b838510156147da5780356147c681615292565b8352600194909401939185019185016147b3565b50979650505050505050565b600080600080608085870312156147fb578182fd5b84516001600160401b0380821115614811578384fd5b61481d8883890161425a565b95506020870151915080821115614832578384fd5b61483e8883890161425a565b94506040870151915080821115614853578384fd5b61485f8883890161425a565b93506060870151915080821115614874578283fd5b5061488187828801614351565b91505092959194509250565b6000806040838503121561489f578182fd5b82356001600160401b03808211156148b5578384fd5b818501915085601f8301126148c8578384fd5b813560206148d861427a83615109565b8083825282820191508286018a848660051b89010111156148f7578889fd5b8896505b848710156149195780358352600196909601959183019183016148fb565b509650508601359250508082111561492f578283fd5b5061493c858286016142d2565b9150509250929050565b600060208284031215614957578081fd5b81516001600160401b0381111561496c578182fd5b61417f84828501614351565b600060208284031215614989578081fd5b8135614492816152a7565b6000602082840312156149a5578081fd5b8151614492816152a7565b6000602082840312156149c1578081fd5b5035919050565b600080604083850312156149da578182fd5b50508035926020909101359150565b6000806000606084860312156149fd578081fd5b505081359360208301359350604090920135919050565b600080600060608486031215614a28578081fd5b833592506020840135915061468460408501614465565b600060208284031215614a50578081fd5b81516001600160401b0380821115614a66578283fd5b9083019060e08286031215614a79578283fd5b614a816150b1565b8251815260208301516020820152614a9b604084016143b9565b6040820152614aac606084016143b9565b6060820152614abd608084016143b9565b608082015260a083015182811115614ad3578485fd5b614adf87828601614410565b60a08301525060c083015182811115614af6578485fd5b614b0287828601614410565b60c08301525095945050505050565b600060a08284031215614b22578081fd5b60405160a081018181106001600160401b0382111715614b4457614b4461527c565b80604052508235815260208301356020820152614b6360408401614465565b6040820152614b7460608401614453565b6060820152614b8560808401614465565b60808201529392505050565b60008060408385031215614ba3578182fd5b82356001600160401b0380821115614bb9578384fd5b9084019060e08287031215614bcc578384fd5b614bd46150b1565b8235815260208301356020820152614bee60408401614465565b6040820152606083013582811115614c04578586fd5b614c10888286016143c4565b606083015250614c2260808401614453565b6080820152614c3360a084016143ae565b60a0820152614c4460c084016143ae565b60c08201529660209590950135955050505050565b600060208284031215614c6a578081fd5b5051919050565b60008060408385031215614c83578182fd5b823591506020830135614c95816152a7565b809150509250929050565b60008060408385031215614cb2578182fd5b505080516020909101519092909150565b6000815180845260208085019450808401835b83811015614cf4578151151587529582019590820190600101614cd6565b509495945050505050565b6000815180845260208085019450808401835b83811015614cf457815187529582019590820190600101614d12565b60008151808452614d468160208601602086016151c0565b601f01601f19169290920160200192915050565b60008451614d6c8184602089016151c0565b80830190506201016960ed1b8082528551614d8e816003850160208a016151c0565b60039201918201528351614da98160068401602088016151c0565b0160060195945050505050565b6001600160a01b038a8116825289166020820152604081018890526060810187905261012060808201819052600090614df183820189614d2e565b905061ffff871660a084015260ff861660c084015282810360e0840152614e188186614cff565b915050826101008301529a9950505050505050505050565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015614e8c5783516001600160a01b031683529284019291840191600101614e67565b50909695505050505050565b6080808252855190820181905260009060209060a0840190828901845b82811015614ed157815184529284019290840190600101614eb5565b50505083810382850152865180825287830191830190845b81811015614f0857835160ff1683529284019291840191600101614ee9565b50508481036040860152614f1c8188614cc3565b925050508281036060840152614f328185614cc3565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614e8c57835183529284019291840191600101614f59565b6020815260006144926020830184614cff565b6000608082018683526020868185015260ff861660408501526080606085015281855480845260a0860191508685528285209350845b81811015614fda57845483526001948501949284019201614fbe565b50909998505050505050505050565b87815286602082015260ff8616604082015260e06060820152600061501160e0830187614d2e565b61ffff95909516608083015250600292830b60a0820152910b60c090910152949350505050565b60006101008a83528060208401526150528184018b614d2e565b905088604084015287606084015286608084015282810360a08401526150788187614cff565b94151560c084015250506001600160a01b039190911660e0909101529695505050505050565b6020815260006144926020830184614d2e565b60405160e081016001600160401b03811182821017156150d3576150d361527c565b60405290565b604051601f8201601f191681016001600160401b03811182821017156151015761510161527c565b604052919050565b60006001600160401b038211156151225761512261527c565b5060051b60200190565b60006001600160401b038211156151455761514561527c565b50601f01601f191660200190565b6000821982111561516657615166615250565b500190565b60008261517a5761517a615266565b500490565b600061ffff808316818516818304811182151516156151a0576151a0615250565b02949350505050565b6000828210156151bb576151bb615250565b500390565b60005b838110156151db5781810151838201526020016151c3565b838111156116dc5750506000910152565b600181811c9082168061520057607f821691505b6020821081141561363b57634e487b7160e01b600052602260045260246000fd5b600060001982141561523557615235615250565b5060010190565b60008261524b5761524b615266565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f8057600080fd5b8015158114610f8057600080fd5b8060020b8114610f8057600080fdfea2646970667358221220d9a7b2f0d65bfbe53a7669e37bd38e27ab6cc4bd175e41101173cc1b8e7d6a9764736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103c55760003560e01c80636c35b775116101ff578063b103feb01161011a578063db0d4579116100ad578063faecc97a1161007c578063faecc97a14610b7b578063fbf1c75514610b84578063fd86b32d14610b97578063ffe1681414610bd157600080fd5b8063db0d457914610b1d578063dc8ad5cb14610b3d578063f05d098214610b60578063f1d56d9714610b7357600080fd5b8063c3b83f5f116100e9578063c3b83f5f14610a99578063ceda8e9014610aac578063d28231bd14610acc578063d93dbbcb14610aef57600080fd5b8063b103feb014610a38578063b4fd729614610a4b578063b811e28014610a63578063bf989b6e14610a8657600080fd5b80638a42af3f1161019257806391b4ded91161016157806391b4ded9146109e45780639740a60c146109ed578063a73a39d814610a10578063ae71dcdf14610a3057600080fd5b80638a42af3f146108e35780638bf502a8146109265780638d37d0b21461094c5780638da5cb5b146109cb57600080fd5b80637dec0dac116101ce5780637dec0dac146108495780637e17027f1461085c5780637e6e97ab1461089f578063879cf437146108b257600080fd5b80636c35b775146107dc57806379ba5097146108055780637b17f7971461080d5780637d018f0f1461082057600080fd5b8063300a0298116102ef5780634dbbf3fe116102825780635938541f116102515780635938541f146107895780635bac88b01461079c5780635c975abb146107af5780635c9ef4a5146107bc57600080fd5b80634dbbf3fe1461071c578063509e2f331461072f57806351aa86ed1461074257806353a47bb71461077657600080fd5b80633cbf9a73116102be5780633cbf9a7314610671578063420209c214610694578063447b1d58146106c85780634adf7219146106fc57600080fd5b8063300a02981461062a578063343d372f1461063257806336b74f621461063b5780633baff8f11461064e57600080fd5b806316c38b3c116103675780631c8db097116103365780631c8db097146105b55780632978b568146105ec5780632b7ac3f31461060f5780632fff70201461062257600080fd5b806316c38b3c14610543578063186b39f7146105565780631999b9dc1461057b5780631afed5cc1461059e57600080fd5b806313af4035116103a357806313af4035146104c557806314bdaa89146104da57806314cb6a711461050d5780631627540c1461053057600080fd5b806305c84a54146103ca5780630fd59f561461040f57806310063fdc1461049a575b600080fd5b6103dd6103d8366004614a14565b610c05565b6040805161ffff9095168552600293840b60208601529190920b90830152151560608201526080015b60405180910390f35b61046861041d366004614a14565b602160209081526000938452604080852082529284528284209052825290208054600182015460029092015490919060ff8082169161ffff6101008204169163010000009091041685565b60408051958652602086019490945260ff9283169385019390935261ffff16606084015216608082015260a001610406565b6005546104ad906001600160a01b031681565b6040516001600160a01b039091168152602001610406565b6104d86104d3366004614476565b610d77565b005b6104fd6104e8366004614476565b60156020526000908152604090205460ff1681565b6040519015158152602001610406565b6104fd61051b3660046149b0565b60086020526000908152604090205460ff1681565b6104d861053e366004614476565b610eb7565b6104d8610551366004614978565b610f0d565b6105696105643660046149e9565b610f83565b60405160ff9091168152602001610406565b61058e6105893660046149b0565b610fd2565b6040516104069493929190614e98565b6105a761232881565b604051908152602001610406565b6105d96105c3366004614476565b60176020526000908152604090205461ffff1681565b60405161ffff9091168152602001610406565b6104fd6105fa366004614476565b601c6020526000908152604090205460ff1681565b6004546104ad906001600160a01b031681565b6105a7600181565b6105a7600281565b6105a761271a81565b6006546104ad906001600160a01b031681565b6104fd61065c366004614476565b600d6020526000908152604090205460ff1681565b6104fd61067f366004614476565b60226020526000908152604090205460ff1681565b6104fd6106a2366004614a14565b601960209081526000938452604080852082529284528284209052825290205460ff1681565b6104ad6106d6366004614720565b600c6020908152600092835260408084209091529082529020546001600160a01b031681565b6105a761070a366004614476565b60096020526000908152604090205481565b6104d861072a366004614476565b6115bc565b6104d861073d366004614600565b611614565b6104fd610750366004614a14565b601860209081526000938452604080852082529284528284209052825290205460ff1681565b6001546104ad906001600160a01b031681565b6104d8610797366004614476565b6116e2565b6104d86107aa366004614b91565b6118e4565b6003546104fd9060ff1681565b6107cf6107ca36600461474b565b611e0c565b6040516104069190614e4b565b6104ad6107ea366004614476565b6012602052600090815260409020546001600160a01b031681565b6104d861202f565b6104d861081b366004614c71565b61212c565b6104ad61082e3660046149b0565b6023602052600090815260409020546001600160a01b031681565b6105a76108573660046149c8565b61218d565b6104ad61086a36600461468d565b60116020908152600094855260408086208252938552838520815291845282842090915282529020546001600160a01b031681565b6107cf6108ad36600461488d565b6121be565b6105a76108c0366004614650565b601060209081526000938452604080852082529284528284209052825290205481565b6104ad6108f13660046146db565b600f6020908152600094855260408086208252938552838520815291845282842090915282529020546001600160a01b031681565b610939610934366004614a14565b612414565b6040516104069796959493929190614fe9565b61099e61095a366004614476565b6001600160a01b039081166000908152601260209081526040808320546009835281842054600a845282852054600b90945291909320549290931693909160ff1690565b604080516001600160a01b03909516855260208501939093529183015260ff166060820152608001610406565b6000546104ad906201000090046001600160a01b031681565b6105a760025481565b6104fd6109fb366004614476565b601d6020526000908152604090205460ff1681565b6105a7610a1e366004614476565b600a6020526000908152604090205481565b6105a7600081565b6105a7610a46366004614720565b6124fd565b6003546104ad9061010090046001600160a01b031681565b6104fd610a71366004614476565b601b6020526000908152604090205460ff1681565b6104d8610a943660046144b5565b612519565b6104d8610aa7366004614476565b6125cb565b6105a7610aba366004614476565b600e6020526000908152604090205481565b6104fd610ada366004614476565b60166020526000908152604090205460ff1681565b6104fd610afd3660046149c8565b601f60209081526000928352604080842090915290825290205460ff1681565b610b30610b2b366004614476565b6126e4565b6040516104069190614f75565b610569610b4b366004614476565b600b6020526000908152604090205460ff1681565b6104d8610b6e366004614510565b6126f5565b6105a760ff81565b6105a7612af881565b6104d8610b92366004614b11565b61288b565b6104ad610ba5366004614650565b60136020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6104fd610bdf366004614a14565b601a60209081526000938452604080852082529284528284209052825290205460ff1681565b6000838152600760209081526040808320858452825280832060ff8086168552908352818420825160e081018452815481526001820154948101949094526002810154909116918301919091526003810180548493849384938493606084019190610c6f906151ec565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9b906151ec565b8015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b820191906000526020600020905b815481529060010190602001808311610ccb57829003601f168201915b50505091835250506004919091015461ffff8116602080840191909152620100008204600290810b810b810b604080860191909152600160281b909304810b810b900b606090930192909252608083015160a084015160c09094015160009c8d5260188452828d209b8d529a8352818c2060ff9a8b168d52909252909920549899909890961695945050505050565b6001600160a01b038116610dd25760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f7420626520300000000000000060448201526064015b60405180910390fd5b600154600160a01b900460ff1615610e3e5760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610dc9565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b610ebf612be1565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610eac565b610f15612be1565b60035460ff1615158115151415610f295750565b6003805460ff191682151590811790915560ff1615610f4757426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001610eac565b50565b602080528260005260406000206020528160005260406000208181548110610faa57600080fd5b906000526020600020906020918282040191900692509250509054906101000a900460ff1681565b600354604051631f138de360e31b81526004810183905260609182918291829160009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561102557600080fd5b505afa158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105d9190614499565b90506000805b6000888152601e60205260409020548110156110ec576000888152601e602052604081208054839081106110a757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548b835281805260408084208285529092529120549091506110d69084615153565b92505080806110e490615221565b915050611063565b50806001600160401b0381111561111357634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561113c578160200160208202803683370190505b509550806001600160401b0381111561116557634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561118e578160200160208202803683370190505b509450806001600160401b038111156111b757634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156111e0578160200160208202803683370190505b509350806001600160401b0381111561120957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611232578160200160208202803683370190505b5092506000805b6000898152601e60205260409020548110156115b1576000898152601e6020526040812080548390811061127d57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548c8352818052604080842082855283528084208054825181860281018601909352808352929550909290919083018282801561130457602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116112d55790505b5050505050905060005b815181101561159b57600082828151811061133957634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160008f8152601983526040808220888352845280822060ff80851684529452902054909250161561158857838c878151811061139157634e487b7160e01b600052603260045260246000fd5b602002602001018181525050808b87815181106113be57634e487b7160e01b600052603260045260246000fd5b60ff92831660209182029290920181019190915260008f8152601a825260408082208883528352808220858516835290925220548b519116908b908890811061141757634e487b7160e01b600052603260045260246000fd5b911515602092830291909101909101526000611434898684612c5b565b600554604051638d924e7360e01b81529192506000916001600160a01b0390911690638d924e739061146a908590600401614e4b565b60006040518083038186803b15801561148257600080fd5b505afa158015611496573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114be91908101906147e6565b505050905060008b89815181106114e557634e487b7160e01b600052603260045260246000fd5b9115156020928302919091019091015260005b82518110156115775781818151811061152157634e487b7160e01b600052603260045260246000fd5b6020026020010151156115655760018c8a8151811061155057634e487b7160e01b600052603260045260246000fd5b91151560209283029190910190910152611577565b8061156f81615221565b9150506114f8565b508761158281615221565b98505050505b508061159381615221565b91505061130e565b50505080806115a990615221565b915050611239565b505050509193509193565b60035461010090046001600160a01b0316331461160b5760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9031b7b739bab6b2b960991b6044820152606401610dc9565b610f8081612d7d565b60035461010090046001600160a01b031633146116635760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9031b7b739bab6b2b960991b6044820152606401610dc9565b6001600160a01b0384166000908152601d602052604090205460ff16156116dc576001600160a01b0384166000908152600d60209081526040808320805460ff1990811688151517909155601b835281842080548216871515179055601c90925290912080549091168215151790556116dc8484612e71565b50505050565b6005546001600160a01b0316331461172b5760405162461bcd60e51b815260206004820152600c60248201526b27b7363c9036b0b730b3b2b960a11b6044820152606401610dc9565b6001600160a01b038082166000818152601260209081526040808320546009835281842054600a845282852054600b8552838620549290971680865260108552838620888752855283862060ff93841680885290865284872054978752602290955292909420549195939491166118dc576117a886600080612f2e565b60028110156117e5576000848152601a60209081526040808320868452825280832060ff861684529091529020805460ff191660011790556118b8565b600160005b8281101561187f576001600160a01b038088166000908152600f60209081526040808320898452825280832060ff808a16855290835281842086855283528184205490941680845260229092529091205490911615801561185d5750886001600160a01b0316816001600160a01b031614155b1561186c57600092505061187f565b508061187781615221565b9150506117ea565b5080156118b6576000858152601a60209081526040808320878452825280832060ff871684529091529020805460ff191660011790555b505b6001600160a01b0386166000908152602260205260409020805460ff191660011790555b505050505050565b6006546001600160a01b0316331461192f5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610dc9565b6003548251604051631f138de360e31b8152600481019190915260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561197c57600080fd5b505afa158015611990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b49190614499565b90506001600160a01b038116158015906119dc575060008281526008602052604090205460ff165b15611e07576119ea83612ffb565b15611d62578251600090815260186020908152604080832082870151845282528083208187015160ff90811685529252909120541680611a4257506001600160a01b0381166000908152601b602052604090205460ff165b80611a6557506001600160a01b0381166000908152601c602052604090205460ff165b15611aca578251600090815260186020908152604080832082870151845282528083208187015160ff1684528252808320805460ff199081169091556001600160a01b0385168452601b8352818420805482169055601c909252909120805490911690555b8251600090815260076020908152604080832082870180518552908352818420828801805160ff9081168752918552929094208751815590516001820155905160028201805460ff1916919094161790925560608501518051869392611b37926003850192910190614187565b5060808201516004909101805460a084015160c090940151600290810b62ffffff908116600160281b0267ffffff0000000000199690920b16620100000264ffffffffff1990921661ffff9094169390931717929092161790556000611b9d84836130a3565b6001600160a01b0383166000908152600d60209081526040808320805460ff19908116909155601d83528184208054909116600117905587518352601f825280832088830151845290915290205490915060ff16611c435783516000908152601f6020908152604080832082880180518552908352818420805460ff1916600190811790915588518552601e845291842090518154928301825590845291909220909101555b8351600090815260196020908152604080832082880151845282528083208188015160ff908116855292529091205416611cfc578351600090815260196020908152604080832082880180518552908352818420828901805160ff9081168752918552838620805460ff191660019081179091558a51875285805284872093518752928552928520925183549283018455928552938390209281049092018054918416601f9093166101000a9283029290930219161790555b83516020808601516040808801516001600160a01b038616600090815260149094529281902090517fc61be96f161d85045cec8df9adaf89ad271f38b3ad65ffd65003c4af0eb1278494611d54949093929091614f88565b60405180910390a150505050565b8251600090815260186020908152604080832082870151845282528083208187015160ff1684529091529020805460ff19166001908117909155611da7908490613409565b50825160208085015160408087015181516001600160a01b03871681529384019490945282015260ff90911660608201527fb01bde7f1f22703d0c6d3f5cd2c574f64158d9ed6dd21cb3d83f08174898b978906080015b60405180910390a15b505050565b60606000805b8351811015611e8757600e6000858381518110611e3f57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482611e739190615153565b915080611e7f81615221565b915050611e12565b50806001600160401b03811115611eae57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611ed7578160200160208202803683370190505b5091506000805b8451811015612027576000600e6000878481518110611f0d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054905060005b81811015612012576000600c6000898681518110611f6957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600083815260200190815260200160002060009054906101000a90046001600160a01b0316905080878681518110611fd957634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015284611ffb81615221565b95505050808061200a90615221565b915050611f3b565b5050808061201f90615221565b915050611ede565b505050919050565b6001546001600160a01b031633146120a75760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610dc9565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b612134612be1565b600082815260086020908152604091829020805460ff19168415159081179091558251858152918201527f929eaf016075fe0cd58ebe9e1c169deb9e2591960438ff5a324740440a150db1910160405180910390a15050565b601e60205281600052604060002081815481106121a957600080fd5b90600052602060002001600091509150505481565b606082516001600160401b038111156121e757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612210578160200160208202803683370190505b50905060005b835181101561240d5760006023600086848151811061224557634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600020546001600160a01b031690506122748161352e565b83838151811061229457634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060006001600160a01b03168383815181106122df57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156123fa57600360019054906101000a90046001600160a01b03166001600160a01b031663e48ef05c85848151811061233a57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161235e919061509e565b60206040518083038186803b15801561237657600080fd5b505afa15801561238a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ae9190614499565b90506123b98161352e565b8383815181106123d957634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b0316815250505b508061240581615221565b915050612216565b5092915050565b600760209081526000938452604080852082529284528284209052825290208054600182015460028301546003840180549394929360ff9092169291612459906151ec565b80601f0160208091040260200160405190810160405280929190818152602001828054612485906151ec565b80156124d25780601f106124a7576101008083540402835291602001916124d2565b820191906000526020600020905b8154815290600101906020018083116124b557829003601f168201915b5050506004909301549192505061ffff811690620100008104600290810b91600160281b9004900b87565b601460205281600052604060002081815481106121a957600080fd5b612521612be1565b60038054610100600160a81b0319166101006001600160a01b0387811691820292909217909255600480546001600160a01b0319908116878416908117909255600580548216878516908117909155600680549092169386169384179091556040805194855260208501929092529083015260608201527fa2cad6ae2699ea86ba233a96ca0e57d895983eeed04f6bd0a770187c58b820dd9060800160405180910390a150505050565b6125d3612be1565b6001600160a01b03811661261b5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610dc9565b600154600160a81b900460ff161561266b5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610dc9565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101610eac565b60606126ef82613642565b92915050565b600054610100900460ff166127105760005460ff1615612714565b303b155b6127775760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610dc9565b600054610100900460ff16158015612799576000805461ffff19166101011790555b6127a287610d77565b60038054610100600160a81b0319166101006001600160a01b038981169190910291909117909155600480546001600160a01b0319908116888416179091556005805482168784161790556006805490911691851691909117905560005b825181101561286f5760016008600085848151811061282f57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550808061286790615221565b915050612800565b508015612882576000805461ff00191690555b50505050505050565b6006546001600160a01b031633146128d65760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610dc9565b6003548151604051631f138de360e31b8152600481019190915260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561292357600080fd5b505afa158015612937573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295b9190614499565b6001600160a01b038116600090815260106020908152604080832086830180518552908352818420878301805160ff90811687529185528386205489518752601a865284872093518752928552838620905182168652909352922054929350909116611e075760005b81811015612b28576001600160a01b038084166000908152600f6020908152604080832088830151845282528083208882015160ff9081168552908352818420868552835281842054909416808452602290925290912054909116612b15578451600090815260186020908152604080832082890151845282528083208189015160ff90811685529252909120541615612ac25760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90612a8f908490600090600401614e30565b600060405180830381600087803b158015612aa957600080fd5b505af1158015612abd573d6000803e3d6000fd5b505050505b60ff856080015160ff161415612ae357612ade81600080612f2e565b612af1565b612af18186606001516136dc565b6001600160a01b0381166000908152602260205260409020805460ff191660011790555b5080612b2081615221565b9150506129c4565b508251600090815260216020908152604080832082870180518552908352818420828801805160ff90811687529185528386208951808255845160018084019190915583516002909301805460608e015160808f0151881663010000000263ff0000001961ffff9092166101000262ffffff19909316968916969096179190911716939093179092558752601a86528487209351875292855283862090519091168552909252909120805460ff19169091179055505050565b6000546201000090046001600160a01b03163314612c595760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610dc9565b565b6001600160a01b0383166000908152601060209081526040808320858452825280832060ff85168452909152902054606090806001600160401b03811115612cb357634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612cdc578160200160208202803683370190505b50915060005b81811015612d74576001600160a01b038087166000908152600f60209081526040808320898452825280832060ff89168452825280832085845290915290205484519116908190859084908110612d4957634e487b7160e01b600052603260045260246000fd5b6001600160a01b03909216602092830291909101909101525080612d6c81615221565b915050612ce2565b50509392505050565b60005b6001600160a01b0382166000908152600e6020526040902054811015612e6d576001600160a01b038083166000908152600c60209081526040808320858452825280832054909316825260229052205460ff16612e5b576005546001600160a01b038381166000908152600c6020908152604080832086845290915280822054905163b91f5e3560e01b81529083166004820152602481019190915291169063b91f5e3590604401600060405180830381600087803b158015612e4257600080fd5b505af1158015612e56573d6000803e3d6000fd5b505050505b80612e6581615221565b915050612d80565b5050565b60005b6001600160a01b0383166000908152600e6020526040902054811015611e07576003546001600160a01b038481166000908152600c602090815260408083208684529091529081902054905163ed5e00eb60e01b815261010090930482169263ed5e00eb92612ee99216908690600401614e30565b600060405180830381600087803b158015612f0357600080fd5b505af1158015612f17573d6000803e3d6000fd5b505050508080612f2690615221565b915050612e74565b60055460405163b91f5e3560e01b81526001600160a01b038581166004830152602482018490529091169063b91f5e3590604401600060405180830381600087803b158015612f7c57600080fd5b505af1158015612f90573d6000803e3d6000fd5b505050506001600160a01b038381166000818152601260209081526040918290205482519384529083018590529092169181019190915261ffff831660608201527f7b72264d363f766973a07f09021df5169917b274b948b57fb5028ecc3cc9b5cd90608001611dfe565b60048054608083015160a084015160c0850151604051631743f79b60e21b815261ffff90931694830194909452600290810b60248301529290920b60448301526000916001600160a01b0390911690635d0fde6c9060640160206040518083038186803b15801561306b57600080fd5b505afa15801561307f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ef9190614994565b6001600160a01b038082166000818152600e60209081526040808320546013835281842088840180518652908452828520898401805160ff908116885291865284872054978752601186528487209251875291855283862091511685528352818420608089015161ffff168552909252822054919390159281169116828061313257506001600160a01b038116155b156132215760006131438787613746565b6001600160a01b0387811660009081526013602090815260408083208c830151845282528083208c82015160ff168452909152902080546001600160a01b0319168383161790559091508316156131fe5760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb906131cb908690600190600401614e30565b600060405180830381600087803b1580156131e557600080fd5b505af11580156131f9573d6000803e3d6000fd5b505050505b61321681886000015189602001518a60400151613a51565b93506126ef92505050565b816001600160a01b0316816001600160a01b0316146133755760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90613271908490600090600401614e30565b600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505060035460405163ed5e00eb60e01b81526101009091046001600160a01b0316925063ed5e00eb91506132da908590600190600401614e30565b600060405180830381600087803b1580156132f457600080fd5b505af1158015613308573d6000803e3d6000fd5b505050506001600160a01b0385811660009081526013602090815260408083208a8301805185529083528184208b8301805160ff1686529352922080546001600160a01b0319169385169390931790925587519051915161336b92849291613a51565b92506126ef915050565b60035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb906133ac908590600090600401614e30565b600060405180830381600087803b1580156133c657600080fd5b505af11580156133da573d6000803e3d6000fd5b505050506133f682876000015188602001518960400151613a51565b5091506126ef9050565b50505092915050565b6003548251604051631f138de360e31b8152600481019190915260009182916101009091046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561345957600080fd5b505afa15801561346d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134919190614499565b6001600160a01b038116600090815260106020908152604080832088830151845282528083208882015160ff1684529091528120549192505b81811015613400576001600160a01b038084166000908152600f602090815260408083208a830151845282528083208a82015160ff16845282528083208584529091529020541661351b8187613ab3565b508061352681615221565b9150506134ca565b60006001600160a01b0382161561363d576000826001600160a01b0316639e3b34bf6040518163ffffffff1660e01b8152600401604080518083038186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b19190614ca0565b5090504281101580156136325750826001600160a01b0316633f6fa6556040518163ffffffff1660e01b815260040160206040518083038186803b1580156135f857600080fd5b505afa15801561360c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136309190614994565b155b1561363b578291505b505b919050565b6001600160a01b03811660009081526015602052604090205460609060ff166136735761366e82613b17565b6126ef565b6001600160a01b038216600090815260146020908152604091829020805483518184028101840190945280845290918301828280156136d157602002820191906000526020600020905b8154815260200190600101908083116136bd575b505050505092915050565b6001600160a01b03821660009081526017602052604081205461ffff16908161370684606461517f565b61ffff16116137365761ffff821661371f84606461517f565b61ffff161061372f576000613739565b6002613739565b60015b90506116dc848483612f2e565b6003548251604051631c2ab73160e21b8152600481019190915260009182916137db9161010090046001600160a01b0316906370aadcc49060240160206040518083038186803b15801561379957600080fd5b505afa1580156137ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137d19190614c59565b8560400151613b54565b60055485519192506001600160a01b031690634cde32ce906137fc87613c24565b600354885160405163c48e62f160e01b815260048101919091526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b15801561384757600080fd5b505afa15801561385b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526138839190810190614a3f565b60200151600060028760018b6040518963ffffffff1660e01b81526004016138b2989796959493929190615038565b602060405180830381600087803b1580156138cc57600080fd5b505af11580156138e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139049190614499565b5060055460408051622610c560e41b815290516001600160a01b039092169163dd5adfa39160019184916302610c50916004808301926020929190829003018186803b15801561395357600080fd5b505afa158015613967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061398b9190614c59565b61399591906151a9565b6040518263ffffffff1660e01b81526004016139b391815260200190565b60206040518083038186803b1580156139cb57600080fd5b505afa1580156139df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a039190614499565b915061240d846000015184848760800151886020015189606001518a6040015188600281518110613a4457634e487b7160e01b600052603260045260246000fd5b6020026020010151613c74565b613a5c838383613eef565b6001600160a01b03851660009081526014602090815260409091208251613a89939192919091019061420b565b5050506001600160a01b039091166000908152601560205260409020805460ff1916600117905550565b60035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90613ae99085908590600401614e30565b600060405180830381600087803b158015613b0357600080fd5b505af11580156118dc573d6000803e3d6000fd5b6001600160a01b038116600090815260096020908152604080832054600a835281842054600b9093529220546060926126ef92909160ff16613eef565b6040805160038082526080820190925260609160009190602082018480368337019050509050613b8684612328615153565b81600081518110613ba757634e487b7160e01b600052603260045260246000fd5b60200260200101818152505061271a81600181518110613bd757634e487b7160e01b600052603260045260246000fd5b6020908102919091010152613bf160ff8416612af8615153565b81600281518110613c1257634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b60608160600151613c3b836040015160ff16614066565b613c4c846080015161ffff16614066565b604051602001613c5e93929190614d5a565b6040516020818303038152906040529050919050565b600354604051624dc46d60e41b8152600481018a90526001600160a01b038881166024830152610100909204909116906304dc46d090604401600060405180830381600087803b158015613cc757600080fd5b505af1158015613cdb573d6000803e3d6000fd5b505050506001600160a01b0386811660008181526009602090815260408083208d9055600a8252808320899055888352602382528083208054958d166001600160a01b03199687168117909155848452600b8352818420805460ff8a1660ff19918216179091556016845282852080549091166001908117909155601284528285208054881683179055818552600c8452828520600e808652848720805488529186529386208054909816909617909655835290528154613d9d908490615153565b90915550506001600160a01b038088166000818152601160209081526040808320898452825280832060ff881680855290835281842061ffff8c168086529084528285208054978e166001600160a01b0319988916811790915580865260178552838620805461ffff1916909217909155858552601384528285208b8652845282852082865284528285208054881682179055858552600f84528285208b865284528285208286528452828520958552601084528285208b865284528285208286528085528386208054875296855292852080549097161790955593825292909252805460019290613e90908490615153565b909155507fad561eb279f0551643e940bd69a05112c9f5e19962eae3312d6490409e19410e905087878a87878a88613ec786613642565b89604051613edd99989796959493929190614db6565b60405180910390a15050505050505050565b604080516002808252606080830184529260009291906020830190803683375050506000868152600760209081526040808320888452825280832060ff881684529091528120600401548251929350620100009004600290810b900b91839190613f6957634e487b7160e01b600052603260045260246000fd5b6020908102919091018101919091526000868152600782526040808220878352835280822060ff8716835290925220600401548151600160281b909104600290810b900b9082906001908110613fcf57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d9749161400991859101614f3d565b60006040518083038186803b15801561402157600080fd5b505afa158015614035573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261405d9190810190614946565b95945050505050565b60608161408a5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156140b4578061409e81615221565b91506140ad9050600a8361516b565b915061408e565b6000816001600160401b038111156140dc57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614106576020820181803683370190505b5090505b841561417f5761411b6001836151a9565b9150614128600a8661523c565b614133906030615153565b60f81b81838151811061415657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350614178600a8661516b565b945061410a565b949350505050565b828054614193906151ec565b90600052602060002090601f0160209004810192826141b557600085556141fb565b82601f106141ce57805160ff19168380011785556141fb565b828001600101855582156141fb579182015b828111156141fb5782518255916020019190600101906141e0565b50614207929150614245565b5090565b8280548282559060005260206000209081019282156141fb57916020028201828111156141fb5782518255916020019190600101906141e0565b5b808211156142075760008155600101614246565b600082601f83011261426a578081fd5b8151602061427f61427a83615109565b6150d9565b80838252828201915082860187848660051b890101111561429e578586fd5b855b858110156142c55781516142b3816152a7565b845292840192908401906001016142a0565b5090979650505050505050565b600082601f8301126142e2578081fd5b813560206142f261427a83615109565b80838252828201915082860187848660051b8901011115614311578586fd5b855b858110156142c55781356001600160401b03811115614330578788fd5b61433e8a87838c01016143c4565b8552509284019290840190600101614313565b600082601f830112614361578081fd5b8151602061437161427a83615109565b80838252828201915082860187848660051b8901011115614390578586fd5b855b858110156142c557815184529284019290840190600101614392565b803561363d816152b5565b805161363d816152b5565b600082601f8301126143d4578081fd5b81356143e261427a8261512c565b8181528460208386010111156143f6578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112614420578081fd5b815161442e61427a8261512c565b818152846020838601011115614442578283fd5b61417f8260208301602087016151c0565b803561ffff8116811461363d57600080fd5b803560ff8116811461363d57600080fd5b600060208284031215614487578081fd5b813561449281615292565b9392505050565b6000602082840312156144aa578081fd5b815161449281615292565b600080600080608085870312156144ca578283fd5b84356144d581615292565b935060208501356144e581615292565b925060408501356144f581615292565b9150606085013561450581615292565b939692955090935050565b60008060008060008060c08789031215614528578384fd5b863561453381615292565b955060208781013561454481615292565b9550604088013561455481615292565b9450606088013561456481615292565b9350608088013561457481615292565b925060a08801356001600160401b0381111561458e578283fd5b8801601f81018a1361459e578283fd5b80356145ac61427a82615109565b8082825284820191508484018d868560051b87010111156145cb578687fd5b8694505b838510156145ed5780358352600194909401939185019185016145cf565b5080955050505050509295509295509295565b60008060008060808587031215614615578182fd5b843561462081615292565b93506020850135614630816152a7565b92506040850135614640816152a7565b91506060850135614505816152a7565b600080600060608486031215614664578081fd5b833561466f81615292565b92506020840135915061468460408501614465565b90509250925092565b600080600080608085870312156146a2578182fd5b84356146ad81615292565b9350602085013592506146c260408601614465565b91506146d060608601614453565b905092959194509250565b600080600080608085870312156146f0578182fd5b84356146fb81615292565b93506020850135925061471060408601614465565b9396929550929360600135925050565b60008060408385031215614732578182fd5b823561473d81615292565b946020939093013593505050565b6000602080838503121561475d578182fd5b82356001600160401b03811115614772578283fd5b8301601f81018513614782578283fd5b803561479061427a82615109565b80828252848201915084840188868560051b87010111156147af578687fd5b8694505b838510156147da5780356147c681615292565b8352600194909401939185019185016147b3565b50979650505050505050565b600080600080608085870312156147fb578182fd5b84516001600160401b0380821115614811578384fd5b61481d8883890161425a565b95506020870151915080821115614832578384fd5b61483e8883890161425a565b94506040870151915080821115614853578384fd5b61485f8883890161425a565b93506060870151915080821115614874578283fd5b5061488187828801614351565b91505092959194509250565b6000806040838503121561489f578182fd5b82356001600160401b03808211156148b5578384fd5b818501915085601f8301126148c8578384fd5b813560206148d861427a83615109565b8083825282820191508286018a848660051b89010111156148f7578889fd5b8896505b848710156149195780358352600196909601959183019183016148fb565b509650508601359250508082111561492f578283fd5b5061493c858286016142d2565b9150509250929050565b600060208284031215614957578081fd5b81516001600160401b0381111561496c578182fd5b61417f84828501614351565b600060208284031215614989578081fd5b8135614492816152a7565b6000602082840312156149a5578081fd5b8151614492816152a7565b6000602082840312156149c1578081fd5b5035919050565b600080604083850312156149da578182fd5b50508035926020909101359150565b6000806000606084860312156149fd578081fd5b505081359360208301359350604090920135919050565b600080600060608486031215614a28578081fd5b833592506020840135915061468460408501614465565b600060208284031215614a50578081fd5b81516001600160401b0380821115614a66578283fd5b9083019060e08286031215614a79578283fd5b614a816150b1565b8251815260208301516020820152614a9b604084016143b9565b6040820152614aac606084016143b9565b6060820152614abd608084016143b9565b608082015260a083015182811115614ad3578485fd5b614adf87828601614410565b60a08301525060c083015182811115614af6578485fd5b614b0287828601614410565b60c08301525095945050505050565b600060a08284031215614b22578081fd5b60405160a081018181106001600160401b0382111715614b4457614b4461527c565b80604052508235815260208301356020820152614b6360408401614465565b6040820152614b7460608401614453565b6060820152614b8560808401614465565b60808201529392505050565b60008060408385031215614ba3578182fd5b82356001600160401b0380821115614bb9578384fd5b9084019060e08287031215614bcc578384fd5b614bd46150b1565b8235815260208301356020820152614bee60408401614465565b6040820152606083013582811115614c04578586fd5b614c10888286016143c4565b606083015250614c2260808401614453565b6080820152614c3360a084016143ae565b60a0820152614c4460c084016143ae565b60c08201529660209590950135955050505050565b600060208284031215614c6a578081fd5b5051919050565b60008060408385031215614c83578182fd5b823591506020830135614c95816152a7565b809150509250929050565b60008060408385031215614cb2578182fd5b505080516020909101519092909150565b6000815180845260208085019450808401835b83811015614cf4578151151587529582019590820190600101614cd6565b509495945050505050565b6000815180845260208085019450808401835b83811015614cf457815187529582019590820190600101614d12565b60008151808452614d468160208601602086016151c0565b601f01601f19169290920160200192915050565b60008451614d6c8184602089016151c0565b80830190506201016960ed1b8082528551614d8e816003850160208a016151c0565b60039201918201528351614da98160068401602088016151c0565b0160060195945050505050565b6001600160a01b038a8116825289166020820152604081018890526060810187905261012060808201819052600090614df183820189614d2e565b905061ffff871660a084015260ff861660c084015282810360e0840152614e188186614cff565b915050826101008301529a9950505050505050505050565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015614e8c5783516001600160a01b031683529284019291840191600101614e67565b50909695505050505050565b6080808252855190820181905260009060209060a0840190828901845b82811015614ed157815184529284019290840190600101614eb5565b50505083810382850152865180825287830191830190845b81811015614f0857835160ff1683529284019291840191600101614ee9565b50508481036040860152614f1c8188614cc3565b925050508281036060840152614f328185614cc3565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614e8c57835183529284019291840191600101614f59565b6020815260006144926020830184614cff565b6000608082018683526020868185015260ff861660408501526080606085015281855480845260a0860191508685528285209350845b81811015614fda57845483526001948501949284019201614fbe565b50909998505050505050505050565b87815286602082015260ff8616604082015260e06060820152600061501160e0830187614d2e565b61ffff95909516608083015250600292830b60a0820152910b60c090910152949350505050565b60006101008a83528060208401526150528184018b614d2e565b905088604084015287606084015286608084015282810360a08401526150788187614cff565b94151560c084015250506001600160a01b039190911660e0909101529695505050505050565b6020815260006144926020830184614d2e565b60405160e081016001600160401b03811182821017156150d3576150d361527c565b60405290565b604051601f8201601f191681016001600160401b03811182821017156151015761510161527c565b604052919050565b60006001600160401b038211156151225761512261527c565b5060051b60200190565b60006001600160401b038211156151455761514561527c565b50601f01601f191660200190565b6000821982111561516657615166615250565b500190565b60008261517a5761517a615266565b500490565b600061ffff808316818516818304811182151516156151a0576151a0615250565b02949350505050565b6000828210156151bb576151bb615250565b500390565b60005b838110156151db5781810151838201526020016151c3565b838111156116dc5750506000910152565b600181811c9082168061520057607f821691505b6020821081141561363b57634e487b7160e01b600052602260045260246000fd5b600060001982141561523557615235615250565b5060010190565b60008261524b5761524b615266565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f8057600080fd5b8015158114610f8057600080fd5b8060020b8114610f8057600080fdfea2646970667358221220d9a7b2f0d65bfbe53a7669e37bd38e27ab6cc4bd175e41101173cc1b8e7d6a9764736f6c63430008040033

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