Contract 0xD4cD4b4f131B3e72D344C51f5D8558837C425D74

Contract Overview

Balance:
0 ETH
Txn Hash Method
Block
From
To
Value
0xe602d7bda5c28288f5ff31f6a31c75984e03470c6bc2472506877c5980ae90bb0x60806040146490672023-09-14 21:16:4215 days 18 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  Create: GamesPlayerProps0 ETH0.0000000433230.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";

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

    /* ========== 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++) {
            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;
        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;
        }
    }

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

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

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

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

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 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 : ContextUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    function initialMint() external view returns (uint);

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

    function getGameId() external view returns (bytes32);

    function deposited() external view returns (uint);

    function optionsCount() external view returns (uint);

    function creator() external view returns (address);

    function resolved() external view returns (bool);

    function cancelled() external view returns (bool);

    function paused() external view returns (bool);

    function phase() external view returns (Phase);

    function canResolve() external view returns (bool);

    function result() external view returns (Side);

    function isChild() external view returns (bool);

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

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

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

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

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

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

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

    function isDoubleChance() external view returns (bool);

    function parentMarket() external view returns (ISportPositionalMarket);

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

    function setPaused(bool _paused) external;

    function updateDates(uint256 _maturity, uint256 _expiry) external;

    function mint(uint value) external;

    function exerciseOptions() external;

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

File 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":"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":"_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"}]

608060405234801561001057600080fd5b50614d69806100206000396000f3fe608060405234801561001057600080fd5b50600436106103af5760003560e01c80635c9ef4a5116101f4578063b103feb01161011a578063db0d4579116100ad578063faecc97a1161007c578063faecc97a14610b29578063fbf1c75514610b32578063fd86b32d14610b45578063ffe1681414610b7f57600080fd5b8063db0d457914610acb578063dc8ad5cb14610aeb578063f05d098214610b0e578063f1d56d9714610b2157600080fd5b8063c3b83f5f116100e9578063c3b83f5f14610a47578063ceda8e9014610a5a578063d28231bd14610a7a578063d93dbbcb14610a9d57600080fd5b8063b103feb0146109e6578063b4fd7296146109f9578063b811e28014610a11578063bf989b6e14610a3457600080fd5b80638a42af3f1161019257806391b4ded91161016157806391b4ded9146109925780639740a60c1461099b578063a73a39d8146109be578063ae71dcdf146109de57600080fd5b80638a42af3f146108915780638bf502a8146108d45780638d37d0b2146108fa5780638da5cb5b1461097957600080fd5b80637b17f797116101ce5780637b17f797146107f75780637dec0dac1461080a5780637e17027f1461081d578063879cf4371461086057600080fd5b80635c9ef4a5146107a65780636c35b775146107c657806379ba5097146107ef57600080fd5b8063300a0298116102d95780634adf72191161027757806353a47bb71161024657806353a47bb7146107605780635938541f146107735780635bac88b0146107865780635c975abb1461079957600080fd5b80634adf7219146106e65780634dbbf3fe14610706578063509e2f331461071957806351aa86ed1461072c57600080fd5b80633baff8f1116102b35780633baff8f1146106385780633cbf9a731461065b578063420209c21461067e578063447b1d58146106b257600080fd5b8063300a029814610614578063343d372f1461061c57806336b74f621461062557600080fd5b806316c38b3c116103515780631c8db097116103205780631c8db0971461059f5780632978b568146105d65780632b7ac3f3146105f95780632fff70201461060c57600080fd5b806316c38b3c1461052d578063186b39f7146105405780631999b9dc146105655780631afed5cc1461058857600080fd5b806313af40351161038d57806313af4035146104af57806314bdaa89146104c457806314cb6a71146104f75780631627540c1461051a57600080fd5b806305c84a54146103b45780630fd59f56146103f957806310063fdc14610484575b600080fd5b6103c76103c23660046144b3565b610bb3565b6040805161ffff9095168552600293840b60208601529190920b90830152151560608201526080015b60405180910390f35b6104526104073660046144b3565b602160209081526000938452604080852082529284528284209052825290208054600182015460029092015490919060ff8082169161ffff6101008204169163010000009091041685565b60408051958652602086019490945260ff9283169385019390935261ffff16606084015216608082015260a0016103f0565b600554610497906001600160a01b031681565b6040516001600160a01b0390911681526020016103f0565b6104c26104bd366004613f9e565b610d25565b005b6104e76104d2366004613f9e565b60156020526000908152604090205460ff1681565b60405190151581526020016103f0565b6104e761050536600461444f565b60086020526000908152604090205460ff1681565b6104c2610528366004613f9e565b610e65565b6104c261053b366004614417565b610ebb565b61055361054e366004614488565b610f31565b60405160ff90911681526020016103f0565b61057861057336600461444f565b610f80565b6040516103f09493929190614914565b61059161232881565b6040519081526020016103f0565b6105c36105ad366004613f9e565b60176020526000908152604090205461ffff1681565b60405161ffff90911681526020016103f0565b6104e76105e4366004613f9e565b601c6020526000908152604090205460ff1681565b600454610497906001600160a01b031681565b610591600181565b610591600281565b61059161271a81565b600654610497906001600160a01b031681565b6104e7610646366004613f9e565b600d6020526000908152604090205460ff1681565b6104e7610669366004613f9e565b60226020526000908152604090205460ff1681565b6104e761068c3660046144b3565b601960209081526000938452604080852082529284528284209052825290205460ff1681565b6104976106c0366004614248565b600c6020908152600092835260408084209091529082529020546001600160a01b031681565b6105916106f4366004613f9e565b60096020526000908152604090205481565b6104c2610714366004613f9e565b611569565b6104c2610727366004614128565b6115c1565b6104e761073a3660046144b3565b601860209081526000938452604080852082529284528284209052825290205460ff1681565b600154610497906001600160a01b031681565b6104c2610781366004613f9e565b61168f565b6104c2610794366004614630565b611891565b6003546104e79060ff1681565b6107b96107b4366004614273565b611db9565b6040516103f091906148c7565b6104976107d4366004613f9e565b6012602052600090815260409020546001600160a01b031681565b6104c2611fdc565b6104c2610805366004614710565b6120d9565b610591610818366004614467565b61213a565b61049761082b3660046141b5565b60116020908152600094855260408086208252938552838520815291845282842090915282529020546001600160a01b031681565b61059161086e366004614178565b601060209081526000938452604080852082529284528284209052825290205481565b61049761089f366004614203565b600f6020908152600094855260408086208252938552838520815291845282842090915282529020546001600160a01b031681565b6108e76108e23660046144b3565b61216b565b6040516103f09796959493929190614a65565b61094c610908366004613f9e565b6001600160a01b039081166000908152601260209081526040808320546009835281842054600a845282852054600b90945291909320549290931693909160ff1690565b604080516001600160a01b03909516855260208501939093529183015260ff1660608201526080016103f0565b600054610497906201000090046001600160a01b031681565b61059160025481565b6104e76109a9366004613f9e565b601d6020526000908152604090205460ff1681565b6105916109cc366004613f9e565b600a6020526000908152604090205481565b610591600081565b6105916109f4366004614248565b612254565b6003546104979061010090046001600160a01b031681565b6104e7610a1f366004613f9e565b601b6020526000908152604090205460ff1681565b6104c2610a42366004613fdd565b612270565b6104c2610a55366004613f9e565b612322565b610591610a68366004613f9e565b600e6020526000908152604090205481565b6104e7610a88366004613f9e565b60166020526000908152604090205460ff1681565b6104e7610aab366004614467565b601f60209081526000928352604080842090915290825290205460ff1681565b610ade610ad9366004613f9e565b61243b565b6040516103f091906149f1565b610553610af9366004613f9e565b600b6020526000908152604090205460ff1681565b6104c2610b1c366004614038565b61244c565b61059160ff81565b610591612af881565b6104c2610b403660046145b0565b6125e2565b610497610b53366004614178565b60136020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6104e7610b8d3660046144b3565b601a60209081526000938452604080852082529284528284209052825290205460ff1681565b6000838152600760209081526040808320858452825280832060ff8086168552908352818420825160e081018452815481526001820154948101949094526002810154909116918301919091526003810180548493849384938493606084019190610c1d90614c55565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4990614c55565b8015610c965780601f10610c6b57610100808354040283529160200191610c96565b820191906000526020600020905b815481529060010190602001808311610c7957829003601f168201915b50505091835250506004919091015461ffff8116602080840191909152620100008204600290810b810b810b604080860191909152600160281b909304810b810b900b606090930192909252608083015160a084015160c09094015160009c8d5260188452828d209b8d529a8352818c2060ff9a8b168d52909252909920549899909890961695945050505050565b6001600160a01b038116610d805760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f7420626520300000000000000060448201526064015b60405180910390fd5b600154600160a01b900460ff1615610dec5760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610d77565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b610e6d612938565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610e5a565b610ec3612938565b60035460ff1615158115151415610ed75750565b6003805460ff191682151590811790915560ff1615610ef557426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001610e5a565b50565b602080528260005260406000206020528160005260406000208181548110610f5857600080fd5b906000526020600020906020918282040191900692509250509054906101000a900460ff1681565b600354604051631f138de360e31b81526004810183905260609182918291829160009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b158015610fd357600080fd5b505afa158015610fe7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100b9190613fc1565b90506000805b6000888152601e602052604090205481101561109a576000888152601e6020526040812080548390811061105557634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548b835281805260408084208285529092529120549091506110849084614bbc565b925050808061109290614c90565b915050611011565b50806001600160401b038111156110c157634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156110ea578160200160208202803683370190505b509550806001600160401b0381111561111357634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561113c578160200160208202803683370190505b509450806001600160401b0381111561116557634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561118e578160200160208202803683370190505b509350806001600160401b038111156111b757634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156111e0578160200160208202803683370190505b5092506000805b6000898152601e602052604090205481101561155e576000898152601e6020526040812080548390811061122b57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548c835281805260408084208285528352808420805482518186028101860190935280835292955090929091908301828280156112b257602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116112835790505b5050505050905060005b81518110156115485760008282815181106112e757634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160008f8152601983526040808220888352845280822060ff80851684529452902054909250161561153557838c878151811061133f57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050808b878151811061136c57634e487b7160e01b600052603260045260246000fd5b60ff92831660209182029290920181019190915260008f8152601a825260408082208883528352808220858516835290925220548b519116908b90889081106113c557634e487b7160e01b600052603260045260246000fd5b9115156020928302919091019091015260006113e28986846129b2565b600554604051638d924e7360e01b81529192506000916001600160a01b0390911690638d924e73906114189085906004016148c7565b60006040518083038186803b15801561143057600080fd5b505afa158015611444573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261146c919081019061430e565b5050905060008b898151811061149257634e487b7160e01b600052603260045260246000fd5b9115156020928302919091019091015260005b8251811015611524578181815181106114ce57634e487b7160e01b600052603260045260246000fd5b6020026020010151156115125760018c8a815181106114fd57634e487b7160e01b600052603260045260246000fd5b91151560209283029190910190910152611524565b8061151c81614c90565b9150506114a5565b508761152f81614c90565b98505050505b508061154081614c90565b9150506112bc565b505050808061155690614c90565b9150506111e7565b505050509193509193565b60035461010090046001600160a01b031633146115b85760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9031b7b739bab6b2b960991b6044820152606401610d77565b610f2e81612ad4565b60035461010090046001600160a01b031633146116105760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9031b7b739bab6b2b960991b6044820152606401610d77565b6001600160a01b0384166000908152601d602052604090205460ff1615611689576001600160a01b0384166000908152600d60209081526040808320805460ff1990811688151517909155601b835281842080548216871515179055601c90925290912080549091168215151790556116898484612b91565b50505050565b6005546001600160a01b031633146116d85760405162461bcd60e51b815260206004820152600c60248201526b27b7363c9036b0b730b3b2b960a11b6044820152606401610d77565b6001600160a01b038082166000818152601260209081526040808320546009835281842054600a845282852054600b8552838620549290971680865260108552838620888752855283862060ff93841680885290865284872054978752602290955292909420549195939491166118895761175586600080612c4e565b6002811015611792576000848152601a60209081526040808320868452825280832060ff861684529091529020805460ff19166001179055611865565b600160005b8281101561182c576001600160a01b038088166000908152600f60209081526040808320898452825280832060ff808a16855290835281842086855283528184205490941680845260229092529091205490911615801561180a5750886001600160a01b0316816001600160a01b031614155b1561181957600092505061182c565b508061182481614c90565b915050611797565b508015611863576000858152601a60209081526040808320878452825280832060ff871684529091529020805460ff191660011790555b505b6001600160a01b0386166000908152602260205260409020805460ff191660011790555b505050505050565b6006546001600160a01b031633146118dc5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610d77565b6003548251604051631f138de360e31b8152600481019190915260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561192957600080fd5b505afa15801561193d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119619190613fc1565b90506001600160a01b03811615801590611989575060008281526008602052604090205460ff165b15611db45761199783612d1b565b15611d0f578251600090815260186020908152604080832082870151845282528083208187015160ff908116855292529091205416806119ef57506001600160a01b0381166000908152601b602052604090205460ff165b80611a1257506001600160a01b0381166000908152601c602052604090205460ff165b15611a77578251600090815260186020908152604080832082870151845282528083208187015160ff1684528252808320805460ff199081169091556001600160a01b0385168452601b8352818420805482169055601c909252909120805490911690555b8251600090815260076020908152604080832082870180518552908352818420828801805160ff9081168752918552929094208751815590516001820155905160028201805460ff1916919094161790925560608501518051869392611ae4926003850192910190613d86565b5060808201516004909101805460a084015160c090940151600290810b62ffffff908116600160281b0267ffffff0000000000199690920b16620100000264ffffffffff1990921661ffff9094169390931717929092161790556000611b4a8483612dc3565b6001600160a01b0383166000908152600d60209081526040808320805460ff19908116909155601d83528184208054909116600117905587518352601f825280832088830151845290915290205490915060ff16611bf05783516000908152601f6020908152604080832082880180518552908352818420805460ff1916600190811790915588518552601e845291842090518154928301825590845291909220909101555b8351600090815260196020908152604080832082880151845282528083208188015160ff908116855292529091205416611ca9578351600090815260196020908152604080832082880180518552908352818420828901805160ff9081168752918552838620805460ff191660019081179091558a51875285805284872093518752928552928520925183549283018455928552938390209281049092018054918416601f9093166101000a9283029290930219161790555b83516020808601516040808801516001600160a01b038616600090815260149094529281902090517fc61be96f161d85045cec8df9adaf89ad271f38b3ad65ffd65003c4af0eb1278494611d01949093929091614a04565b60405180910390a150505050565b8251600090815260186020908152604080832082870151845282528083208187015160ff1684529091529020805460ff19166001908117909155611d54908490613129565b50825160208085015160408087015181516001600160a01b03871681529384019490945282015260ff90911660608201527fb01bde7f1f22703d0c6d3f5cd2c574f64158d9ed6dd21cb3d83f08174898b978906080015b60405180910390a15b505050565b60606000805b8351811015611e3457600e6000858381518110611dec57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482611e209190614bbc565b915080611e2c81614c90565b915050611dbf565b50806001600160401b03811115611e5b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611e84578160200160208202803683370190505b5091506000805b8451811015611fd4576000600e6000878481518110611eba57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054905060005b81811015611fbf576000600c6000898681518110611f1657634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600083815260200190815260200160002060009054906101000a90046001600160a01b0316905080878681518110611f8657634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015284611fa881614c90565b955050508080611fb790614c90565b915050611ee8565b50508080611fcc90614c90565b915050611e8b565b505050919050565b6001546001600160a01b031633146120545760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610d77565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b6120e1612938565b600082815260086020908152604091829020805460ff19168415159081179091558251858152918201527f929eaf016075fe0cd58ebe9e1c169deb9e2591960438ff5a324740440a150db1910160405180910390a15050565b601e602052816000526040600020818154811061215657600080fd5b90600052602060002001600091509150505481565b600760209081526000938452604080852082529284528284209052825290208054600182015460028301546003840180549394929360ff90921692916121b090614c55565b80601f01602080910402602001604051908101604052809291908181526020018280546121dc90614c55565b80156122295780601f106121fe57610100808354040283529160200191612229565b820191906000526020600020905b81548152906001019060200180831161220c57829003601f168201915b5050506004909301549192505061ffff811690620100008104600290810b91600160281b9004900b87565b6014602052816000526040600020818154811061215657600080fd5b612278612938565b60038054610100600160a81b0319166101006001600160a01b0387811691820292909217909255600480546001600160a01b0319908116878416908117909255600580548216878516908117909155600680549092169386169384179091556040805194855260208501929092529083015260608201527fa2cad6ae2699ea86ba233a96ca0e57d895983eeed04f6bd0a770187c58b820dd9060800160405180910390a150505050565b61232a612938565b6001600160a01b0381166123725760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610d77565b600154600160a81b900460ff16156123c25760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610d77565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101610e5a565b60606124468261324e565b92915050565b600054610100900460ff166124675760005460ff161561246b565b303b155b6124ce5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d77565b600054610100900460ff161580156124f0576000805461ffff19166101011790555b6124f987610d25565b60038054610100600160a81b0319166101006001600160a01b038981169190910291909117909155600480546001600160a01b0319908116888416179091556005805482168784161790556006805490911691851691909117905560005b82518110156125c65760016008600085848151811061258657634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff02191690831515021790555080806125be90614c90565b915050612557565b5080156125d9576000805461ff00191690555b50505050505050565b6006546001600160a01b0316331461262d5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610d77565b6003548151604051631f138de360e31b8152600481019190915260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561267a57600080fd5b505afa15801561268e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b29190613fc1565b6001600160a01b038116600090815260106020908152604080832086830180518552908352818420878301805160ff90811687529185528386205489518752601a865284872093518752928552838620905182168652909352922054929350909116611db45760005b8181101561287f576001600160a01b038084166000908152600f6020908152604080832088830151845282528083208882015160ff908116855290835281842086855283528184205490941680845260229092529091205490911661286c578451600090815260186020908152604080832082890151845282528083208189015160ff908116855292529091205416156128195760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb906127e69084906000906004016148ac565b600060405180830381600087803b15801561280057600080fd5b505af1158015612814573d6000803e3d6000fd5b505050505b60ff856080015160ff16141561283a5761283581600080612c4e565b612848565b6128488186606001516132e8565b6001600160a01b0381166000908152602260205260409020805460ff191660011790555b508061287781614c90565b91505061271b565b508251600090815260216020908152604080832082870180518552908352818420828801805160ff90811687529185528386208951808255845160018084019190915583516002909301805460608e015160808f0151881663010000000263ff0000001961ffff9092166101000262ffffff19909316968916969096179190911716939093179092558752601a86528487209351875292855283862090519091168552909252909120805460ff19169091179055505050565b6000546201000090046001600160a01b031633146129b05760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610d77565b565b6001600160a01b0383166000908152601060209081526040808320858452825280832060ff85168452909152902054606090806001600160401b03811115612a0a57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612a33578160200160208202803683370190505b50915060005b81811015612acb576001600160a01b038087166000908152600f60209081526040808320898452825280832060ff89168452825280832085845290915290205484519116908190859084908110612aa057634e487b7160e01b600052603260045260246000fd5b6001600160a01b03909216602092830291909101909101525080612ac381614c90565b915050612a39565b50509392505050565b60005b6001600160a01b0382166000908152600e6020526040902054811015612b8d576005546001600160a01b038381166000908152600c6020908152604080832086845290915280822054905163b91f5e3560e01b81529083166004820152602481019190915291169063b91f5e3590604401600060405180830381600087803b158015612b6257600080fd5b505af1158015612b76573d6000803e3d6000fd5b505050508080612b8590614c90565b915050612ad7565b5050565b60005b6001600160a01b0383166000908152600e6020526040902054811015611db4576003546001600160a01b038481166000908152600c602090815260408083208684529091529081902054905163ed5e00eb60e01b815261010090930482169263ed5e00eb92612c0992169086906004016148ac565b600060405180830381600087803b158015612c2357600080fd5b505af1158015612c37573d6000803e3d6000fd5b505050508080612c4690614c90565b915050612b94565b60055460405163b91f5e3560e01b81526001600160a01b038581166004830152602482018490529091169063b91f5e3590604401600060405180830381600087803b158015612c9c57600080fd5b505af1158015612cb0573d6000803e3d6000fd5b505050506001600160a01b038381166000818152601260209081526040918290205482519384529083018590529092169181019190915261ffff831660608201527f7b72264d363f766973a07f09021df5169917b274b948b57fb5028ecc3cc9b5cd90608001611dab565b60048054608083015160a084015160c0850151604051631743f79b60e21b815261ffff90931694830194909452600290810b60248301529290920b60448301526000916001600160a01b0390911690635d0fde6c9060640160206040518083038186803b158015612d8b57600080fd5b505afa158015612d9f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124469190614433565b6001600160a01b038082166000818152600e60209081526040808320546013835281842088840180518652908452828520898401805160ff908116885291865284872054978752601186528487209251875291855283862091511685528352818420608089015161ffff1685529092528220549193901592811691168280612e5257506001600160a01b038116155b15612f41576000612e638787613352565b6001600160a01b0387811660009081526013602090815260408083208c830151845282528083208c82015160ff168452909152902080546001600160a01b031916838316179055909150831615612f1e5760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90612eeb9086906001906004016148ac565b600060405180830381600087803b158015612f0557600080fd5b505af1158015612f19573d6000803e3d6000fd5b505050505b612f3681886000015189602001518a60400151613664565b935061244692505050565b816001600160a01b0316816001600160a01b0316146130955760035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb90612f919084906000906004016148ac565b600060405180830381600087803b158015612fab57600080fd5b505af1158015612fbf573d6000803e3d6000fd5b505060035460405163ed5e00eb60e01b81526101009091046001600160a01b0316925063ed5e00eb9150612ffa9085906001906004016148ac565b600060405180830381600087803b15801561301457600080fd5b505af1158015613028573d6000803e3d6000fd5b505050506001600160a01b0385811660009081526013602090815260408083208a8301805185529083528184208b8301805160ff1686529352922080546001600160a01b0319169385169390931790925587519051915161308b92849291613664565b9250612446915050565b60035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb906130cc9085906000906004016148ac565b600060405180830381600087803b1580156130e657600080fd5b505af11580156130fa573d6000803e3d6000fd5b5050505061311682876000015188602001518960400151613664565b5091506124469050565b50505092915050565b6003548251604051631f138de360e31b8152600481019190915260009182916101009091046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561317957600080fd5b505afa15801561318d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131b19190613fc1565b6001600160a01b038116600090815260106020908152604080832088830151845282528083208882015160ff1684529091528120549192505b81811015613120576001600160a01b038084166000908152600f602090815260408083208a830151845282528083208a82015160ff16845282528083208584529091529020541661323b81876136c6565b508061324681614c90565b9150506131ea565b6001600160a01b03811660009081526015602052604090205460609060ff1661327f5761327a8261372a565b612446565b6001600160a01b038216600090815260146020908152604091829020805483518184028101840190945280845290918301828280156132dd57602002820191906000526020600020905b8154815260200190600101908083116132c9575b505050505092915050565b6001600160a01b03821660009081526017602052604081205461ffff169081613312846064614be8565b61ffff16116133425761ffff821661332b846064614be8565b61ffff161061333b576000613345565b6002613345565b60015b9050611689848483612c4e565b6003548251604051631c2ab73160e21b8152600481019190915260009182916133e79161010090046001600160a01b0316906370aadcc49060240160206040518083038186803b1580156133a557600080fd5b505afa1580156133b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133dd91906146f8565b8560400151613767565b60055485519192506001600160a01b031690634cde32ce9061340887613837565b600354885160405163c48e62f160e01b815260048101919091526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b15801561345357600080fd5b505afa158015613467573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261348f91908101906144de565b60200151600060028760018b6040518963ffffffff1660e01b81526004016134be989796959493929190614ab4565b602060405180830381600087803b1580156134d857600080fd5b505af11580156134ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135109190613fc1565b5060055460408051622610c560e41b815290516001600160a01b039092169163dd5adfa39160019184916302610c50916004808301926020929190829003018186803b15801561355f57600080fd5b505afa158015613573573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359791906146f8565b6135a19190614c12565b6040518263ffffffff1660e01b81526004016135bf91815260200190565b60206040518083038186803b1580156135d757600080fd5b505afa1580156135eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061360f9190613fc1565b915061365d846000015184848760800151886020015189606001518a604001518860028151811061365057634e487b7160e01b600052603260045260246000fd5b6020026020010151613887565b5092915050565b61366f838383613aee565b6001600160a01b0385166000908152601460209081526040909120825161369c9391929190910190613e0a565b5050506001600160a01b039091166000908152601560205260409020805460ff1916600117905550565b60035460405163ed5e00eb60e01b81526101009091046001600160a01b03169063ed5e00eb906136fc90859085906004016148ac565b600060405180830381600087803b15801561371657600080fd5b505af1158015611889573d6000803e3d6000fd5b6001600160a01b038116600090815260096020908152604080832054600a835281842054600b90935292205460609261244692909160ff16613aee565b604080516003808252608082019092526060916000919060208201848036833701905050905061379984612328614bbc565b816000815181106137ba57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505061271a816001815181106137ea57634e487b7160e01b600052603260045260246000fd5b602090810291909101015261380460ff8416612af8614bbc565b8160028151811061382557634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b6060816060015161384e836040015160ff16613c65565b61385f846080015161ffff16613c65565b604051602001613871939291906147d6565b6040516020818303038152906040529050919050565b600354604051624dc46d60e41b8152600481018a90526001600160a01b038881166024830152610100909204909116906304dc46d090604401600060405180830381600087803b1580156138da57600080fd5b505af11580156138ee573d6000803e3d6000fd5b505050506001600160a01b0386811660008181526009602090815260408083208d9055600a8252808320899055600b8252808320805460ff1990811660ff8a161790915560168352818420805490911660019081179091556012835281842080546001600160a01b0319908116978f16978817909155868552600c8452828520600e80865284872080548852918652938620805490921690961790559483529052815461399c908490614bbc565b90915550506001600160a01b038088166000818152601160209081526040808320898452825280832060ff881680855290835281842061ffff8c168086529084528285208054978e166001600160a01b0319988916811790915580865260178552838620805461ffff1916909217909155858552601384528285208b8652845282852082865284528285208054881682179055858552600f84528285208b865284528285208286528452828520958552601084528285208b865284528285208286528085528386208054875296855292852080549097161790955593825292909252805460019290613a8f908490614bbc565b909155507fad561eb279f0551643e940bd69a05112c9f5e19962eae3312d6490409e19410e905087878a87878a88613ac68661324e565b89604051613adc99989796959493929190614832565b60405180910390a15050505050505050565b604080516002808252606080830184529260009291906020830190803683375050506000868152600760209081526040808320888452825280832060ff881684529091528120600401548251929350620100009004600290810b900b91839190613b6857634e487b7160e01b600052603260045260246000fd5b6020908102919091018101919091526000868152600782526040808220878352835280822060ff8716835290925220600401548151600160281b909104600290810b900b9082906001908110613bce57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d97491613c08918591016149b9565b60006040518083038186803b158015613c2057600080fd5b505afa158015613c34573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613c5c9190810190614391565b95945050505050565b606081613c895750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613cb35780613c9d81614c90565b9150613cac9050600a83614bd4565b9150613c8d565b6000816001600160401b03811115613cdb57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613d05576020820181803683370190505b5090505b8415613d7e57613d1a600183614c12565b9150613d27600a86614cab565b613d32906030614bbc565b60f81b818381518110613d5557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350613d77600a86614bd4565b9450613d09565b949350505050565b828054613d9290614c55565b90600052602060002090601f016020900481019282613db45760008555613dfa565b82601f10613dcd57805160ff1916838001178555613dfa565b82800160010185558215613dfa579182015b82811115613dfa578251825591602001919060010190613ddf565b50613e06929150613e44565b5090565b828054828255906000526020600020908101928215613dfa5791602002820182811115613dfa578251825591602001919060010190613ddf565b5b80821115613e065760008155600101613e45565b600082601f830112613e69578081fd5b81516020613e7e613e7983614b72565b614b42565b80838252828201915082860187848660051b8901011115613e9d578586fd5b855b85811015613ec4578151613eb281614d16565b84529284019290840190600101613e9f565b5090979650505050505050565b8035613edc81614d24565b919050565b8051613edc81614d24565b600082601f830112613efc578081fd5b8135613f0a613e7982614b95565b818152846020838601011115613f1e578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112613f48578081fd5b8151613f56613e7982614b95565b818152846020838601011115613f6a578283fd5b613d7e826020830160208701614c29565b803561ffff81168114613edc57600080fd5b803560ff81168114613edc57600080fd5b600060208284031215613faf578081fd5b8135613fba81614d01565b9392505050565b600060208284031215613fd2578081fd5b8151613fba81614d01565b60008060008060808587031215613ff2578283fd5b8435613ffd81614d01565b9350602085013561400d81614d01565b9250604085013561401d81614d01565b9150606085013561402d81614d01565b939692955090935050565b60008060008060008060c08789031215614050578384fd5b863561405b81614d01565b955060208781013561406c81614d01565b9550604088013561407c81614d01565b9450606088013561408c81614d01565b9350608088013561409c81614d01565b925060a08801356001600160401b038111156140b6578283fd5b8801601f81018a136140c6578283fd5b80356140d4613e7982614b72565b8082825284820191508484018d868560051b87010111156140f3578687fd5b8694505b838510156141155780358352600194909401939185019185016140f7565b5080955050505050509295509295509295565b6000806000806080858703121561413d578182fd5b843561414881614d01565b9350602085013561415881614d16565b9250604085013561416881614d16565b9150606085013561402d81614d16565b60008060006060848603121561418c578081fd5b833561419781614d01565b9250602084013591506141ac60408501613f8d565b90509250925092565b600080600080608085870312156141ca578182fd5b84356141d581614d01565b9350602085013592506141ea60408601613f8d565b91506141f860608601613f7b565b905092959194509250565b60008060008060808587031215614218578182fd5b843561422381614d01565b93506020850135925061423860408601613f8d565b9396929550929360600135925050565b6000806040838503121561425a578182fd5b823561426581614d01565b946020939093013593505050565b60006020808385031215614285578182fd5b82356001600160401b0381111561429a578283fd5b8301601f810185136142aa578283fd5b80356142b8613e7982614b72565b80828252848201915084840188868560051b87010111156142d7578687fd5b8694505b838510156143025780356142ee81614d01565b8352600194909401939185019185016142db565b50979650505050505050565b600080600060608486031215614322578081fd5b83516001600160401b0380821115614338578283fd5b61434487838801613e59565b94506020860151915080821115614359578283fd5b61436587838801613e59565b9350604086015191508082111561437a578283fd5b5061438786828701613e59565b9150509250925092565b600060208083850312156143a3578182fd5b82516001600160401b038111156143b8578283fd5b8301601f810185136143c8578283fd5b80516143d6613e7982614b72565b80828252848201915084840188868560051b87010111156143f5578687fd5b8694505b838510156143025780518352600194909401939185019185016143f9565b600060208284031215614428578081fd5b8135613fba81614d16565b600060208284031215614444578081fd5b8151613fba81614d16565b600060208284031215614460578081fd5b5035919050565b60008060408385031215614479578182fd5b50508035926020909101359150565b60008060006060848603121561449c578081fd5b505081359360208301359350604090920135919050565b6000806000606084860312156144c7578081fd5b83359250602084013591506141ac60408501613f8d565b6000602082840312156144ef578081fd5b81516001600160401b0380821115614505578283fd5b9083019060e08286031215614518578283fd5b614520614b1a565b825181526020830151602082015261453a60408401613ee1565b604082015261454b60608401613ee1565b606082015261455c60808401613ee1565b608082015260a083015182811115614572578485fd5b61457e87828601613f38565b60a08301525060c083015182811115614595578485fd5b6145a187828601613f38565b60c08301525095945050505050565b600060a082840312156145c1578081fd5b60405160a081018181106001600160401b03821117156145e3576145e3614ceb565b8060405250823581526020830135602082015261460260408401613f8d565b604082015261461360608401613f7b565b606082015261462460808401613f8d565b60808201529392505050565b60008060408385031215614642578182fd5b82356001600160401b0380821115614658578384fd5b9084019060e0828703121561466b578384fd5b614673614b1a565b823581526020830135602082015261468d60408401613f8d565b60408201526060830135828111156146a3578586fd5b6146af88828601613eec565b6060830152506146c160808401613f7b565b60808201526146d260a08401613ed1565b60a08201526146e360c08401613ed1565b60c08201529660209590950135955050505050565b600060208284031215614709578081fd5b5051919050565b60008060408385031215614722578182fd5b82359150602083013561473481614d16565b809150509250929050565b6000815180845260208085019450808401835b83811015614770578151151587529582019590820190600101614752565b509495945050505050565b6000815180845260208085019450808401835b838110156147705781518752958201959082019060010161478e565b600081518084526147c2816020860160208601614c29565b601f01601f19169290920160200192915050565b600084516147e8818460208901614c29565b80830190506201016960ed1b808252855161480a816003850160208a01614c29565b60039201918201528351614825816006840160208801614c29565b0160060195945050505050565b6001600160a01b038a811682528916602082015260408101889052606081018790526101206080820181905260009061486d838201896147aa565b905061ffff871660a084015260ff861660c084015282810360e0840152614894818661477b565b915050826101008301529a9950505050505050505050565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156149085783516001600160a01b0316835292840192918401916001016148e3565b50909695505050505050565b6080808252855190820181905260009060209060a0840190828901845b8281101561494d57815184529284019290840190600101614931565b50505083810382850152865180825287830191830190845b8181101561498457835160ff1683529284019291840191600101614965565b50508481036040860152614998818861473f565b9250505082810360608401526149ae818561473f565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614908578351835292840192918401916001016149d5565b602081526000613fba602083018461477b565b6000608082018683526020868185015260ff861660408501526080606085015281855480845260a0860191508685528285209350845b81811015614a5657845483526001948501949284019201614a3a565b50909998505050505050505050565b87815286602082015260ff8616604082015260e060608201526000614a8d60e08301876147aa565b61ffff95909516608083015250600292830b60a0820152910b60c090910152949350505050565b60006101008a8352806020840152614ace8184018b6147aa565b905088604084015287606084015286608084015282810360a0840152614af4818761477b565b94151560c084015250506001600160a01b039190911660e0909101529695505050505050565b60405160e081016001600160401b0381118282101715614b3c57614b3c614ceb565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614b6a57614b6a614ceb565b604052919050565b60006001600160401b03821115614b8b57614b8b614ceb565b5060051b60200190565b60006001600160401b03821115614bae57614bae614ceb565b50601f01601f191660200190565b60008219821115614bcf57614bcf614cbf565b500190565b600082614be357614be3614cd5565b500490565b600061ffff80831681851681830481118215151615614c0957614c09614cbf565b02949350505050565b600082821015614c2457614c24614cbf565b500390565b60005b83811015614c44578181015183820152602001614c2c565b838111156116895750506000910152565b600181811c90821680614c6957607f821691505b60208210811415614c8a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415614ca457614ca4614cbf565b5060010190565b600082614cba57614cba614cd5565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f2e57600080fd5b8015158114610f2e57600080fd5b8060020b8114610f2e57600080fdfea2646970667358221220f5b3678539f447ccd67f73588dd389ae335d3e61d0f1e886f37b42daa340ec3664736f6c63430008040033

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