Contract 0xf3c6bd1DE606f8Ed3b7047Be3f935efeAb6aFa38 7

 

Contract Overview

Balance:
0 ETH

ETH Value:
$0.00

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x622e5b499a0f8b926ecdc5145d4b7cf01437a988b765d0270fb2da596b8fe812Request Games Re...1349993182023-09-27 5:18:212 hrs 8 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005517 0.1
0xd235fbaacce877560364d7850dbafd0d920a9e6acde673d625373ef774e34d8cRequest Games Re...1349933122023-09-27 4:51:372 hrs 35 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00006473 0.1
0x8de58823dfe07e60df341f9db3f9d2af40a47a0ceb1693030c454baa99387a46Request Games Re...1349644882023-09-27 2:41:584 hrs 45 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005893 0.1
0xd009e84ed30dafc5592dad1e31122415cb2f916c9a53f949ef1f8d4f33789c4bRequest Games Re...1349611802023-09-27 2:27:044 hrs 59 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00006037 0.1
0xbb6c57ec7064eed52b82918e6fe3e1c760d5caeea7d7df27e016d55cba509789Request Games Re...1349578692023-09-27 2:12:105 hrs 14 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005488 0.1
0x1a12f522d5831baf4d150047068c5920701791590f7b7d0f568b30093c3f6182Request Games Re...1349520632023-09-27 1:45:475 hrs 41 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.000065 0.1
0x2d6351eddab68d96e2aa28787789b25e3cb227435ad9aedd94880436fbffa99aRequest Games Re...1349488942023-09-27 1:30:565 hrs 56 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005393 0.1
0xa9ff6b1aed10e7c5cc8c097547da50404d8743bc410e0f00903d2d451ae2688fRequest Games Re...1349458042023-09-27 1:16:046 hrs 10 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00006387 0.1
0x631e07bce22ed01cd2a5d9529910622f38bcb002819a980e570b83af8b18b6bcRequest Games Re...1349377152023-09-27 0:38:006 hrs 49 mins ago0x1580d13d37daa6a412fa6e31e04f30c85279783f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005688 0.1
0x212c87db935cb227a4f48cc76b55c78eafa42b1e5c35e256c7275f1d5502452dRequest Games Re...1349339622023-09-27 0:19:537 hrs 7 mins ago0x8b7eb9ca240a317078b5c15a118399f086f6d8bf IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005764 0.1
0x5c9d4b261eda04c301ea31b50f5beca712c75a64a3d99a0209b16e59212419e0Request Games Re...1349339052023-09-27 0:19:387 hrs 7 mins ago0x8b7eb9ca240a317078b5c15a118399f086f6d8bf IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005834 0.1
0xf89979bedbecb4ce9266da92ea005af9585b22cc85035c571b6a49fe63cfaa84Request Games Re...1349338002023-09-27 0:19:067 hrs 7 mins ago0x8b7eb9ca240a317078b5c15a118399f086f6d8bf IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005824 0.1
0x59509d6d00a737b594a4c8ab2b3099444f607e38c968010ddf0557aafe11a8f9Request Games Re...1349335542023-09-27 0:17:577 hrs 9 mins ago0x8b7eb9ca240a317078b5c15a118399f086f6d8bf IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00006145 0.1
0x887eb9e5b266998373dc969dc11de479788ef2ae636a3fbd62bf91b7242ad6aaRequest Games Re...1349081962023-09-26 22:19:329 hrs 7 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00008866 0.1
0x2bc3df5896cab4d502b4b761e40315a4ed05865349af28e25fb1d0c78ca2f805Request Games Re...1349057522023-09-26 22:08:179 hrs 18 mins ago0x8b7eb9ca240a317078b5c15a118399f086f6d8bf IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00016079 0.1
0x8f1ee83cf3f903b6aa4a055b1f52f4cb467484146f87fa52a695968ec209009aRequest Games Re...1349001562023-09-26 21:42:119 hrs 44 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00008561 0.1
0x92ae8fcb70f2addcbe65e02ce9f23f9013ffbfbb1b94492413f10f2eb6c09a2cRequest Games Re...1348918432023-09-26 21:04:3110 hrs 22 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.0000859 0.1
0x1b4065f322e8eceb323bf191784dee4ed4b0f5db0e0ea7b747b20da91f554b6eRequest Games Re...1348886172023-09-26 20:50:0610 hrs 36 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00008311 0.1
0xc31565dcbb39e9a4cf299aef59952ab2a6d34d95745801be4f4fed4139cac7b3Request Games Re...1348648522023-09-26 19:03:2812 hrs 23 mins ago0xe74b3abc6e67dd1f568720e0288fff7d28ea675f IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00014449 0.1
0x17aa8a0c7f8e6f2dba17e03ed70c7e6b9f2ffc8eb22454b5b27b6b4332705571Request Games Re...1347182262023-09-26 8:22:0723 hrs 4 mins ago0x89135d0598596cf676618eb9dfa2ea68fe5086a7 IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00007161 0.1
0x9c8f2883d1b3e641dcfd18afe7bd6169ed60475fe3ab7caa35c7f1e8fc2559feRequest Player P...1347077662023-09-26 7:37:5523 hrs 49 mins ago0xc1dc482a46db8a7c9f3eb599ca70143605bef97e IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00008002 0.1
0xae4af0ef06228690d615d0093d694df0fde57c9ba733e41efc0fe66923fbd500Request Player P...1347077292023-09-26 7:37:4623 hrs 49 mins ago0xc1dc482a46db8a7c9f3eb599ca70143605bef97e IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.0000811 0.1
0xe4b4324af86b79b82aa25cec38e6e35a0ed4a5886b1717caad487a16d11bb047Request Player P...1347076982023-09-26 7:37:3823 hrs 49 mins ago0xc1dc482a46db8a7c9f3eb599ca70143605bef97e IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00008034 0.1
0xe9016515ec0168881de85dd35c50b6c45e9f53133c424b59cb5e60b6627f2b6dRequest Games Re...1346797372023-09-26 5:40:051 day 1 hr ago0x8b7eb9ca240a317078b5c15a118399f086f6d8bf IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.0000552 0.1
0xe813fe4ace5f68dd7c48cd73fe5b3f2b497cdd384642fd5a3677be9ca2758bfaRequest Games Re...1346796852023-09-26 5:39:511 day 1 hr ago0x8b7eb9ca240a317078b5c15a118399f086f6d8bf IN  0xf3c6bd1de606f8ed3b7047be3f935efeab6afa380 ETH0.00005558 0.1
[ 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"}]

608060405260016004553480156200001657600080fd5b506040516200472538038062004725833981016040819052620000399162000185565b620000443362000116565b6006805460ff60a01b19169055600280546001600160a01b0319166001600160a01b038d16179055600380546001600160a01b0319166001600160a01b038c16179055600780546001600160a01b03199081166001600160a01b039b8c1617909155600d98909855600e96909655600f94909455601080548716998816999099179098556011919091556013805485169186169190911790556008805484169685169690961790955560098054831695841695909517909455600a805490911693909116929092179091555062000243565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200018057600080fd5b919050565b60008060008060008060008060008060006101608c8e031215620001a7578687fd5b620001b28c62000168565b9a50620001c260208d0162000168565b9950620001d260408d0162000168565b985060608c0151975060808c0151965060a08c0151955060c08c01519450620001fe60e08d0162000168565b93506200020f6101008d0162000168565b9250620002206101208d0162000168565b9150620002316101408d0162000168565b90509295989b509295989b9093969950565b6144d280620002536000396000f3fe608060405234801561001057600080fd5b50600436106103995760003560e01c80637daaa7ff116101e9578063abe025c21161010f578063c7f70079116100ad578063e34077701161007c578063e340777014610822578063eb83f34a14610835578063efccb47a14610848578063f2fde38b1461085b57600080fd5b8063c7f70079146107d6578063c9925288146107e9578063d8033ef1146107fc578063db8f6ef71461080f57600080fd5b8063b4fd7296116100e9578063b4fd72961461078a578063bd7dcd221461079d578063bf62086f146107b0578063c475e0b3146107c357600080fd5b8063abe025c21461075c578063affa98d11461076f578063b18b78dd1461078257600080fd5b806392e889da116101875780639a066f5d116101565780639a066f5d1461070a5780639a2a8aa11461071d5780639c5481b514610740578063a1b778b61461074957600080fd5b806392e889da146106c857806394547fcc146106db578063977a6449146106ee57806399d9f2b9146106f757600080fd5b80638b2a4364116101c35780638b2a4364146106785780638bd6e4c91461068b5780638da5cb5b146106ae57806390c6fb27146106bf57600080fd5b80637daaa7ff146106395780637f6fd1401461064257806380a743751461065557600080fd5b806350b18b28116102ce5780635c975abb1161026c57806373f457b01161023b57806373f457b0146105ed57806375863da6146106005780637adbf973146106135780637b81c28c1461062657600080fd5b80635c975abb146105ad5780635d7fb8e2146105bf57806363a579d5146105d2578063715018a6146105e557600080fd5b806356b78887116102a857806356b788871461053157806357970e931461056457806359aeaada146105775780635b4f9d9b1461059a57600080fd5b806350b18b28146104eb57806351864c0c146104fe5780635437988d1461051e57600080fd5b806336661e1a1161033b578063436d765a11610315578063436d765a14610492578063451b57d5146104a557806346c92c58146104b857806346e38c28146104cb57600080fd5b806336661e1a146104595780633ca672f21461046c5780633eda5fcb1461047f57600080fd5b806310fe9ae81161037757806310fe9ae8146103ef578063282e9a1f1461040f5780632b7ac3f31461043d5780632bd13da11461045057600080fd5b806301e41efa1461039e578063029a39cd146103b35780630312eb35146103c6575b600080fd5b6103b16103ac366004613dbb565b61086e565b005b6103b16103c1366004613883565b6109f1565b6103d96103d4366004613d4d565b610c9e565b6040516103e6919061408b565b60405180910390f35b6103f7610d57565b6040516001600160a01b0390911681526020016103e6565b61042f61041d366004613b3a565b600c6020526000908152604090205481565b6040519081526020016103e6565b6008546103f7906001600160a01b031681565b61042f600d5481565b6103b1610467366004613b96565b610d70565b6103b161047a366004613bea565b611005565b6103b161048d366004613b3a565b6112f2565b6103d96104a0366004613d4d565b611356565b6103b16104b3366004613b52565b611372565b6103b16104c6366004613b3a565b61147c565b6104de6104d9366004613b3a565b6114b9565b6040516103e69190613f8b565b6103b16104f9366004613883565b611541565b61042f61050c366004613b3a565b600b6020526000908152604090205481565b6103b161052c366004613883565b6115bd565b61055461053f366004613b3a565b601c6020526000908152604090205460ff1681565b60405190151581526020016103e6565b6010546103f7906001600160a01b031681565b610554610585366004613b3a565b601d6020526000908152604090205460ff1681565b6103b16105a836600461389f565b611639565b600654600160a01b900460ff16610554565b600a546103f7906001600160a01b031681565b6103b16105e0366004613883565b61165c565b6103b16116d8565b6103b16105fb366004613d6e565b6116ec565b6103b161060e366004613c89565b611818565b6103b1610621366004613883565b611abb565b61055461063436600461391a565b611b3d565b61042f600f5481565b6103b1610650366004613d6e565b611bb4565b610554610663366004613b3a565b601a6020526000908152604090205460ff1681565b6103b1610686366004613b3a565b611c9f565b610554610699366004613b3a565b601b6020526000908152604090205460ff1681565b6006546001600160a01b03166103f7565b61042f60115481565b6105546106d636600461391a565b611cdc565b6103b16106e9366004613883565b611d4a565b61042f600e5481565b6104de610705366004613b3a565b611de1565b6103b1610718366004613883565b611e13565b61055461072b366004613b3a565b601e6020526000908152604090205460ff1681565b61042f60125481565b6103b1610757366004613883565b611e8f565b6103b161076a366004613b52565b611f0b565b6103b161077d366004613b3a565b611fde565b6103f761203b565b6007546103f7906001600160a01b031681565b6103d96107ab366004613d4d565b61204f565b6103b16107be366004613b3a565b61206b565b6103d96107d1366004613d4d565b6120c8565b6103b16107e4366004613d6e565b6120e4565b6013546103f7906001600160a01b031681565b61055461080a36600461391a565b6121c6565b61055461081d36600461391a565b612234565b6009546103f7906001600160a01b031681565b6103b1610843366004613883565b6122a2565b6103d9610856366004613d4d565b61276f565b6103b1610869366004613883565b61278b565b610876612801565b6007546040516334d2a49760e11b8152600481018590526001600160a01b03909116906369a5492e9060240160206040518083038186803b1580156108ba57600080fd5b505afa1580156108ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f29190613b1a565b6109175760405162461bcd60e51b815260040161090e90614127565b60405180910390fd5b600061092b853063c7f7007960e01b61284e565b6040805180820190915260048152636461746560e01b602082015290915061095590829085612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261097f90829086612875565b8151156109b05760408051808201909152600781526667616d6549647360c81b60208201526109b090829084612898565b6109bc33600f5461291e565b60006109ca82600f54612936565b6000908152600b6020908152604080832097909755600c9052949094209290925550505050565b6109f9612801565b6013546001600160a01b03163314610a235760405162461bcd60e51b815260040161090e906141a6565b600f546010546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610a6957600080fd5b505afa158015610a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa19190613e12565b10610c9b576007546040516356e4194d60e01b81526001600160a01b03838116600483015260009283929116906356e4194d9060240160606040518083038186803b158015610aef57600080fd5b505afa158015610b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b279190613e2a565b5060075460405163a50267a560e01b815260048101849052602481018390529294509092506000916001600160a01b039091169063a50267a59060440160006040518083038186803b158015610b7c57600080fd5b505afa158015610b90573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bb891908101906139ac565b601154600854604051630574513160e11b8152929350610c4f92869186916001600160a01b0390911690630ae8a26290610bf6908890600401613f8b565b60006040518083038186803b158015610c0e57600080fd5b505afa158015610c22573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c4a9190810190613a32565b612950565b60408051848152602081018490526001600160a01b0386168183015290517f7c7905e4aa6d903c8f8e60c93891dbf754e35cae604e0fecb08d8ca45ffb91fa9181900360600190a15050505b50565b60196020528160005260406000208181548110610cba57600080fd5b90600052602060002001600091509150508054610cd6906143cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610d02906143cb565b8015610d4f5780601f10610d2457610100808354040283529160200191610d4f565b820191906000526020600020905b815481529060010190602001808311610d3257829003601f168201915b505050505081565b6000610d6b6002546001600160a01b031690565b905090565b610d78612801565b60085460405163645de6cb60e11b8152849184916001600160a01b039091169063c8bbcd9690610dac90859060040161408b565b60206040518083038186803b158015610dc457600080fd5b505afa158015610dd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfc9190613b1a565b610e185760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b158015610e5c57600080fd5b505afa158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e949190613b1a565b610eb05760405162461bcd60e51b815260040161090e90614127565b610eb8613584565b6040516563726561746560d01b60208201526000906026016040516020818303038152906040528051906020012087604051602001610ef79190613ed7565b604051602081830303815290604052805190602001201415610f3157610f25883063073f457b60e41b61284e565b9150600d549050610f4b565b610f4388306301fdbf4560e61b61284e565b9150600e5490505b6040805180820190915260048152636461746560e01b6020820152610f7290839087612875565b6040805180820190915260068152651b585c9ad95d60d21b6020820152610f9b908390896129e9565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152610fc590839088612875565b610fcf338261291e565b6000610fdb8383612936565b6000908152600b6020908152604080832099909955600c9052969096209490945550505050505050565b61100d612801565b60085460405163645de6cb60e11b8152869186916001600160a01b039091169063c8bbcd969061104190859060040161408b565b60206040518083038186803b15801561105957600080fd5b505afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190613b1a565b6110ad5760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b1580156110f157600080fd5b505afa158015611105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111299190613b1a565b6111455760405162461bcd60e51b815260040161090e90614127565b61114d613584565b6040516563726561746560d01b6020820152600090602601604051602081830303815290604052805190602001208960405160200161118c9190613ed7565b6040516020818303038152906040528051906020012014156111c6576111ba8a3063073f457b60e41b61284e565b9150600d5490506111e0565b6111d88a306301fdbf4560e61b61284e565b9150600e5490505b6040805180820190915260048152636461746560e01b602082015261120790839089612875565b6040805180820190915260068152651b585c9ad95d60d21b60208201526112309083908b6129e9565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261125a9083908a612875565b60408051808201909152600981526873746174757349647360b81b602082015261128690839088612898565b60408051808201909152600781526667616d6549647360c81b60208201526112b090839087612898565b6112ba338261291e565b60006112c68383612936565b6000908152600b602090815260408083209b909b55600c90529890982096909655505050505050505050565b6112fa612a07565b6000811161131a5760405162461bcd60e51b815260040161090e906140fe565b600f8190556040518181527f523e038e803877ea42acb6426444bcd23d2bbf31ad9f41ea0991762c20ee6d14906020015b60405180910390a150565b60156020528160005260406000208181548110610cba57600080fd5b60008281526005602052604090205482906001600160a01b031633146113aa5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a2600083815260186020908152604090912083516113fa928501906135bf565b506000838152601d602052604090819020805460ff191660011790556009549051630b0c3d6b60e11b81526001600160a01b03909116906316187ad690611445908590600401613fcf565b600060405180830381600087803b15801561145f57600080fd5b505af1158015611473573d6000803e3d6000fd5b50505050505050565b611484612a07565b60128190556040518181527f633028df9cc13b2f152a25567a61148994bd27575fed48eabdffaa626cac8fae9060200161134b565b6008546040516308dc718560e31b8152600481018390526060916001600160a01b0316906346e38c28906024015b60006040518083038186803b1580156114ff57600080fd5b505afa158015611513573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261153b91908101906139ac565b92915050565b611549612a07565b6001600160a01b03811661156f5760405162461bcd60e51b815260040161090e906140d5565b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527f39230f38176805abdd7f21682a360b20f3fc0b6123eb928ee222adf3b3f9e8d89060200161134b565b6115c5612a07565b6001600160a01b0381166115eb5760405162461bcd60e51b815260040161090e906140d5565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527fa1fd6a6669acb930bae242943bb9fa08ddcba665c707261e9730ee0305fb85e59060200161134b565b611641612a07565b601054611658906001600160a01b03168383612a61565b5050565b611664612a07565b6001600160a01b03811661168a5760405162461bcd60e51b815260040161090e906140d5565b600780546001600160a01b0319166001600160a01b0383169081179091556040519081527f96e60d35957ee680a1536282a3d7e57e96e55cf15f3fc5997088c2b07f411f949060200161134b565b6116e0612a07565b6116ea6000612ac4565b565b60008381526005602052604090205483906001600160a01b031633146117245760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008481526014602090815260409091208351611774928501906135bf565b506000848152601a60209081526040808320805460ff1916600117905560178252808320869055600754600b835281842054600c9093529281902054905163a400a89160e01b81526001600160a01b039093169263a400a891926117e09289928892919060040161405f565b600060405180830381600087803b1580156117fa57600080fd5b505af115801561180e573d6000803e3d6000fd5b5050505050505050565b611820612801565b60085460405163645de6cb60e11b8152879186916001600160a01b039091169063c8bbcd969061185490859060040161408b565b60206040518083038186803b15801561186c57600080fd5b505afa158015611880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a49190613b1a565b6118c05760405162461bcd60e51b815260040161090e9061409e565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b15801561190457600080fd5b505afa158015611918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193c9190613b1a565b6119585760405162461bcd60e51b815260040161090e90614127565b611960613584565b60006119748b3063451b57d560e01b61284e565b600e546040805180820190915260068152651b585c9ad95d60d21b602082015291935091506119a59083908c6129e9565b6040805180820190915260048152636461746560e01b60208201526119cc9083908b612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b60208201526119f69083908a612875565b60408051808201909152600781526667616d6549647360c81b6020820152611a2090839089612898565b604080518082019091526009815268706c6179657249647360b81b6020820152611a4c90839088612898565b6040805180820190915260098152686f7074696f6e49647360b81b6020820152611a7890839087612898565b611a82338261291e565b6000611a8e8383612936565b6000908152600b602090815260408083209b909b55600c9052989098209890985550505050505050505050565b611ac3612a07565b6001600160a01b038116611ae95760405162461bcd60e51b815260040161090e906140d5565b600380546001600160a01b0319166001600160a01b0383161790556040516001600160a01b03821681527f83b00e25c000adada62072ff4992b6702b635a6e3d57e135bbd60a01be113ead9060200161134b565b6000805b8251811015611bab57601d6000848381518110611b6e57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611b995750600092915050565b80611ba381614400565b915050611b41565b50600192915050565b60008381526005602052604090205483906001600160a01b03163314611bec5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008481526015602090815260409091208351611c3c928501906135bf565b506000848152601b60209081526040808320805460ff1916600117905560178252808320869055600754600b90925291829020549151632f73199d60e01b81526001600160a01b0390911691632f73199d916117e0918891879190600401614036565b611ca7612a07565b60118190556040518181527fa9654d85422e4e0fb6544086f22f928d2d39fe8ab1c13ee9636c64cbdcf99fcb9060200161134b565b6000805b8251811015611bab57601c6000848381518110611d0d57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611d385750600092915050565b80611d4281614400565b915050611ce0565b611d52612a07565b6001600160a01b038116611d785760405162461bcd60e51b815260040161090e906140d5565b600280546001600160a01b0319166001600160a01b038316179055601080546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f0a79df54a5f0809c9853241a307e8bf1dfe87ad5323398cc566df6e34705999060200161134b565b6008546040516399d9f2b960e01b8152600481018390526060916001600160a01b0316906399d9f2b9906024016114e7565b611e1b612a07565b6001600160a01b038116611e415760405162461bcd60e51b815260040161090e906140d5565b600a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f23041e186c2c775aca744354ade0052500ac68eff5afc82d66f6146257b037979060200161134b565b611e97612a07565b6001600160a01b038116611ebd5760405162461bcd60e51b815260040161090e906140d5565b601380546001600160a01b0319166001600160a01b0383169081179091556040519081527f3a310361002138b9ae7ac040259a1e871d3263696335223ddf2dc1af218a222b9060200161134b565b60008281526005602052604090205482906001600160a01b03163314611f435760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a260008381526019602090815260409091208351611f93928501906135bf565b506000838152601e602052604090819020805460ff19166001179055600954905163c1a0e03b60e01b81526001600160a01b039091169063c1a0e03b90611445908590600401613fcf565b611fe6612a07565b600081116120065760405162461bcd60e51b815260040161090e906140fe565b600d8190556040518181527f29a88aaedea4371894af2af86b4d24f2cfcbb494532f46b5b761cbc4cc5ff2a39060200161134b565b6000610d6b6003546001600160a01b031690565b60186020528160005260406000208181548110610cba57600080fd5b612073612a07565b600081116120935760405162461bcd60e51b815260040161090e906140fe565b600e8190556040518181527f2e959719b856a4dda43c92d8d13eb48b37668b25366584f6167cf86b653df9f69060200161134b565b60146020528160005260406000208181548110610cba57600080fd5b60008381526005602052604090205483906001600160a01b0316331461211c5760405162461bcd60e51b815260040161090e9061415e565b60008181526005602052604080822080546001600160a01b031916905551829160008051602061447d83398151915291a26000848152601660209081526040909120835161216c928501906135bf565b506000848152601760209081526040808320869055601c90915290819020805460ff191660011790556007549051631ecbaea760e11b81526001600160a01b0390911690633d975d4e906117e0908790869060040161401d565b6000805b8251811015611bab57601a60008483815181106121f757634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166122225750600092915050565b8061222c81614400565b9150506121ca565b6000805b8251811015611bab57601b600084838151811061226557634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166122905750600092915050565b8061229a81614400565b915050612238565b6122aa612801565b6013546001600160a01b031633146122d45760405162461bcd60e51b815260040161090e906141a6565b600f546010546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561231a57600080fd5b505afa15801561232e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123529190613e12565b10610c9b57600a5460405163469be85960e11b81526001600160a01b0383811660048301526000928392839283921690638d37d0b29060240160806040518083038186803b1580156123a357600080fd5b505afa1580156123b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123db91906138ca565b60408051600180825281830190925294985092965090945092506000919060208083019080368337019050509050838160008151811061242b57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050838160008151811061247c57634e487b7160e01b600052603260045260246000fd5b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905083816000815181106124cd57634e487b7160e01b600052603260045260246000fd5b60ff92909216602092830291909101909101526007546040516356e4194d60e01b81526001600160a01b03898116600483015260009283929116906356e4194d9060240160606040518083038186803b15801561252957600080fd5b505afa15801561253d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125619190613e2a565b50601254600854604051630574513160e11b8152939550919350612704929091859185916001600160a01b031690630ae8a262906125a3908c90600401613f8b565b60006040518083038186803b1580156125bb57600080fd5b505afa1580156125cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125f79190810190613a32565b600854604051630574513160e11b81526001600160a01b0390911690630ae8a26290612627908c90600401613f8b565b60006040518083038186803b15801561263f57600080fd5b505afa158015612653573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261267b9190810190613a32565b600854604051636d2dc16960e11b81526001600160a01b039091169063da5b82d2906126ab908c90600401613fe2565b60006040518083038186803b1580156126c357600080fd5b505afa1580156126d7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126ff9190810190613a32565b612b16565b60408051838152602081018390526001600160a01b038c1681830152606081018a90526080810189905260ff881660a082015290517f77340c5b6a25fac6af6f39892ff7da024bcbbda96d7b58bd30d512dd7284925b9181900360c00190a150505050505050505050565b60166020528160005260406000208181548110610cba57600080fd5b612793612a07565b6001600160a01b0381166127f85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161090e565b610c9b81612ac4565b600654600160a01b900460ff16156116ea5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161090e565b612856613584565b61285e613584565b61286a81868686612c37565b9150505b9392505050565b60808301516128849083612c7d565b60808301516128939082612c94565b505050565b60808301516128a79083612c7d565b6128b48360800151612cb9565b60005b8151811015612910576128fe8282815181106128e357634e487b7160e01b600052603260045260246000fd5b60200260200101518560800151612c7d90919063ffffffff16565b8061290881614400565b9150506128b7565b506128938360800151612cc4565b601054611658906001600160a01b0316833084612ccf565b60035460009061286e906001600160a01b03168484612d0d565b6000612964853063c7f7007960e01b61284e565b6040805180820190915260048152636461746560e01b602082015290915061298e90829085612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b60208201526129b890829086612875565b8151156109bc5760408051808201909152600781526667616d6549647360c81b60208201526109bc90829084612898565b60808301516129f89083612c7d565b60808301516128939082612c7d565b6006546001600160a01b031633146116ea5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090e565b6040516001600160a01b03831660248201526044810182905261289390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612da0565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000612b2a87306355f012e160e11b61284e565b6040805180820190915260048152636461746560e01b6020820152909150612b5490829087612875565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152612b7e90829088612875565b60408051808201909152600781526667616d6549647360c81b6020820152612ba890829086612898565b604080518082019091526009815268706c6179657249647360b81b6020820152612bd490829085612898565b6040805180820190915260098152686f7074696f6e49647360b81b6020820152612c0090829084612898565b6000612c0e82600f54612936565b6000908152600b6020908152604080832099909955600c90529690962094909455505050505050565b612c3f613584565b612c4f8560800151610100612e72565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b612c8a8260038351612ed7565b6128938282612fde565b6001600160401b03811115612cad576116588282613005565b61165882600083612ed7565b610c9b81600461303c565b610c9b81600761303c565b6040516001600160a01b0380851660248301528316604482015260648101829052612d079085906323b872dd60e01b90608401612a8d565b50505050565b600454600090612d1e816001614266565b600455835160408086015160808701515191516000936320214ca360e11b93612d569386938493923092918a91600191602401613ef3565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050612d9686838684613051565b9695505050505050565b6000612df5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131be9092919063ffffffff16565b8051909150156128935780806020019051810190612e139190613b1a565b6128935760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161090e565b604080518082019091526060815260006020820152612e9260208361441b565b15612eba57612ea260208361441b565b612ead906020614388565b612eb79083614266565b91505b506020828101829052604080518085526000815290920101905290565b6017816001600160401b031611612efb57612d078360e0600585901b1683176131cd565b60ff816001600160401b031611612f3757612f21836018611fe0600586901b16176131cd565b50612d07836001600160401b03831660016131f2565b61ffff816001600160401b031611612f7457612f5e836019611fe0600586901b16176131cd565b50612d07836001600160401b03831660026131f2565b63ffffffff816001600160401b031611612fb357612f9d83601a611fe0600586901b16176131cd565b50612d07836001600160401b03831660046131f2565b612fc883601b611fe0600586901b16176131cd565b50612d07836001600160401b03831660086131f2565b60408051808201909152606081526000602082015261286e83846000015151848551613218565b6130108260c26131cd565b50611658828260405160200161302891815260200190565b604051602081830303815290604052613302565b61289382601f611fe0600585901b16176131cd565b6040516bffffffffffffffffffffffff193060601b1660208201526034810184905260009060540160408051808303601f1901815282825280516020918201206000818152600590925291812080546001600160a01b0319166001600160a01b038a1617905590925082917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af99190a2600254604051630200057560e51b81526001600160a01b0390911690634000aea09061311490889087908790600401613f5b565b602060405180830381600087803b15801561312e57600080fd5b505af1158015613142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131669190613b1a565b612c755760405162461bcd60e51b815260206004820152602360248201527f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261604482015262636c6560e81b606482015260840161090e565b6060612c75848460008561330f565b60408051808201909152606081526000602082015261286e8384600001515184613440565b604080518082019091526060815260006020820152612c7584856000015151858561349c565b604080518082019091526060815260006020820152825182111561323b57600080fd5b602085015161324a8386614266565b111561327d5761327d8561326d876020015187866132689190614266565b61351d565b613278906002614369565b613534565b60008086518051876020830101935080888701111561329c5787860182525b505050602084015b602084106132dc57805182526132bb602083614266565b91506132c8602082614266565b90506132d5602085614388565b93506132a4565b51815160001960208690036101000a019081169019919091161790525083949350505050565b612c8a8260028351612ed7565b6060824710156133705760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161090e565b6001600160a01b0385163b6133c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161090e565b600080866001600160a01b031685876040516133e39190613ed7565b60006040518083038185875af1925050503d8060008114613420576040519150601f19603f3d011682016040523d82523d6000602084013e613425565b606091505b509150915061343582828661354b565b979650505050505050565b604080518082019091526060815260006020820152836020015183106134755761347584856020015160026132789190614369565b835180516020858301018481535080851415613492576001810182525b5093949350505050565b60408051808201909152606081526000602082015260208501516134c08584614266565b11156134d4576134d48561326d8685614266565b600060016134e4846101006142c1565b6134ee9190614388565b90508551838682010185831982511617815250805184870111156135125783860181525b509495945050505050565b60008183111561352e57508161153b565b50919050565b81516135408383612e72565b50612d078382612fde565b6060831561355a57508161286e565b82511561356a5782518084602001fd5b8160405162461bcd60e51b815260040161090e919061408b565b6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b82805482825590600052602060002090810192821561360c579160200282015b8281111561360c57825180516135fc91849160209091019061361c565b50916020019190600101906135df565b5061361892915061369c565b5090565b828054613628906143cb565b90600052602060002090601f01602090048101928261364a5760008555613690565b82601f1061366357805160ff1916838001178555613690565b82800160010185558215613690579182015b82811115613690578251825591602001919060010190613675565b506136189291506136b9565b808211156136185760006136b082826136ce565b5060010161369c565b5b8082111561361857600081556001016136ba565b5080546136da906143cb565b6000825580601f106136ea575050565b601f016020900490600052602060002090810190610c9b91906136b9565b600061371b6137168461423f565b6141ec565b905082815283838301111561372f57600080fd5b828260208301376000602084830101529392505050565b600082601f830112613756578081fd5b813560206137666137168361421c565b80838252828201915082860187848660051b8901011115613785578586fd5b855b858110156137d85781356001600160401b038111156137a4578788fd5b8801603f81018a136137b4578788fd5b6137c58a8783013560408401613708565b8552509284019290840190600101613787565b5090979650505050505050565b600082601f8301126137f5578081fd5b813560206138056137168361421c565b80838252828201915082860187848660051b8901011115613824578586fd5b855b858110156137d85781356001600160401b03811115613843578788fd5b6138518a87838c0101613864565b8552509284019290840190600101613826565b600082601f830112613874578081fd5b61286e83833560208501613708565b600060208284031215613894578081fd5b813561286e81614467565b600080604083850312156138b1578081fd5b82356138bc81614467565b946020939093013593505050565b600080600080608085870312156138df578182fd5b84516138ea81614467565b809450506020850151925060408501519150606085015160ff8116811461390f578182fd5b939692955090935050565b6000602080838503121561392c578182fd5b82356001600160401b03811115613941578283fd5b8301601f81018513613951578283fd5b803561395f6137168261421c565b80828252848201915084840188868560051b870101111561397e578687fd5b8694505b838510156139a0578035835260019490940193918501918501613982565b50979650505050505050565b600060208083850312156139be578182fd5b82516001600160401b038111156139d3578283fd5b8301601f810185136139e3578283fd5b80516139f16137168261421c565b80828252848201915084840188868560051b8701011115613a10578687fd5b8694505b838510156139a0578051835260019490940193918501918501613a14565b60006020808385031215613a44578182fd5b82516001600160401b0380821115613a5a578384fd5b818501915085601f830112613a6d578384fd5b8151613a7b6137168261421c565b80828252858201915085850189878560051b8801011115613a9a578788fd5b875b84811015613b0b57815186811115613ab257898afd5b8701603f81018c13613ac257898afd5b888101516040613ad46137168361423f565b8281528e82848601011115613ae7578c8dfd5b613af6838d830184870161439f565b87525050509287019290870190600101613a9c565b50909998505050505050505050565b600060208284031215613b2b578081fd5b8151801515811461286e578182fd5b600060208284031215613b4b578081fd5b5035919050565b60008060408385031215613b64578182fd5b8235915060208301356001600160401b03811115613b80578182fd5b613b8c85828601613746565b9150509250929050565b60008060008060808587031215613bab578182fd5b8435935060208501356001600160401b03811115613bc7578283fd5b613bd387828801613864565b949794965050505060408301359260600135919050565b60008060008060008060c08789031215613c02578384fd5b8635955060208701356001600160401b0380821115613c1f578586fd5b613c2b8a838b01613864565b965060408901359550606089013594506080890135915080821115613c4e578384fd5b613c5a8a838b016137e5565b935060a0890135915080821115613c6f578283fd5b50613c7c89828a016137e5565b9150509295509295509295565b600080600080600080600060e0888a031215613ca3578485fd5b8735965060208801356001600160401b0380821115613cc0578687fd5b613ccc8b838c01613864565b975060408a0135965060608a0135955060808a0135915080821115613cef578283fd5b613cfb8b838c016137e5565b945060a08a0135915080821115613d10578283fd5b613d1c8b838c016137e5565b935060c08a0135915080821115613d31578283fd5b50613d3e8a828b016137e5565b91505092959891949750929550565b60008060408385031215613d5f578182fd5b50508035926020909101359150565b600080600060608486031215613d82578081fd5b833592506020840135915060408401356001600160401b03811115613da5578182fd5b613db186828701613746565b9150509250925092565b60008060008060808587031215613dd0578182fd5b84359350602085013592506040850135915060608501356001600160401b03811115613dfa578182fd5b613e06878288016137e5565b91505092959194509250565b600060208284031215613e23578081fd5b5051919050565b600080600060608486031215613e3e578081fd5b8351925060208401519150604084015190509250925092565b600081518084526020808501808196508360051b81019150828601855b85811015613e9e578284038952613e8c848351613eab565b98850198935090840190600101613e74565b5091979650505050505050565b60008151808452613ec381602086016020860161439f565b601f01601f19169290920160200192915050565b60008251613ee981846020870161439f565b9190910192915050565b6001600160a01b0389811682526020820189905260408201889052861660608201526001600160e01b03198516608082015260a0810184905260c0810183905261010060e08201819052600090613f4c83820185613eab565b9b9a5050505050505050505050565b60018060a01b0384168152826020820152606060408201526000613f826060830184613eab565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613fc357835183529284019291840191600101613fa7565b50909695505050505050565b60208152600061286e6020830184613e57565b6020808252825182820181905260009190848201906040850190845b81811015613fc357835160ff1683529284019291840191600101613ffe565b828152604060208201526000612c756040830184613e57565b83815260606020820152600061404f6060830185613e57565b9050826040830152949350505050565b8481526080602082015260006140786080830186613e57565b6040830194909452506060015292915050565b60208152600061286e6020830184613eab565b60208082526017908201527f4d61726b6574206973206e6f7420737570706f72746564000000000000000000604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b6020808252600f908201526e43616e206e6f74206265207a65726f60881b604082015260600190565b60208082526018908201527f53706f72744964206973206e6f7420737570706f727465640000000000000000604082015260600190565b60208082526028908201527f536f75726365206d75737420626520746865206f7261636c65206f6620746865604082015267081c995c5d595cdd60c21b606082015260800190565b60208082526026908201527f4f6e6c792053706f72747320414d4d2063616e2063616c6c20746869732066756040820152653731ba34b7b760d11b606082015260800190565b604051601f8201601f191681016001600160401b038111828210171561421457614214614451565b604052919050565b60006001600160401b0382111561423557614235614451565b5060051b60200190565b60006001600160401b0382111561425857614258614451565b50601f01601f191660200190565b600082198211156142795761427961443b565b500190565b600181815b808511156142b957816000190482111561429f5761429f61443b565b808516156142ac57918102915b93841c9390800290614283565b509250929050565b600061286e83836000826142d75750600161153b565b816142e45750600061153b565b81600181146142fa576002811461430457614320565b600191505061153b565b60ff8411156143155761431561443b565b50506001821b61153b565b5060208310610133831016604e8410600b8410161715614343575081810a61153b565b61434d838361427e565b80600019048211156143615761436161443b565b029392505050565b60008160001904831182151516156143835761438361443b565b500290565b60008282101561439a5761439a61443b565b500390565b60005b838110156143ba5781810151838201526020016143a2565b83811115612d075750506000910152565b600181811c908216806143df57607f821691505b6020821081141561352e57634e487b7160e01b600052602260045260246000fd5b60006000198214156144145761441461443b565b5060010190565b60008261443657634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c9b57600080fdfe7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63aa2646970667358221220de9d06092007abc051f038721d41a100f1c5b63b3b3dac698d92a201007e483b64736f6c63430008040033000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb40000000000000000000000001fb5081677b453c8fbc4946da3a9751df590dfe10000000000000000000000000abdaf0c4cff91f96f817809d4735929fca75b80000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc100003230646438613738373265343436303862386438323239636566333666623638000000000000000000000000ae56177e405929c95e5d4b04c0c87e428cb6432b0000000000000000000000000b13071b5f3f860f4d52c836d898a79fe104c9b40000000000000000000000005311ef5370eaf6eb428dd4ea556aa3461269aee0000000000000000000000000da835388e4f17701e352390778f9b4e2f96ad049

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

000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb40000000000000000000000001fb5081677b453c8fbc4946da3a9751df590dfe10000000000000000000000000abdaf0c4cff91f96f817809d4735929fca75b80000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc100003230646438613738373265343436303862386438323239636566333666623638000000000000000000000000ae56177e405929c95e5d4b04c0c87e428cb6432b0000000000000000000000000b13071b5f3f860f4d52c836d898a79fe104c9b40000000000000000000000005311ef5370eaf6eb428dd4ea556aa3461269aee0000000000000000000000000da835388e4f17701e352390778f9b4e2f96ad049

-----Decoded View---------------
Arg [0] : _link (address): 0xf97f4df75117a78c1a5a0dbb814af92458539fb4
Arg [1] : _oracle (address): 0x1fb5081677b453c8fbc4946da3a9751df590dfe1
Arg [2] : _consumer (address): 0x0abdaf0c4cff91f96f817809d4735929fca75b80
Arg [3] : _paymentCreate (uint256): 10000000000000000
Arg [4] : _paymentResolve (uint256): 10000000000000000
Arg [5] : _paymentOdds (uint256): 10000000000000000
Arg [6] : _oddsSpecId (bytes32): 0x3230646438613738373265343436303862386438323239636566333666623638
Arg [7] : _sportsAMM (address): 0xae56177e405929c95e5d4b04c0c87e428cb6432b
Arg [8] : _verifier (address): 0x0b13071b5f3f860f4d52c836d898a79fe104c9b4
Arg [9] : _playerPropsReciever (address): 0x5311ef5370eaf6eb428dd4ea556aa3461269aee0
Arg [10] : _playerProps (address): 0xda835388e4f17701e352390778f9b4e2f96ad049

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb4
Arg [1] : 0000000000000000000000001fb5081677b453c8fbc4946da3a9751df590dfe1
Arg [2] : 0000000000000000000000000abdaf0c4cff91f96f817809d4735929fca75b80
Arg [3] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [4] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [5] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [6] : 3230646438613738373265343436303862386438323239636566333666623638
Arg [7] : 000000000000000000000000ae56177e405929c95e5d4b04c0c87e428cb6432b
Arg [8] : 0000000000000000000000000b13071b5f3f860f4d52c836d898a79fe104c9b4
Arg [9] : 0000000000000000000000005311ef5370eaf6eb428dd4ea556aa3461269aee0
Arg [10] : 000000000000000000000000da835388e4f17701e352390778f9b4e2f96ad049


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.