Contract 0x20B1E06300A01568da8D82f2ae05BA14B4c93822

  Note: Our ETH balance display is temporarily unavailable. Please check back later.
Txn Hash Method
Block
From
To
Value
0x0fcc78112c7daf49184b57b3fbeae8870a11a8517de859926cf833a3fb805cc7Request Games Re...202862382024-01-23 9:02:2487 days 20 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006048375612.500000252
0x85cf1b28eef881d753f0074ee2628ef34de5a8fbff66aaeb1e7d895a8606d2d9Request Games Re...188659612023-12-21 11:59:50120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005813350582.500000252
0xb7d838aa76f0eaba34ce72feaa5b4adec752a9efd2ff96ee86da456a734841f2Request Games Re...188659572023-12-21 11:59:42120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005813050582.500000252
0xc630769c6194b83c18475935bd0c1858ad3bae3ea21e4e8997a4cc167d037a89Request Games Re...188659542023-12-21 11:59:36120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005813350582.500000252
0x7cb90af2e2f03c3310fcceeb7285abd39a510739ff710722effd6677117a849cRequest Games Re...188659522023-12-21 11:59:32120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005813050582.500000252
0x118d821dd4a2d4e72822c9a84dd2baeb29a346e40907790b687e7c2c7a937c56Request Games Re...188652932023-12-21 11:37:34120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006166225622.500000252
0x8fed3c60999fdfc3636bb0e877035ece09cd24b03f7ae094d0ecf22de2d3be37Request Games Re...188652862023-12-21 11:37:20120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424775652.500000252
0x47fe3d77b8ff5fb0895c8b635a2583e501560493857563537adeb50bda9821ceRequest Games Re...188652802023-12-21 11:37:08120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424775652.500000252
0x6c1aa62f71b0fdd1b352dcf06a33554ae4cc2c61a03c218725f8282b4ff82e31Request Games Re...188652742023-12-21 11:36:56120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006283800632.500000252
0xd09cf9599d0ba5dedc8fea2684fb49826ae5507116a7863f7a5000df6b0b0e36Request Games Re...188652692023-12-21 11:36:46120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424475652.500000252
0xc726c6c75d05118688eabb8c17e5f46719e730c01545e6455bd47976e2dd4971Request Games Re...188652532023-12-21 11:36:14120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006284100632.500000252
0x36509f3097afc05ca0b9298986858ca11a8c262acad14e737e236bd02de97d49Request Games Re...188652482023-12-21 11:36:04120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424775652.500000252
0xca5511b904ab62b7098843f9cd613b8e117f167a122088c1a92341046e7a3798Request Games Re...188652422023-12-21 11:35:52120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005930825592.500000252
0xcbf2a66f2db9600f5ba0f5cc7a6ad9b181870f238f97092d99219c87b7add845Request Games Re...188652362023-12-21 11:35:40120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424475652.500000252
0x85a59c93600a225359f8f202f05e6eed7f6825589b65650c3d6bf15c533138b4Request Games Re...188652302023-12-21 11:35:28120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424475652.500000252
0x4bc484deb4a21799b39721276c0a030f4a69593a29fc14aa33c959e9e55c395cRequest Games Re...188652232023-12-21 11:35:14120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006165925622.500000252
0x3884994548bcd78a96cb92f44de12c22166fd92b4608952aa12ce20f0fcca46aRequest Games Re...188652172023-12-21 11:35:02120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424775652.500000252
0x5d47027aee195126a10a9bef3ca2bb245f76001dd693e228f9821470e9438df6Request Games Re...188652122023-12-21 11:34:52120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006424775652.500000252
0x1308470b477de70cdc53db32bbec63f66d38390f87ac4bee99fc4d917334b24fRequest Games Re...188652092023-12-21 11:34:46120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005930825592.500000252
0x645363e2812c222b6cc9c103103c1aafb558902b258bcecff09219a262509810Request Games Re...188652062023-12-21 11:34:40120 days 17 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005931125592.500000252
0x02ddb3f38e79e5128a54065c0a627b20f415679ffdf3b836b35d6fca80293b40Request Player P...183024672023-12-08 10:56:42133 days 18 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006132950612.500000252
0xb8ab02e5ba5f155852918bb4b9c78596a0b087eb611ddd454e21fab314a3d829Request Player P...183024612023-12-08 10:56:30133 days 18 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006855400692.500000252
0xb1fcfa56eb596241428f2a317168934d73c8fc8f8b5db22ec9b5c545f965bf11Request Player P...183024562023-12-08 10:56:20133 days 18 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006855400692.500000253
0x18c9967d08cc1327d1bdd7269ba8faac5fac1df87d44dc8c63e71b4201ac98a3Request Games Re...183024262023-12-08 10:55:20133 days 18 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0005931175592.500000252
0xab4538810066cb8cfc49e9b8fcfe351487b6c2c72f4b761abec963bccd97a683Request Games Re...183022902023-12-08 10:50:48133 days 18 hrs ago0xd866b2332d4383c1bf719732177e2d9109c99dbc IN  0x20b1e06300a01568da8d82f2ae05ba14b4c938220 ETH0.0006283675642.500000256
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TherundownConsumerWrapper

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 23 : TherundownConsumerWrapper.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// external
import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@openzeppelin/contracts-4.4.1/security/Pausable.sol";
import "@openzeppelin/contracts-4.4.1/access/Ownable.sol";
import "@openzeppelin/contracts-4.4.1/token/ERC20/utils/SafeERC20.sol";

// internal
import "../../interfaces/ITherundownConsumer.sol";
import "../../interfaces/ITherundownConsumerVerifier.sol";
import "../../interfaces/IGamesPlayerPropsReceiver.sol";
import "../../interfaces/IGamesPlayerProps.sol";

/// @title Wrapper contract which calls CL sports data (Link to docs: https://market.link/nodes/TheRundown/integrations)
/// @author gruja
contract TherundownConsumerWrapper is ChainlinkClient, Ownable, Pausable {
    using Chainlink for Chainlink.Request;
    using SafeERC20 for IERC20;

    ITherundownConsumer public consumer;
    ITherundownConsumerVerifier public verifier;
    IGamesPlayerPropsReciever public playerPropsReciever;
    IGamesPlayerProps public playerProps;
    mapping(bytes32 => uint) public sportIdPerRequestId;
    mapping(bytes32 => uint) public datePerRequest;
    uint public paymentCreate;
    uint public paymentResolve;
    uint public paymentOdds;
    IERC20 public linkToken;
    bytes32 public oddsSpecId;
    bytes32 public oddsSpecIdPlayerProps;
    address public sportsAMM;

    mapping(bytes32 => bytes[]) public requestIdGamesCreated;
    mapping(bytes32 => bytes[]) public requestIdGamesResolved;
    mapping(bytes32 => bytes[]) public requestIdGamesOdds;
    mapping(bytes32 => uint256) private requestIdRemainder;
    mapping(bytes32 => bytes[]) public requestIdPlayerPropsResolved;
    mapping(bytes32 => bytes[]) public requestIdPlayerProps;

    mapping(bytes32 => bool) public requestIdGamesCreatedFulFilled;
    mapping(bytes32 => bool) public requestIdGamesResolvedFulFilled;
    mapping(bytes32 => bool) public requestIdGamesOddsFulFilled;
    mapping(bytes32 => bool) public requestIdPlayerPropsResolvedFulFilled;
    mapping(bytes32 => bool) public requestIdPlayerPropsFulFilled;

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

    constructor(
        address _link,
        address _oracle,
        address _consumer,
        uint _paymentCreate,
        uint _paymentResolve,
        uint _paymentOdds,
        bytes32 _oddsSpecId,
        address _sportsAMM,
        address _verifier,
        address _playerPropsReciever,
        address _playerProps
    ) {
        setChainlinkToken(_link);
        setChainlinkOracle(_oracle);
        consumer = ITherundownConsumer(_consumer);
        paymentCreate = _paymentCreate;
        paymentResolve = _paymentResolve;
        paymentOdds = _paymentOdds;
        linkToken = IERC20(_link);
        oddsSpecId = _oddsSpecId;
        sportsAMM = _sportsAMM;
        verifier = ITherundownConsumerVerifier(_verifier);
        playerPropsReciever = IGamesPlayerPropsReciever(_playerPropsReciever);
        playerProps = IGamesPlayerProps(_playerProps);
    }

    /* ========== CONSUMER REQUEST FUNCTIONS ========== */

    /// @notice request of create/resolve games on a specific date with specific sport with optional filters
    /// @param _specId specification id which is provided by CL
    /// @param _market string which can be "create" or "resolve"
    /// @param _sportId sports id which is provided from CL (Example: NBA = 4)
    /// @param _date date on which game/games are played
    /// @param _statusIds optional param, grap only for specific statusess
    /// @param _gameIds optional param, grap only for specific games
    function requestGamesResolveWithFilters(
        bytes32 _specId,
        string memory _market,
        uint256 _sportId,
        uint256 _date,
        string[] memory _statusIds,
        string[] memory _gameIds
    ) public whenNotPaused isValidRequest(_market, _sportId) {
        Chainlink.Request memory req;
        uint payment;

        if (keccak256(abi.encodePacked(_market)) == keccak256(abi.encodePacked("create"))) {
            req = buildChainlinkRequest(_specId, address(this), this.fulfillGamesCreated.selector);
            payment = paymentCreate;
        } else {
            req = buildChainlinkRequest(_specId, address(this), this.fulfillGamesResolved.selector);
            payment = paymentResolve;
        }

        req.addUint("date", _date);
        req.add("market", _market);
        req.addUint("sportId", _sportId);
        req.addStringArray("statusIds", _statusIds);
        req.addStringArray("gameIds", _gameIds);

        _putLink(msg.sender, payment);

        bytes32 requestId = sendChainlinkRequest(req, payment);
        sportIdPerRequestId[requestId] = _sportId;
        datePerRequest[requestId] = _date;
    }

    /// @notice request of resolve player props for sport/game/player/option
    /// @param _specId specification id which is provided by CL
    /// @param _market string which can be "create" or "resolve"
    /// @param _date date on which game/games are played
    /// @param _sportId sports id which is provided from CL (Example: NBA = 4)
    /// @param _gameIds game which player is playing
    /// @param _playerIds player id as string
    /// @param _optionIds option id as string
    function requestPlayerPropsResolveWithFilters(
        bytes32 _specId,
        string memory _market,
        uint256 _date,
        uint256 _sportId,
        string[] memory _gameIds,
        string[] memory _playerIds,
        string[] memory _optionIds
    ) public whenNotPaused isValidRequest(_market, _sportId) {
        Chainlink.Request memory req;
        uint payment;

        req = buildChainlinkRequest(_specId, address(this), this.fulfillPlayerPropsResolved.selector);
        payment = paymentResolve;

        req.add("market", _market);
        req.addUint("date", _date);
        req.addUint("sportId", _sportId);
        req.addStringArray("gameIds", _gameIds);
        req.addStringArray("playerIds", _playerIds);
        req.addStringArray("optionIds", _optionIds);

        _putLink(msg.sender, payment);

        bytes32 requestId = sendChainlinkRequest(req, payment);
        sportIdPerRequestId[requestId] = _sportId;
        datePerRequest[requestId] = _date;
    }

    /// @notice request of create/resolve games on a specific date with specific sport without filters
    /// @param _specId specification id which is provided by CL
    /// @param _market string which can be "create" or "resolve"
    /// @param _sportId sports id which is provided from CL (Example: NBA = 4)
    /// @param _date date on which game/games are played
    function requestGames(
        bytes32 _specId,
        string memory _market,
        uint256 _sportId,
        uint256 _date
    ) public whenNotPaused isValidRequest(_market, _sportId) {
        Chainlink.Request memory req;
        uint payment;

        if (keccak256(abi.encodePacked(_market)) == keccak256(abi.encodePacked("create"))) {
            req = buildChainlinkRequest(_specId, address(this), this.fulfillGamesCreated.selector);
            payment = paymentCreate;
        } else {
            req = buildChainlinkRequest(_specId, address(this), this.fulfillGamesResolved.selector);
            payment = paymentResolve;
        }

        req.addUint("date", _date);
        req.add("market", _market);
        req.addUint("sportId", _sportId);

        _putLink(msg.sender, payment);

        bytes32 requestId = sendChainlinkRequest(req, payment);
        sportIdPerRequestId[requestId] = _sportId;
        datePerRequest[requestId] = _date;
    }

    /// @notice request for odds in games on a specific date with specific sport with filters
    /// @param _specId specification id which is provided by CL
    /// @param _sportId sports id which is provided from CL (Example: NBA = 4)
    /// @param _date date on which game/games are played
    /// @param _gameIds optional param, grap only for specific games
    function requestOddsWithFilters(
        bytes32 _specId,
        uint256 _sportId,
        uint256 _date,
        string[] memory _gameIds
    ) public whenNotPaused {
        require(consumer.supportedSport(_sportId), "SportId is not supported");

        Chainlink.Request memory req = buildChainlinkRequest(_specId, address(this), this.fulfillGamesOdds.selector);

        req.addUint("date", _date);
        req.addUint("sportId", _sportId);

        // optional param.
        if (_gameIds.length > 0) {
            req.addStringArray("gameIds", _gameIds);
        }

        _putLink(msg.sender, paymentOdds);

        bytes32 requestId = sendChainlinkRequest(req, paymentOdds);
        sportIdPerRequestId[requestId] = _sportId;
        datePerRequest[requestId] = _date;
    }

    /// @notice request for odds in games on a specific date with specific sport with filters
    /// @param _marketAddress market address which triggered
    function callUpdateOddsForSpecificGame(address _marketAddress) external whenNotPaused {
        require(msg.sender == sportsAMM, "Only Sports AMM can call this function");

        // don't fail if no link in it
        if (linkToken.balanceOf(address(this)) >= paymentOdds) {
            (uint _sportId, uint _date, ) = consumer.getGamePropsForOdds(_marketAddress);
            bytes32[] memory _ids = consumer.getGamesPerDatePerSport(_sportId, _date);
            _requestOddsWithFiltersFromAmm(oddsSpecId, _sportId, _date, verifier.getStringIDsFromBytesArrayIDs(_ids));
            emit UpdateOddsFromAMMForAGame(_sportId, _date, _marketAddress);
        }
    }

    /// @notice Request odds update for specific player props when triggered by a market address
    /// @param _marketAddress Market address that triggered the update
    function callUpdateOddsForSpecificPlayerProps(address _marketAddress) external whenNotPaused {
        require(msg.sender == sportsAMM, "Only Sports AMM can call this function");
        if (linkToken.balanceOf(address(this)) >= paymentOdds) {
            // Get player props data for the market
            (address _parent, bytes32 _gameId, bytes32 _playerId, uint8 _optionId) = playerProps.getPlayerPropsDataForMarket(
                _marketAddress
            );

            // Create arrays with single elements for filtering
            bytes32[] memory _gameIds = new bytes32[](1);
            _gameIds[0] = _gameId;
            bytes32[] memory _playerIds = new bytes32[](1);
            _playerIds[0] = _playerId;
            uint8[] memory _optionIds = new uint8[](1);
            _optionIds[0] = _optionId;

            // Get sport and date information
            (uint _sportId, uint _date, ) = consumer.getGamePropsForOdds(_parent);

            // Request odds update using the filtered data
            _requestPlayerPropsOddsWithFiltersFromAmm(
                oddsSpecIdPlayerProps,
                _sportId,
                _date,
                verifier.getStringIDsFromBytesArrayIDs(_gameIds),
                verifier.getStringIDsFromBytesArrayIDs(_playerIds),
                verifier.convertUintToString(_optionIds)
            );

            // Emit an event to log the update request
            emit UpdatePlayerPropsOddsFromAMM(_sportId, _date, _marketAddress, _gameId, _playerId, _optionId);
        }
    }

    /// @notice getting bookmaker by sports id
    /// @param _sportId id of a sport for fetching
    function getBookmakerIdsBySportId(uint256 _sportId) external view returns (uint256[] memory) {
        return verifier.getBookmakerIdsBySportId(_sportId);
    }

    /// @notice getting bookmaker by sports id for playerprops
    /// @param _sportId id of a sport for fetching
    function getBookmakerIdsBySportIdForPlayerProps(uint256 _sportId) external view returns (uint256[] memory) {
        return verifier.getBookmakerIdsBySportIdForPlayerProps(_sportId);
    }

    /* ========== CONSUMER FULFILL FUNCTIONS ========== */

    /// @notice proxy all retrieved data for created games from CL to consumer
    /// @param _requestId request id autogenerated from CL
    /// @param _games array of a games
    function fulfillGamesCreated(
        bytes32 _requestId,
        uint256 _remainder,
        bytes[] memory _games
    ) external recordChainlinkFulfillment(_requestId) {
        requestIdGamesCreated[_requestId] = _games;
        requestIdGamesCreatedFulFilled[_requestId] = true;
        requestIdRemainder[_requestId] = _remainder;
        consumer.fulfillGamesCreated(_requestId, _games, sportIdPerRequestId[_requestId], datePerRequest[_requestId]);
    }

    /// @notice proxy all retrieved data for resolved games from CL to consumer
    /// @param _requestId request id autogenerated from CL
    /// @param _games array of a games
    function fulfillGamesResolved(
        bytes32 _requestId,
        uint256 _remainder,
        bytes[] memory _games
    ) external recordChainlinkFulfillment(_requestId) {
        requestIdGamesResolved[_requestId] = _games;
        requestIdGamesResolvedFulFilled[_requestId] = true;
        requestIdRemainder[_requestId] = _remainder;
        consumer.fulfillGamesResolved(_requestId, _games, sportIdPerRequestId[_requestId]);
    }

    /// @notice proxy all retrieved data for resolved games from CL to consumer
    /// @param _requestId request id autogenerated from CL
    /// @param _playerProps array of a player props
    function fulfillPlayerPropsResolved(bytes32 _requestId, bytes[] memory _playerProps)
        external
        recordChainlinkFulfillment(_requestId)
    {
        requestIdPlayerPropsResolved[_requestId] = _playerProps;
        requestIdPlayerPropsResolvedFulFilled[_requestId] = true;
        playerPropsReciever.fulfillPlayerPropsCLResolved(_playerProps);
    }

    /// @notice proxy all retrieved data for odds in games from CL to consumer
    /// @param _requestId request id autogenerated from CL
    /// @param _games array of a games
    function fulfillGamesOdds(
        bytes32 _requestId,
        uint256 _remainder,
        bytes[] memory _games
    ) external recordChainlinkFulfillment(_requestId) {
        requestIdGamesOdds[_requestId] = _games;
        requestIdRemainder[_requestId] = _remainder;
        requestIdGamesOddsFulFilled[_requestId] = true;
        consumer.fulfillGamesOdds(_requestId, _games);
    }

    /// @notice proxy all retrieved data for odds in games from CL to consumer
    /// @param _requestId request id autogenerated from CL
    /// @param _playerProps array of a playerProps
    function fulfillPlayerPropsOdds(bytes32 _requestId, bytes[] memory _playerProps)
        external
        recordChainlinkFulfillment(_requestId)
    {
        requestIdPlayerProps[_requestId] = _playerProps;
        requestIdPlayerPropsFulFilled[_requestId] = true;
        playerPropsReciever.fulfillPlayerPropsCL(_playerProps);
    }

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

    /// @notice getting oracle address for CL data sport feed
    /// @return address of oracle
    function getOracleAddress() external view returns (address) {
        return chainlinkOracleAddress();
    }

    /// @notice getting LINK token address for payment for requests
    /// @return address of LINK token
    function getTokenAddress() external view returns (address) {
        return chainlinkTokenAddress();
    }

    /// @notice add all odds request fulfilled
    /// @param _requestsIds array of request ids
    /// @return bool if all fullfilled or not
    function areOddsRequestIdsFulFilled(bytes32[] memory _requestsIds) external view returns (bool) {
        for (uint i = 0; i < _requestsIds.length; i++) {
            if (!requestIdGamesOddsFulFilled[_requestsIds[i]]) {
                return false;
            }
        }
        return true;
    }

    /// @notice add all creation request fulfilled
    /// @param _requestsIds array of request ids
    /// @return bool if all fullfilled or not
    function areCreatedRequestIdsFulFilled(bytes32[] memory _requestsIds) external view returns (bool) {
        for (uint i = 0; i < _requestsIds.length; i++) {
            if (!requestIdGamesCreatedFulFilled[_requestsIds[i]]) {
                return false;
            }
        }
        return true;
    }

    /// @notice add all resolve request fulfilled
    /// @param _requestsIds array of request ids
    /// @return bool if all fullfilled or not
    function areResolvedRequestIdsFulFilled(bytes32[] memory _requestsIds) external view returns (bool) {
        for (uint i = 0; i < _requestsIds.length; i++) {
            if (!requestIdGamesResolvedFulFilled[_requestsIds[i]]) {
                return false;
            }
        }
        return true;
    }

    /// @notice add all resolve request fulfilled
    /// @param _requestsIds array of request ids
    /// @return bool if all fullfilled or not
    function areResolvedPlayerPropsRequestIdsFulFilled(bytes32[] memory _requestsIds) external view returns (bool) {
        for (uint i = 0; i < _requestsIds.length; i++) {
            if (!requestIdPlayerPropsResolvedFulFilled[_requestsIds[i]]) {
                return false;
            }
        }
        return true;
    }

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

    function _putLink(address _sender, uint _payment) internal {
        linkToken.safeTransferFrom(_sender, address(this), _payment);
    }

    function _requestOddsWithFiltersFromAmm(
        bytes32 _specId,
        uint256 _sportId,
        uint256 _date,
        string[] memory _gameIds
    ) internal {
        Chainlink.Request memory req = buildChainlinkRequest(_specId, address(this), this.fulfillGamesOdds.selector);

        req.addUint("date", _date);
        req.addUint("sportId", _sportId);

        // optional param.
        if (_gameIds.length > 0) {
            req.addStringArray("gameIds", _gameIds);
        }

        bytes32 requestId = sendChainlinkRequest(req, paymentOdds);
        sportIdPerRequestId[requestId] = _sportId;
        datePerRequest[requestId] = _date;
    }

    function _requestPlayerPropsOddsWithFiltersFromAmm(
        bytes32 _specId,
        uint256 _sportId,
        uint256 _date,
        string[] memory _gameIds,
        string[] memory _playerIds,
        string[] memory _optionIds
    ) internal {
        Chainlink.Request memory req = buildChainlinkRequest(_specId, address(this), this.fulfillPlayerPropsOdds.selector);

        req.addUint("date", _date);
        req.addUint("sportId", _sportId);
        req.addStringArray("gameIds", _gameIds);
        req.addStringArray("playerIds", _playerIds);
        req.addStringArray("optionIds", _optionIds);

        bytes32 requestId = sendChainlinkRequest(req, paymentOdds);
        sportIdPerRequestId[requestId] = _sportId;
        datePerRequest[requestId] = _date;
    }

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

    /// @notice setting payment for game creation request
    /// @param _paymentCreate amount of LINK per request for create games
    function setPaymentCreate(uint _paymentCreate) external onlyOwner {
        require(_paymentCreate > 0, "Can not be zero");
        paymentCreate = _paymentCreate;
        emit NewPaymentAmountCreate(_paymentCreate);
    }

    /// @notice setting payment for game resolve request
    /// @param _paymentResolve amount of LINK per request for resolve games
    function setPaymentResolve(uint _paymentResolve) external onlyOwner {
        require(_paymentResolve > 0, "Can not be zero");
        paymentResolve = _paymentResolve;
        emit NewPaymentAmountResolve(_paymentResolve);
    }

    /// @notice setting payment for odds request
    /// @param _paymentOdds amount of LINK per request for game odds
    function setPaymentOdds(uint _paymentOdds) external onlyOwner {
        require(_paymentOdds > 0, "Can not be zero");
        paymentOdds = _paymentOdds;
        emit NewPaymentAmountOdds(_paymentOdds);
    }

    /// @notice setting new oracle address
    /// @param _oracle address of oracle sports data feed
    function setOracle(address _oracle) external onlyOwner {
        require(_oracle != address(0), "Invalid address");
        setChainlinkOracle(_oracle);
        emit NewOracleAddress(_oracle);
    }

    /// @notice setting consumer address
    /// @param _consumer address of a consumer which gets the data from CL requests
    function setConsumer(address _consumer) external onlyOwner {
        require(_consumer != address(0), "Invalid address");
        consumer = ITherundownConsumer(_consumer);
        emit NewConsumer(_consumer);
    }

    /// @notice setting consumer verifier address
    /// @param _verifier address of a consumer verifier
    function setVerifier(address _verifier) external onlyOwner {
        require(_verifier != address(0), "Invalid address");
        verifier = ITherundownConsumerVerifier(_verifier);
        emit NewVerifier(_verifier);
    }

    /// @notice setting link address
    /// @param _link address of a LINK which request will be paid
    function setLink(address _link) external onlyOwner {
        require(_link != address(0), "Invalid address");
        setChainlinkToken(_link);
        linkToken = IERC20(_link);
        emit NewLinkAddress(_link);
    }

    /// @notice setting odds spec id
    /// @param _specId spec id
    function setOddsSpecId(bytes32 _specId) external onlyOwner {
        oddsSpecId = _specId;
        emit NewOddsSpecId(_specId);
    }

    /// @notice setting odds spec id for player props
    /// @param _specId spec id
    function setOddsSpecIdForPlayerProps(bytes32 _specId) external onlyOwner {
        oddsSpecIdPlayerProps = _specId;
        emit NewOddsSpecIdPlayerProps(_specId);
    }

    /// @notice setting amm address
    /// @param _sportsAmm amm address
    function setSportsAmmAddress(address _sportsAmm) external onlyOwner {
        require(_sportsAmm != address(0), "Invalid address");
        sportsAMM = _sportsAmm;
        emit NewSportsAmmAddress(_sportsAmm);
    }

    /// @notice setting player props reciever address
    /// @param _playerPropsReciever props reciever address
    function setPlayerPropsReceiverAddress(address _playerPropsReciever) external onlyOwner {
        require(_playerPropsReciever != address(0), "Invalid address");
        playerPropsReciever = IGamesPlayerPropsReciever(_playerPropsReciever);
        emit NewPlayerPropsReciever(_playerPropsReciever);
    }

    /// @notice setting player props  address
    /// @param _playerProps props address
    function setPlayerPropsAddress(address _playerProps) external onlyOwner {
        require(_playerProps != address(0), "Invalid address");
        playerProps = IGamesPlayerProps(_playerProps);
        emit NewPlayerProps(_playerProps);
    }

    /// @notice Retrieve LINK from the contract
    /// @param account whom to send the LINK
    /// @param amount how much LINK to retrieve
    function retrieveLINKAmount(address payable account, uint amount) external onlyOwner {
        linkToken.safeTransfer(account, amount);
    }

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

    modifier isValidRequest(string memory _market, uint256 _sportId) {
        require(verifier.isSupportedMarketType(_market), "Market is not supported");
        require(consumer.supportedSport(_sportId), "SportId is not supported");
        _;
    }

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

    event NewOracleAddress(address _oracle);
    event NewPaymentAmountCreate(uint _paymentCreate);
    event NewPaymentAmountResolve(uint _paymentResolve);
    event NewPaymentAmountOdds(uint _paymentOdds);
    event NewConsumer(address _consumer);
    event NewVerifier(address _verifier);
    event NewLinkAddress(address _link);
    event NewOddsSpecId(bytes32 _specId);
    event NewSportsAmmAddress(address _sportsAmm);
    event UpdateOddsFromAMMForAGame(uint256 _sportId, uint256 _date, address _marketAddress);
    event NewPlayerPropsReciever(address _playerPropsReciever);
    event NewPlayerProps(address _playerProps);
    event NewOddsSpecIdPlayerProps(bytes32 _specId);
    event UpdatePlayerPropsOddsFromAMM(
        uint256 _sportId,
        uint256 _date,
        address _marketAddress,
        bytes32 _gameId,
        bytes32 _playerId,
        uint8 _optionId
    );
}

File 2 of 23 : ChainlinkClient.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./Chainlink.sol";
import "./interfaces/ENSInterface.sol";
import "./interfaces/LinkTokenInterface.sol";
import "./interfaces/ChainlinkRequestInterface.sol";
import "./interfaces/OperatorInterface.sol";
import "./interfaces/PointerInterface.sol";
import {ENSResolver as ENSResolver_Chainlink} from "./vendor/ENSResolver.sol";

/**
 * @title The ChainlinkClient contract
 * @notice Contract writers can inherit this contract in order to create requests for the
 * Chainlink network
 */
abstract contract ChainlinkClient {
  using Chainlink for Chainlink.Request;

  uint256 internal constant LINK_DIVISIBILITY = 10**18;
  uint256 private constant AMOUNT_OVERRIDE = 0;
  address private constant SENDER_OVERRIDE = address(0);
  uint256 private constant ORACLE_ARGS_VERSION = 1;
  uint256 private constant OPERATOR_ARGS_VERSION = 2;
  bytes32 private constant ENS_TOKEN_SUBNAME = keccak256("link");
  bytes32 private constant ENS_ORACLE_SUBNAME = keccak256("oracle");
  address private constant LINK_TOKEN_POINTER = 0xC89bD4E1632D3A43CB03AAAd5262cbe4038Bc571;

  ENSInterface private s_ens;
  bytes32 private s_ensNode;
  LinkTokenInterface private s_link;
  OperatorInterface private s_oracle;
  uint256 private s_requestCount = 1;
  mapping(bytes32 => address) private s_pendingRequests;

  event ChainlinkRequested(bytes32 indexed id);
  event ChainlinkFulfilled(bytes32 indexed id);
  event ChainlinkCancelled(bytes32 indexed id);

  /**
   * @notice Creates a request that can hold additional parameters
   * @param specId The Job Specification ID that the request will be created for
   * @param callbackAddr address to operate the callback on
   * @param callbackFunctionSignature function signature to use for the callback
   * @return A Chainlink Request struct in memory
   */
  function buildChainlinkRequest(
    bytes32 specId,
    address callbackAddr,
    bytes4 callbackFunctionSignature
  ) internal pure returns (Chainlink.Request memory) {
    Chainlink.Request memory req;
    return req.initialize(specId, callbackAddr, callbackFunctionSignature);
  }

  /**
   * @notice Creates a request that can hold additional parameters
   * @param specId The Job Specification ID that the request will be created for
   * @param callbackFunctionSignature function signature to use for the callback
   * @return A Chainlink Request struct in memory
   */
  function buildOperatorRequest(bytes32 specId, bytes4 callbackFunctionSignature)
    internal
    view
    returns (Chainlink.Request memory)
  {
    Chainlink.Request memory req;
    return req.initialize(specId, address(this), callbackFunctionSignature);
  }

  /**
   * @notice Creates a Chainlink request to the stored oracle address
   * @dev Calls `chainlinkRequestTo` with the stored oracle address
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendChainlinkRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
    return sendChainlinkRequestTo(address(s_oracle), req, payment);
  }

  /**
   * @notice Creates a Chainlink request to the specified oracle address
   * @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
   * send LINK which creates a request on the target oracle contract.
   * Emits ChainlinkRequested event.
   * @param oracleAddress The address of the oracle for the request
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendChainlinkRequestTo(
    address oracleAddress,
    Chainlink.Request memory req,
    uint256 payment
  ) internal returns (bytes32 requestId) {
    uint256 nonce = s_requestCount;
    s_requestCount = nonce + 1;
    bytes memory encodedRequest = abi.encodeWithSelector(
      ChainlinkRequestInterface.oracleRequest.selector,
      SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
      AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
      req.id,
      address(this),
      req.callbackFunctionId,
      nonce,
      ORACLE_ARGS_VERSION,
      req.buf.buf
    );
    return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
  }

  /**
   * @notice Creates a Chainlink request to the stored oracle address
   * @dev This function supports multi-word response
   * @dev Calls `sendOperatorRequestTo` with the stored oracle address
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendOperatorRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
    return sendOperatorRequestTo(address(s_oracle), req, payment);
  }

  /**
   * @notice Creates a Chainlink request to the specified oracle address
   * @dev This function supports multi-word response
   * @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
   * send LINK which creates a request on the target oracle contract.
   * Emits ChainlinkRequested event.
   * @param oracleAddress The address of the oracle for the request
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendOperatorRequestTo(
    address oracleAddress,
    Chainlink.Request memory req,
    uint256 payment
  ) internal returns (bytes32 requestId) {
    uint256 nonce = s_requestCount;
    s_requestCount = nonce + 1;
    bytes memory encodedRequest = abi.encodeWithSelector(
      OperatorInterface.operatorRequest.selector,
      SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
      AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
      req.id,
      req.callbackFunctionId,
      nonce,
      OPERATOR_ARGS_VERSION,
      req.buf.buf
    );
    return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
  }

  /**
   * @notice Make a request to an oracle
   * @param oracleAddress The address of the oracle for the request
   * @param nonce used to generate the request ID
   * @param payment The amount of LINK to send for the request
   * @param encodedRequest data encoded for request type specific format
   * @return requestId The request ID
   */
  function _rawRequest(
    address oracleAddress,
    uint256 nonce,
    uint256 payment,
    bytes memory encodedRequest
  ) private returns (bytes32 requestId) {
    requestId = keccak256(abi.encodePacked(this, nonce));
    s_pendingRequests[requestId] = oracleAddress;
    emit ChainlinkRequested(requestId);
    require(s_link.transferAndCall(oracleAddress, payment, encodedRequest), "unable to transferAndCall to oracle");
  }

  /**
   * @notice Allows a request to be cancelled if it has not been fulfilled
   * @dev Requires keeping track of the expiration value emitted from the oracle contract.
   * Deletes the request from the `pendingRequests` mapping.
   * Emits ChainlinkCancelled event.
   * @param requestId The request ID
   * @param payment The amount of LINK sent for the request
   * @param callbackFunc The callback function specified for the request
   * @param expiration The time of the expiration for the request
   */
  function cancelChainlinkRequest(
    bytes32 requestId,
    uint256 payment,
    bytes4 callbackFunc,
    uint256 expiration
  ) internal {
    OperatorInterface requested = OperatorInterface(s_pendingRequests[requestId]);
    delete s_pendingRequests[requestId];
    emit ChainlinkCancelled(requestId);
    requested.cancelOracleRequest(requestId, payment, callbackFunc, expiration);
  }

  /**
   * @notice the next request count to be used in generating a nonce
   * @dev starts at 1 in order to ensure consistent gas cost
   * @return returns the next request count to be used in a nonce
   */
  function getNextRequestCount() internal view returns (uint256) {
    return s_requestCount;
  }

  /**
   * @notice Sets the stored oracle address
   * @param oracleAddress The address of the oracle contract
   */
  function setChainlinkOracle(address oracleAddress) internal {
    s_oracle = OperatorInterface(oracleAddress);
  }

  /**
   * @notice Sets the LINK token address
   * @param linkAddress The address of the LINK token contract
   */
  function setChainlinkToken(address linkAddress) internal {
    s_link = LinkTokenInterface(linkAddress);
  }

  /**
   * @notice Sets the Chainlink token address for the public
   * network as given by the Pointer contract
   */
  function setPublicChainlinkToken() internal {
    setChainlinkToken(PointerInterface(LINK_TOKEN_POINTER).getAddress());
  }

  /**
   * @notice Retrieves the stored address of the LINK token
   * @return The address of the LINK token
   */
  function chainlinkTokenAddress() internal view returns (address) {
    return address(s_link);
  }

  /**
   * @notice Retrieves the stored address of the oracle contract
   * @return The address of the oracle contract
   */
  function chainlinkOracleAddress() internal view returns (address) {
    return address(s_oracle);
  }

  /**
   * @notice Allows for a request which was created on another contract to be fulfilled
   * on this contract
   * @param oracleAddress The address of the oracle contract that will fulfill the request
   * @param requestId The request ID used for the response
   */
  function addChainlinkExternalRequest(address oracleAddress, bytes32 requestId) internal notPendingRequest(requestId) {
    s_pendingRequests[requestId] = oracleAddress;
  }

  /**
   * @notice Sets the stored oracle and LINK token contracts with the addresses resolved by ENS
   * @dev Accounts for subnodes having different resolvers
   * @param ensAddress The address of the ENS contract
   * @param node The ENS node hash
   */
  function useChainlinkWithENS(address ensAddress, bytes32 node) internal {
    s_ens = ENSInterface(ensAddress);
    s_ensNode = node;
    bytes32 linkSubnode = keccak256(abi.encodePacked(s_ensNode, ENS_TOKEN_SUBNAME));
    ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(linkSubnode));
    setChainlinkToken(resolver.addr(linkSubnode));
    updateChainlinkOracleWithENS();
  }

  /**
   * @notice Sets the stored oracle contract with the address resolved by ENS
   * @dev This may be called on its own as long as `useChainlinkWithENS` has been called previously
   */
  function updateChainlinkOracleWithENS() internal {
    bytes32 oracleSubnode = keccak256(abi.encodePacked(s_ensNode, ENS_ORACLE_SUBNAME));
    ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(oracleSubnode));
    setChainlinkOracle(resolver.addr(oracleSubnode));
  }

  /**
   * @notice Ensures that the fulfillment is valid for this contract
   * @dev Use if the contract developer prefers methods instead of modifiers for validation
   * @param requestId The request ID for fulfillment
   */
  function validateChainlinkCallback(bytes32 requestId)
    internal
    recordChainlinkFulfillment(requestId)
  // solhint-disable-next-line no-empty-blocks
  {

  }

  /**
   * @dev Reverts if the sender is not the oracle of the request.
   * Emits ChainlinkFulfilled event.
   * @param requestId The request ID for fulfillment
   */
  modifier recordChainlinkFulfillment(bytes32 requestId) {
    require(msg.sender == s_pendingRequests[requestId], "Source must be the oracle of the request");
    delete s_pendingRequests[requestId];
    emit ChainlinkFulfilled(requestId);
    _;
  }

  /**
   * @dev Reverts if the request is already pending
   * @param requestId The request ID for fulfillment
   */
  modifier notPendingRequest(bytes32 requestId) {
    require(s_pendingRequests[requestId] == address(0), "Request is already pending");
    _;
  }
}

File 3 of 23 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.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 Pausable is Context {
    /**
     * @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.
     */
    constructor() {
        _paused = false;
    }

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

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

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

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        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());
    }
}

File 4 of 23 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 5 of 23 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 6 of 23 : ITherundownConsumer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    function setPausedByCanceledStatus(address _market, bool _flag) external;

    function setGameIdPerChildMarket(bytes32 _gameId, address _child) external;

    function pauseOrUnpauseMarket(address _market, bool _pause) external;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 7 of 23 : ITherundownConsumerVerifier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 8 of 23 : IGamesPlayerPropsReceiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IGamesPlayerPropsReciever {
    function fulfillPlayerPropsCLResolved(bytes[] memory _playerProps) external;

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

File 9 of 23 : IGamesPlayerProps.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

    function resolvePlayerProps(PlayerPropsResolver memory _result) external;

    function cancelMarketFromManager(address _market) external;

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

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

    function cancelPlayerPropsMarketForMain(address _main) external;

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

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

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

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

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

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

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

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

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

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

File 10 of 23 : Chainlink.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {CBORChainlink} from "./vendor/CBORChainlink.sol";
import {BufferChainlink} from "./vendor/BufferChainlink.sol";

/**
 * @title Library for common Chainlink functions
 * @dev Uses imported CBOR library for encoding to buffer
 */
library Chainlink {
  uint256 internal constant defaultBufferSize = 256; // solhint-disable-line const-name-snakecase

  using CBORChainlink for BufferChainlink.buffer;

  struct Request {
    bytes32 id;
    address callbackAddress;
    bytes4 callbackFunctionId;
    uint256 nonce;
    BufferChainlink.buffer buf;
  }

  /**
   * @notice Initializes a Chainlink request
   * @dev Sets the ID, callback address, and callback function signature on the request
   * @param self The uninitialized request
   * @param jobId The Job Specification ID
   * @param callbackAddr The callback address
   * @param callbackFunc The callback function signature
   * @return The initialized request
   */
  function initialize(
    Request memory self,
    bytes32 jobId,
    address callbackAddr,
    bytes4 callbackFunc
  ) internal pure returns (Chainlink.Request memory) {
    BufferChainlink.init(self.buf, defaultBufferSize);
    self.id = jobId;
    self.callbackAddress = callbackAddr;
    self.callbackFunctionId = callbackFunc;
    return self;
  }

  /**
   * @notice Sets the data for the buffer without encoding CBOR on-chain
   * @dev CBOR can be closed with curly-brackets {} or they can be left off
   * @param self The initialized request
   * @param data The CBOR data
   */
  function setBuffer(Request memory self, bytes memory data) internal pure {
    BufferChainlink.init(self.buf, data.length);
    BufferChainlink.append(self.buf, data);
  }

  /**
   * @notice Adds a string value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The string value to add
   */
  function add(
    Request memory self,
    string memory key,
    string memory value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeString(value);
  }

  /**
   * @notice Adds a bytes value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The bytes value to add
   */
  function addBytes(
    Request memory self,
    string memory key,
    bytes memory value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeBytes(value);
  }

  /**
   * @notice Adds a int256 value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The int256 value to add
   */
  function addInt(
    Request memory self,
    string memory key,
    int256 value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeInt(value);
  }

  /**
   * @notice Adds a uint256 value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The uint256 value to add
   */
  function addUint(
    Request memory self,
    string memory key,
    uint256 value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeUInt(value);
  }

  /**
   * @notice Adds an array of strings to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param values The array of string values to add
   */
  function addStringArray(
    Request memory self,
    string memory key,
    string[] memory values
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.startArray();
    for (uint256 i = 0; i < values.length; i++) {
      self.buf.encodeString(values[i]);
    }
    self.buf.endSequence();
  }
}

File 11 of 23 : ENSInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ENSInterface {
  // Logged when the owner of a node assigns a new owner to a subnode.
  event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);

  // Logged when the owner of a node transfers ownership to a new account.
  event Transfer(bytes32 indexed node, address owner);

  // Logged when the resolver for a node changes.
  event NewResolver(bytes32 indexed node, address resolver);

  // Logged when the TTL of a node changes
  event NewTTL(bytes32 indexed node, uint64 ttl);

  function setSubnodeOwner(
    bytes32 node,
    bytes32 label,
    address owner
  ) external;

  function setResolver(bytes32 node, address resolver) external;

  function setOwner(bytes32 node, address owner) external;

  function setTTL(bytes32 node, uint64 ttl) external;

  function owner(bytes32 node) external view returns (address);

  function resolver(bytes32 node) external view returns (address);

  function ttl(bytes32 node) external view returns (uint64);
}

File 12 of 23 : LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);

  function approve(address spender, uint256 value) external returns (bool success);

  function balanceOf(address owner) external view returns (uint256 balance);

  function decimals() external view returns (uint8 decimalPlaces);

  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);

  function increaseApproval(address spender, uint256 subtractedValue) external;

  function name() external view returns (string memory tokenName);

  function symbol() external view returns (string memory tokenSymbol);

  function totalSupply() external view returns (uint256 totalTokensIssued);

  function transfer(address to, uint256 value) external returns (bool success);

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

  function transferFrom(
    address from,
    address to,
    uint256 value
  ) external returns (bool success);
}

File 13 of 23 : ChainlinkRequestInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ChainlinkRequestInterface {
  function oracleRequest(
    address sender,
    uint256 requestPrice,
    bytes32 serviceAgreementID,
    address callbackAddress,
    bytes4 callbackFunctionId,
    uint256 nonce,
    uint256 dataVersion,
    bytes calldata data
  ) external;

  function cancelOracleRequest(
    bytes32 requestId,
    uint256 payment,
    bytes4 callbackFunctionId,
    uint256 expiration
  ) external;
}

File 14 of 23 : OperatorInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./OracleInterface.sol";
import "./ChainlinkRequestInterface.sol";

interface OperatorInterface is OracleInterface, ChainlinkRequestInterface {
  function operatorRequest(
    address sender,
    uint256 payment,
    bytes32 specId,
    bytes4 callbackFunctionId,
    uint256 nonce,
    uint256 dataVersion,
    bytes calldata data
  ) external;

  function fulfillOracleRequest2(
    bytes32 requestId,
    uint256 payment,
    address callbackAddress,
    bytes4 callbackFunctionId,
    uint256 expiration,
    bytes calldata data
  ) external returns (bool);

  function ownerTransferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

  function distributeFunds(address payable[] calldata receivers, uint256[] calldata amounts) external payable;

  function getAuthorizedSenders() external returns (address[] memory);

  function setAuthorizedSenders(address[] calldata senders) external;

  function getForwarder() external returns (address);
}

File 15 of 23 : PointerInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface PointerInterface {
  function getAddress() external view returns (address);
}

File 16 of 23 : ENSResolver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

abstract contract ENSResolver {
  function addr(bytes32 node) public view virtual returns (address);
}

File 17 of 23 : CBORChainlink.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.19;

import {BufferChainlink} from "./BufferChainlink.sol";

library CBORChainlink {
  using BufferChainlink for BufferChainlink.buffer;

  uint8 private constant MAJOR_TYPE_INT = 0;
  uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1;
  uint8 private constant MAJOR_TYPE_BYTES = 2;
  uint8 private constant MAJOR_TYPE_STRING = 3;
  uint8 private constant MAJOR_TYPE_ARRAY = 4;
  uint8 private constant MAJOR_TYPE_MAP = 5;
  uint8 private constant MAJOR_TYPE_TAG = 6;
  uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7;

  uint8 private constant TAG_TYPE_BIGNUM = 2;
  uint8 private constant TAG_TYPE_NEGATIVE_BIGNUM = 3;

  function encodeFixedNumeric(BufferChainlink.buffer memory buf, uint8 major, uint64 value) private pure {
    if(value <= 23) {
      buf.appendUint8(uint8((major << 5) | value));
    } else if (value <= 0xFF) {
      buf.appendUint8(uint8((major << 5) | 24));
      buf.appendInt(value, 1);
    } else if (value <= 0xFFFF) {
      buf.appendUint8(uint8((major << 5) | 25));
      buf.appendInt(value, 2);
    } else if (value <= 0xFFFFFFFF) {
      buf.appendUint8(uint8((major << 5) | 26));
      buf.appendInt(value, 4);
    } else {
      buf.appendUint8(uint8((major << 5) | 27));
      buf.appendInt(value, 8);
    }
  }

  function encodeIndefiniteLengthType(BufferChainlink.buffer memory buf, uint8 major) private pure {
    buf.appendUint8(uint8((major << 5) | 31));
  }

  function encodeUInt(BufferChainlink.buffer memory buf, uint value) internal pure {
    if(value > 0xFFFFFFFFFFFFFFFF) {
      encodeBigNum(buf, value);
    } else {
      encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(value));
    }
  }

  function encodeInt(BufferChainlink.buffer memory buf, int value) internal pure {
    if(value < -0x10000000000000000) {
      encodeSignedBigNum(buf, value);
    } else if(value > 0xFFFFFFFFFFFFFFFF) {
      encodeBigNum(buf, uint(value));
    } else if(value >= 0) {
      encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(uint256(value)));
    } else {
      encodeFixedNumeric(buf, MAJOR_TYPE_NEGATIVE_INT, uint64(uint256(-1 - value)));
    }
  }

  function encodeBytes(BufferChainlink.buffer memory buf, bytes memory value) internal pure {
    encodeFixedNumeric(buf, MAJOR_TYPE_BYTES, uint64(value.length));
    buf.append(value);
  }

  function encodeBigNum(BufferChainlink.buffer memory buf, uint value) internal pure {
    buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_BIGNUM));
    encodeBytes(buf, abi.encode(value));
  }

  function encodeSignedBigNum(BufferChainlink.buffer memory buf, int input) internal pure {
    buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_NEGATIVE_BIGNUM));
    encodeBytes(buf, abi.encode(uint256(-1 - input)));
  }

  function encodeString(BufferChainlink.buffer memory buf, string memory value) internal pure {
    encodeFixedNumeric(buf, MAJOR_TYPE_STRING, uint64(bytes(value).length));
    buf.append(bytes(value));
  }

  function startArray(BufferChainlink.buffer memory buf) internal pure {
    encodeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY);
  }

  function startMap(BufferChainlink.buffer memory buf) internal pure {
    encodeIndefiniteLengthType(buf, MAJOR_TYPE_MAP);
  }

  function endSequence(BufferChainlink.buffer memory buf) internal pure {
    encodeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE);
  }
}

File 18 of 23 : BufferChainlink.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @dev A library for working with mutable byte buffers in Solidity.
 *
 * Byte buffers are mutable and expandable, and provide a variety of primitives
 * for writing to them. At any time you can fetch a bytes object containing the
 * current contents of the buffer. The bytes object should not be stored between
 * operations, as it may change due to resizing of the buffer.
 */
library BufferChainlink {
  /**
   * @dev Represents a mutable buffer. Buffers have a current value (buf) and
   *      a capacity. The capacity may be longer than the current value, in
   *      which case it can be extended without the need to allocate more memory.
   */
  struct buffer {
    bytes buf;
    uint256 capacity;
  }

  /**
   * @dev Initializes a buffer with an initial capacity.
   * @param buf The buffer to initialize.
   * @param capacity The number of bytes of space to allocate the buffer.
   * @return The buffer, for chaining.
   */
  function init(buffer memory buf, uint256 capacity) internal pure returns (buffer memory) {
    if (capacity % 32 != 0) {
      capacity += 32 - (capacity % 32);
    }
    // Allocate space for the buffer data
    buf.capacity = capacity;
    assembly {
      let ptr := mload(0x40)
      mstore(buf, ptr)
      mstore(ptr, 0)
      mstore(0x40, add(32, add(ptr, capacity)))
    }
    return buf;
  }

  /**
   * @dev Initializes a new buffer from an existing bytes object.
   *      Changes to the buffer may mutate the original value.
   * @param b The bytes object to initialize the buffer with.
   * @return A new buffer.
   */
  function fromBytes(bytes memory b) internal pure returns (buffer memory) {
    buffer memory buf;
    buf.buf = b;
    buf.capacity = b.length;
    return buf;
  }

  function resize(buffer memory buf, uint256 capacity) private pure {
    bytes memory oldbuf = buf.buf;
    init(buf, capacity);
    append(buf, oldbuf);
  }

  function max(uint256 a, uint256 b) private pure returns (uint256) {
    if (a > b) {
      return a;
    }
    return b;
  }

  /**
   * @dev Sets buffer length to 0.
   * @param buf The buffer to truncate.
   * @return The original buffer, for chaining..
   */
  function truncate(buffer memory buf) internal pure returns (buffer memory) {
    assembly {
      let bufptr := mload(buf)
      mstore(bufptr, 0)
    }
    return buf;
  }

  /**
   * @dev Writes a byte string to a buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The start offset to write to.
   * @param data The data to append.
   * @param len The number of bytes to copy.
   * @return The original buffer, for chaining.
   */
  function write(
    buffer memory buf,
    uint256 off,
    bytes memory data,
    uint256 len
  ) internal pure returns (buffer memory) {
    require(len <= data.length);

    if (off + len > buf.capacity) {
      resize(buf, max(buf.capacity, len + off) * 2);
    }

    uint256 dest;
    uint256 src;
    assembly {
      // Memory address of the buffer data
      let bufptr := mload(buf)
      // Length of existing buffer data
      let buflen := mload(bufptr)
      // Start address = buffer address + offset + sizeof(buffer length)
      dest := add(add(bufptr, 32), off)
      // Update buffer length if we're extending it
      if gt(add(len, off), buflen) {
        mstore(bufptr, add(len, off))
      }
      src := add(data, 32)
    }

    // Copy word-length chunks while possible
    for (; len >= 32; len -= 32) {
      assembly {
        mstore(dest, mload(src))
      }
      dest += 32;
      src += 32;
    }

    // Copy remaining bytes
    unchecked {
      uint256 mask = (256**(32 - len)) - 1;
      assembly {
        let srcpart := and(mload(src), not(mask))
        let destpart := and(mload(dest), mask)
        mstore(dest, or(destpart, srcpart))
      }
    }

    return buf;
  }

  /**
   * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @param len The number of bytes to copy.
   * @return The original buffer, for chaining.
   */
  function append(
    buffer memory buf,
    bytes memory data,
    uint256 len
  ) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, data, len);
  }

  /**
   * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, data, data.length);
  }

  /**
   * @dev Writes a byte to the buffer. Resizes if doing so would exceed the
   *      capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write the byte at.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function writeUint8(
    buffer memory buf,
    uint256 off,
    uint8 data
  ) internal pure returns (buffer memory) {
    if (off >= buf.capacity) {
      resize(buf, buf.capacity * 2);
    }

    assembly {
      // Memory address of the buffer data
      let bufptr := mload(buf)
      // Length of existing buffer data
      let buflen := mload(bufptr)
      // Address = buffer address + sizeof(buffer length) + off
      let dest := add(add(bufptr, off), 32)
      mstore8(dest, data)
      // Update buffer length if we extended it
      if eq(off, buflen) {
        mstore(bufptr, add(buflen, 1))
      }
    }
    return buf;
  }

  /**
   * @dev Appends a byte to the buffer. Resizes if doing so would exceed the
   *      capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function appendUint8(buffer memory buf, uint8 data) internal pure returns (buffer memory) {
    return writeUint8(buf, buf.buf.length, data);
  }

  /**
   * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
   *      exceed the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write at.
   * @param data The data to append.
   * @param len The number of bytes to write (left-aligned).
   * @return The original buffer, for chaining.
   */
  function write(
    buffer memory buf,
    uint256 off,
    bytes32 data,
    uint256 len
  ) private pure returns (buffer memory) {
    if (len + off > buf.capacity) {
      resize(buf, (len + off) * 2);
    }

    unchecked {
      uint256 mask = (256**len) - 1;
      // Right-align data
      data = data >> (8 * (32 - len));
      assembly {
        // Memory address of the buffer data
        let bufptr := mload(buf)
        // Address = buffer address + sizeof(buffer length) + off + len
        let dest := add(add(bufptr, off), len)
        mstore(dest, or(and(mload(dest), not(mask)), data))
        // Update buffer length if we extended it
        if gt(add(off, len), mload(bufptr)) {
          mstore(bufptr, add(off, len))
        }
      }
    }
    return buf;
  }

  /**
   * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
   *      capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write at.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function writeBytes20(
    buffer memory buf,
    uint256 off,
    bytes20 data
  ) internal pure returns (buffer memory) {
    return write(buf, off, bytes32(data), 20);
  }

  /**
   * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chhaining.
   */
  function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, bytes32(data), 20);
  }

  /**
   * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, data, 32);
  }

  /**
   * @dev Writes an integer to the buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write at.
   * @param data The data to append.
   * @param len The number of bytes to write (right-aligned).
   * @return The original buffer, for chaining.
   */
  function writeInt(
    buffer memory buf,
    uint256 off,
    uint256 data,
    uint256 len
  ) private pure returns (buffer memory) {
    if (len + off > buf.capacity) {
      resize(buf, (len + off) * 2);
    }

    uint256 mask = (256**len) - 1;
    assembly {
      // Memory address of the buffer data
      let bufptr := mload(buf)
      // Address = buffer address + off + sizeof(buffer length) + len
      let dest := add(add(bufptr, off), len)
      mstore(dest, or(and(mload(dest), not(mask)), data))
      // Update buffer length if we extended it
      if gt(add(off, len), mload(bufptr)) {
        mstore(bufptr, add(off, len))
      }
    }
    return buf;
  }

  /**
   * @dev Appends a byte to the end of the buffer. Resizes if doing so would
   * exceed the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer.
   */
  function appendInt(
    buffer memory buf,
    uint256 data,
    uint256 len
  ) internal pure returns (buffer memory) {
    return writeInt(buf, buf.buf.length, data, len);
  }
}

File 19 of 23 : OracleInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface OracleInterface {
  function fulfillOracleRequest(
    bytes32 requestId,
    uint256 payment,
    address callbackAddress,
    bytes4 callbackFunctionId,
    uint256 expiration,
    bytes32 data
  ) external returns (bool);

  function isAuthorizedSender(address node) external view returns (bool);

  function withdraw(address recipient, uint256 amount) external;

  function withdrawable() external view returns (uint256);
}

File 20 of 23 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @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 Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 21 of 23 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 22 of 23 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

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

        (bool success, bytes memory returndata) = target.delegatecall(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
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_link","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_consumer","type":"address"},{"internalType":"uint256","name":"_paymentCreate","type":"uint256"},{"internalType":"uint256","name":"_paymentResolve","type":"uint256"},{"internalType":"uint256","name":"_paymentOdds","type":"uint256"},{"internalType":"bytes32","name":"_oddsSpecId","type":"bytes32"},{"internalType":"address","name":"_sportsAMM","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"address","name":"_playerPropsReciever","type":"address"},{"internalType":"address","name":"_playerProps","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_consumer","type":"address"}],"name":"NewConsumer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_link","type":"address"}],"name":"NewLinkAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_specId","type":"bytes32"}],"name":"NewOddsSpecId","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_specId","type":"bytes32"}],"name":"NewOddsSpecIdPlayerProps","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_oracle","type":"address"}],"name":"NewOracleAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_paymentCreate","type":"uint256"}],"name":"NewPaymentAmountCreate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_paymentOdds","type":"uint256"}],"name":"NewPaymentAmountOdds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_paymentResolve","type":"uint256"}],"name":"NewPaymentAmountResolve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_playerProps","type":"address"}],"name":"NewPlayerProps","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_playerPropsReciever","type":"address"}],"name":"NewPlayerPropsReciever","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sportsAmm","type":"address"}],"name":"NewSportsAmmAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_verifier","type":"address"}],"name":"NewVerifier","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_date","type":"uint256"},{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"}],"name":"UpdateOddsFromAMMForAGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_date","type":"uint256"},{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_playerId","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"_optionId","type":"uint8"}],"name":"UpdatePlayerPropsOddsFromAMM","type":"event"},{"inputs":[{"internalType":"bytes32[]","name":"_requestsIds","type":"bytes32[]"}],"name":"areCreatedRequestIdsFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_requestsIds","type":"bytes32[]"}],"name":"areOddsRequestIdsFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_requestsIds","type":"bytes32[]"}],"name":"areResolvedPlayerPropsRequestIdsFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_requestsIds","type":"bytes32[]"}],"name":"areResolvedRequestIdsFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_marketAddress","type":"address"}],"name":"callUpdateOddsForSpecificGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_marketAddress","type":"address"}],"name":"callUpdateOddsForSpecificPlayerProps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"consumer","outputs":[{"internalType":"contract ITherundownConsumer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"datePerRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"uint256","name":"_remainder","type":"uint256"},{"internalType":"bytes[]","name":"_games","type":"bytes[]"}],"name":"fulfillGamesCreated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"uint256","name":"_remainder","type":"uint256"},{"internalType":"bytes[]","name":"_games","type":"bytes[]"}],"name":"fulfillGamesOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"uint256","name":"_remainder","type":"uint256"},{"internalType":"bytes[]","name":"_games","type":"bytes[]"}],"name":"fulfillGamesResolved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"bytes[]","name":"_playerProps","type":"bytes[]"}],"name":"fulfillPlayerPropsOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"bytes[]","name":"_playerProps","type":"bytes[]"}],"name":"fulfillPlayerPropsResolved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"}],"name":"getBookmakerIdsBySportId","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"}],"name":"getBookmakerIdsBySportIdForPlayerProps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracleAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oddsSpecId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oddsSpecIdPlayerProps","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":[],"name":"paymentCreate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentOdds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentResolve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"playerProps","outputs":[{"internalType":"contract IGamesPlayerProps","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"playerPropsReciever","outputs":[{"internalType":"contract IGamesPlayerPropsReciever","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_specId","type":"bytes32"},{"internalType":"string","name":"_market","type":"string"},{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"uint256","name":"_date","type":"uint256"}],"name":"requestGames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_specId","type":"bytes32"},{"internalType":"string","name":"_market","type":"string"},{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"uint256","name":"_date","type":"uint256"},{"internalType":"string[]","name":"_statusIds","type":"string[]"},{"internalType":"string[]","name":"_gameIds","type":"string[]"}],"name":"requestGamesResolveWithFilters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdGamesCreated","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdGamesCreatedFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdGamesOdds","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdGamesOddsFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdGamesResolved","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdGamesResolvedFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdPlayerProps","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdPlayerPropsFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdPlayerPropsResolved","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdPlayerPropsResolvedFulFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_specId","type":"bytes32"},{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"uint256","name":"_date","type":"uint256"},{"internalType":"string[]","name":"_gameIds","type":"string[]"}],"name":"requestOddsWithFilters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_specId","type":"bytes32"},{"internalType":"string","name":"_market","type":"string"},{"internalType":"uint256","name":"_date","type":"uint256"},{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"string[]","name":"_gameIds","type":"string[]"},{"internalType":"string[]","name":"_playerIds","type":"string[]"},{"internalType":"string[]","name":"_optionIds","type":"string[]"}],"name":"requestPlayerPropsResolveWithFilters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"retrieveLINKAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_consumer","type":"address"}],"name":"setConsumer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_link","type":"address"}],"name":"setLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_specId","type":"bytes32"}],"name":"setOddsSpecId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_specId","type":"bytes32"}],"name":"setOddsSpecIdForPlayerProps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_paymentCreate","type":"uint256"}],"name":"setPaymentCreate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_paymentOdds","type":"uint256"}],"name":"setPaymentOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_paymentResolve","type":"uint256"}],"name":"setPaymentResolve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_playerProps","type":"address"}],"name":"setPlayerPropsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_playerPropsReciever","type":"address"}],"name":"setPlayerPropsReceiverAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sportsAmm","type":"address"}],"name":"setSportsAmmAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_verifier","type":"address"}],"name":"setVerifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"sportIdPerRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sportsAMM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract ITherundownConsumerVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405260016004553480156200001657600080fd5b506040516200472538038062004725833981016040819052620000399162000185565b620000443362000116565b6006805460ff60a01b19169055600280546001600160a01b0319166001600160a01b038d16179055600380546001600160a01b0319166001600160a01b038c16179055600780546001600160a01b03199081166001600160a01b039b8c1617909155600d98909855600e96909655600f94909455601080548716998816999099179098556011919091556013805485169186169190911790556008805484169685169690961790955560098054831695841695909517909455600a805490911693909116929092179091555062000243565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200018057600080fd5b919050565b60008060008060008060008060008060006101608c8e031215620001a7578687fd5b620001b28c62000168565b9a50620001c260208d0162000168565b9950620001d260408d0162000168565b985060608c0151975060808c0151965060a08c0151955060c08c01519450620001fe60e08d0162000168565b93506200020f6101008d0162000168565b9250620002206101208d0162000168565b9150620002316101408d0162000168565b90509295989b509295989b9093969950565b6144d280620002536000396000f3fe608060405234801561001057600080fd5b50600436106103995760003560e01c80637daaa7ff116101e9578063abe025c21161010f578063c7f70079116100ad578063e34077701161007c578063e340777014610822578063eb83f34a14610835578063efccb47a14610848578063f2fde38b1461085b57600080fd5b8063c7f70079146107d6578063c9925288146107e9578063d8033ef1146107fc578063db8f6ef71461080f57600080fd5b8063b4fd7296116100e9578063b4fd72961461078a578063bd7dcd221461079d578063bf62086f146107b0578063c475e0b3146107c357600080fd5b8063abe025c21461075c578063affa98d11461076f578063b18b78dd1461078257600080fd5b806392e889da116101875780639a066f5d116101565780639a066f5d1461070a5780639a2a8aa11461071d5780639c5481b514610740578063a1b778b61461074957600080fd5b806392e889da146106c857806394547fcc146106db578063977a6449146106ee57806399d9f2b9146106f757600080fd5b80638b2a4364116101c35780638b2a4364146106785780638bd6e4c91461068b5780638da5cb5b146106ae57806390c6fb27146106bf57600080fd5b80637daaa7ff146106395780637f6fd1401461064257806380a743751461065557600080fd5b806350b18b28116102ce5780635c975abb1161026c57806373f457b01161023b57806373f457b0146105ed57806375863da6146106005780637adbf973146106135780637b81c28c1461062657600080fd5b80635c975abb146105ad5780635d7fb8e2146105bf57806363a579d5146105d2578063715018a6146105e557600080fd5b806356b78887116102a857806356b788871461053157806357970e931461056457806359aeaada146105775780635b4f9d9b1461059a57600080fd5b806350b18b28146104eb57806351864c0c146104fe5780635437988d1461051e57600080fd5b806336661e1a1161033b578063436d765a11610315578063436d765a14610492578063451b57d5146104a557806346c92c58146104b857806346e38c28146104cb57600080fd5b806336661e1a146104595780633ca672f21461046c5780633eda5fcb1461047f57600080fd5b806310fe9ae81161037757806310fe9ae8146103ef578063282e9a1f1461040f5780632b7ac3f31461043d5780632bd13da11461045057600080fd5b806301e41efa1461039e578063029a39cd146103b35780630312eb35146103c6575b600080fd5b6103b16103ac366004613dbb565b61086e565b005b6103b16103c1366004613883565b6109f1565b6103d96103d4366004613d4d565b610c9e565b6040516103e6919061408b565b60405180910390f35b6103f7610d57565b6040516001600160a01b0390911681526020016103e6565b61042f61041d366004613b3a565b600c6020526000908152604090205481565b6040519081526020016103e6565b6008546103f7906001600160a01b031681565b61042f600d5481565b6103b1610467366004613b96565b610d70565b6103b161047a366004613bea565b611005565b6103b161048d366004613b3a565b6112f2565b6103d96104a0366004613d4d565b611356565b6103b16104b3366004613b52565b611372565b6103b16104c6366004613b3a565b61147c565b6104de6104d9366004613b3a565b6114b9565b6040516103e69190613f8b565b6103b16104f9366004613883565b611541565b61042f61050c366004613b3a565b600b6020526000908152604090205481565b6103b161052c366004613883565b6115bd565b61055461053f366004613b3a565b601c6020526000908152604090205460ff1681565b60405190151581526020016103e6565b6010546103f7906001600160a01b031681565b610554610585366004613b3a565b601d6020526000908152604090205460ff1681565b6103b16105a836600461389f565b611639565b600654600160a01b900460ff16610554565b600a546103f7906001600160a01b031681565b6103b16105e0366004613883565b61165c565b6103b16116d8565b6103b16105fb366004613d6e565b6116ec565b6103b161060e366004613c89565b611818565b6103b1610621366004613883565b611abb565b61055461063436600461391a565b611b3d565b61042f600f5481565b6103b1610650366004613d6e565b611bb4565b610554610663366004613b3a565b601a6020526000908152604090205460ff1681565b6103b1610686366004613b3a565b611c9f565b610554610699366004613b3a565b601b6020526000908152604090205460ff1681565b6006546001600160a01b03166103f7565b61042f60115481565b6105546106d636600461391a565b611cdc565b6103b16106e9366004613883565b611d4a565b61042f600e5481565b6104de610705366004613b3a565b611de1565b6103b1610718366004613883565b611e13565b61055461072b366004613b3a565b601e6020526000908152604090205460ff1681565b61042f60125481565b6103b1610757366004613883565b611e8f565b6103b161076a366004613b52565b611f0b565b6103b161077d366004613b3a565b611fde565b6103f761203b565b6007546103f7906001600160a01b031681565b6103d96107ab366004613d4d565b61204f565b6103b16107be366004613b3a565b61206b565b6103d96107d1366004613d4d565b6120c8565b6103b16107e4366004613d6e565b6120e4565b6013546103f7906001600160a01b031681565b61055461080a36600461391a565b6121c6565b61055461081d36600461391a565b612234565b6009546103f7906001600160a01b031681565b6103b1610843366004613883565b6122a2565b6103d9610856366004613d4d565b61276f565b6103b1610869366004613883565b61278b565b610876612801565b6007546040516334d2a49760e11b8152600481018590526001600160a01b03909116906369a5492e9060240160206040518083038186803b1580156108ba57600080fd5b505afa1580156108ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f29190613b1a565b6109175760405162461bcd60e51b815260040161090e90614127565b60405180910390fd5b600061092b853063c7f7007960e01b61284e565b6040805180820190915260048152636461746560e01b602082015290915061095590829085612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261097f90829086612875565b8151156109b05760408051808201909152600781526667616d6549647360c81b60208201526109b090829084612898565b6109bc33600f5461291e565b60006109ca82600f54612936565b6000908152600b6020908152604080832097909755600c9052949094209290925550505050565b6109f9612801565b6013546001600160a01b03163314610a235760405162461bcd60e51b815260040161090e906141a6565b600f546010546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610a6957600080fd5b505afa158015610a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa19190613e12565b10610c9b576007546040516356e4194d60e01b81526001600160a01b03838116600483015260009283929116906356e4194d9060240160606040518083038186803b158015610aef57600080fd5b505afa158015610b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b279190613e2a565b5060075460405163a50267a560e01b815260048101849052602481018390529294509092506000916001600160a01b039091169063a50267a59060440160006040518083038186803b158015610b7c57600080fd5b505afa158015610b90573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bb891908101906139ac565b601154600854604051630574513160e11b8152929350610c4f92869186916001600160a01b0390911690630ae8a26290610bf6908890600401613f8b565b60006040518083038186803b158015610c0e57600080fd5b505afa158015610c22573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c4a9190810190613a32565b612950565b60408051848152602081018490526001600160a01b0386168183015290517f7c7905e4aa6d903c8f8e60c93891dbf754e35cae604e0fecb08d8ca45ffb91fa9181900360600190a15050505b50565b60196020528160005260406000208181548110610cba57600080fd5b90600052602060002001600091509150508054610cd6906143cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610d02906143cb565b8015610d4f5780601f10610d2457610100808354040283529160200191610d4f565b820191906000526020600020905b815481529060010190602001808311610d3257829003601f168201915b505050505081565b6000610d6b6002546001600160a01b031690565b905090565b610d78612801565b60085460405163645de6cb60e11b8152849184916001600160a01b039091169063c8bbcd9690610dac90859060040161408b565b60206040518083038186803b158015610dc457600080fd5b505afa158015610dd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfc9190613b1a565b610e185760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b158015610e5c57600080fd5b505afa158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e949190613b1a565b610eb05760405162461bcd60e51b815260040161090e90614127565b610eb8613584565b6040516563726561746560d01b60208201526000906026016040516020818303038152906040528051906020012087604051602001610ef79190613ed7565b604051602081830303815290604052805190602001201415610f3157610f25883063073f457b60e41b61284e565b9150600d549050610f4b565b610f4388306301fdbf4560e61b61284e565b9150600e5490505b6040805180820190915260048152636461746560e01b6020820152610f7290839087612875565b6040805180820190915260068152651b585c9ad95d60d21b6020820152610f9b908390896129e9565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152610fc590839088612875565b610fcf338261291e565b6000610fdb8383612936565b6000908152600b6020908152604080832099909955600c9052969096209490945550505050505050565b61100d612801565b60085460405163645de6cb60e11b8152869186916001600160a01b039091169063c8bbcd969061104190859060040161408b565b60206040518083038186803b15801561105957600080fd5b505afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190613b1a565b6110ad5760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b1580156110f157600080fd5b505afa158015611105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111299190613b1a565b6111455760405162461bcd60e51b815260040161090e90614127565b61114d613584565b6040516563726561746560d01b6020820152600090602601604051602081830303815290604052805190602001208960405160200161118c9190613ed7565b6040516020818303038152906040528051906020012014156111c6576111ba8a3063073f457b60e41b61284e565b9150600d5490506111e0565b6111d88a306301fdbf4560e61b61284e565b9150600e5490505b6040805180820190915260048152636461746560e01b602082015261120790839089612875565b6040805180820190915260068152651b585c9ad95d60d21b60208201526112309083908b6129e9565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261125a9083908a612875565b60408051808201909152600981526873746174757349647360b81b602082015261128690839088612898565b60408051808201909152600781526667616d6549647360c81b60208201526112b090839087612898565b6112ba338261291e565b60006112c68383612936565b6000908152600b602090815260408083209b909b55600c90529890982096909655505050505050505050565b6112fa612a07565b6000811161131a5760405162461bcd60e51b815260040161090e906140fe565b600f8190556040518181527f523e038e803877ea42acb6426444bcd23d2bbf31ad9f41ea0991762c20ee6d14906020015b60405180910390a150565b60156020528160005260406000208181548110610cba57600080fd5b60008281526005602052604090205482906001600160a01b031633146113aa5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a2600083815260186020908152604090912083516113fa928501906135bf565b506000838152601d602052604090819020805460ff191660011790556009549051630b0c3d6b60e11b81526001600160a01b03909116906316187ad690611445908590600401613fcf565b600060405180830381600087803b15801561145f57600080fd5b505af1158015611473573d6000803e3d6000fd5b50505050505050565b611484612a07565b60128190556040518181527f633028df9cc13b2f152a25567a61148994bd27575fed48eabdffaa626cac8fae9060200161134b565b6008546040516308dc718560e31b8152600481018390526060916001600160a01b0316906346e38c28906024015b60006040518083038186803b1580156114ff57600080fd5b505afa158015611513573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261153b91908101906139ac565b92915050565b611549612a07565b6001600160a01b03811661156f5760405162461bcd60e51b815260040161090e906140d5565b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527f39230f38176805abdd7f21682a360b20f3fc0b6123eb928ee222adf3b3f9e8d89060200161134b565b6115c5612a07565b6001600160a01b0381166115eb5760405162461bcd60e51b815260040161090e906140d5565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527fa1fd6a6669acb930bae242943bb9fa08ddcba665c707261e9730ee0305fb85e59060200161134b565b611641612a07565b601054611658906001600160a01b03168383612a61565b5050565b611664612a07565b6001600160a01b03811661168a5760405162461bcd60e51b815260040161090e906140d5565b600780546001600160a01b0319166001600160a01b0383169081179091556040519081527f96e60d35957ee680a1536282a3d7e57e96e55cf15f3fc5997088c2b07f411f949060200161134b565b6116e0612a07565b6116ea6000612ac4565b565b60008381526005602052604090205483906001600160a01b031633146117245760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008481526014602090815260409091208351611774928501906135bf565b506000848152601a60209081526040808320805460ff1916600117905560178252808320869055600754600b835281842054600c9093529281902054905163a400a89160e01b81526001600160a01b039093169263a400a891926117e09289928892919060040161405f565b600060405180830381600087803b1580156117fa57600080fd5b505af115801561180e573d6000803e3d6000fd5b5050505050505050565b611820612801565b60085460405163645de6cb60e11b8152879186916001600160a01b039091169063c8bbcd969061185490859060040161408b565b60206040518083038186803b15801561186c57600080fd5b505afa158015611880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a49190613b1a565b6118c05760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b15801561190457600080fd5b505afa158015611918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193c9190613b1a565b6119585760405162461bcd60e51b815260040161090e90614127565b611960613584565b60006119748b3063451b57d560e01b61284e565b600e546040805180820190915260068152651b585c9ad95d60d21b602082015291935091506119a59083908c6129e9565b6040805180820190915260048152636461746560e01b60208201526119cc9083908b612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b60208201526119f69083908a612875565b60408051808201909152600781526667616d6549647360c81b6020820152611a2090839089612898565b604080518082019091526009815268706c6179657249647360b81b6020820152611a4c90839088612898565b6040805180820190915260098152686f7074696f6e49647360b81b6020820152611a7890839087612898565b611a82338261291e565b6000611a8e8383612936565b6000908152600b602090815260408083209b909b55600c9052989098209890985550505050505050505050565b611ac3612a07565b6001600160a01b038116611ae95760405162461bcd60e51b815260040161090e906140d5565b600380546001600160a01b0319166001600160a01b0383161790556040516001600160a01b03821681527f83b00e25c000adada62072ff4992b6702b635a6e3d57e135bbd60a01be113ead9060200161134b565b6000805b8251811015611bab57601d6000848381518110611b6e57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611b995750600092915050565b80611ba381614400565b915050611b41565b50600192915050565b60008381526005602052604090205483906001600160a01b03163314611bec5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008481526015602090815260409091208351611c3c928501906135bf565b506000848152601b60209081526040808320805460ff1916600117905560178252808320869055600754600b90925291829020549151632f73199d60e01b81526001600160a01b0390911691632f73199d916117e0918891879190600401614036565b611ca7612a07565b60118190556040518181527fa9654d85422e4e0fb6544086f22f928d2d39fe8ab1c13ee9636c64cbdcf99fcb9060200161134b565b6000805b8251811015611bab57601c6000848381518110611d0d57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611d385750600092915050565b80611d4281614400565b915050611ce0565b611d52612a07565b6001600160a01b038116611d785760405162461bcd60e51b815260040161090e906140d5565b600280546001600160a01b0319166001600160a01b038316179055601080546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f0a79df54a5f0809c9853241a307e8bf1dfe87ad5323398cc566df6e34705999060200161134b565b6008546040516399d9f2b960e01b8152600481018390526060916001600160a01b0316906399d9f2b9906024016114e7565b611e1b612a07565b6001600160a01b038116611e415760405162461bcd60e51b815260040161090e906140d5565b600a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f23041e186c2c775aca744354ade0052500ac68eff5afc82d66f6146257b037979060200161134b565b611e97612a07565b6001600160a01b038116611ebd5760405162461bcd60e51b815260040161090e906140d5565b601380546001600160a01b0319166001600160a01b0383169081179091556040519081527f3a310361002138b9ae7ac040259a1e871d3263696335223ddf2dc1af218a222b9060200161134b565b60008281526005602052604090205482906001600160a01b03163314611f435760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008381526019602090815260409091208351611f93928501906135bf565b506000838152601e602052604090819020805460ff19166001179055600954905163c1a0e03b60e01b81526001600160a01b039091169063c1a0e03b90611445908590600401613fcf565b611fe6612a07565b600081116120065760405162461bcd60e51b815260040161090e906140fe565b600d8190556040518181527f29a88aaedea4371894af2af86b4d24f2cfcbb494532f46b5b761cbc4cc5ff2a39060200161134b565b6000610d6b6003546001600160a01b031690565b60186020528160005260406000208181548110610cba57600080fd5b612073612a07565b600081116120935760405162461bcd60e51b815260040161090e906140fe565b600e8190556040518181527f2e959719b856a4dda43c92d8d13eb48b37668b25366584f6167cf86b653df9f69060200161134b565b60146020528160005260406000208181548110610cba57600080fd5b60008381526005602052604090205483906001600160a01b0316331461211c5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a26000848152601660209081526040909120835161216c928501906135bf565b506000848152601760209081526040808320869055601c90915290819020805460ff191660011790556007549051631ecbaea760e11b81526001600160a01b0390911690633d975d4e906117e0908790869060040161401d565b6000805b8251811015611bab57601a60008483815181106121f757634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166122225750600092915050565b8061222c81614400565b9150506121ca565b6000805b8251811015611bab57601b600084838151811061226557634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166122905750600092915050565b8061229a81614400565b915050612238565b6122aa612801565b6013546001600160a01b031633146122d45760405162461bcd60e51b815260040161090e906141a6565b600f546010546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561231a57600080fd5b505afa15801561232e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123529190613e12565b10610c9b57600a5460405163469be85960e11b81526001600160a01b0383811660048301526000928392839283921690638d37d0b29060240160806040518083038186803b1580156123a357600080fd5b505afa1580156123b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123db91906138ca565b60408051600180825281830190925294985092965090945092506000919060208083019080368337019050509050838160008151811061242b57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050838160008151811061247c57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905083816000815181106124cd57634e487b7160e01b600052603260045260246000fd5b60ff92909216602092830291909101909101526007546040516356e4194d60e01b81526001600160a01b03898116600483015260009283929116906356e4194d9060240160606040518083038186803b15801561252957600080fd5b505afa15801561253d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125619190613e2a565b50601254600854604051630574513160e11b8152939550919350612704929091859185916001600160a01b031690630ae8a262906125a3908c90600401613f8b565b60006040518083038186803b1580156125bb57600080fd5b505afa1580156125cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125f79190810190613a32565b600854604051630574513160e11b81526001600160a01b0390911690630ae8a26290612627908c90600401613f8b565b60006040518083038186803b15801561263f57600080fd5b505afa158015612653573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261267b9190810190613a32565b600854604051636d2dc16960e11b81526001600160a01b039091169063da5b82d2906126ab908c90600401613fe2565b60006040518083038186803b1580156126c357600080fd5b505afa1580156126d7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126ff9190810190613a32565b612b16565b60408051838152602081018390526001600160a01b038c1681830152606081018a90526080810189905260ff881660a082015290517f77340c5b6a25fac6af6f39892ff7da024bcbbda96d7b58bd30d512dd7284925b9181900360c00190a150505050505050505050565b60166020528160005260406000208181548110610cba57600080fd5b612793612a07565b6001600160a01b0381166127f85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161090e565b610c9b81612ac4565b600654600160a01b900460ff16156116ea5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161090e565b612856613584565b61285e613584565b61286a81868686612c37565b9150505b9392505050565b60808301516128849083612c7d565b60808301516128939082612c94565b505050565b60808301516128a79083612c7d565b6128b48360800151612cb9565b60005b8151811015612910576128fe8282815181106128e357634e487b7160e01b600052603260045260246000fd5b60200260200101518560800151612c7d90919063ffffffff16565b8061290881614400565b9150506128b7565b506128938360800151612cc4565b601054611658906001600160a01b0316833084612ccf565b60035460009061286e906001600160a01b03168484612d0d565b6000612964853063c7f7007960e01b61284e565b6040805180820190915260048152636461746560e01b602082015290915061298e90829085612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b60208201526129b890829086612875565b8151156109bc5760408051808201909152600781526667616d6549647360c81b60208201526109bc90829084612898565b60808301516129f89083612c7d565b60808301516128939082612c7d565b6006546001600160a01b031633146116ea5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090e565b6040516001600160a01b03831660248201526044810182905261289390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612da0565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000612b2a87306355f012e160e11b61284e565b6040805180820190915260048152636461746560e01b6020820152909150612b5490829087612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152612b7e90829088612875565b60408051808201909152600781526667616d6549647360c81b6020820152612ba890829086612898565b604080518082019091526009815268706c6179657249647360b81b6020820152612bd490829085612898565b6040805180820190915260098152686f7074696f6e49647360b81b6020820152612c0090829084612898565b6000612c0e82600f54612936565b6000908152600b6020908152604080832099909955600c90529690962094909455505050505050565b612c3f613584565b612c4f8560800151610100612e72565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b612c8a8260038351612ed7565b6128938282612fde565b6001600160401b03811115612cad576116588282613005565b61165882600083612ed7565b610c9b81600461303c565b610c9b81600761303c565b6040516001600160a01b0380851660248301528316604482015260648101829052612d079085906323b872dd60e01b90608401612a8d565b50505050565b600454600090612d1e816001614266565b600455835160408086015160808701515191516000936320214ca360e11b93612d569386938493923092918a91600191602401613ef3565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050612d9686838684613051565b9695505050505050565b6000612df5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131be9092919063ffffffff16565b8051909150156128935780806020019051810190612e139190613b1a565b6128935760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161090e565b604080518082019091526060815260006020820152612e9260208361441b565b15612eba57612ea260208361441b565b612ead906020614388565b612eb79083614266565b91505b506020828101829052604080518085526000815290920101905290565b6017816001600160401b031611612efb57612d078360e0600585901b1683176131cd565b60ff816001600160401b031611612f3757612f21836018611fe0600586901b16176131cd565b50612d07836001600160401b03831660016131f2565b61ffff816001600160401b031611612f7457612f5e836019611fe0600586901b16176131cd565b50612d07836001600160401b03831660026131f2565b63ffffffff816001600160401b031611612fb357612f9d83601a611fe0600586901b16176131cd565b50612d07836001600160401b03831660046131f2565b612fc883601b611fe0600586901b16176131cd565b50612d07836001600160401b03831660086131f2565b60408051808201909152606081526000602082015261286e83846000015151848551613218565b6130108260c26131cd565b50611658828260405160200161302891815260200190565b604051602081830303815290604052613302565b61289382601f611fe0600585901b16176131cd565b6040516bffffffffffffffffffffffff193060601b1660208201526034810184905260009060540160408051808303601f1901815282825280516020918201206000818152600590925291812080546001600160a01b0319166001600160a01b038a1617905590925082917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af99190a2600254604051630200057560e51b81526001600160a01b0390911690634000aea09061311490889087908790600401613f5b565b602060405180830381600087803b15801561312e57600080fd5b505af1158015613142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131669190613b1a565b612c755760405162461bcd60e51b815260206004820152602360248201527f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261604482015262636c6560e81b606482015260840161090e565b6060612c75848460008561330f565b60408051808201909152606081526000602082015261286e8384600001515184613440565b604080518082019091526060815260006020820152612c7584856000015151858561349c565b604080518082019091526060815260006020820152825182111561323b57600080fd5b602085015161324a8386614266565b111561327d5761327d8561326d876020015187866132689190614266565b61351d565b613278906002614369565b613534565b60008086518051876020830101935080888701111561329c5787860182525b505050602084015b602084106132dc57805182526132bb602083614266565b91506132c8602082614266565b90506132d5602085614388565b93506132a4565b51815160001960208690036101000a019081169019919091161790525083949350505050565b612c8a8260028351612ed7565b6060824710156133705760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161090e565b6001600160a01b0385163b6133c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161090e565b600080866001600160a01b031685876040516133e39190613ed7565b60006040518083038185875af1925050503d8060008114613420576040519150601f19603f3d011682016040523d82523d6000602084013e613425565b606091505b509150915061343582828661354b565b979650505050505050565b604080518082019091526060815260006020820152836020015183106134755761347584856020015160026132789190614369565b835180516020858301018481535080851415613492576001810182525b5093949350505050565b60408051808201909152606081526000602082015260208501516134c08584614266565b11156134d4576134d48561326d8685614266565b600060016134e4846101006142c1565b6134ee9190614388565b90508551838682010185831982511617815250805184870111156135125783860181525b509495945050505050565b60008183111561352e57508161153b565b50919050565b81516135408383612e72565b50612d078382612fde565b6060831561355a57508161286e565b82511561356a5782518084602001fd5b8160405162461bcd60e51b815260040161090e919061408b565b6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b82805482825590600052602060002090810192821561360c579160200282015b8281111561360c57825180516135fc91849160209091019061361c565b50916020019190600101906135df565b5061361892915061369c565b5090565b828054613628906143cb565b90600052602060002090601f01602090048101928261364a5760008555613690565b82601f1061366357805160ff1916838001178555613690565b82800160010185558215613690579182015b82811115613690578251825591602001919060010190613675565b506136189291506136b9565b808211156136185760006136b082826136ce565b5060010161369c565b5b8082111561361857600081556001016136ba565b5080546136da906143cb565b6000825580601f106136ea575050565b601f016020900490600052602060002090810190610c9b91906136b9565b600061371b6137168461423f565b6141ec565b905082815283838301111561372f57600080fd5b828260208301376000602084830101529392505050565b600082601f830112613756578081fd5b813560206137666137168361421c565b80838252828201915082860187848660051b8901011115613785578586fd5b855b858110156137d85781356001600160401b038111156137a4578788fd5b8801603f81018a136137b4578788fd5b6137c58a8783013560408401613708565b8552509284019290840190600101613787565b5090979650505050505050565b600082601f8301126137f5578081fd5b813560206138056137168361421c565b80838252828201915082860187848660051b8901011115613824578586fd5b855b858110156137d85781356001600160401b03811115613843578788fd5b6138518a87838c0101613864565b8552509284019290840190600101613826565b600082601f830112613874578081fd5b61286e83833560208501613708565b600060208284031215613894578081fd5b813561286e81614467565b600080604083850312156138b1578081fd5b82356138bc81614467565b946020939093013593505050565b600080600080608085870312156138df578182fd5b84516138ea81614467565b809450506020850151925060408501519150606085015160ff8116811461390f578182fd5b939692955090935050565b6000602080838503121561392c578182fd5b82356001600160401b03811115613941578283fd5b8301601f81018513613951578283fd5b803561395f6137168261421c565b80828252848201915084840188868560051b870101111561397e578687fd5b8694505b838510156139a0578035835260019490940193918501918501613982565b50979650505050505050565b600060208083850312156139be578182fd5b82516001600160401b038111156139d3578283fd5b8301601f810185136139e3578283fd5b80516139f16137168261421c565b80828252848201915084840188868560051b8701011115613a10578687fd5b8694505b838510156139a0578051835260019490940193918501918501613a14565b60006020808385031215613a44578182fd5b82516001600160401b0380821115613a5a578384fd5b818501915085601f830112613a6d578384fd5b8151613a7b6137168261421c565b80828252858201915085850189878560051b8801011115613a9a578788fd5b875b84811015613b0b57815186811115613ab257898afd5b8701603f81018c13613ac257898afd5b888101516040613ad46137168361423f565b8281528e82848601011115613ae7578c8dfd5b613af6838d830184870161439f565b87525050509287019290870190600101613a9c565b50909998505050505050505050565b600060208284031215613b2b578081fd5b8151801515811461286e578182fd5b600060208284031215613b4b578081fd5b5035919050565b60008060408385031215613b64578182fd5b8235915060208301356001600160401b03811115613b80578182fd5b613b8c85828601613746565b9150509250929050565b60008060008060808587031215613bab578182fd5b8435935060208501356001600160401b03811115613bc7578283fd5b613bd387828801613864565b949794965050505060408301359260600135919050565b60008060008060008060c08789031215613c02578384fd5b8635955060208701356001600160401b0380821115613c1f578586fd5b613c2b8a838b01613864565b965060408901359550606089013594506080890135915080821115613c4e578384fd5b613c5a8a838b016137e5565b935060a0890135915080821115613c6f578283fd5b50613c7c89828a016137e5565b9150509295509295509295565b600080600080600080600060e0888a031215613ca3578485fd5b8735965060208801356001600160401b0380821115613cc0578687fd5b613ccc8b838c01613864565b975060408a0135965060608a0135955060808a0135915080821115613cef578283fd5b613cfb8b838c016137e5565b945060a08a0135915080821115613d10578283fd5b613d1c8b838c016137e5565b935060c08a0135915080821115613d31578283fd5b50613d3e8a828b016137e5565b91505092959891949750929550565b60008060408385031215613d5f578182fd5b50508035926020909101359150565b600080600060608486031215613d82578081fd5b833592506020840135915060408401356001600160401b03811115613da5578182fd5b613db186828701613746565b9150509250925092565b60008060008060808587031215613dd0578182fd5b84359350602085013592506040850135915060608501356001600160401b03811115613dfa578182fd5b613e06878288016137e5565b91505092959194509250565b600060208284031215613e23578081fd5b5051919050565b600080600060608486031215613e3e578081fd5b8351925060208401519150604084015190509250925092565b600081518084526020808501808196508360051b81019150828601855b85811015613e9e578284038952613e8c848351613eab565b98850198935090840190600101613e74565b5091979650505050505050565b60008151808452613ec381602086016020860161439f565b601f01601f19169290920160200192915050565b60008251613ee981846020870161439f565b9190910192915050565b6001600160a01b0389811682526020820189905260408201889052861660608201526001600160e01b03198516608082015260a0810184905260c0810183905261010060e08201819052600090613f4c83820185613eab565b9b9a5050505050505050505050565b60018060a01b0384168152826020820152606060408201526000613f826060830184613eab565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613fc357835183529284019291840191600101613fa7565b50909695505050505050565b60208152600061286e6020830184613e57565b6020808252825182820181905260009190848201906040850190845b81811015613fc357835160ff1683529284019291840191600101613ffe565b828152604060208201526000612c756040830184613e57565b83815260606020820152600061404f6060830185613e57565b9050826040830152949350505050565b8481526080602082015260006140786080830186613e57565b6040830194909452506060015292915050565b60208152600061286e6020830184613eab565b60208082526017908201527f4d61726b6574206973206e6f7420737570706f72746564000000000000000000604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b6020808252600f908201526e43616e206e6f74206265207a65726f60881b604082015260600190565b60208082526018908201527f53706f72744964206973206e6f7420737570706f727465640000000000000000604082015260600190565b60208082526028908201527f536f75726365206d75737420626520746865206f7261636c65206f6620746865604082015267081c995c5d595cdd60c21b606082015260800190565b60208082526026908201527f4f6e6c792053706f72747320414d4d2063616e2063616c6c20746869732066756040820152653731ba34b7b760d11b606082015260800190565b604051601f8201601f191681016001600160401b038111828210171561421457614214614451565b604052919050565b60006001600160401b0382111561423557614235614451565b5060051b60200190565b60006001600160401b0382111561425857614258614451565b50601f01601f191660200190565b600082198211156142795761427961443b565b500190565b600181815b808511156142b957816000190482111561429f5761429f61443b565b808516156142ac57918102915b93841c9390800290614283565b509250929050565b600061286e83836000826142d75750600161153b565b816142e45750600061153b565b81600181146142fa576002811461430457614320565b600191505061153b565b60ff8411156143155761431561443b565b50506001821b61153b565b5060208310610133831016604e8410600b8410161715614343575081810a61153b565b61434d838361427e565b80600019048211156143615761436161443b565b029392505050565b60008160001904831182151516156143835761438361443b565b500290565b60008282101561439a5761439a61443b565b500390565b60005b838110156143ba5781810151838201526020016143a2565b83811115612d075750506000910152565b600181811c908216806143df57607f821691505b6020821081141561352e57634e487b7160e01b600052602260045260246000fd5b60006000198214156144145761441461443b565b5060010190565b60008261443657634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c9b57600080fdfe7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63aa2646970667358221220de9d06092007abc051f038721d41a100f1c5b63b3b3dac698d92a201007e483b64736f6c63430008040033000000000000000000000000dc2cc710e42857672e7907cf474a69b63b93089f00000000000000000000000059a3b51081a3d7e47206cec6cddc1e8c45e1c82b000000000000000000000000db6eb989127d0c33bc630d7b5b53f87ceced3ce1000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc1000032306464386137383732653434363038623864383232396365663336666236380000000000000000000000007465c5d60d3d095443cf9991da03304a30d42eae00000000000000000000000086991efb34b0cf55af38e9dace3f82cd8b70188f000000000000000000000000cefdad247275b0657b2275df05b677938dd6a43f000000000000000000000000738d5996f9e87a238ebca7352909c20ef27c54d0

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103995760003560e01c80637daaa7ff116101e9578063abe025c21161010f578063c7f70079116100ad578063e34077701161007c578063e340777014610822578063eb83f34a14610835578063efccb47a14610848578063f2fde38b1461085b57600080fd5b8063c7f70079146107d6578063c9925288146107e9578063d8033ef1146107fc578063db8f6ef71461080f57600080fd5b8063b4fd7296116100e9578063b4fd72961461078a578063bd7dcd221461079d578063bf62086f146107b0578063c475e0b3146107c357600080fd5b8063abe025c21461075c578063affa98d11461076f578063b18b78dd1461078257600080fd5b806392e889da116101875780639a066f5d116101565780639a066f5d1461070a5780639a2a8aa11461071d5780639c5481b514610740578063a1b778b61461074957600080fd5b806392e889da146106c857806394547fcc146106db578063977a6449146106ee57806399d9f2b9146106f757600080fd5b80638b2a4364116101c35780638b2a4364146106785780638bd6e4c91461068b5780638da5cb5b146106ae57806390c6fb27146106bf57600080fd5b80637daaa7ff146106395780637f6fd1401461064257806380a743751461065557600080fd5b806350b18b28116102ce5780635c975abb1161026c57806373f457b01161023b57806373f457b0146105ed57806375863da6146106005780637adbf973146106135780637b81c28c1461062657600080fd5b80635c975abb146105ad5780635d7fb8e2146105bf57806363a579d5146105d2578063715018a6146105e557600080fd5b806356b78887116102a857806356b788871461053157806357970e931461056457806359aeaada146105775780635b4f9d9b1461059a57600080fd5b806350b18b28146104eb57806351864c0c146104fe5780635437988d1461051e57600080fd5b806336661e1a1161033b578063436d765a11610315578063436d765a14610492578063451b57d5146104a557806346c92c58146104b857806346e38c28146104cb57600080fd5b806336661e1a146104595780633ca672f21461046c5780633eda5fcb1461047f57600080fd5b806310fe9ae81161037757806310fe9ae8146103ef578063282e9a1f1461040f5780632b7ac3f31461043d5780632bd13da11461045057600080fd5b806301e41efa1461039e578063029a39cd146103b35780630312eb35146103c6575b600080fd5b6103b16103ac366004613dbb565b61086e565b005b6103b16103c1366004613883565b6109f1565b6103d96103d4366004613d4d565b610c9e565b6040516103e6919061408b565b60405180910390f35b6103f7610d57565b6040516001600160a01b0390911681526020016103e6565b61042f61041d366004613b3a565b600c6020526000908152604090205481565b6040519081526020016103e6565b6008546103f7906001600160a01b031681565b61042f600d5481565b6103b1610467366004613b96565b610d70565b6103b161047a366004613bea565b611005565b6103b161048d366004613b3a565b6112f2565b6103d96104a0366004613d4d565b611356565b6103b16104b3366004613b52565b611372565b6103b16104c6366004613b3a565b61147c565b6104de6104d9366004613b3a565b6114b9565b6040516103e69190613f8b565b6103b16104f9366004613883565b611541565b61042f61050c366004613b3a565b600b6020526000908152604090205481565b6103b161052c366004613883565b6115bd565b61055461053f366004613b3a565b601c6020526000908152604090205460ff1681565b60405190151581526020016103e6565b6010546103f7906001600160a01b031681565b610554610585366004613b3a565b601d6020526000908152604090205460ff1681565b6103b16105a836600461389f565b611639565b600654600160a01b900460ff16610554565b600a546103f7906001600160a01b031681565b6103b16105e0366004613883565b61165c565b6103b16116d8565b6103b16105fb366004613d6e565b6116ec565b6103b161060e366004613c89565b611818565b6103b1610621366004613883565b611abb565b61055461063436600461391a565b611b3d565b61042f600f5481565b6103b1610650366004613d6e565b611bb4565b610554610663366004613b3a565b601a6020526000908152604090205460ff1681565b6103b1610686366004613b3a565b611c9f565b610554610699366004613b3a565b601b6020526000908152604090205460ff1681565b6006546001600160a01b03166103f7565b61042f60115481565b6105546106d636600461391a565b611cdc565b6103b16106e9366004613883565b611d4a565b61042f600e5481565b6104de610705366004613b3a565b611de1565b6103b1610718366004613883565b611e13565b61055461072b366004613b3a565b601e6020526000908152604090205460ff1681565b61042f60125481565b6103b1610757366004613883565b611e8f565b6103b161076a366004613b52565b611f0b565b6103b161077d366004613b3a565b611fde565b6103f761203b565b6007546103f7906001600160a01b031681565b6103d96107ab366004613d4d565b61204f565b6103b16107be366004613b3a565b61206b565b6103d96107d1366004613d4d565b6120c8565b6103b16107e4366004613d6e565b6120e4565b6013546103f7906001600160a01b031681565b61055461080a36600461391a565b6121c6565b61055461081d36600461391a565b612234565b6009546103f7906001600160a01b031681565b6103b1610843366004613883565b6122a2565b6103d9610856366004613d4d565b61276f565b6103b1610869366004613883565b61278b565b610876612801565b6007546040516334d2a49760e11b8152600481018590526001600160a01b03909116906369a5492e9060240160206040518083038186803b1580156108ba57600080fd5b505afa1580156108ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f29190613b1a565b6109175760405162461bcd60e51b815260040161090e90614127565b60405180910390fd5b600061092b853063c7f7007960e01b61284e565b6040805180820190915260048152636461746560e01b602082015290915061095590829085612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261097f90829086612875565b8151156109b05760408051808201909152600781526667616d6549647360c81b60208201526109b090829084612898565b6109bc33600f5461291e565b60006109ca82600f54612936565b6000908152600b6020908152604080832097909755600c9052949094209290925550505050565b6109f9612801565b6013546001600160a01b03163314610a235760405162461bcd60e51b815260040161090e906141a6565b600f546010546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610a6957600080fd5b505afa158015610a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa19190613e12565b10610c9b576007546040516356e4194d60e01b81526001600160a01b03838116600483015260009283929116906356e4194d9060240160606040518083038186803b158015610aef57600080fd5b505afa158015610b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b279190613e2a565b5060075460405163a50267a560e01b815260048101849052602481018390529294509092506000916001600160a01b039091169063a50267a59060440160006040518083038186803b158015610b7c57600080fd5b505afa158015610b90573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bb891908101906139ac565b601154600854604051630574513160e11b8152929350610c4f92869186916001600160a01b0390911690630ae8a26290610bf6908890600401613f8b565b60006040518083038186803b158015610c0e57600080fd5b505afa158015610c22573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c4a9190810190613a32565b612950565b60408051848152602081018490526001600160a01b0386168183015290517f7c7905e4aa6d903c8f8e60c93891dbf754e35cae604e0fecb08d8ca45ffb91fa9181900360600190a15050505b50565b60196020528160005260406000208181548110610cba57600080fd5b90600052602060002001600091509150508054610cd6906143cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610d02906143cb565b8015610d4f5780601f10610d2457610100808354040283529160200191610d4f565b820191906000526020600020905b815481529060010190602001808311610d3257829003601f168201915b505050505081565b6000610d6b6002546001600160a01b031690565b905090565b610d78612801565b60085460405163645de6cb60e11b8152849184916001600160a01b039091169063c8bbcd9690610dac90859060040161408b565b60206040518083038186803b158015610dc457600080fd5b505afa158015610dd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfc9190613b1a565b610e185760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b158015610e5c57600080fd5b505afa158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e949190613b1a565b610eb05760405162461bcd60e51b815260040161090e90614127565b610eb8613584565b6040516563726561746560d01b60208201526000906026016040516020818303038152906040528051906020012087604051602001610ef79190613ed7565b604051602081830303815290604052805190602001201415610f3157610f25883063073f457b60e41b61284e565b9150600d549050610f4b565b610f4388306301fdbf4560e61b61284e565b9150600e5490505b6040805180820190915260048152636461746560e01b6020820152610f7290839087612875565b6040805180820190915260068152651b585c9ad95d60d21b6020820152610f9b908390896129e9565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152610fc590839088612875565b610fcf338261291e565b6000610fdb8383612936565b6000908152600b6020908152604080832099909955600c9052969096209490945550505050505050565b61100d612801565b60085460405163645de6cb60e11b8152869186916001600160a01b039091169063c8bbcd969061104190859060040161408b565b60206040518083038186803b15801561105957600080fd5b505afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190613b1a565b6110ad5760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b1580156110f157600080fd5b505afa158015611105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111299190613b1a565b6111455760405162461bcd60e51b815260040161090e90614127565b61114d613584565b6040516563726561746560d01b6020820152600090602601604051602081830303815290604052805190602001208960405160200161118c9190613ed7565b6040516020818303038152906040528051906020012014156111c6576111ba8a3063073f457b60e41b61284e565b9150600d5490506111e0565b6111d88a306301fdbf4560e61b61284e565b9150600e5490505b6040805180820190915260048152636461746560e01b602082015261120790839089612875565b6040805180820190915260068152651b585c9ad95d60d21b60208201526112309083908b6129e9565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261125a9083908a612875565b60408051808201909152600981526873746174757349647360b81b602082015261128690839088612898565b60408051808201909152600781526667616d6549647360c81b60208201526112b090839087612898565b6112ba338261291e565b60006112c68383612936565b6000908152600b602090815260408083209b909b55600c90529890982096909655505050505050505050565b6112fa612a07565b6000811161131a5760405162461bcd60e51b815260040161090e906140fe565b600f8190556040518181527f523e038e803877ea42acb6426444bcd23d2bbf31ad9f41ea0991762c20ee6d14906020015b60405180910390a150565b60156020528160005260406000208181548110610cba57600080fd5b60008281526005602052604090205482906001600160a01b031633146113aa5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a2600083815260186020908152604090912083516113fa928501906135bf565b506000838152601d602052604090819020805460ff191660011790556009549051630b0c3d6b60e11b81526001600160a01b03909116906316187ad690611445908590600401613fcf565b600060405180830381600087803b15801561145f57600080fd5b505af1158015611473573d6000803e3d6000fd5b50505050505050565b611484612a07565b60128190556040518181527f633028df9cc13b2f152a25567a61148994bd27575fed48eabdffaa626cac8fae9060200161134b565b6008546040516308dc718560e31b8152600481018390526060916001600160a01b0316906346e38c28906024015b60006040518083038186803b1580156114ff57600080fd5b505afa158015611513573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261153b91908101906139ac565b92915050565b611549612a07565b6001600160a01b03811661156f5760405162461bcd60e51b815260040161090e906140d5565b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527f39230f38176805abdd7f21682a360b20f3fc0b6123eb928ee222adf3b3f9e8d89060200161134b565b6115c5612a07565b6001600160a01b0381166115eb5760405162461bcd60e51b815260040161090e906140d5565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527fa1fd6a6669acb930bae242943bb9fa08ddcba665c707261e9730ee0305fb85e59060200161134b565b611641612a07565b601054611658906001600160a01b03168383612a61565b5050565b611664612a07565b6001600160a01b03811661168a5760405162461bcd60e51b815260040161090e906140d5565b600780546001600160a01b0319166001600160a01b0383169081179091556040519081527f96e60d35957ee680a1536282a3d7e57e96e55cf15f3fc5997088c2b07f411f949060200161134b565b6116e0612a07565b6116ea6000612ac4565b565b60008381526005602052604090205483906001600160a01b031633146117245760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008481526014602090815260409091208351611774928501906135bf565b506000848152601a60209081526040808320805460ff1916600117905560178252808320869055600754600b835281842054600c9093529281902054905163a400a89160e01b81526001600160a01b039093169263a400a891926117e09289928892919060040161405f565b600060405180830381600087803b1580156117fa57600080fd5b505af115801561180e573d6000803e3d6000fd5b5050505050505050565b611820612801565b60085460405163645de6cb60e11b8152879186916001600160a01b039091169063c8bbcd969061185490859060040161408b565b60206040518083038186803b15801561186c57600080fd5b505afa158015611880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a49190613b1a565b6118c05760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b15801561190457600080fd5b505afa158015611918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193c9190613b1a565b6119585760405162461bcd60e51b815260040161090e90614127565b611960613584565b60006119748b3063451b57d560e01b61284e565b600e546040805180820190915260068152651b585c9ad95d60d21b602082015291935091506119a59083908c6129e9565b6040805180820190915260048152636461746560e01b60208201526119cc9083908b612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b60208201526119f69083908a612875565b60408051808201909152600781526667616d6549647360c81b6020820152611a2090839089612898565b604080518082019091526009815268706c6179657249647360b81b6020820152611a4c90839088612898565b6040805180820190915260098152686f7074696f6e49647360b81b6020820152611a7890839087612898565b611a82338261291e565b6000611a8e8383612936565b6000908152600b602090815260408083209b909b55600c9052989098209890985550505050505050505050565b611ac3612a07565b6001600160a01b038116611ae95760405162461bcd60e51b815260040161090e906140d5565b600380546001600160a01b0319166001600160a01b0383161790556040516001600160a01b03821681527f83b00e25c000adada62072ff4992b6702b635a6e3d57e135bbd60a01be113ead9060200161134b565b6000805b8251811015611bab57601d6000848381518110611b6e57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611b995750600092915050565b80611ba381614400565b915050611b41565b50600192915050565b60008381526005602052604090205483906001600160a01b03163314611bec5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008481526015602090815260409091208351611c3c928501906135bf565b506000848152601b60209081526040808320805460ff1916600117905560178252808320869055600754600b90925291829020549151632f73199d60e01b81526001600160a01b0390911691632f73199d916117e0918891879190600401614036565b611ca7612a07565b60118190556040518181527fa9654d85422e4e0fb6544086f22f928d2d39fe8ab1c13ee9636c64cbdcf99fcb9060200161134b565b6000805b8251811015611bab57601c6000848381518110611d0d57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611d385750600092915050565b80611d4281614400565b915050611ce0565b611d52612a07565b6001600160a01b038116611d785760405162461bcd60e51b815260040161090e906140d5565b600280546001600160a01b0319166001600160a01b038316179055601080546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f0a79df54a5f0809c9853241a307e8bf1dfe87ad5323398cc566df6e34705999060200161134b565b6008546040516399d9f2b960e01b8152600481018390526060916001600160a01b0316906399d9f2b9906024016114e7565b611e1b612a07565b6001600160a01b038116611e415760405162461bcd60e51b815260040161090e906140d5565b600a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f23041e186c2c775aca744354ade0052500ac68eff5afc82d66f6146257b037979060200161134b565b611e97612a07565b6001600160a01b038116611ebd5760405162461bcd60e51b815260040161090e906140d5565b601380546001600160a01b0319166001600160a01b0383169081179091556040519081527f3a310361002138b9ae7ac040259a1e871d3263696335223ddf2dc1af218a222b9060200161134b565b60008281526005602052604090205482906001600160a01b03163314611f435760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008381526019602090815260409091208351611f93928501906135bf565b506000838152601e602052604090819020805460ff19166001179055600954905163c1a0e03b60e01b81526001600160a01b039091169063c1a0e03b90611445908590600401613fcf565b611fe6612a07565b600081116120065760405162461bcd60e51b815260040161090e906140fe565b600d8190556040518181527f29a88aaedea4371894af2af86b4d24f2cfcbb494532f46b5b761cbc4cc5ff2a39060200161134b565b6000610d6b6003546001600160a01b031690565b60186020528160005260406000208181548110610cba57600080fd5b612073612a07565b600081116120935760405162461bcd60e51b815260040161090e906140fe565b600e8190556040518181527f2e959719b856a4dda43c92d8d13eb48b37668b25366584f6167cf86b653df9f69060200161134b565b60146020528160005260406000208181548110610cba57600080fd5b60008381526005602052604090205483906001600160a01b0316331461211c5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a26000848152601660209081526040909120835161216c928501906135bf565b506000848152601760209081526040808320869055601c90915290819020805460ff191660011790556007549051631ecbaea760e11b81526001600160a01b0390911690633d975d4e906117e0908790869060040161401d565b6000805b8251811015611bab57601a60008483815181106121f757634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166122225750600092915050565b8061222c81614400565b9150506121ca565b6000805b8251811015611bab57601b600084838151811061226557634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166122905750600092915050565b8061229a81614400565b915050612238565b6122aa612801565b6013546001600160a01b031633146122d45760405162461bcd60e51b815260040161090e906141a6565b600f546010546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561231a57600080fd5b505afa15801561232e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123529190613e12565b10610c9b57600a5460405163469be85960e11b81526001600160a01b0383811660048301526000928392839283921690638d37d0b29060240160806040518083038186803b1580156123a357600080fd5b505afa1580156123b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123db91906138ca565b60408051600180825281830190925294985092965090945092506000919060208083019080368337019050509050838160008151811061242b57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050838160008151811061247c57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905083816000815181106124cd57634e487b7160e01b600052603260045260246000fd5b60ff92909216602092830291909101909101526007546040516356e4194d60e01b81526001600160a01b03898116600483015260009283929116906356e4194d9060240160606040518083038186803b15801561252957600080fd5b505afa15801561253d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125619190613e2a565b50601254600854604051630574513160e11b8152939550919350612704929091859185916001600160a01b031690630ae8a262906125a3908c90600401613f8b565b60006040518083038186803b1580156125bb57600080fd5b505afa1580156125cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125f79190810190613a32565b600854604051630574513160e11b81526001600160a01b0390911690630ae8a26290612627908c90600401613f8b565b60006040518083038186803b15801561263f57600080fd5b505afa158015612653573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261267b9190810190613a32565b600854604051636d2dc16960e11b81526001600160a01b039091169063da5b82d2906126ab908c90600401613fe2565b60006040518083038186803b1580156126c357600080fd5b505afa1580156126d7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126ff9190810190613a32565b612b16565b60408051838152602081018390526001600160a01b038c1681830152606081018a90526080810189905260ff881660a082015290517f77340c5b6a25fac6af6f39892ff7da024bcbbda96d7b58bd30d512dd7284925b9181900360c00190a150505050505050505050565b60166020528160005260406000208181548110610cba57600080fd5b612793612a07565b6001600160a01b0381166127f85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161090e565b610c9b81612ac4565b600654600160a01b900460ff16156116ea5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161090e565b612856613584565b61285e613584565b61286a81868686612c37565b9150505b9392505050565b60808301516128849083612c7d565b60808301516128939082612c94565b505050565b60808301516128a79083612c7d565b6128b48360800151612cb9565b60005b8151811015612910576128fe8282815181106128e357634e487b7160e01b600052603260045260246000fd5b60200260200101518560800151612c7d90919063ffffffff16565b8061290881614400565b9150506128b7565b506128938360800151612cc4565b601054611658906001600160a01b0316833084612ccf565b60035460009061286e906001600160a01b03168484612d0d565b6000612964853063c7f7007960e01b61284e565b6040805180820190915260048152636461746560e01b602082015290915061298e90829085612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b60208201526129b890829086612875565b8151156109bc5760408051808201909152600781526667616d6549647360c81b60208201526109bc90829084612898565b60808301516129f89083612c7d565b60808301516128939082612c7d565b6006546001600160a01b031633146116ea5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090e565b6040516001600160a01b03831660248201526044810182905261289390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612da0565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000612b2a87306355f012e160e11b61284e565b6040805180820190915260048152636461746560e01b6020820152909150612b5490829087612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152612b7e90829088612875565b60408051808201909152600781526667616d6549647360c81b6020820152612ba890829086612898565b604080518082019091526009815268706c6179657249647360b81b6020820152612bd490829085612898565b6040805180820190915260098152686f7074696f6e49647360b81b6020820152612c0090829084612898565b6000612c0e82600f54612936565b6000908152600b6020908152604080832099909955600c90529690962094909455505050505050565b612c3f613584565b612c4f8560800151610100612e72565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b612c8a8260038351612ed7565b6128938282612fde565b6001600160401b03811115612cad576116588282613005565b61165882600083612ed7565b610c9b81600461303c565b610c9b81600761303c565b6040516001600160a01b0380851660248301528316604482015260648101829052612d079085906323b872dd60e01b90608401612a8d565b50505050565b600454600090612d1e816001614266565b600455835160408086015160808701515191516000936320214ca360e11b93612d569386938493923092918a91600191602401613ef3565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050612d9686838684613051565b9695505050505050565b6000612df5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131be9092919063ffffffff16565b8051909150156128935780806020019051810190612e139190613b1a565b6128935760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161090e565b604080518082019091526060815260006020820152612e9260208361441b565b15612eba57612ea260208361441b565b612ead906020614388565b612eb79083614266565b91505b506020828101829052604080518085526000815290920101905290565b6017816001600160401b031611612efb57612d078360e0600585901b1683176131cd565b60ff816001600160401b031611612f3757612f21836018611fe0600586901b16176131cd565b50612d07836001600160401b03831660016131f2565b61ffff816001600160401b031611612f7457612f5e836019611fe0600586901b16176131cd565b50612d07836001600160401b03831660026131f2565b63ffffffff816001600160401b031611612fb357612f9d83601a611fe0600586901b16176131cd565b50612d07836001600160401b03831660046131f2565b612fc883601b611fe0600586901b16176131cd565b50612d07836001600160401b03831660086131f2565b60408051808201909152606081526000602082015261286e83846000015151848551613218565b6130108260c26131cd565b50611658828260405160200161302891815260200190565b604051602081830303815290604052613302565b61289382601f611fe0600585901b16176131cd565b6040516bffffffffffffffffffffffff193060601b1660208201526034810184905260009060540160408051808303601f1901815282825280516020918201206000818152600590925291812080546001600160a01b0319166001600160a01b038a1617905590925082917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af99190a2600254604051630200057560e51b81526001600160a01b0390911690634000aea09061311490889087908790600401613f5b565b602060405180830381600087803b15801561312e57600080fd5b505af1158015613142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131669190613b1a565b612c755760405162461bcd60e51b815260206004820152602360248201527f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261604482015262636c6560e81b606482015260840161090e565b6060612c75848460008561330f565b60408051808201909152606081526000602082015261286e8384600001515184613440565b604080518082019091526060815260006020820152612c7584856000015151858561349c565b604080518082019091526060815260006020820152825182111561323b57600080fd5b602085015161324a8386614266565b111561327d5761327d8561326d876020015187866132689190614266565b61351d565b613278906002614369565b613534565b60008086518051876020830101935080888701111561329c5787860182525b505050602084015b602084106132dc57805182526132bb602083614266565b91506132c8602082614266565b90506132d5602085614388565b93506132a4565b51815160001960208690036101000a019081169019919091161790525083949350505050565b612c8a8260028351612ed7565b6060824710156133705760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161090e565b6001600160a01b0385163b6133c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161090e565b600080866001600160a01b031685876040516133e39190613ed7565b60006040518083038185875af1925050503d8060008114613420576040519150601f19603f3d011682016040523d82523d6000602084013e613425565b606091505b509150915061343582828661354b565b979650505050505050565b604080518082019091526060815260006020820152836020015183106134755761347584856020015160026132789190614369565b835180516020858301018481535080851415613492576001810182525b5093949350505050565b60408051808201909152606081526000602082015260208501516134c08584614266565b11156134d4576134d48561326d8685614266565b600060016134e4846101006142c1565b6134ee9190614388565b90508551838682010185831982511617815250805184870111156135125783860181525b509495945050505050565b60008183111561352e57508161153b565b50919050565b81516135408383612e72565b50612d078382612fde565b6060831561355a57508161286e565b82511561356a5782518084602001fd5b8160405162461bcd60e51b815260040161090e919061408b565b6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b82805482825590600052602060002090810192821561360c579160200282015b8281111561360c57825180516135fc91849160209091019061361c565b50916020019190600101906135df565b5061361892915061369c565b5090565b828054613628906143cb565b90600052602060002090601f01602090048101928261364a5760008555613690565b82601f1061366357805160ff1916838001178555613690565b82800160010185558215613690579182015b82811115613690578251825591602001919060010190613675565b506136189291506136b9565b808211156136185760006136b082826136ce565b5060010161369c565b5b8082111561361857600081556001016136ba565b5080546136da906143cb565b6000825580601f106136ea575050565b601f016020900490600052602060002090810190610c9b91906136b9565b600061371b6137168461423f565b6141ec565b905082815283838301111561372f57600080fd5b828260208301376000602084830101529392505050565b600082601f830112613756578081fd5b813560206137666137168361421c565b80838252828201915082860187848660051b8901011115613785578586fd5b855b858110156137d85781356001600160401b038111156137a4578788fd5b8801603f81018a136137b4578788fd5b6137c58a8783013560408401613708565b8552509284019290840190600101613787565b5090979650505050505050565b600082601f8301126137f5578081fd5b813560206138056137168361421c565b80838252828201915082860187848660051b8901011115613824578586fd5b855b858110156137d85781356001600160401b03811115613843578788fd5b6138518a87838c0101613864565b8552509284019290840190600101613826565b600082601f830112613874578081fd5b61286e83833560208501613708565b600060208284031215613894578081fd5b813561286e81614467565b600080604083850312156138b1578081fd5b82356138bc81614467565b946020939093013593505050565b600080600080608085870312156138df578182fd5b84516138ea81614467565b809450506020850151925060408501519150606085015160ff8116811461390f578182fd5b939692955090935050565b6000602080838503121561392c578182fd5b82356001600160401b03811115613941578283fd5b8301601f81018513613951578283fd5b803561395f6137168261421c565b80828252848201915084840188868560051b870101111561397e578687fd5b8694505b838510156139a0578035835260019490940193918501918501613982565b50979650505050505050565b600060208083850312156139be578182fd5b82516001600160401b038111156139d3578283fd5b8301601f810185136139e3578283fd5b80516139f16137168261421c565b80828252848201915084840188868560051b8701011115613a10578687fd5b8694505b838510156139a0578051835260019490940193918501918501613a14565b60006020808385031215613a44578182fd5b82516001600160401b0380821115613a5a578384fd5b818501915085601f830112613a6d578384fd5b8151613a7b6137168261421c565b80828252858201915085850189878560051b8801011115613a9a578788fd5b875b84811015613b0b57815186811115613ab257898afd5b8701603f81018c13613ac257898afd5b888101516040613ad46137168361423f565b8281528e82848601011115613ae7578c8dfd5b613af6838d830184870161439f565b87525050509287019290870190600101613a9c565b50909998505050505050505050565b600060208284031215613b2b578081fd5b8151801515811461286e578182fd5b600060208284031215613b4b578081fd5b5035919050565b60008060408385031215613b64578182fd5b8235915060208301356001600160401b03811115613b80578182fd5b613b8c85828601613746565b9150509250929050565b60008060008060808587031215613bab578182fd5b8435935060208501356001600160401b03811115613bc7578283fd5b613bd387828801613864565b949794965050505060408301359260600135919050565b60008060008060008060c08789031215613c02578384fd5b8635955060208701356001600160401b0380821115613c1f578586fd5b613c2b8a838b01613864565b965060408901359550606089013594506080890135915080821115613c4e578384fd5b613c5a8a838b016137e5565b935060a0890135915080821115613c6f578283fd5b50613c7c89828a016137e5565b9150509295509295509295565b600080600080600080600060e0888a031215613ca3578485fd5b8735965060208801356001600160401b0380821115613cc0578687fd5b613ccc8b838c01613864565b975060408a0135965060608a0135955060808a0135915080821115613cef578283fd5b613cfb8b838c016137e5565b945060a08a0135915080821115613d10578283fd5b613d1c8b838c016137e5565b935060c08a0135915080821115613d31578283fd5b50613d3e8a828b016137e5565b91505092959891949750929550565b60008060408385031215613d5f578182fd5b50508035926020909101359150565b600080600060608486031215613d82578081fd5b833592506020840135915060408401356001600160401b03811115613da5578182fd5b613db186828701613746565b9150509250925092565b60008060008060808587031215613dd0578182fd5b84359350602085013592506040850135915060608501356001600160401b03811115613dfa578182fd5b613e06878288016137e5565b91505092959194509250565b600060208284031215613e23578081fd5b5051919050565b600080600060608486031215613e3e578081fd5b8351925060208401519150604084015190509250925092565b600081518084526020808501808196508360051b81019150828601855b85811015613e9e578284038952613e8c848351613eab565b98850198935090840190600101613e74565b5091979650505050505050565b60008151808452613ec381602086016020860161439f565b601f01601f19169290920160200192915050565b60008251613ee981846020870161439f565b9190910192915050565b6001600160a01b0389811682526020820189905260408201889052861660608201526001600160e01b03198516608082015260a0810184905260c0810183905261010060e08201819052600090613f4c83820185613eab565b9b9a5050505050505050505050565b60018060a01b0384168152826020820152606060408201526000613f826060830184613eab565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613fc357835183529284019291840191600101613fa7565b50909695505050505050565b60208152600061286e6020830184613e57565b6020808252825182820181905260009190848201906040850190845b81811015613fc357835160ff1683529284019291840191600101613ffe565b828152604060208201526000612c756040830184613e57565b83815260606020820152600061404f6060830185613e57565b9050826040830152949350505050565b8481526080602082015260006140786080830186613e57565b6040830194909452506060015292915050565b60208152600061286e6020830184613eab565b60208082526017908201527f4d61726b6574206973206e6f7420737570706f72746564000000000000000000604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b6020808252600f908201526e43616e206e6f74206265207a65726f60881b604082015260600190565b60208082526018908201527f53706f72744964206973206e6f7420737570706f727465640000000000000000604082015260600190565b60208082526028908201527f536f75726365206d75737420626520746865206f7261636c65206f6620746865604082015267081c995c5d595cdd60c21b606082015260800190565b60208082526026908201527f4f6e6c792053706f72747320414d4d2063616e2063616c6c20746869732066756040820152653731ba34b7b760d11b606082015260800190565b604051601f8201601f191681016001600160401b038111828210171561421457614214614451565b604052919050565b60006001600160401b0382111561423557614235614451565b5060051b60200190565b60006001600160401b0382111561425857614258614451565b50601f01601f191660200190565b600082198211156142795761427961443b565b500190565b600181815b808511156142b957816000190482111561429f5761429f61443b565b808516156142ac57918102915b93841c9390800290614283565b509250929050565b600061286e83836000826142d75750600161153b565b816142e45750600061153b565b81600181146142fa576002811461430457614320565b600191505061153b565b60ff8411156143155761431561443b565b50506001821b61153b565b5060208310610133831016604e8410600b8410161715614343575081810a61153b565b61434d838361427e565b80600019048211156143615761436161443b565b029392505050565b60008160001904831182151516156143835761438361443b565b500290565b60008282101561439a5761439a61443b565b500390565b60005b838110156143ba5781810151838201526020016143a2565b83811115612d075750506000910152565b600181811c908216806143df57607f821691505b6020821081141561352e57634e487b7160e01b600052602260045260246000fd5b60006000198214156144145761441461443b565b5060010190565b60008261443657634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c9b57600080fdfe7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63aa2646970667358221220de9d06092007abc051f038721d41a100f1c5b63b3b3dac698d92a201007e483b64736f6c63430008040033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000dc2cc710e42857672e7907cf474a69b63b93089f00000000000000000000000059a3b51081a3d7e47206cec6cddc1e8c45e1c82b000000000000000000000000db6eb989127d0c33bc630d7b5b53f87ceced3ce1000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc1000032306464386137383732653434363038623864383232396365663336666236380000000000000000000000007465c5d60d3d095443cf9991da03304a30d42eae00000000000000000000000086991efb34b0cf55af38e9dace3f82cd8b70188f000000000000000000000000cefdad247275b0657b2275df05b677938dd6a43f000000000000000000000000738d5996f9e87a238ebca7352909c20ef27c54d0

-----Decoded View---------------
Arg [0] : _link (address): 0xdc2CC710e42857672E7907CF474a69B63B93089f
Arg [1] : _oracle (address): 0x59a3B51081a3d7e47206CEc6CddC1E8c45E1c82B
Arg [2] : _consumer (address): 0xdB6EB989127D0c33bC630d7b5B53f87ceCED3ce1
Arg [3] : _paymentCreate (uint256): 10000000000000000
Arg [4] : _paymentResolve (uint256): 10000000000000000
Arg [5] : _paymentOdds (uint256): 10000000000000000
Arg [6] : _oddsSpecId (bytes32): 0x3230646438613738373265343436303862386438323239636566333666623638
Arg [7] : _sportsAMM (address): 0x7465c5d60d3d095443CF9991Da03304A30D42Eae
Arg [8] : _verifier (address): 0x86991efb34B0Cf55af38E9dACE3f82CD8B70188F
Arg [9] : _playerPropsReciever (address): 0xCEfdad247275b0657b2275DF05B677938dd6a43F
Arg [10] : _playerProps (address): 0x738D5996f9E87A238EbCa7352909c20EF27c54d0

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000dc2cc710e42857672e7907cf474a69b63b93089f
Arg [1] : 00000000000000000000000059a3b51081a3d7e47206cec6cddc1e8c45e1c82b
Arg [2] : 000000000000000000000000db6eb989127d0c33bc630d7b5b53f87ceced3ce1
Arg [3] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [4] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [5] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [6] : 3230646438613738373265343436303862386438323239636566333666623638
Arg [7] : 0000000000000000000000007465c5d60d3d095443cf9991da03304a30d42eae
Arg [8] : 00000000000000000000000086991efb34b0cf55af38e9dace3f82cd8b70188f
Arg [9] : 000000000000000000000000cefdad247275b0657b2275df05b677938dd6a43f
Arg [10] : 000000000000000000000000738d5996f9e87a238ebca7352909c20ef27c54d0


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