Contract 0xE7f23496c1bD0d60128309eA892dEf16800Ca3A7

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

Contract Overview

Balance:
Txn Hash Method
Block
From
To
Value
0xac154a5065868c14f447fde615d4e9a3ae193440153d92ca3e4c98a5a44ae93c0x60806040179785502023-11-30 22:59:28145 days 6 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  Create: SportAMMRiskManager0 ETH0.0000000270150.00001
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SportAMMRiskManager

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

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

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

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

// interface
import "../interfaces/ISportPositionalMarketManager.sol";

/// @title Sports AMM Risk contract
/// @author gruja
contract SportAMMRiskManager is Initializable, ProxyOwned, PausableUpgradeable, ProxyReentrancyGuard {
    /* ========== RISK MANAGER CONST VARIABLES ========== */
    uint public constant MIN_TAG_NUMBER = 9000;
    uint public constant MIN_CHILD_NUMBER = 10000;
    uint public constant MIN_PLAYER_PROPS_NUMBER = 11000;
    uint public constant DEFAULT_DYNAMIC_LIQUIDITY_CUTOFF_DIVIDER = 2e18;
    uint private constant ONE = 1e18;

    /* ========== RISK MANAGER STATE VARIABLES ========== */
    address public manager;
    uint public defaultCapPerGame;
    mapping(uint => uint) public capPerSport;
    mapping(uint => mapping(uint => uint)) public capPerSportAndChild;
    mapping(address => uint) public capPerMarket;

    uint public defaultRiskMultiplier;
    mapping(uint => uint) public riskMultiplierForSport;
    mapping(address => uint) public riskMultiplierPerMarket;

    uint public maxCap;
    uint public maxRiskMultiplier;

    mapping(uint => bool) public isMarketForSportOnePositional;
    mapping(uint => bool) public isMarketForPlayerPropsOnePositional;

    // @return specific min_spread per address
    mapping(uint => mapping(uint => uint)) public minSpreadPerSport;

    /// @return The maximum supported odd for sport
    mapping(uint => uint) public minSupportedOddsPerSport;

    /// @return The maximum supported odd for sport
    mapping(uint => uint) public maxSpreadPerSport;

    mapping(uint => uint) public dynamicLiquidityCutoffTimePerSport;
    mapping(uint => uint) public dynamicLiquidityCutoffDividerPerSport;

    address public sportsAMMCancellationPool;


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

    function initialize(
        address _owner,
        address _manager,
        uint _defaultCapPerGame,
        uint[] memory _sportIds,
        uint[] memory _capsPerSport,
        uint[] memory _sportIdsForChilds,
        uint[] memory _childsIds,
        uint[] memory _capsForChilds,
        uint _defaultRiskMultiplier,
        uint[] memory _sportIdsForMultiplier,
        uint[] memory _riskMultiplierPerSport
    ) public initializer {
        setOwner(_owner);
        initNonReentrant();
        defaultCapPerGame = _defaultCapPerGame;
        defaultRiskMultiplier = _defaultRiskMultiplier;
        manager = _manager;

        for (uint i; i < _sportIds.length; i++) {
            capPerSport[_sportIds[i]] = _capsPerSport[i];
        }

        for (uint i; i < _sportIdsForChilds.length; i++) {
            capPerSportAndChild[_sportIdsForChilds[i]][_childsIds[i]] = _capsForChilds[i];
        }

        for (uint i; i < _sportIdsForMultiplier.length; i++) {
            riskMultiplierForSport[_sportIdsForMultiplier[i]] = _riskMultiplierPerSport[i];
        }
    }

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

    /// @notice calculate which cap needs to be applied to the given market
    /// @param _market to get cap for
    /// @return toReturn cap to use
    function calculateCapToBeUsed(address _market) external view returns (uint toReturn) {
        (uint tag1, uint tag2) = ISportPositionalMarket(_market).getTags();
        return _calculateCapToBeUsed(_market, tag1, tag2);
    }

    /// @notice returns if market is in to much of a risk
    /// @param _totalSpent total spent on market
    /// @param _market for which is calculation done
    /// @return _isNotRisky true/false
    function isTotalSpendingLessThanTotalRisk(uint _totalSpent, address _market) external view returns (bool _isNotRisky) {
        (uint tag1, uint tag2) = ISportPositionalMarket(_market).getTags();
        uint capToBeUsed = _calculateCapToBeUsed(_market, tag1, tag2);
        uint riskMultiplier = _calculateRiskMultiplier(_market, tag1, tag2);
        return _totalSpent <= capToBeUsed * riskMultiplier;
    }

    /// @notice returns all data (caps, min spread, etc.) for given sports
    /// @param _sportIds sport ids
    /// @return _capsPerSport caps per sport
    /// @return _capsPerSportH caps per child H
    /// @return _capsPerSportT caps per child T
    /// @return _capsPerSportPP caps per child PP
    /// @return _minSpreadSport min spread per sport
    /// @return _minSpreadSportH min spread per child H
    /// @return _minSpreadSportT min spread per child T
    /// @return _minSpreadSportPP min spread per child PP
    function getAllDataForSports(uint[] memory _sportIds)
        external
        view
        returns (
            uint[] memory _capsPerSport,
            uint[] memory _capsPerSportH,
            uint[] memory _capsPerSportT,
            uint[] memory _capsPerSportPP,
            uint[] memory _minSpreadSport,
            uint[] memory _minSpreadSportH,
            uint[] memory _minSpreadSportT,
            uint[] memory _minSpreadSportPP
        )
    {
        _capsPerSport = new uint[](_sportIds.length);
        _capsPerSportH = new uint[](_sportIds.length);
        _capsPerSportT = new uint[](_sportIds.length);
        _capsPerSportPP = new uint[](_sportIds.length);
        _minSpreadSport = new uint[](_sportIds.length);
        _minSpreadSportH = new uint[](_sportIds.length);
        _minSpreadSportT = new uint[](_sportIds.length);
        _minSpreadSportPP = new uint[](_sportIds.length);

        for (uint i = 0; i < _sportIds.length; i++) {
            _capsPerSport[i] = capPerSport[_sportIds[i]];
            _capsPerSportH[i] = capPerSportAndChild[_sportIds[i]][MIN_CHILD_NUMBER + 1];
            _capsPerSportT[i] = capPerSportAndChild[_sportIds[i]][MIN_CHILD_NUMBER + 2];
            _capsPerSportPP[i] = capPerSportAndChild[_sportIds[i]][MIN_CHILD_NUMBER + 10];
            _minSpreadSport[i] = minSpreadPerSport[_sportIds[i]][0];
            _minSpreadSportH[i] = minSpreadPerSport[_sportIds[i]][MIN_CHILD_NUMBER + 1];
            _minSpreadSportT[i] = minSpreadPerSport[_sportIds[i]][MIN_CHILD_NUMBER + 2];
            _minSpreadSportPP[i] = minSpreadPerSport[_sportIds[i]][MIN_CHILD_NUMBER + 10];
        }
    }

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

    function _calculateRiskMultiplier(
        address market,
        uint tag1,
        uint tag2
    ) internal view returns (uint toReturn) {
        uint marketRisk = riskMultiplierPerMarket[market];

        if (marketRisk == 0) {
            uint riskPerTag = riskMultiplierForSport[tag1];
            marketRisk = riskPerTag > 0 ? riskPerTag : defaultRiskMultiplier;
        }

        toReturn = marketRisk;
    }

    function _calculateCapToBeUsed(
        address market,
        uint tag1,
        uint tag2
    ) internal view returns (uint toReturn) {
        toReturn = capPerMarket[market];
        if (toReturn == 0) {
            uint capFirstTag = capPerSport[tag1];
            capFirstTag = capFirstTag > 0 ? capFirstTag : defaultCapPerGame;
            toReturn = capFirstTag;

            if (tag2 > 0) {
                uint capSecondTag = capPerSportAndChild[tag1][tag2];
                toReturn = capSecondTag > 0 ? capSecondTag : capFirstTag / 2;
            }
        }

        uint dynamicLiquidityCutoffTime = dynamicLiquidityCutoffTimePerSport[tag1];
        if (dynamicLiquidityCutoffTime > 0) {
            (uint maturity, ) = ISportPositionalMarket(market).times();
            uint timeToStart = maturity - block.timestamp;
            uint cutOffLiquidity = (toReturn * ONE) /
                (
                    dynamicLiquidityCutoffDividerPerSport[tag1] > 0
                        ? dynamicLiquidityCutoffDividerPerSport[tag1]
                        : DEFAULT_DYNAMIC_LIQUIDITY_CUTOFF_DIVIDER
                );
            if (timeToStart >= dynamicLiquidityCutoffTime) {
                toReturn = cutOffLiquidity;
            } else {
                uint remainingFromCutOff = toReturn - cutOffLiquidity;
                toReturn =
                    cutOffLiquidity +
                    (((dynamicLiquidityCutoffTime - timeToStart) * remainingFromCutOff) / dynamicLiquidityCutoffTime);
            }
        }
    }

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

    /// @notice Setting the dynamic liquidity params
    /// @param _sportID The tagID used for sport (9004)
    /// @param _dynamicLiquidityCutoffTime when to start increasing the liquidity linearly, if 0 assume 100% liquidity all the time since market creation
    /// @param _dynamicLiquidityCutoffDivider e.g. if 2 it means liquidity up until cut off time is 50%, then increases linearly. if 0 use default
    function setDynamicLiquidityParamsPerSport(
        uint _sportID,
        uint _dynamicLiquidityCutoffTime,
        uint _dynamicLiquidityCutoffDivider
    ) external onlyOwner {
        require(_sportID > MIN_TAG_NUMBER, "Invalid tag for sport");
        dynamicLiquidityCutoffTimePerSport[_sportID] = _dynamicLiquidityCutoffTime;
        dynamicLiquidityCutoffDividerPerSport[_sportID] = _dynamicLiquidityCutoffDivider;
        emit SetDynamicLiquidityParams(_sportID, _dynamicLiquidityCutoffTime, _dynamicLiquidityCutoffDivider);
    }

    /// @notice Setting the Cap per spec. market
    /// @param _markets market addresses
    /// @param _capPerMarket The cap amount used for the specific markets
    function setCapPerMarket(address[] memory _markets, uint _capPerMarket) external {
        require(
            msg.sender == owner || ISportPositionalMarketManager(manager).isWhitelistedAddress(msg.sender),
            "Invalid sender"
        );
        require(_capPerMarket <= maxCap, "Invalid cap");
        for (uint i; i < _markets.length; i++) {
            require(_markets[i] != address(0), "Invalid address");
            capPerMarket[_markets[i]] = _capPerMarket;
            emit SetCapPerMarket(_markets[i], _capPerMarket);
        }
    }

    /// @notice Setting the Cap per Sport ID
    /// @param _sportID The tagID used for sport (9004)
    /// @param _childID The tagID used for childid (10002)
    /// @param _capPerChild The cap amount used for the sportID
    function setCapPerSportAndChild(
        uint _sportID,
        uint _childID,
        uint _capPerChild
    ) external onlyOwner {
        uint currentCapPerSport = capPerSport[_sportID] > 0 ? capPerSport[_sportID] : defaultCapPerGame;
        require(_capPerChild <= currentCapPerSport, "Invalid cap");
        require(_sportID > MIN_TAG_NUMBER, "Invalid tag for sport");
        require(_childID > MIN_CHILD_NUMBER, "Invalid tag for child");
        capPerSportAndChild[_sportID][_childID] = _capPerChild;
        emit SetCapPerSportAndChild(_sportID, _childID, _capPerChild);
    }

    /// @notice Setting the Cap per Sport ID
    /// @param _sportID The tagID used for each market
    /// @param _capPerSport The cap amount used for the sportID
    function setCapPerSport(uint _sportID, uint _capPerSport) external onlyOwner {
        require(_sportID > MIN_TAG_NUMBER, "Invalid tag for sport");
        require(_capPerSport <= maxCap, "Invalid cap");
        capPerSport[_sportID] = _capPerSport;
        emit SetCapPerSport(_sportID, _capPerSport);
    }

    /// @notice Setting the Cap per game default value
    /// @param _capPerGame default cap
    function setDefaultCapPerGame(uint _capPerGame) external onlyOwner {
        require(_capPerGame <= maxCap, "Invalid cap");
        defaultCapPerGame = _capPerGame;
        emit SetDefaultCapPerGame(_capPerGame);
    }

    /// @notice default risk multiplier
    /// @param _riskMultiplier risk multiplier
    function setDefaultRiskMultiplier(uint _riskMultiplier) external onlyOwner {
        require(_riskMultiplier <= maxRiskMultiplier, "Invalid multiplier");
        defaultRiskMultiplier = _riskMultiplier;
        emit SetDefaultRiskMultiplier(_riskMultiplier);
    }

    /// @notice Setting the risk multiplier per Sport ID
    /// @param _sportID The tagID used for each market
    /// @param _riskMultiplier The risk multiplier amount used for the sportID
    function setRiskMultiplierPerSport(uint _sportID, uint _riskMultiplier) external onlyOwner {
        require(_sportID > MIN_TAG_NUMBER, "Invalid tag for sport");
        require(_riskMultiplier <= maxRiskMultiplier, "Invalid multiplier");
        riskMultiplierForSport[_sportID] = _riskMultiplier;
        emit SetRiskMultiplierPerSport(_sportID, _riskMultiplier);
    }

    /// @notice Setting the risk multiplier per spec. market
    /// @param _markets market addresses
    /// @param _riskMultiplier The risk multiplier used for the specific markets
    function setRiskMultiplierMarket(address[] memory _markets, uint _riskMultiplier) external {
        require(
            msg.sender == owner || ISportPositionalMarketManager(manager).isWhitelistedAddress(msg.sender),
            "Invalid sender"
        );
        require(_riskMultiplier <= maxRiskMultiplier, "Invalid multiplier");
        for (uint i; i < _markets.length; i++) {
            require(_markets[i] != address(0), "Invalid address");
            riskMultiplierPerMarket[_markets[i]] = _riskMultiplier;
            emit SetRiskMultiplierPerMarket(_markets[i], _riskMultiplier);
        }
    }

    /// @notice Setting the Sport Positional Manager contract address
    /// @param _manager Address of Staking contract
    function setSportsPositionalMarketManager(address _manager) external onlyOwner {
        require(_manager != address(0), "Invalid address");
        manager = _manager;
        emit SetSportsPositionalMarketManager(_manager);
    }

    /// @notice Setting the max cap and risk per market
    /// @param _maxCap max cap per market
    /// @param _maxRisk max risk multiplier
    function setMaxCapAndRisk(uint _maxCap, uint _maxRisk) external onlyOwner {
        require(_maxCap > defaultCapPerGame && _maxRisk > defaultRiskMultiplier, "Invalid input");
        maxCap = _maxCap;
        maxRiskMultiplier = _maxRisk;
        emit SetMaxCapAndRisk(_maxCap, _maxRisk);
    }

    function setMinSupportedOddsAndMaxSpreadPerSportPerSport(
        uint _sportID,
        uint _minSupportedOdds,
        uint _maxSpreadPerSport
    ) external onlyOwner {
        minSupportedOddsPerSport[_sportID] = _minSupportedOdds;
        maxSpreadPerSport[_sportID] = _maxSpreadPerSport;
        emit SetMinSupportedOddsAndMaxSpreadPerSport(_sportID, _minSupportedOdds, _maxSpreadPerSport);
    }

    /// @notice Setting the Min Spread per Sport ID
    /// @param _tag1 The first tagID used for each market
    /// @param _tag2 The second tagID used for each market
    /// @param _minSpread The min spread amount used for the sportID
    function setMinSpreadPerSport(
        uint _tag1,
        uint _tag2,
        uint _minSpread
    ) external onlyOwner {
        minSpreadPerSport[_tag1][_tag2] = _minSpread;
        emit SetMinSpreadPerSport(_tag1, _tag2, _minSpread);
    }

    /// @notice setting one positional sport
    /// @param _sportID tag id for sport
    /// @param _flag is one positional sport flag
    function setSportOnePositional(uint _sportID, bool _flag) external onlyOwner {
        require(_sportID > MIN_TAG_NUMBER, "Invalid tag for sport");
        require(isMarketForSportOnePositional[_sportID] != _flag, "Invalid flag");
        isMarketForSportOnePositional[_sportID] = _flag;
        emit SetSportOnePositional(_sportID, _flag);
    }

    /// @notice setting one positional sport
    /// @param _playerPropsOptionTag tag id for PP
    /// @param _flag is one positional sport flag
    function setPlayerPropsOnePositional(uint _playerPropsOptionTag, bool _flag) external onlyOwner {
        require(_playerPropsOptionTag > MIN_PLAYER_PROPS_NUMBER, "Invalid tag for player props");
        require(isMarketForPlayerPropsOnePositional[_playerPropsOptionTag] != _flag, "Invalid flag");
        isMarketForPlayerPropsOnePositional[_playerPropsOptionTag] = _flag;
        emit SetPlayerPropsOnePositional(_playerPropsOptionTag, _flag);
    }

    function getMinSpreadToUse(
        bool useDefaultMinSpread,
        address market,
        uint min_spread,
        uint min_spreadPerAddress
    ) external view returns (uint min_spreadToUse) {
        (uint tag1, uint tag2) = ISportPositionalMarket(market).getTags();
        uint minSpreadByTags = minSpreadPerSport[tag1][tag2];
        uint minSpreadByPrimaryTag = minSpreadPerSport[tag1][0];
        uint spreadForTag = tag2 > 0 && minSpreadByTags > 0 ? minSpreadByTags : minSpreadByPrimaryTag;
        min_spreadToUse = useDefaultMinSpread
            ? (spreadForTag > 0 ? spreadForTag : min_spread)
            : (min_spreadPerAddress > 0 ? min_spreadPerAddress : (spreadForTag > 0 ? spreadForTag : min_spread));
    }

    function getMaxSpreadForMarket(address _market, uint max_spread) external view returns (uint maxSpread) {
        (uint tag1, ) = ISportPositionalMarket(_market).getTags();
        uint _maxSpreadPerSport = maxSpreadPerSport[tag1];
        maxSpread = _maxSpreadPerSport > 0 ? _maxSpreadPerSport : max_spread;
    }

    function getCapAndMaxSpreadForMarket(address _market, uint max_spread) public view returns (uint cap, uint maxSpread) {
        (uint tag1, uint tag2) = ISportPositionalMarket(_market).getTags();
        uint _maxSpreadPerSport = maxSpreadPerSport[tag1];
        maxSpread = _maxSpreadPerSport > 0 ? _maxSpreadPerSport : max_spread;
        cap = _calculateCapToBeUsed(_market, tag1, tag2);
    }

    function getCapMaxSpreadAndMinOddsForMarket(
        address _market,
        uint max_spread,
        uint minSupportedOdds
    )
        external
        view
        returns (
            uint cap,
            uint maxSpread,
            uint minOddsForMarket
        )
    {
        (uint tag1, uint tag2) = ISportPositionalMarket(_market).getTags();
        uint _maxSpreadPerSport = maxSpreadPerSport[tag1];
        maxSpread = _maxSpreadPerSport > 0 ? _maxSpreadPerSport : max_spread;
        cap = _calculateCapToBeUsed(_market, tag1, tag2);
        uint _minSupportedOddsPerSport = minSupportedOddsPerSport[tag1];
        minOddsForMarket = _minSupportedOddsPerSport > 0 ? _minSupportedOddsPerSport : minSupportedOdds;
    }

    function getMinOddsForMarket(address _market, uint minSupportedOdds) external view returns (uint minOdds) {
        (uint tag1, ) = ISportPositionalMarket(_market).getTags();
        uint _minSupportedOddsPerSport = minSupportedOddsPerSport[tag1];
        minOdds = _minSupportedOddsPerSport > 0 ? _minSupportedOddsPerSport : minSupportedOdds;
    }

    /* ========== MODIFIERS ========== */
    /* ========== EVENTS ========== */
    event SetCapPerSport(uint _sport, uint _cap);
    event SetCapPerMarket(address _market, uint _cap);
    event SetCapPerSportAndChild(uint _sport, uint _child, uint _cap);
    event SetSportsPositionalMarketManager(address _manager);
    event SetDefaultCapPerGame(uint _cap);
    event SetDefaultRiskMultiplier(uint _riskMultiplier);
    event SetRiskMultiplierPerSport(uint _sport, uint _riskMultiplier);
    event SetRiskMultiplierPerMarket(address _market, uint _riskMultiplier);
    event SetMaxCapAndRisk(uint _maxCap, uint _maxRisk);
    event SetMinSpreadPerSport(uint _tag1, uint _tag2, uint _spread);
    event SetMinSupportedOddsAndMaxSpreadPerSport(uint _sport, uint _minSupportedOddsPerSport, uint _maxSpreadPerSport);
    event SetSportOnePositional(uint _sport, bool _flag);
    event SetPlayerPropsOnePositional(uint _playerPropsOptionTag, bool _flag);
    event SetDynamicLiquidityParams(uint _sport, uint _dynamicLiquidityCutoffTime, uint _dynamicLiquidityCutoffDivider);
}

File 2 of 13 : 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 3 of 13 : 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 4 of 13 : ProxyReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the `nonReentrant` modifier
 * available, which can be aplied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 */
contract ProxyReentrancyGuard {
    /// @dev counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;
    bool private _initialized;

    function initNonReentrant() public {
        require(!_initialized, "Already initialized");
        _initialized = true;
        _guardCounter = 1;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call");
    }
}

File 5 of 13 : 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 13 : ISportPositionalMarketManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

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

    function marketCreationEnabled() external view returns (bool);

    function totalDeposited() external view returns (uint);

    function numActiveMarkets() external view returns (uint);

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

    function numMaturedMarkets() external view returns (uint);

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

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

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

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

    function isDoubleChanceSupported() external view returns (bool);

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

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

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

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

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

    function expiryDuration() external view returns (uint);

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

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

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

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

    function setMarketPaused(address _market, bool _paused) external;

    function updateDatesForMarket(address _market, uint256 _newStartTime) external;

    function resolveMarket(address market, uint outcome) external;

    function expireMarkets(address[] calldata market) external;

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

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

File 7 of 13 : 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 8 of 13 : 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 9 of 13 : ISportPositionalMarket.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16;

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

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

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

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

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

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

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

    function getGameId() external view returns (bytes32);

    function deposited() external view returns (uint);

    function optionsCount() external view returns (uint);

    function creator() external view returns (address);

    function resolved() external view returns (bool);

    function cancelled() external view returns (bool);

    function paused() external view returns (bool);

    function phase() external view returns (Phase);

    function canResolve() external view returns (bool);

    function result() external view returns (Side);

    function isChild() external view returns (bool);

    function optionsInitialized() external view returns (bool);

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

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

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

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

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

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

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

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

    function isDoubleChance() external view returns (bool);

    function parentMarket() external view returns (ISportPositionalMarket);

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

    function setPaused(bool _paused) external;

    function updateDates(uint256 _maturity, uint256 _expiry) external;

    function mint(uint value) external;

    function exerciseOptions() external;

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

File 10 of 13 : 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 11 of 13 : 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 12 of 13 : 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 13 of 13 : 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":"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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_market","type":"address"},{"indexed":false,"internalType":"uint256","name":"_cap","type":"uint256"}],"name":"SetCapPerMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sport","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_cap","type":"uint256"}],"name":"SetCapPerSport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sport","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_child","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_cap","type":"uint256"}],"name":"SetCapPerSportAndChild","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_cap","type":"uint256"}],"name":"SetDefaultCapPerGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_riskMultiplier","type":"uint256"}],"name":"SetDefaultRiskMultiplier","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sport","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_dynamicLiquidityCutoffTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_dynamicLiquidityCutoffDivider","type":"uint256"}],"name":"SetDynamicLiquidityParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_maxCap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_maxRisk","type":"uint256"}],"name":"SetMaxCapAndRisk","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tag1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tag2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_spread","type":"uint256"}],"name":"SetMinSpreadPerSport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sport","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_minSupportedOddsPerSport","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_maxSpreadPerSport","type":"uint256"}],"name":"SetMinSupportedOddsAndMaxSpreadPerSport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_playerPropsOptionTag","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_flag","type":"bool"}],"name":"SetPlayerPropsOnePositional","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_market","type":"address"},{"indexed":false,"internalType":"uint256","name":"_riskMultiplier","type":"uint256"}],"name":"SetRiskMultiplierPerMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sport","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_riskMultiplier","type":"uint256"}],"name":"SetRiskMultiplierPerSport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sport","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_flag","type":"bool"}],"name":"SetSportOnePositional","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_manager","type":"address"}],"name":"SetSportsPositionalMarketManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_DYNAMIC_LIQUIDITY_CUTOFF_DIVIDER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_CHILD_NUMBER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_PLAYER_PROPS_NUMBER","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":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"calculateCapToBeUsed","outputs":[{"internalType":"uint256","name":"toReturn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"capPerMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"capPerSport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"capPerSportAndChild","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultCapPerGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRiskMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dynamicLiquidityCutoffDividerPerSport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dynamicLiquidityCutoffTimePerSport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_sportIds","type":"uint256[]"}],"name":"getAllDataForSports","outputs":[{"internalType":"uint256[]","name":"_capsPerSport","type":"uint256[]"},{"internalType":"uint256[]","name":"_capsPerSportH","type":"uint256[]"},{"internalType":"uint256[]","name":"_capsPerSportT","type":"uint256[]"},{"internalType":"uint256[]","name":"_capsPerSportPP","type":"uint256[]"},{"internalType":"uint256[]","name":"_minSpreadSport","type":"uint256[]"},{"internalType":"uint256[]","name":"_minSpreadSportH","type":"uint256[]"},{"internalType":"uint256[]","name":"_minSpreadSportT","type":"uint256[]"},{"internalType":"uint256[]","name":"_minSpreadSportPP","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"max_spread","type":"uint256"}],"name":"getCapAndMaxSpreadForMarket","outputs":[{"internalType":"uint256","name":"cap","type":"uint256"},{"internalType":"uint256","name":"maxSpread","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"max_spread","type":"uint256"},{"internalType":"uint256","name":"minSupportedOdds","type":"uint256"}],"name":"getCapMaxSpreadAndMinOddsForMarket","outputs":[{"internalType":"uint256","name":"cap","type":"uint256"},{"internalType":"uint256","name":"maxSpread","type":"uint256"},{"internalType":"uint256","name":"minOddsForMarket","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"max_spread","type":"uint256"}],"name":"getMaxSpreadForMarket","outputs":[{"internalType":"uint256","name":"maxSpread","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"minSupportedOdds","type":"uint256"}],"name":"getMinOddsForMarket","outputs":[{"internalType":"uint256","name":"minOdds","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"useDefaultMinSpread","type":"bool"},{"internalType":"address","name":"market","type":"address"},{"internalType":"uint256","name":"min_spread","type":"uint256"},{"internalType":"uint256","name":"min_spreadPerAddress","type":"uint256"}],"name":"getMinSpreadToUse","outputs":[{"internalType":"uint256","name":"min_spreadToUse","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initNonReentrant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_manager","type":"address"},{"internalType":"uint256","name":"_defaultCapPerGame","type":"uint256"},{"internalType":"uint256[]","name":"_sportIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_capsPerSport","type":"uint256[]"},{"internalType":"uint256[]","name":"_sportIdsForChilds","type":"uint256[]"},{"internalType":"uint256[]","name":"_childsIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_capsForChilds","type":"uint256[]"},{"internalType":"uint256","name":"_defaultRiskMultiplier","type":"uint256"},{"internalType":"uint256[]","name":"_sportIdsForMultiplier","type":"uint256[]"},{"internalType":"uint256[]","name":"_riskMultiplierPerSport","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isMarketForPlayerPropsOnePositional","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isMarketForSportOnePositional","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalSpent","type":"uint256"},{"internalType":"address","name":"_market","type":"address"}],"name":"isTotalSpendingLessThanTotalRisk","outputs":[{"internalType":"bool","name":"_isNotRisky","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRiskMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"maxSpreadPerSport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"minSpreadPerSport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"minSupportedOddsPerSport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"riskMultiplierForSport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"riskMultiplierPerMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_markets","type":"address[]"},{"internalType":"uint256","name":"_capPerMarket","type":"uint256"}],"name":"setCapPerMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportID","type":"uint256"},{"internalType":"uint256","name":"_capPerSport","type":"uint256"}],"name":"setCapPerSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportID","type":"uint256"},{"internalType":"uint256","name":"_childID","type":"uint256"},{"internalType":"uint256","name":"_capPerChild","type":"uint256"}],"name":"setCapPerSportAndChild","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_capPerGame","type":"uint256"}],"name":"setDefaultCapPerGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_riskMultiplier","type":"uint256"}],"name":"setDefaultRiskMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportID","type":"uint256"},{"internalType":"uint256","name":"_dynamicLiquidityCutoffTime","type":"uint256"},{"internalType":"uint256","name":"_dynamicLiquidityCutoffDivider","type":"uint256"}],"name":"setDynamicLiquidityParamsPerSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxCap","type":"uint256"},{"internalType":"uint256","name":"_maxRisk","type":"uint256"}],"name":"setMaxCapAndRisk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tag1","type":"uint256"},{"internalType":"uint256","name":"_tag2","type":"uint256"},{"internalType":"uint256","name":"_minSpread","type":"uint256"}],"name":"setMinSpreadPerSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportID","type":"uint256"},{"internalType":"uint256","name":"_minSupportedOdds","type":"uint256"},{"internalType":"uint256","name":"_maxSpreadPerSport","type":"uint256"}],"name":"setMinSupportedOddsAndMaxSpreadPerSportPerSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_playerPropsOptionTag","type":"uint256"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setPlayerPropsOnePositional","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_markets","type":"address[]"},{"internalType":"uint256","name":"_riskMultiplier","type":"uint256"}],"name":"setRiskMultiplierMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportID","type":"uint256"},{"internalType":"uint256","name":"_riskMultiplier","type":"uint256"}],"name":"setRiskMultiplierPerSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportID","type":"uint256"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setSportOnePositional","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setSportsPositionalMarketManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sportsAMMCancellationPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"transferOwnershipAtInit","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50612fe6806100206000396000f3fe608060405234801561001057600080fd5b50600436106103275760003560e01c80635d6a738c116101b8578063aa0f0bb011610104578063e365da78116100a2578063ecc716851161007c578063ecc7168514610791578063f2c69934146107b1578063f88b7571146107d1578063f9f211ae146107e457600080fd5b8063e365da7814610756578063e4d34a0314610776578063ebc797721461078957600080fd5b8063be2f1227116100de578063be2f1227146106f0578063bf7ff78b14610710578063c3b83f5f14610723578063cbeb9d661461073657600080fd5b8063aa0f0bb0146106a9578063b4cb26de146106b2578063ba0ed4ed146106dd57600080fd5b806379ba5097116101715780638dfd117e1161014b5780638dfd117e1461063f57806392294b0a146106625780639bfa23dc1461068d578063a89ea2c01461069657600080fd5b806379ba50971461060b578063857bfa68146106135780638da5cb5b1461062657600080fd5b80635d6a738c1461058957806360315786146105a9578063625ffa29146105c9578063691824dd146105dc5780636ff5f440146105e5578063771927d8146105f857600080fd5b806338347e121161027757806348ad44f8116102305780634dfbc89c1161020a5780634dfbc89c1461054f5780634f2cc14a1461055857806353a47bb71461056b5780635c975abb1461057e57600080fd5b806348ad44f8146105165780634b28fb05146105295780634c7976c91461053c57600080fd5b806338347e12146104955780633c30ac76146104a85780633f282a8d146104bb578063429386c4146104ca57806343b8a12d146104d3578063481c6a75146104e657600080fd5b80631afed5cc116102e45780632229d3cc116102be5780632229d3cc1461041f57806323548b8b14610446578063275b6ac61461044f5780632b29bb2c1461048257600080fd5b80631afed5cc146103db5780631b4e2587146103e4578063216efd541461040c57600080fd5b80630c49d79b1461032c578063108a442b1461034157806313af4035146103745780631627540c146103875780631a930f761461039a5780631ad483b5146103c8575b600080fd5b61033f61033a366004612c96565b6107f7565b005b61035461034f366004612ac2565b61089b565b604080519384526020840192909252908201526060015b60405180910390f35b61033f610382366004612924565b61096f565b61033f610395366004612924565b610aaa565b6103ba6103a8366004612924565b606b6020526000908152604090205481565b60405190815260200161036b565b61033f6103d6366004612cda565b610b00565b6103ba61232881565b6103f76103f2366004612a99565b610b8c565b6040805192835260208301919091520161036b565b6103ba61041a366004612a99565b610c3c565b61043261042d366004612b93565b610cd8565b60405161036b989796959493929190612d3f565b6103ba606f5481565b61047261045d366004612c24565b60726020526000908152604090205460ff1681565b604051901515815260200161036b565b6103ba610490366004612be1565b6113a8565b61033f6104a3366004612cda565b6114aa565b61033f6104b6366004612af4565b6115ca565b6103ba671bc16d674ec8000081565b6103ba60685481565b61033f6104e1366004612c24565b611804565b6067546104fe9061010090046001600160a01b031681565b6040516001600160a01b03909116815260200161036b565b61033f610524366004612c24565b611863565b61033f610537366004612945565b6118c2565b61033f61054a366004612af4565b611b8b565b6103ba60705481565b6103ba610566366004612924565b611dc0565b6001546104fe906001600160a01b031681565b60345460ff16610472565b6103ba610597366004612c24565b60696020526000908152604090205481565b6103ba6105b7366004612c24565b60766020526000908152604090205481565b6078546104fe906001600160a01b031681565b6103ba612af881565b61033f6105f3366004612c96565b611e4c565b61033f610606366004612c96565b611edf565b61033f611f75565b61033f610621366004612c67565b612072565b6000546104fe906201000090046001600160a01b031681565b61047261064d366004612c24565b60716020526000908152604090205460ff1681565b6103ba610670366004612c96565b607360209081526000928352604080842090915290825290205481565b6103ba61271081565b61033f6106a4366004612cda565b612171565b6103ba606c5481565b6103ba6106c0366004612c96565b606a60209081526000928352604080842090915290825290205481565b6104726106eb366004612c3c565b6121d1565b6103ba6106fe366004612c24565b60756020526000908152604090205481565b6103ba61071e366004612a99565b612280565b61033f610731366004612924565b612311565b6103ba610744366004612c24565b60746020526000908152604090205481565b6103ba610764366004612c24565b60776020526000908152604090205481565b61033f610784366004612cda565b612408565b61033f61246a565b6103ba61079f366004612924565b606e6020526000908152604090205481565b6103ba6107bf366004612c24565b606d6020526000908152604090205481565b61033f6107df366004612924565b6124c8565b61033f6107f2366004612c67565b61254c565b6107ff61261b565b61232882116108295760405162461bcd60e51b815260040161082090612e43565b60405180910390fd5b60705481111561084b5760405162461bcd60e51b815260040161082090612dee565b6000828152606d602090815260409182902083905581518481529081018390527fbc374ebda39a7586f4916c1911f82c2b045a44439acc485b4097428bf24ab9f991015b60405180910390a15050565b6000806000806000876001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b1580156108db57600080fd5b505afa1580156108ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109139190612cb7565b6000828152607560205260409020549193509150806109325787610934565b805b9450610941898484612695565b6000848152607460205260409020549096508061095e5787610960565b805b94505050505093509350939050565b6001600160a01b0381166109c55760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610820565b600154600160a01b900460ff1615610a315760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610820565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b610ab261261b565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610a9f565b610b0861261b565b6123288311610b295760405162461bcd60e51b815260040161082090612e43565b6000838152607660209081526040808320859055607782529182902083905581518581529081018490529081018290527f73231c1da1a7341edd4af21892fc5e1c1f340ae5726ee3e20714c146c968558a906060015b60405180910390a1505050565b600080600080856001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c029190612cb7565b600082815260756020526040902054919350915080610c215785610c23565b805b9350610c30878484612695565b94505050509250929050565b600080836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610caf9190612cb7565b5060008181526075602052604090205490915080610ccd5783610ccf565b805b95945050505050565b60608060608060608060608088516001600160401b03811115610d0b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d34578160200160208202803683370190505b50975088516001600160401b03811115610d5e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d87578160200160208202803683370190505b50965088516001600160401b03811115610db157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610dda578160200160208202803683370190505b50955088516001600160401b03811115610e0457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610e2d578160200160208202803683370190505b50945088516001600160401b03811115610e5757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610e80578160200160208202803683370190505b50935088516001600160401b03811115610eaa57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610ed3578160200160208202803683370190505b50925088516001600160401b03811115610efd57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f26578160200160208202803683370190505b50915088516001600160401b03811115610f5057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f79578160200160208202803683370190505b50905060005b895181101561139c57606960008b8381518110610fac57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002054898281518110610fe357634e487b7160e01b600052603260045260246000fd5b602002602001018181525050606a60008b838151811061101357634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000612710600161103a9190612eea565b81526020019081526020016000205488828151811061106957634e487b7160e01b600052603260045260246000fd5b602002602001018181525050606a60008b838151811061109957634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020600061271060026110c09190612eea565b8152602001908152602001600020548782815181106110ef57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050606a60008b838151811061111f57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000612710600a6111469190612eea565b81526020019081526020016000205486828151811061117557634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b83815181106111a557634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000808152602001908152602001600020548582815181106111ed57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b838151811061121d57634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020600061271060016112449190612eea565b81526020019081526020016000205484828151811061127357634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b83815181106112a357634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020600061271060026112ca9190612eea565b8152602001908152602001600020548382815181106112f957634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b838151811061132957634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000612710600a6113509190612eea565b81526020019081526020016000205482828151811061137f57634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061139481612f58565b915050610f7f565b50919395975091939597565b6000806000856001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b1580156113e557600080fd5b505afa1580156113f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141d9190612cb7565b6000828152607360209081526040808320848452909152808220548280529082205493955091935090919083158015906114575750600083115b6114615781611463565b825b90508961148c57600087116114865760008111611480578761149c565b8061149c565b8661149c565b6000811161149a578761149c565b805b9a9950505050505050505050565b6114b261261b565b6000838152606960205260408120546114cd576068546114dd565b6000848152606960205260409020545b9050808211156114ff5760405162461bcd60e51b815260040161082090612e72565b61232884116115205760405162461bcd60e51b815260040161082090612e43565b61271083116115695760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081d1859c8199bdc8818da1a5b19605a1b6044820152606401610820565b6000848152606a6020908152604080832086845282529182902084905581518681529081018590529081018390527fc2b787ecc817a49494dd17cf35e456f8e9ee45d2d3841f15b8b27c9cf0e38c2e9060600160405180910390a150505050565b6000546201000090046001600160a01b03163314806116635750606754604051632fd702bb60e11b81523360048201526101009091046001600160a01b031690635fae05769060240160206040518083038186803b15801561162b57600080fd5b505afa15801561163f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116639190612bc5565b6116a05760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610820565b606f548111156116c25760405162461bcd60e51b815260040161082090612e72565b60005b82518110156117ff5760006001600160a01b03168382815181106116f957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156117285760405162461bcd60e51b815260040161082090612e1a565b81606b600085848151811061174d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055507f4af79f840a87acdf2b8b0488af1ede97e28e3d7a90e84a80606780b4a7bcaf258382815181106117ba57634e487b7160e01b600052603260045260246000fd5b6020026020010151836040516117e59291906001600160a01b03929092168252602082015260400190565b60405180910390a1806117f781612f58565b9150506116c5565b505050565b61180c61261b565b60705481111561182e5760405162461bcd60e51b815260040161082090612dee565b606c8190556040518181527fa62b41709b2bfcafa1ac4f8210b069163514fac8d10d5ab82425fc56dba7722090602001610a9f565b61186b61261b565b606f5481111561188d5760405162461bcd60e51b815260040161082090612e72565b60688190556040518181527f53b46e874b12d8436d1ddd17fad23fc2d1bf244839714ba05f4dc3a772094a4290602001610a9f565b600054610100900460ff166118dd5760005460ff16156118e1565b303b155b6119445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610820565b600054610100900460ff16158015611966576000805461ffff19166101011790555b61196f8c61096f565b61197761246a565b60688a9055606c84905560678054610100600160a81b0319166101006001600160a01b038e160217905560005b8951811015611a26578881815181106119cd57634e487b7160e01b600052603260045260246000fd5b6020026020010151606960008c84815181106119f957634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611a1e90612f58565b9150506119a4565b5060005b8751811015611ae457858181518110611a5357634e487b7160e01b600052603260045260246000fd5b6020026020010151606a60008a8481518110611a7f57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000898481518110611ab757634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611adc90612f58565b915050611a2a565b5060005b8351811015611b6a57828181518110611b1157634e487b7160e01b600052603260045260246000fd5b6020026020010151606d6000868481518110611b3d57634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611b6290612f58565b915050611ae8565b508015611b7d576000805461ff00191690555b505050505050505050505050565b6000546201000090046001600160a01b0316331480611c245750606754604051632fd702bb60e11b81523360048201526101009091046001600160a01b031690635fae05769060240160206040518083038186803b158015611bec57600080fd5b505afa158015611c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c249190612bc5565b611c615760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610820565b607054811115611c835760405162461bcd60e51b815260040161082090612dee565b60005b82518110156117ff5760006001600160a01b0316838281518110611cba57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415611ce95760405162461bcd60e51b815260040161082090612e1a565b81606e6000858481518110611d0e57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055507f0666fbd74a2734b7994bc0921440912f46e0e82eea322eefb5f637af35bafc84838281518110611d7b57634e487b7160e01b600052603260045260246000fd5b602002602001015183604051611da69291906001600160a01b03929092168252602082015260400190565b60405180910390a180611db881612f58565b915050611c86565b6000806000836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b158015611dfd57600080fd5b505afa158015611e11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e359190612cb7565b91509150611e44848383612695565b949350505050565b611e5461261b565b6123288211611e755760405162461bcd60e51b815260040161082090612e43565b606f54811115611e975760405162461bcd60e51b815260040161082090612e72565b60008281526069602090815260409182902083905581518481529081018390527fdd336d23e5a148c17f76389d3ac4d0ab595ec1bc30e226f1d6ee3cd7714dd6f8910161088f565b611ee761261b565b60685482118015611ef95750606c5481115b611f355760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610820565b606f829055607081905560408051838152602081018390527faee5893610936166f6b866698dc8074fa7278f39a43971179f1679565e404331910161088f565b6001546001600160a01b03163314611fed5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610820565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b61207a61261b565b612af882116120cb5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c69642074616720666f7220706c617965722070726f7073000000006044820152606401610820565b60008281526072602052604090205460ff161515811515141561211f5760405162461bcd60e51b815260206004820152600c60248201526b496e76616c696420666c616760a01b6044820152606401610820565b600082815260726020908152604091829020805460ff19168415159081179091558251858152918201527f55f31caa03e942f489a3937429669e9560deae1f3641bb2b0bcb7f27046ac123910161088f565b61217961261b565b600083815260736020908152604080832085845282529182902083905581518581529081018490529081018290527f7f7dca69aeedcc1ad02bd2c02f9fd876840091fb7d939d6dfafeb9cd308ba06190606001610b7f565b6000806000836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b15801561220e57600080fd5b505afa158015612222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122469190612cb7565b915091506000612257858484612695565b90506000612266868585612853565b90506122728183612f22565b909611159695505050505050565b600080836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b1580156122bb57600080fd5b505afa1580156122cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f39190612cb7565b5060008181526074602052604090205490915080610ccd5783610ccf565b61231961261b565b6001600160a01b03811661233f5760405162461bcd60e51b815260040161082090612e1a565b600154600160a81b900460ff161561238f5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610820565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101610a9f565b61241061261b565b6000838152607460209081526040808320859055607582529182902083905581518581529081018490529081018290527f991710c3fe78c1915a791ed2dceeaac2a00c464dc95b92b8e040bb02b9da48e590606001610b7f565b60675460ff16156124b35760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610820565b6067805460ff19166001908117909155606655565b6124d061261b565b6001600160a01b0381166124f65760405162461bcd60e51b815260040161082090612e1a565b60678054610100600160a81b0319166101006001600160a01b038416908102919091179091556040519081527f1f728ba0a73bcdf17f9e0f260b7db049043dfa6b907980f715e30767d36bc70690602001610a9f565b61255461261b565b61232882116125755760405162461bcd60e51b815260040161082090612e43565b60008281526071602052604090205460ff16151581151514156125c95760405162461bcd60e51b815260206004820152600c60248201526b496e76616c696420666c616760a01b6044820152606401610820565b600082815260716020908152604091829020805460ff19168415159081179091558251858152918201527fafe707b2c4a7c26188d0cf21a3e5a465a7a270670e11a2ca8cab34053a1cd3a2910161088f565b6000546201000090046001600160a01b031633146126935760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610820565b565b6001600160a01b0383166000908152606b60205260409020548061271357600083815260696020526040902054806126cf576068546126d1565b805b91508190508215612711576000848152606a602090815260408083208684529091529020548061270b57612706600283612f02565b61270d565b805b9250505b505b600083815260766020526040902054801561284b576000856001600160a01b0316639e3b34bf6040518163ffffffff1660e01b8152600401604080518083038186803b15801561276257600080fd5b505afa158015612776573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279a9190612cb7565b50905060006127a94283612f41565b600087815260776020526040812054919250906127ce57671bc16d674ec800006127de565b6000878152607760205260409020545b6127f0670de0b6b3a764000087612f22565b6127fa9190612f02565b905083821061280b57809450612847565b60006128178287612f41565b905084816128258583612f41565b61282f9190612f22565b6128399190612f02565b6128439083612eea565b9550505b5050505b509392505050565b6001600160a01b0383166000908152606e602052604081205480611e44576000848152606d60205260409020548061288d57606c5461288f565b805b9695505050505050565b80356001600160a01b03811681146128b057600080fd5b919050565b600082601f8301126128c5578081fd5b813560206128da6128d583612ec7565b612e97565b80838252828201915082860187848660051b89010111156128f9578586fd5b855b85811015612917578135845292840192908401906001016128fb565b5090979650505050505050565b600060208284031215612935578081fd5b61293e82612899565b9392505050565b60008060008060008060008060008060006101608c8e031215612966578687fd5b61296f8c612899565b9a5061297d60208d01612899565b995060408c013598506001600160401b038060608e0135111561299e578788fd5b6129ae8e60608f01358f016128b5565b98508060808e013511156129c0578788fd5b6129d08e60808f01358f016128b5565b97508060a08e013511156129e2578687fd5b6129f28e60a08f01358f016128b5565b96508060c08e01351115612a04578586fd5b612a148e60c08f01358f016128b5565b95508060e08e01351115612a26578485fd5b612a368e60e08f01358f016128b5565b94506101008d01359350806101208e01351115612a51578283fd5b612a628e6101208f01358f016128b5565b9250806101408e01351115612a75578182fd5b50612a878d6101408e01358e016128b5565b90509295989b509295989b9093969950565b60008060408385031215612aab578182fd5b612ab483612899565b946020939093013593505050565b600080600060608486031215612ad6578283fd5b612adf84612899565b95602085013595506040909401359392505050565b60008060408385031215612b06578182fd5b82356001600160401b03811115612b1b578283fd5b8301601f81018513612b2b578283fd5b80356020612b3b6128d583612ec7565b80838252828201915082850189848660051b8801011115612b5a578788fd5b8795505b84861015612b8357612b6f81612899565b835260019590950194918301918301612b5e565b5098969091013596505050505050565b600060208284031215612ba4578081fd5b81356001600160401b03811115612bb9578182fd5b611e44848285016128b5565b600060208284031215612bd6578081fd5b815161293e81612f9f565b60008060008060808587031215612bf6578384fd5b8435612c0181612f9f565b9350612c0f60208601612899565b93969395505050506040820135916060013590565b600060208284031215612c35578081fd5b5035919050565b60008060408385031215612c4e578182fd5b82359150612c5e60208401612899565b90509250929050565b60008060408385031215612c79578182fd5b823591506020830135612c8b81612f9f565b809150509250929050565b60008060408385031215612ca8578182fd5b50508035926020909101359150565b60008060408385031215612cc9578182fd5b505080516020909101519092909150565b600080600060608486031215612cee578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b83811015612d3457815187529582019590820190600101612d18565b509495945050505050565b6000610100808352612d538184018c612d05565b90508281036020840152612d67818b612d05565b90508281036040840152612d7b818a612d05565b90508281036060840152612d8f8189612d05565b90508281036080840152612da38188612d05565b905082810360a0840152612db78187612d05565b905082810360c0840152612dcb8186612d05565b905082810360e0840152612ddf8185612d05565b9b9a5050505050505050505050565b60208082526012908201527124b73b30b634b21036bab63a34b83634b2b960711b604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b602080825260159082015274125b9d985b1a59081d1859c8199bdc881cdc1bdc9d605a1b604082015260600190565b6020808252600b908201526a0496e76616c6964206361760ac1b604082015260600190565b604051601f8201601f191681016001600160401b0381118282101715612ebf57612ebf612f89565b604052919050565b60006001600160401b03821115612ee057612ee0612f89565b5060051b60200190565b60008219821115612efd57612efd612f73565b500190565b600082612f1d57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612f3c57612f3c612f73565b500290565b600082821015612f5357612f53612f73565b500390565b6000600019821415612f6c57612f6c612f73565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114612fad57600080fd5b5056fea2646970667358221220a7794b88a3d35adf6d27f452f88739bc4ab1d61b1af4fc503b4f5dcee83b14af64736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103275760003560e01c80635d6a738c116101b8578063aa0f0bb011610104578063e365da78116100a2578063ecc716851161007c578063ecc7168514610791578063f2c69934146107b1578063f88b7571146107d1578063f9f211ae146107e457600080fd5b8063e365da7814610756578063e4d34a0314610776578063ebc797721461078957600080fd5b8063be2f1227116100de578063be2f1227146106f0578063bf7ff78b14610710578063c3b83f5f14610723578063cbeb9d661461073657600080fd5b8063aa0f0bb0146106a9578063b4cb26de146106b2578063ba0ed4ed146106dd57600080fd5b806379ba5097116101715780638dfd117e1161014b5780638dfd117e1461063f57806392294b0a146106625780639bfa23dc1461068d578063a89ea2c01461069657600080fd5b806379ba50971461060b578063857bfa68146106135780638da5cb5b1461062657600080fd5b80635d6a738c1461058957806360315786146105a9578063625ffa29146105c9578063691824dd146105dc5780636ff5f440146105e5578063771927d8146105f857600080fd5b806338347e121161027757806348ad44f8116102305780634dfbc89c1161020a5780634dfbc89c1461054f5780634f2cc14a1461055857806353a47bb71461056b5780635c975abb1461057e57600080fd5b806348ad44f8146105165780634b28fb05146105295780634c7976c91461053c57600080fd5b806338347e12146104955780633c30ac76146104a85780633f282a8d146104bb578063429386c4146104ca57806343b8a12d146104d3578063481c6a75146104e657600080fd5b80631afed5cc116102e45780632229d3cc116102be5780632229d3cc1461041f57806323548b8b14610446578063275b6ac61461044f5780632b29bb2c1461048257600080fd5b80631afed5cc146103db5780631b4e2587146103e4578063216efd541461040c57600080fd5b80630c49d79b1461032c578063108a442b1461034157806313af4035146103745780631627540c146103875780631a930f761461039a5780631ad483b5146103c8575b600080fd5b61033f61033a366004612c96565b6107f7565b005b61035461034f366004612ac2565b61089b565b604080519384526020840192909252908201526060015b60405180910390f35b61033f610382366004612924565b61096f565b61033f610395366004612924565b610aaa565b6103ba6103a8366004612924565b606b6020526000908152604090205481565b60405190815260200161036b565b61033f6103d6366004612cda565b610b00565b6103ba61232881565b6103f76103f2366004612a99565b610b8c565b6040805192835260208301919091520161036b565b6103ba61041a366004612a99565b610c3c565b61043261042d366004612b93565b610cd8565b60405161036b989796959493929190612d3f565b6103ba606f5481565b61047261045d366004612c24565b60726020526000908152604090205460ff1681565b604051901515815260200161036b565b6103ba610490366004612be1565b6113a8565b61033f6104a3366004612cda565b6114aa565b61033f6104b6366004612af4565b6115ca565b6103ba671bc16d674ec8000081565b6103ba60685481565b61033f6104e1366004612c24565b611804565b6067546104fe9061010090046001600160a01b031681565b6040516001600160a01b03909116815260200161036b565b61033f610524366004612c24565b611863565b61033f610537366004612945565b6118c2565b61033f61054a366004612af4565b611b8b565b6103ba60705481565b6103ba610566366004612924565b611dc0565b6001546104fe906001600160a01b031681565b60345460ff16610472565b6103ba610597366004612c24565b60696020526000908152604090205481565b6103ba6105b7366004612c24565b60766020526000908152604090205481565b6078546104fe906001600160a01b031681565b6103ba612af881565b61033f6105f3366004612c96565b611e4c565b61033f610606366004612c96565b611edf565b61033f611f75565b61033f610621366004612c67565b612072565b6000546104fe906201000090046001600160a01b031681565b61047261064d366004612c24565b60716020526000908152604090205460ff1681565b6103ba610670366004612c96565b607360209081526000928352604080842090915290825290205481565b6103ba61271081565b61033f6106a4366004612cda565b612171565b6103ba606c5481565b6103ba6106c0366004612c96565b606a60209081526000928352604080842090915290825290205481565b6104726106eb366004612c3c565b6121d1565b6103ba6106fe366004612c24565b60756020526000908152604090205481565b6103ba61071e366004612a99565b612280565b61033f610731366004612924565b612311565b6103ba610744366004612c24565b60746020526000908152604090205481565b6103ba610764366004612c24565b60776020526000908152604090205481565b61033f610784366004612cda565b612408565b61033f61246a565b6103ba61079f366004612924565b606e6020526000908152604090205481565b6103ba6107bf366004612c24565b606d6020526000908152604090205481565b61033f6107df366004612924565b6124c8565b61033f6107f2366004612c67565b61254c565b6107ff61261b565b61232882116108295760405162461bcd60e51b815260040161082090612e43565b60405180910390fd5b60705481111561084b5760405162461bcd60e51b815260040161082090612dee565b6000828152606d602090815260409182902083905581518481529081018390527fbc374ebda39a7586f4916c1911f82c2b045a44439acc485b4097428bf24ab9f991015b60405180910390a15050565b6000806000806000876001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b1580156108db57600080fd5b505afa1580156108ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109139190612cb7565b6000828152607560205260409020549193509150806109325787610934565b805b9450610941898484612695565b6000848152607460205260409020549096508061095e5787610960565b805b94505050505093509350939050565b6001600160a01b0381166109c55760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610820565b600154600160a01b900460ff1615610a315760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610820565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b610ab261261b565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610a9f565b610b0861261b565b6123288311610b295760405162461bcd60e51b815260040161082090612e43565b6000838152607660209081526040808320859055607782529182902083905581518581529081018490529081018290527f73231c1da1a7341edd4af21892fc5e1c1f340ae5726ee3e20714c146c968558a906060015b60405180910390a1505050565b600080600080856001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c029190612cb7565b600082815260756020526040902054919350915080610c215785610c23565b805b9350610c30878484612695565b94505050509250929050565b600080836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610caf9190612cb7565b5060008181526075602052604090205490915080610ccd5783610ccf565b805b95945050505050565b60608060608060608060608088516001600160401b03811115610d0b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d34578160200160208202803683370190505b50975088516001600160401b03811115610d5e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d87578160200160208202803683370190505b50965088516001600160401b03811115610db157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610dda578160200160208202803683370190505b50955088516001600160401b03811115610e0457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610e2d578160200160208202803683370190505b50945088516001600160401b03811115610e5757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610e80578160200160208202803683370190505b50935088516001600160401b03811115610eaa57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610ed3578160200160208202803683370190505b50925088516001600160401b03811115610efd57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f26578160200160208202803683370190505b50915088516001600160401b03811115610f5057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f79578160200160208202803683370190505b50905060005b895181101561139c57606960008b8381518110610fac57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002054898281518110610fe357634e487b7160e01b600052603260045260246000fd5b602002602001018181525050606a60008b838151811061101357634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000612710600161103a9190612eea565b81526020019081526020016000205488828151811061106957634e487b7160e01b600052603260045260246000fd5b602002602001018181525050606a60008b838151811061109957634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020600061271060026110c09190612eea565b8152602001908152602001600020548782815181106110ef57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050606a60008b838151811061111f57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000612710600a6111469190612eea565b81526020019081526020016000205486828151811061117557634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b83815181106111a557634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000808152602001908152602001600020548582815181106111ed57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b838151811061121d57634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020600061271060016112449190612eea565b81526020019081526020016000205484828151811061127357634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b83815181106112a357634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020600061271060026112ca9190612eea565b8152602001908152602001600020548382815181106112f957634e487b7160e01b600052603260045260246000fd5b602002602001018181525050607360008b838151811061132957634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000612710600a6113509190612eea565b81526020019081526020016000205482828151811061137f57634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061139481612f58565b915050610f7f565b50919395975091939597565b6000806000856001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b1580156113e557600080fd5b505afa1580156113f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141d9190612cb7565b6000828152607360209081526040808320848452909152808220548280529082205493955091935090919083158015906114575750600083115b6114615781611463565b825b90508961148c57600087116114865760008111611480578761149c565b8061149c565b8661149c565b6000811161149a578761149c565b805b9a9950505050505050505050565b6114b261261b565b6000838152606960205260408120546114cd576068546114dd565b6000848152606960205260409020545b9050808211156114ff5760405162461bcd60e51b815260040161082090612e72565b61232884116115205760405162461bcd60e51b815260040161082090612e43565b61271083116115695760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081d1859c8199bdc8818da1a5b19605a1b6044820152606401610820565b6000848152606a6020908152604080832086845282529182902084905581518681529081018590529081018390527fc2b787ecc817a49494dd17cf35e456f8e9ee45d2d3841f15b8b27c9cf0e38c2e9060600160405180910390a150505050565b6000546201000090046001600160a01b03163314806116635750606754604051632fd702bb60e11b81523360048201526101009091046001600160a01b031690635fae05769060240160206040518083038186803b15801561162b57600080fd5b505afa15801561163f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116639190612bc5565b6116a05760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610820565b606f548111156116c25760405162461bcd60e51b815260040161082090612e72565b60005b82518110156117ff5760006001600160a01b03168382815181106116f957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156117285760405162461bcd60e51b815260040161082090612e1a565b81606b600085848151811061174d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055507f4af79f840a87acdf2b8b0488af1ede97e28e3d7a90e84a80606780b4a7bcaf258382815181106117ba57634e487b7160e01b600052603260045260246000fd5b6020026020010151836040516117e59291906001600160a01b03929092168252602082015260400190565b60405180910390a1806117f781612f58565b9150506116c5565b505050565b61180c61261b565b60705481111561182e5760405162461bcd60e51b815260040161082090612dee565b606c8190556040518181527fa62b41709b2bfcafa1ac4f8210b069163514fac8d10d5ab82425fc56dba7722090602001610a9f565b61186b61261b565b606f5481111561188d5760405162461bcd60e51b815260040161082090612e72565b60688190556040518181527f53b46e874b12d8436d1ddd17fad23fc2d1bf244839714ba05f4dc3a772094a4290602001610a9f565b600054610100900460ff166118dd5760005460ff16156118e1565b303b155b6119445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610820565b600054610100900460ff16158015611966576000805461ffff19166101011790555b61196f8c61096f565b61197761246a565b60688a9055606c84905560678054610100600160a81b0319166101006001600160a01b038e160217905560005b8951811015611a26578881815181106119cd57634e487b7160e01b600052603260045260246000fd5b6020026020010151606960008c84815181106119f957634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611a1e90612f58565b9150506119a4565b5060005b8751811015611ae457858181518110611a5357634e487b7160e01b600052603260045260246000fd5b6020026020010151606a60008a8481518110611a7f57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000898481518110611ab757634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611adc90612f58565b915050611a2a565b5060005b8351811015611b6a57828181518110611b1157634e487b7160e01b600052603260045260246000fd5b6020026020010151606d6000868481518110611b3d57634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611b6290612f58565b915050611ae8565b508015611b7d576000805461ff00191690555b505050505050505050505050565b6000546201000090046001600160a01b0316331480611c245750606754604051632fd702bb60e11b81523360048201526101009091046001600160a01b031690635fae05769060240160206040518083038186803b158015611bec57600080fd5b505afa158015611c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c249190612bc5565b611c615760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610820565b607054811115611c835760405162461bcd60e51b815260040161082090612dee565b60005b82518110156117ff5760006001600160a01b0316838281518110611cba57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415611ce95760405162461bcd60e51b815260040161082090612e1a565b81606e6000858481518110611d0e57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055507f0666fbd74a2734b7994bc0921440912f46e0e82eea322eefb5f637af35bafc84838281518110611d7b57634e487b7160e01b600052603260045260246000fd5b602002602001015183604051611da69291906001600160a01b03929092168252602082015260400190565b60405180910390a180611db881612f58565b915050611c86565b6000806000836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b158015611dfd57600080fd5b505afa158015611e11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e359190612cb7565b91509150611e44848383612695565b949350505050565b611e5461261b565b6123288211611e755760405162461bcd60e51b815260040161082090612e43565b606f54811115611e975760405162461bcd60e51b815260040161082090612e72565b60008281526069602090815260409182902083905581518481529081018390527fdd336d23e5a148c17f76389d3ac4d0ab595ec1bc30e226f1d6ee3cd7714dd6f8910161088f565b611ee761261b565b60685482118015611ef95750606c5481115b611f355760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610820565b606f829055607081905560408051838152602081018390527faee5893610936166f6b866698dc8074fa7278f39a43971179f1679565e404331910161088f565b6001546001600160a01b03163314611fed5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610820565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b61207a61261b565b612af882116120cb5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c69642074616720666f7220706c617965722070726f7073000000006044820152606401610820565b60008281526072602052604090205460ff161515811515141561211f5760405162461bcd60e51b815260206004820152600c60248201526b496e76616c696420666c616760a01b6044820152606401610820565b600082815260726020908152604091829020805460ff19168415159081179091558251858152918201527f55f31caa03e942f489a3937429669e9560deae1f3641bb2b0bcb7f27046ac123910161088f565b61217961261b565b600083815260736020908152604080832085845282529182902083905581518581529081018490529081018290527f7f7dca69aeedcc1ad02bd2c02f9fd876840091fb7d939d6dfafeb9cd308ba06190606001610b7f565b6000806000836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b15801561220e57600080fd5b505afa158015612222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122469190612cb7565b915091506000612257858484612695565b90506000612266868585612853565b90506122728183612f22565b909611159695505050505050565b600080836001600160a01b031663995d9ab76040518163ffffffff1660e01b8152600401604080518083038186803b1580156122bb57600080fd5b505afa1580156122cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f39190612cb7565b5060008181526074602052604090205490915080610ccd5783610ccf565b61231961261b565b6001600160a01b03811661233f5760405162461bcd60e51b815260040161082090612e1a565b600154600160a81b900460ff161561238f5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610820565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101610a9f565b61241061261b565b6000838152607460209081526040808320859055607582529182902083905581518581529081018490529081018290527f991710c3fe78c1915a791ed2dceeaac2a00c464dc95b92b8e040bb02b9da48e590606001610b7f565b60675460ff16156124b35760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610820565b6067805460ff19166001908117909155606655565b6124d061261b565b6001600160a01b0381166124f65760405162461bcd60e51b815260040161082090612e1a565b60678054610100600160a81b0319166101006001600160a01b038416908102919091179091556040519081527f1f728ba0a73bcdf17f9e0f260b7db049043dfa6b907980f715e30767d36bc70690602001610a9f565b61255461261b565b61232882116125755760405162461bcd60e51b815260040161082090612e43565b60008281526071602052604090205460ff16151581151514156125c95760405162461bcd60e51b815260206004820152600c60248201526b496e76616c696420666c616760a01b6044820152606401610820565b600082815260716020908152604091829020805460ff19168415159081179091558251858152918201527fafe707b2c4a7c26188d0cf21a3e5a465a7a270670e11a2ca8cab34053a1cd3a2910161088f565b6000546201000090046001600160a01b031633146126935760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610820565b565b6001600160a01b0383166000908152606b60205260409020548061271357600083815260696020526040902054806126cf576068546126d1565b805b91508190508215612711576000848152606a602090815260408083208684529091529020548061270b57612706600283612f02565b61270d565b805b9250505b505b600083815260766020526040902054801561284b576000856001600160a01b0316639e3b34bf6040518163ffffffff1660e01b8152600401604080518083038186803b15801561276257600080fd5b505afa158015612776573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279a9190612cb7565b50905060006127a94283612f41565b600087815260776020526040812054919250906127ce57671bc16d674ec800006127de565b6000878152607760205260409020545b6127f0670de0b6b3a764000087612f22565b6127fa9190612f02565b905083821061280b57809450612847565b60006128178287612f41565b905084816128258583612f41565b61282f9190612f22565b6128399190612f02565b6128439083612eea565b9550505b5050505b509392505050565b6001600160a01b0383166000908152606e602052604081205480611e44576000848152606d60205260409020548061288d57606c5461288f565b805b9695505050505050565b80356001600160a01b03811681146128b057600080fd5b919050565b600082601f8301126128c5578081fd5b813560206128da6128d583612ec7565b612e97565b80838252828201915082860187848660051b89010111156128f9578586fd5b855b85811015612917578135845292840192908401906001016128fb565b5090979650505050505050565b600060208284031215612935578081fd5b61293e82612899565b9392505050565b60008060008060008060008060008060006101608c8e031215612966578687fd5b61296f8c612899565b9a5061297d60208d01612899565b995060408c013598506001600160401b038060608e0135111561299e578788fd5b6129ae8e60608f01358f016128b5565b98508060808e013511156129c0578788fd5b6129d08e60808f01358f016128b5565b97508060a08e013511156129e2578687fd5b6129f28e60a08f01358f016128b5565b96508060c08e01351115612a04578586fd5b612a148e60c08f01358f016128b5565b95508060e08e01351115612a26578485fd5b612a368e60e08f01358f016128b5565b94506101008d01359350806101208e01351115612a51578283fd5b612a628e6101208f01358f016128b5565b9250806101408e01351115612a75578182fd5b50612a878d6101408e01358e016128b5565b90509295989b509295989b9093969950565b60008060408385031215612aab578182fd5b612ab483612899565b946020939093013593505050565b600080600060608486031215612ad6578283fd5b612adf84612899565b95602085013595506040909401359392505050565b60008060408385031215612b06578182fd5b82356001600160401b03811115612b1b578283fd5b8301601f81018513612b2b578283fd5b80356020612b3b6128d583612ec7565b80838252828201915082850189848660051b8801011115612b5a578788fd5b8795505b84861015612b8357612b6f81612899565b835260019590950194918301918301612b5e565b5098969091013596505050505050565b600060208284031215612ba4578081fd5b81356001600160401b03811115612bb9578182fd5b611e44848285016128b5565b600060208284031215612bd6578081fd5b815161293e81612f9f565b60008060008060808587031215612bf6578384fd5b8435612c0181612f9f565b9350612c0f60208601612899565b93969395505050506040820135916060013590565b600060208284031215612c35578081fd5b5035919050565b60008060408385031215612c4e578182fd5b82359150612c5e60208401612899565b90509250929050565b60008060408385031215612c79578182fd5b823591506020830135612c8b81612f9f565b809150509250929050565b60008060408385031215612ca8578182fd5b50508035926020909101359150565b60008060408385031215612cc9578182fd5b505080516020909101519092909150565b600080600060608486031215612cee578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b83811015612d3457815187529582019590820190600101612d18565b509495945050505050565b6000610100808352612d538184018c612d05565b90508281036020840152612d67818b612d05565b90508281036040840152612d7b818a612d05565b90508281036060840152612d8f8189612d05565b90508281036080840152612da38188612d05565b905082810360a0840152612db78187612d05565b905082810360c0840152612dcb8186612d05565b905082810360e0840152612ddf8185612d05565b9b9a5050505050505050505050565b60208082526012908201527124b73b30b634b21036bab63a34b83634b2b960711b604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b602080825260159082015274125b9d985b1a59081d1859c8199bdc881cdc1bdc9d605a1b604082015260600190565b6020808252600b908201526a0496e76616c6964206361760ac1b604082015260600190565b604051601f8201601f191681016001600160401b0381118282101715612ebf57612ebf612f89565b604052919050565b60006001600160401b03821115612ee057612ee0612f89565b5060051b60200190565b60008219821115612efd57612efd612f73565b500190565b600082612f1d57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612f3c57612f3c612f73565b500290565b600082821015612f5357612f53612f73565b500390565b6000600019821415612f6c57612f6c612f73565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114612fad57600080fd5b5056fea2646970667358221220a7794b88a3d35adf6d27f452f88739bc4ab1d61b1af4fc503b4f5dcee83b14af64736f6c63430008040033

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