Contract 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6

  Note: Our ETH balance display is temporarily unavailable. Please check back later.
Txn Hash Method
Block
From
To
Value
0x15df463240aa1cac7ca0e585ccb811aa0fbfd0a4f06a882aad5080d31d50df4cRequest Games Re...132953892023-08-14 13:14:06305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006167050122.50000005
0x5f0ba466e6e37b982895bba172487362c4cd66f3435846774551e3c1d40a05d3Request Games Re...132953832023-08-14 13:13:54305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006167350122.50000005
0x223ecbaa4a2fb9948860c0c1264b9f41bfc9a78cb242ca7ad227d0af88fb4f1bRequest Games Re...132953772023-08-14 13:13:42305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006049500122.50000005
0xff7f404edf515e6cab667bd4d39a959cf8fb5f22cbecc84d53c2b9a58638fd70Request Games Re...132950122023-08-14 13:01:32305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006177475122.50000005
0x12ea9de8b70c829b17ff04dcb2e9e6388d012a53dd1076d39221e5455b452ea3Request Games Re...132950062023-08-14 13:01:20305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006177475122.50000005
0xf760b99b9bbabf967fc2e726dc0486b0814c31678291196ff370f858ec5c9706Request Games Re...132950022023-08-14 13:01:12305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006177475122.50000005
0x4b52eaae1877efc52525abbce665db3703dc7913b2b281a581a33e0d17b7c223Request Games Re...132949982023-08-14 13:01:04305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006177475122.50000005
0x57cef7b9465a09c35504b08ac4e86de3394ff55d3db7948281a74f8139425971Request Games Re...132949932023-08-14 13:00:54305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006177475122.50000005
0x226f0bff7b6541ac8fc6350f1f1633f9e196c3c5fd917bfc857c98068c1fa1cfRequest Games Re...132949872023-08-14 13:00:42305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006177475122.50000005
0x8c5286a81ad6e0418a2c52c4726410d1705e28c82193475a2bbd7211d4d6cef7Request Games Re...132949652023-08-14 12:59:58305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005977675122.50000005
0x75dd5387947301a763b07e8f98550ebdc8cf2cc4ff1a79d4422fee89b0a50664Request Games Re...132949582023-08-14 12:59:44305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005976350122.50000005
0x7d455f346a7d6a2ff208650e2d122b4a909402875a532e1c76a6651e2dcbc675Request Games Re...132949522023-08-14 12:59:32305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005917975112.50000005
0x760f1a5f2a7a45102d5ee7168d09fa33ce92e53243d196bd00f859fe9c03b0a8Request Games Re...132949462023-08-14 12:59:20305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006035025122.50000005
0x55bb2306e5e9c30018bcf1d13cc5d71b93ccdd462cdad542f9c1b19b864939a7Request Games Re...132949402023-08-14 12:59:08305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006035325122.50000005
0x3aa7a35d14284fb0d0a341bf5509565a36cfaebc88a050ef7b2adff6ecfdcad4Request Games Re...132949342023-08-14 12:58:56305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005917675112.50000005
0x094ebc332d270f8db010ea89f38e297b36bc3b7ef76702149d59b24611b217eeRequest Games Re...132949272023-08-14 12:58:42305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006094075122.50000005
0xc7104b14148bbb09147d6799136b5c2ab52f17d19b64a60e505f6ef64d93464eRequest Games Re...132949212023-08-14 12:58:30305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006094375122.50000005
0x3b18f9a3c87d407cd36e861bbfaa0796c4d9673514959e110232a0faffad3324Request Games Re...132949142023-08-14 12:58:16305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005917675112.50000005
0xc61c9fa692e848e5bd34efdccbe2b3d6185032f01764a7f8d330f4abd3426e02Request Games Re...132949072023-08-14 12:58:02305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005976350122.50000005
0x46908796d94f317510cc2934f4d04510411e8ad47a9d45e7b991243c83b0f7c9Request Games Re...132949032023-08-14 12:57:54305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006035325122.50000005
0x452e4ca862326b1b3478e58bd293cb6ab9c19c80a67b172b336687f9a07c9b0fRequest Games Re...132948982023-08-14 12:57:44305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005976350122.50000005
0x504c19f386eab53bca3579c2e296f05b97b9d30486d497f347ff56eac4fd0e0aRequest Games Re...132948942023-08-14 12:57:36305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005917975112.50000005
0x229aa89605f446bd637044452de210afc1ed307668636ffa4f9bb884e63a9e11Request Games Re...132948872023-08-14 12:57:22305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006035025122.50000005
0x07f1876d55706f29607e8c27c369bc7ea7d43604dd353b2d05723f7db0da7593Request Games Re...132948812023-08-14 12:57:10305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0006176150122.50000005
0xfe39dd41f990115e8c8b4d83ed608d251afb76a7e895c91acaadb86893089495Request Games Re...132947952023-08-14 12:54:18305 days 13 hrs ago0x9841484a4a6c0b61c4eea71376d76453fd05ec9c IN  0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH0.0005931950112.50000005
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 13 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 13 hrs ago 0x7465c5d60d3d095443cf9991da03304a30d42eae 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 13 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0x8ff2203827015e1d75c41036118ce5d82ff07303d851f810a0d5e28f2f989b99125599432023-07-28 12:39:14322 days 13 hrs ago 0x7465c5d60d3d095443cf9991da03304a30d42eae 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0x84b72774e52e89fb53fe946b576c61b56933abf3a8357687a19575108efeade7125599322023-07-28 12:38:52322 days 13 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0x84b72774e52e89fb53fe946b576c61b56933abf3a8357687a19575108efeade7125599322023-07-28 12:38:52322 days 13 hrs ago 0x7465c5d60d3d095443cf9991da03304a30d42eae 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0x7e78f4268b7ad7f1730e34a6890289ed9a41e7bb470e22e13ed79f489f15a9f2125599262023-07-28 12:38:40322 days 13 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0x7e78f4268b7ad7f1730e34a6890289ed9a41e7bb470e22e13ed79f489f15a9f2125599262023-07-28 12:38:40322 days 13 hrs ago 0x7465c5d60d3d095443cf9991da03304a30d42eae 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0xfce3dfec39c85677e9ee01f6a104d8822651995cc3bee09af1de72bafcaceac6125151092023-07-27 11:44:46323 days 14 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0xfce3dfec39c85677e9ee01f6a104d8822651995cc3bee09af1de72bafcaceac6125151092023-07-27 11:44:46323 days 14 hrs ago 0x7465c5d60d3d095443cf9991da03304a30d42eae 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0xfce3dfec39c85677e9ee01f6a104d8822651995cc3bee09af1de72bafcaceac6125151092023-07-27 11:44:46323 days 14 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0xfce3dfec39c85677e9ee01f6a104d8822651995cc3bee09af1de72bafcaceac6125151092023-07-27 11:44:46323 days 14 hrs ago 0x7465c5d60d3d095443cf9991da03304a30d42eae 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0x33f8be6902409b7158fb6ef57201aa95015ef8e5e9f3722d7245e706b6b50106125131842023-07-27 10:40:36323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce10 ETH
0x33f8be6902409b7158fb6ef57201aa95015ef8e5e9f3722d7245e706b6b50106125131842023-07-27 10:40:36323 days 15 hrs ago 0x59a3b51081a3d7e47206cec6cddc1e8c45e1c82b 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0xec5005f23164e4139d10c4c2c6d289552b1224c5a45de36e20ca2c6d97020c24125131812023-07-27 10:40:30323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0xec5005f23164e4139d10c4c2c6d289552b1224c5a45de36e20ca2c6d97020c24125131812023-07-27 10:40:30323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0xec5005f23164e4139d10c4c2c6d289552b1224c5a45de36e20ca2c6d97020c24125131812023-07-27 10:40:30323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce10 ETH
0xec5005f23164e4139d10c4c2c6d289552b1224c5a45de36e20ca2c6d97020c24125131812023-07-27 10:40:30323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0x86991efb34b0cf55af38e9dace3f82cd8b70188f0 ETH
0x08ed64a2dc7b17d5a244c71beedc95bc7d0bfdb0e23110095a27bc62db4e4ac0125131802023-07-27 10:40:28323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce10 ETH
0x08ed64a2dc7b17d5a244c71beedc95bc7d0bfdb0e23110095a27bc62db4e4ac0125131802023-07-27 10:40:28323 days 15 hrs ago 0x59a3b51081a3d7e47206cec6cddc1e8c45e1c82b 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd60 ETH
0x9654e56af57e13c4cec0a4a8a79a1d4e245e1fdc4c1c058fc8fcdd7829d13c28125131772023-07-27 10:40:22323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0x9654e56af57e13c4cec0a4a8a79a1d4e245e1fdc4c1c058fc8fcdd7829d13c28125131772023-07-27 10:40:22323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
0x9654e56af57e13c4cec0a4a8a79a1d4e245e1fdc4c1c058fc8fcdd7829d13c28125131772023-07-27 10:40:22323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdb6eb989127d0c33bc630d7b5b53f87ceced3ce10 ETH
0x9654e56af57e13c4cec0a4a8a79a1d4e245e1fdc4c1c058fc8fcdd7829d13c28125131772023-07-27 10:40:22323 days 15 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0x86991efb34b0cf55af38e9dace3f82cd8b70188f0 ETH
0x7c4d8831a448d94278652960725aa5046a79eb2a89a093f20d335e93a4e8e556123805282023-07-24 8:58:44326 days 17 hrs ago 0x0c6bf9a7eb31777acf77d68ea7ea46d5382cfdd6 0xdc2cc710e42857672e7907cf474a69b63b93089f0 ETH
[ Download CSV Export 
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 21 : 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";

/// @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;
    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;
    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 => bool) public requestIdGamesCreatedFulFilled;
    mapping(bytes32 => bool) public requestIdGamesResolvedFulFilled;
    mapping(bytes32 => bool) public requestIdGamesOddsFulFilled;

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

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

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

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

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

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

    /* ========== 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 amm address
    /// @param _sportsAmm amm address
    function setSportsAmmAddress(address _sportsAmm) external onlyOwner {
        require(_sportsAmm != address(0), "Invalid address");
        sportsAMM = _sportsAmm;
        emit NewSportsAmmAddress(_sportsAmm);
    }

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

File 2 of 21 : 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 21 : 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 21 : 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 21 : 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 21 : 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 getNormalizedOdds(bytes32 _gameId) external view returns (uint[] memory);

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

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

    function getNormalizedOddsForTwoPosition(bytes32 _gameId) 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);

    // 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 setChildMarkets(
        bytes32 _gameId,
        address _main,
        address _child,
        bool _isSpread,
        int16 _spreadHome,
        uint24 _totalOver
    ) external;

    function resolveMarketManually(
        address _market,
        uint _outcome,
        uint8 _homeScore,
        uint8 _awayScore
    ) 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 21 : 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 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 getStringIDsFromBytesArrayIDs(bytes32[] memory _ids) external view returns (string[] memory);
}

File 8 of 21 : 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 9 of 21 : 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 10 of 21 : 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 11 of 21 : 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 12 of 21 : 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 13 of 21 : PointerInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

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

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

File 15 of 21 : 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 16 of 21 : 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 17 of 21 : 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 18 of 21 : 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 19 of 21 : 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 20 of 21 : 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 21 of 21 : 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"}],"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":"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":"_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"},{"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":"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":[],"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":"uint256","name":"_sportId","type":"uint256"}],"name":"getBookmakerIdsBySportId","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":"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":"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":"_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":"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":"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":"_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"}]

608060405260016004553480156200001657600080fd5b506040516200366738038062003667833981016040819052620000399162000166565b6200004433620000f7565b6006805460ff60a01b19169055600280546001600160a01b0319166001600160a01b038b16179055600380546001600160a01b0319166001600160a01b038a16179055600780546001600160a01b03199081166001600160a01b03998a1617909155600b96909655600c94909455600d92909255600e8054851697861697909717909655600f959095556010805483169584169590951790945560088054909116939091169290921790915550620001fc565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200016157600080fd5b919050565b60008060008060008060008060006101208a8c03121562000185578485fd5b620001908a62000149565b9850620001a060208b0162000149565b9750620001b060408b0162000149565b965060608a0151955060808a0151945060a08a0151935060c08a01519250620001dc60e08b0162000149565b9150620001ed6101008b0162000149565b90509295985092959850929598565b61345b806200020c6000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80637f6fd14011610151578063affa98d1116100c3578063c7f7007911610087578063c7f7007914610582578063c992528814610595578063d8033ef1146105a8578063db8f6ef7146105bb578063efccb47a146105ce578063f2fde38b146105e157600080fd5b8063affa98d11461052e578063b18b78dd14610541578063b4fd729614610549578063bf62086f1461055c578063c475e0b31461056f57600080fd5b806390c6fb271161011557806390c6fb27146104c357806392e889da146104cc57806394547fcc146104df578063977a6449146104f257806399d9f2b9146104fb578063a1b778b61461051b57600080fd5b80637f6fd1401461044657806380a74375146104595780638b2a43641461047c5780638bd6e4c91461048f5780638da5cb5b146104b257600080fd5b806351864c0c116101ea5780635c975abb116101ae5780635c975abb146103ea57806363a579d5146103fc578063715018a61461040f57806373f457b0146104175780637adbf9731461042a5780637daaa7ff1461043d57600080fd5b806351864c0c1461035e5780635437988d1461037e57806356b788871461039157806357970e93146103c45780635b4f9d9b146103d757600080fd5b80632bd13da1116102315780632bd13da1146102fc57806336661e1a146103055780633ca672f2146103185780633eda5fcb1461032b578063436d765a1461033e57600080fd5b806301e41efa1461026e578063029a39cd1461028357806310fe9ae814610296578063282e9a1f146102bb5780632b7ac3f3146102e9575b600080fd5b61028161027c366004612e2f565b6105f4565b005b6102816102913660046129c4565b610777565b61029e610a63565b6040516001600160a01b0390911681526020015b60405180910390f35b6102db6102c9366004612c2b565b600a6020526000908152604090205481565b6040519081526020016102b2565b60085461029e906001600160a01b031681565b6102db600b5481565b610281610313366004612c43565b610a7c565b610281610326366004612c97565b610d3b565b610281610339366004612c2b565b611052565b61035161034c366004612d36565b6110b6565b6040516102b291906130b1565b6102db61036c366004612c2b565b60096020526000908152604090205481565b61028161038c3660046129c4565b61116f565b6103b461039f366004612c2b565b60176020526000908152604090205460ff1681565b60405190151581526020016102b2565b600e5461029e906001600160a01b031681565b6102816103e53660046129e0565b6111eb565b600654600160a01b900460ff166103b4565b61028161040a3660046129c4565b61120e565b61028161128a565b610281610425366004612d57565b61129e565b6102816104383660046129c4565b6113dc565b6102db600d5481565b610281610454366004612d57565b61145e565b6103b4610467366004612c2b565b60156020526000908152604090205460ff1681565b61028161048a366004612c2b565b61155b565b6103b461049d366004612c2b565b60166020526000908152604090205460ff1681565b6006546001600160a01b031661029e565b6102db600f5481565b6103b46104da366004612a0b565b611598565b6102816104ed3660046129c4565b61160f565b6102db600c5481565b61050e610509366004612c2b565b6116a6565b6040516102b29190612fff565b6102816105293660046129c4565b61172d565b61028161053c366004612c2b565b6117a9565b61029e611806565b60075461029e906001600160a01b031681565b61028161056a366004612c2b565b61181a565b61035161057d366004612d36565b611877565b610281610590366004612d57565b611893565b60105461029e906001600160a01b031681565b6103b46105b6366004612a0b565b611987565b6103b46105c9366004612a0b565b6119f5565b6103516105dc366004612d36565b611a63565b6102816105ef3660046129c4565b611a7f565b6105fc611af5565b6007546040516334d2a49760e11b8152600481018590526001600160a01b03909116906369a5492e9060240160206040518083038186803b15801561064057600080fd5b505afa158015610654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106789190612c0b565b61069d5760405162461bcd60e51b815260040161069490613116565b60405180910390fd5b60006106b1853063c7f7007960e01b611b42565b6040805180820190915260048152636461746560e01b60208201529091506106db90829085611b69565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261070590829086611b69565b8151156107365760408051808201909152600781526667616d6549647360c81b602082015261073690829084611b8c565b61074233600d54611c12565b600061075082600d54611c2a565b600090815260096020908152604080832097909755600a9052949094209290925550505050565b61077f611af5565b6010546001600160a01b031633146107e85760405162461bcd60e51b815260206004820152602660248201527f4f6e6c792053706f72747320414d4d2063616e2063616c6c20746869732066756044820152653731ba34b7b760d11b6064820152608401610694565b600d54600e546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561082e57600080fd5b505afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190612e86565b10610a60576007546040516356e4194d60e01b81526001600160a01b03838116600483015260009283929116906356e4194d9060240160606040518083038186803b1580156108b457600080fd5b505afa1580156108c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ec9190612e9e565b5060075460405163a50267a560e01b815260048101849052602481018390529294509092506000916001600160a01b039091169063a50267a59060440160006040518083038186803b15801561094157600080fd5b505afa158015610955573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261097d9190810190612a9d565b600f54600854604051630574513160e11b8152929350610a1492869186916001600160a01b0390911690630ae8a262906109bb908890600401612fff565b60006040518083038186803b1580156109d357600080fd5b505afa1580156109e7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a0f9190810190612b23565b611c44565b60408051848152602081018490526001600160a01b0386168183015290517f7c7905e4aa6d903c8f8e60c93891dbf754e35cae604e0fecb08d8ca45ffb91fa9181900360600190a15050505b50565b6000610a776002546001600160a01b031690565b905090565b610a84611af5565b60085460405163645de6cb60e11b8152849184916001600160a01b039091169063c8bbcd9690610ab89085906004016130b1565b60206040518083038186803b158015610ad057600080fd5b505afa158015610ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b089190612c0b565b610b4e5760405162461bcd60e51b815260206004820152601760248201527613585c9ad95d081a5cc81b9bdd081cdd5c1c1bdc9d1959604a1b6044820152606401610694565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b158015610b9257600080fd5b505afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bca9190612c0b565b610be65760405162461bcd60e51b815260040161069490613116565b610bee612757565b6040516563726561746560d01b60208201526000906026016040516020818303038152906040528051906020012087604051602001610c2d9190612f4b565b604051602081830303815290604052805190602001201415610c6757610c5b883063073f457b60e41b611b42565b9150600b549050610c81565b610c7988306301fdbf4560e61b611b42565b9150600c5490505b6040805180820190915260048152636461746560e01b6020820152610ca890839087611b69565b6040805180820190915260068152651b585c9ad95d60d21b6020820152610cd190839089611cdd565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152610cfb90839088611b69565b610d053382611c12565b6000610d118383611c2a565b600090815260096020908152604080832099909955600a9052969096209490945550505050505050565b610d43611af5565b60085460405163645de6cb60e11b8152869186916001600160a01b039091169063c8bbcd9690610d779085906004016130b1565b60206040518083038186803b158015610d8f57600080fd5b505afa158015610da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc79190612c0b565b610e0d5760405162461bcd60e51b815260206004820152601760248201527613585c9ad95d081a5cc81b9bdd081cdd5c1c1bdc9d1959604a1b6044820152606401610694565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b158015610e5157600080fd5b505afa158015610e65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e899190612c0b565b610ea55760405162461bcd60e51b815260040161069490613116565b610ead612757565b6040516563726561746560d01b60208201526000906026016040516020818303038152906040528051906020012089604051602001610eec9190612f4b565b604051602081830303815290604052805190602001201415610f2657610f1a8a3063073f457b60e41b611b42565b9150600b549050610f40565b610f388a306301fdbf4560e61b611b42565b9150600c5490505b6040805180820190915260048152636461746560e01b6020820152610f6790839089611b69565b6040805180820190915260068152651b585c9ad95d60d21b6020820152610f909083908b611cdd565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152610fba9083908a611b69565b60408051808201909152600981526873746174757349647360b81b6020820152610fe690839088611b8c565b60408051808201909152600781526667616d6549647360c81b602082015261101090839087611b8c565b61101a3382611c12565b60006110268383611c2a565b60009081526009602090815260408083209b909b55600a90529890982096909655505050505050505050565b61105a611cfb565b6000811161107a5760405162461bcd60e51b8152600401610694906130ed565b600d8190556040518181527f523e038e803877ea42acb6426444bcd23d2bbf31ad9f41ea0991762c20ee6d14906020015b60405180910390a150565b601260205281600052604060002081815481106110d257600080fd5b906000526020600020016000915091505080546110ee90613374565b80601f016020809104026020016040519081016040528092919081815260200182805461111a90613374565b80156111675780601f1061113c57610100808354040283529160200191611167565b820191906000526020600020905b81548152906001019060200180831161114a57829003601f168201915b505050505081565b611177611cfb565b6001600160a01b03811661119d5760405162461bcd60e51b8152600401610694906130c4565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527fa1fd6a6669acb930bae242943bb9fa08ddcba665c707261e9730ee0305fb85e5906020016110ab565b6111f3611cfb565b600e5461120a906001600160a01b03168383611d55565b5050565b611216611cfb565b6001600160a01b03811661123c5760405162461bcd60e51b8152600401610694906130c4565b600780546001600160a01b0319166001600160a01b0383169081179091556040519081527f96e60d35957ee680a1536282a3d7e57e96e55cf15f3fc5997088c2b07f411f94906020016110ab565b611292611cfb565b61129c6000611db8565b565b60008381526005602052604090205483906001600160a01b031633146112d65760405162461bcd60e51b81526004016106949061314d565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a26000848152601160209081526040909120835161133892850190612792565b506000848152601560209081526040808320805460ff19166001179055601482528083208690556007546009835281842054600a9093529281902054905163a400a89160e01b81526001600160a01b039093169263a400a891926113a492899288929190600401613085565b600060405180830381600087803b1580156113be57600080fd5b505af11580156113d2573d6000803e3d6000fd5b5050505050505050565b6113e4611cfb565b6001600160a01b03811661140a5760405162461bcd60e51b8152600401610694906130c4565b600380546001600160a01b0319166001600160a01b0383161790556040516001600160a01b03821681527f83b00e25c000adada62072ff4992b6702b635a6e3d57e135bbd60a01be113ead906020016110ab565b60008381526005602052604090205483906001600160a01b031633146114965760405162461bcd60e51b81526004016106949061314d565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a2600084815260126020908152604090912083516114f892850190612792565b506000848152601660209081526040808320805460ff1916600117905560148252808320869055600754600990925291829020549151632f73199d60e01b81526001600160a01b0390911691632f73199d916113a491889187919060040161305c565b611563611cfb565b600f8190556040518181527fa9654d85422e4e0fb6544086f22f928d2d39fe8ab1c13ee9636c64cbdcf99fcb906020016110ab565b6000805b825181101561160657601760008483815181106115c957634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166115f45750600092915050565b806115fe816133a9565b91505061159c565b50600192915050565b611617611cfb565b6001600160a01b03811661163d5760405162461bcd60e51b8152600401610694906130c4565b600280546001600160a01b0319166001600160a01b038316179055600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f0a79df54a5f0809c9853241a307e8bf1dfe87ad5323398cc566df6e3470599906020016110ab565b6008546040516399d9f2b960e01b8152600481018390526060916001600160a01b0316906399d9f2b99060240160006040518083038186803b1580156116eb57600080fd5b505afa1580156116ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117279190810190612a9d565b92915050565b611735611cfb565b6001600160a01b03811661175b5760405162461bcd60e51b8152600401610694906130c4565b601080546001600160a01b0319166001600160a01b0383169081179091556040519081527f3a310361002138b9ae7ac040259a1e871d3263696335223ddf2dc1af218a222b906020016110ab565b6117b1611cfb565b600081116117d15760405162461bcd60e51b8152600401610694906130ed565b600b8190556040518181527f29a88aaedea4371894af2af86b4d24f2cfcbb494532f46b5b761cbc4cc5ff2a3906020016110ab565b6000610a776003546001600160a01b031690565b611822611cfb565b600081116118425760405162461bcd60e51b8152600401610694906130ed565b600c8190556040518181527f2e959719b856a4dda43c92d8d13eb48b37668b25366584f6167cf86b653df9f6906020016110ab565b601160205281600052604060002081815481106110d257600080fd5b60008381526005602052604090205483906001600160a01b031633146118cb5760405162461bcd60e51b81526004016106949061314d565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a26000848152601360209081526040909120835161192d92850190612792565b506000848152601460209081526040808320869055601790915290819020805460ff191660011790556007549051631ecbaea760e11b81526001600160a01b0390911690633d975d4e906113a49087908690600401613043565b6000805b825181101561160657601560008483815181106119b857634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166119e35750600092915050565b806119ed816133a9565b91505061198b565b6000805b82518110156116065760166000848381518110611a2657634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611a515750600092915050565b80611a5b816133a9565b9150506119f9565b601360205281600052604060002081815481106110d257600080fd5b611a87611cfb565b6001600160a01b038116611aec5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610694565b610a6081611db8565b600654600160a01b900460ff161561129c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610694565b611b4a612757565b611b52612757565b611b5e81868686611e0a565b9150505b9392505050565b6080830151611b789083611e50565b6080830151611b879082611e67565b505050565b6080830151611b9b9083611e50565b611ba88360800151611e8c565b60005b8151811015611c0457611bf2828281518110611bd757634e487b7160e01b600052603260045260246000fd5b60200260200101518560800151611e5090919063ffffffff16565b80611bfc816133a9565b915050611bab565b50611b878360800151611e97565b600e5461120a906001600160a01b0316833084611ea2565b600354600090611b62906001600160a01b03168484611ee0565b6000611c58853063c7f7007960e01b611b42565b6040805180820190915260048152636461746560e01b6020820152909150611c8290829085611b69565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152611cac90829086611b69565b8151156107425760408051808201909152600781526667616d6549647360c81b602082015261074290829084611b8c565b6080830151611cec9083611e50565b6080830151611b879082611e50565b6006546001600160a01b0316331461129c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610694565b6040516001600160a01b038316602482015260448101829052611b8790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611f73565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611e12612757565b611e228560800151610100612045565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b611e5d82600383516120aa565b611b8782826121b1565b6001600160401b03811115611e805761120a82826121d8565b61120a826000836120aa565b610a6081600461220f565b610a6081600761220f565b6040516001600160a01b0380851660248301528316604482015260648101829052611eda9085906323b872dd60e01b90608401611d81565b50505050565b600454600090611ef181600161320f565b600455835160408086015160808701515191516000936320214ca360e11b93611f299386938493923092918a91600191602401612f67565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050611f6986838684612224565b9695505050505050565b6000611fc8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166123919092919063ffffffff16565b805190915015611b875780806020019051810190611fe69190612c0b565b611b875760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610694565b6040805180820190915260608152600060208201526120656020836133c4565b1561208d576120756020836133c4565b612080906020613331565b61208a908361320f565b91505b506020828101829052604080518085526000815290920101905290565b6017816001600160401b0316116120ce57611eda8360e0600585901b1683176123a0565b60ff816001600160401b03161161210a576120f4836018611fe0600586901b16176123a0565b50611eda836001600160401b03831660016123c5565b61ffff816001600160401b03161161214757612131836019611fe0600586901b16176123a0565b50611eda836001600160401b03831660026123c5565b63ffffffff816001600160401b0316116121865761217083601a611fe0600586901b16176123a0565b50611eda836001600160401b03831660046123c5565b61219b83601b611fe0600586901b16176123a0565b50611eda836001600160401b03831660086123c5565b604080518082019091526060815260006020820152611b62838460000151518485516123eb565b6121e38260c26123a0565b5061120a82826040516020016121fb91815260200190565b6040516020818303038152906040526124d5565b611b8782601f611fe0600585901b16176123a0565b6040516bffffffffffffffffffffffff193060601b1660208201526034810184905260009060540160408051808303601f1901815282825280516020918201206000818152600590925291812080546001600160a01b0319166001600160a01b038a1617905590925082917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af99190a2600254604051630200057560e51b81526001600160a01b0390911690634000aea0906122e790889087908790600401612fcf565b602060405180830381600087803b15801561230157600080fd5b505af1158015612315573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123399190612c0b565b611e485760405162461bcd60e51b815260206004820152602360248201527f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261604482015262636c6560e81b6064820152608401610694565b6060611e4884846000856124e2565b604080518082019091526060815260006020820152611b628384600001515184612613565b604080518082019091526060815260006020820152611e4884856000015151858561266f565b604080518082019091526060815260006020820152825182111561240e57600080fd5b602085015161241d838661320f565b111561245057612450856124408760200151878661243b919061320f565b6126f0565b61244b906002613312565b612707565b60008086518051876020830101935080888701111561246f5787860182525b505050602084015b602084106124af578051825261248e60208361320f565b915061249b60208261320f565b90506124a8602085613331565b9350612477565b51815160001960208690036101000a019081169019919091161790525083949350505050565b611e5d82600283516120aa565b6060824710156125435760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610694565b6001600160a01b0385163b61259a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610694565b600080866001600160a01b031685876040516125b69190612f4b565b60006040518083038185875af1925050503d80600081146125f3576040519150601f19603f3d011682016040523d82523d6000602084013e6125f8565b606091505b509150915061260882828661271e565b979650505050505050565b6040805180820190915260608152600060208201528360200151831061264857612648848560200151600261244b9190613312565b835180516020858301018481535080851415612665576001810182525b5093949350505050565b6040805180820190915260608152600060208201526020850151612693858461320f565b11156126a7576126a785612440868561320f565b600060016126b78461010061326a565b6126c19190613331565b90508551838682010185831982511617815250805184870111156126e55783860181525b509495945050505050565b600081831115612701575081611727565b50919050565b81516127138383612045565b50611eda83826121b1565b6060831561272d575081611b62565b82511561273d5782518084602001fd5b8160405162461bcd60e51b815260040161069491906130b1565b6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b8280548282559060005260206000209081019282156127df579160200282015b828111156127df57825180516127cf9184916020909101906127ef565b50916020019190600101906127b2565b506127eb92915061286f565b5090565b8280546127fb90613374565b90600052602060002090601f01602090048101928261281d5760008555612863565b82601f1061283657805160ff1916838001178555612863565b82800160010185558215612863579182015b82811115612863578251825591602001919060010190612848565b506127eb92915061288c565b808211156127eb57600061288382826128a1565b5060010161286f565b5b808211156127eb576000815560010161288d565b5080546128ad90613374565b6000825580601f106128bd575050565b601f016020900490600052602060002090810190610a60919061288c565b60006128ee6128e9846131e8565b613195565b905082815283838301111561290257600080fd5b828260208301376000602084830101529392505050565b600082601f830112612929578081fd5b813560206129396128e9836131c5565b80838252828201915082860187848660051b8901011115612958578586fd5b855b858110156129985781356001600160401b03811115612977578788fd5b6129858a87838c01016129a5565b855250928401929084019060010161295a565b5090979650505050505050565b600082601f8301126129b5578081fd5b611b62838335602085016128db565b6000602082840312156129d5578081fd5b8135611b6281613410565b600080604083850312156129f2578081fd5b82356129fd81613410565b946020939093013593505050565b60006020808385031215612a1d578182fd5b82356001600160401b03811115612a32578283fd5b8301601f81018513612a42578283fd5b8035612a506128e9826131c5565b80828252848201915084840188868560051b8701011115612a6f578687fd5b8694505b83851015612a91578035835260019490940193918501918501612a73565b50979650505050505050565b60006020808385031215612aaf578182fd5b82516001600160401b03811115612ac4578283fd5b8301601f81018513612ad4578283fd5b8051612ae26128e9826131c5565b80828252848201915084840188868560051b8701011115612b01578687fd5b8694505b83851015612a91578051835260019490940193918501918501612b05565b60006020808385031215612b35578182fd5b82516001600160401b0380821115612b4b578384fd5b818501915085601f830112612b5e578384fd5b8151612b6c6128e9826131c5565b80828252858201915085850189878560051b8801011115612b8b578788fd5b875b84811015612bfc57815186811115612ba357898afd5b8701603f81018c13612bb357898afd5b888101516040612bc56128e9836131e8565b8281528e82848601011115612bd8578c8dfd5b612be7838d8301848701613348565b87525050509287019290870190600101612b8d565b50909998505050505050505050565b600060208284031215612c1c578081fd5b81518015158114611b62578182fd5b600060208284031215612c3c578081fd5b5035919050565b60008060008060808587031215612c58578182fd5b8435935060208501356001600160401b03811115612c74578283fd5b612c80878288016129a5565b949794965050505060408301359260600135919050565b60008060008060008060c08789031215612caf578384fd5b8635955060208701356001600160401b0380821115612ccc578586fd5b612cd88a838b016129a5565b965060408901359550606089013594506080890135915080821115612cfb578384fd5b612d078a838b01612919565b935060a0890135915080821115612d1c578283fd5b50612d2989828a01612919565b9150509295509295509295565b60008060408385031215612d48578182fd5b50508035926020909101359150565b600080600060608486031215612d6b578081fd5b8335925060208085013592506040808601356001600160401b0380821115612d91578485fd5b818801915088601f830112612da4578485fd5b8135612db26128e9826131c5565b8082825286820191508685018c888560051b8801011115612dd1578889fd5b885b84811015612e1c57813586811115612de9578a8bfd5b8701603f81018f13612df9578a8bfd5b612e098f8b8301358b84016128db565b8552509288019290880190600101612dd3565b5050809750505050505050509250925092565b60008060008060808587031215612e44578182fd5b84359350602085013592506040850135915060608501356001600160401b03811115612e6e578182fd5b612e7a87828801612919565b91505092959194509250565b600060208284031215612e97578081fd5b5051919050565b600080600060608486031215612eb2578081fd5b8351925060208401519150604084015190509250925092565b600081518084526020808501808196508360051b81019150828601855b85811015612f12578284038952612f00848351612f1f565b98850198935090840190600101612ee8565b5091979650505050505050565b60008151808452612f37816020860160208601613348565b601f01601f19169290920160200192915050565b60008251612f5d818460208701613348565b9190910192915050565b6001600160a01b0389811682526020820189905260408201889052861660608201526001600160e01b03198516608082015260a0810184905260c0810183905261010060e08201819052600090612fc083820185612f1f565b9b9a5050505050505050505050565b60018060a01b0384168152826020820152606060408201526000612ff66060830184612f1f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156130375783518352928401929184019160010161301b565b50909695505050505050565b828152604060208201526000611e486040830184612ecb565b8381526060602082015260006130756060830185612ecb565b9050826040830152949350505050565b84815260806020820152600061309e6080830186612ecb565b6040830194909452506060015292915050565b602081526000611b626020830184612f1f565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b6020808252600f908201526e43616e206e6f74206265207a65726f60881b604082015260600190565b60208082526018908201527f53706f72744964206973206e6f7420737570706f727465640000000000000000604082015260600190565b60208082526028908201527f536f75726365206d75737420626520746865206f7261636c65206f6620746865604082015267081c995c5d595cdd60c21b606082015260800190565b604051601f8201601f191681016001600160401b03811182821017156131bd576131bd6133fa565b604052919050565b60006001600160401b038211156131de576131de6133fa565b5060051b60200190565b60006001600160401b03821115613201576132016133fa565b50601f01601f191660200190565b60008219821115613222576132226133e4565b500190565b600181815b80851115613262578160001904821115613248576132486133e4565b8085161561325557918102915b93841c939080029061322c565b509250929050565b6000611b62838360008261328057506001611727565b8161328d57506000611727565b81600181146132a357600281146132ad576132c9565b6001915050611727565b60ff8411156132be576132be6133e4565b50506001821b611727565b5060208310610133831016604e8410600b84101617156132ec575081810a611727565b6132f68383613227565b806000190482111561330a5761330a6133e4565b029392505050565b600081600019048311821515161561332c5761332c6133e4565b500290565b600082821015613343576133436133e4565b500390565b60005b8381101561336357818101518382015260200161334b565b83811115611eda5750506000910152565b600181811c9082168061338857607f821691505b6020821081141561270157634e487b7160e01b600052602260045260246000fd5b60006000198214156133bd576133bd6133e4565b5060010190565b6000826133df57634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a6057600080fdfea26469706673582212208932709a31fbc334667459d5b69e3ee789acc3a6d6c76d77c5ac971524c0684764736f6c63430008040033000000000000000000000000dc2cc710e42857672e7907cf474a69b63b93089f000000000000000000000000e7b1e93b6e79970b699a4daeb40dcd709ac876ea000000000000000000000000db6eb989127d0c33bc630d7b5b53f87ceced3ce1000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc1000032306464386137383732653434363038623864383232396365663336666236380000000000000000000000007465c5d60d3d095443cf9991da03304a30d42eae00000000000000000000000086991efb34b0cf55af38e9dace3f82cd8b70188f

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102695760003560e01c80637f6fd14011610151578063affa98d1116100c3578063c7f7007911610087578063c7f7007914610582578063c992528814610595578063d8033ef1146105a8578063db8f6ef7146105bb578063efccb47a146105ce578063f2fde38b146105e157600080fd5b8063affa98d11461052e578063b18b78dd14610541578063b4fd729614610549578063bf62086f1461055c578063c475e0b31461056f57600080fd5b806390c6fb271161011557806390c6fb27146104c357806392e889da146104cc57806394547fcc146104df578063977a6449146104f257806399d9f2b9146104fb578063a1b778b61461051b57600080fd5b80637f6fd1401461044657806380a74375146104595780638b2a43641461047c5780638bd6e4c91461048f5780638da5cb5b146104b257600080fd5b806351864c0c116101ea5780635c975abb116101ae5780635c975abb146103ea57806363a579d5146103fc578063715018a61461040f57806373f457b0146104175780637adbf9731461042a5780637daaa7ff1461043d57600080fd5b806351864c0c1461035e5780635437988d1461037e57806356b788871461039157806357970e93146103c45780635b4f9d9b146103d757600080fd5b80632bd13da1116102315780632bd13da1146102fc57806336661e1a146103055780633ca672f2146103185780633eda5fcb1461032b578063436d765a1461033e57600080fd5b806301e41efa1461026e578063029a39cd1461028357806310fe9ae814610296578063282e9a1f146102bb5780632b7ac3f3146102e9575b600080fd5b61028161027c366004612e2f565b6105f4565b005b6102816102913660046129c4565b610777565b61029e610a63565b6040516001600160a01b0390911681526020015b60405180910390f35b6102db6102c9366004612c2b565b600a6020526000908152604090205481565b6040519081526020016102b2565b60085461029e906001600160a01b031681565b6102db600b5481565b610281610313366004612c43565b610a7c565b610281610326366004612c97565b610d3b565b610281610339366004612c2b565b611052565b61035161034c366004612d36565b6110b6565b6040516102b291906130b1565b6102db61036c366004612c2b565b60096020526000908152604090205481565b61028161038c3660046129c4565b61116f565b6103b461039f366004612c2b565b60176020526000908152604090205460ff1681565b60405190151581526020016102b2565b600e5461029e906001600160a01b031681565b6102816103e53660046129e0565b6111eb565b600654600160a01b900460ff166103b4565b61028161040a3660046129c4565b61120e565b61028161128a565b610281610425366004612d57565b61129e565b6102816104383660046129c4565b6113dc565b6102db600d5481565b610281610454366004612d57565b61145e565b6103b4610467366004612c2b565b60156020526000908152604090205460ff1681565b61028161048a366004612c2b565b61155b565b6103b461049d366004612c2b565b60166020526000908152604090205460ff1681565b6006546001600160a01b031661029e565b6102db600f5481565b6103b46104da366004612a0b565b611598565b6102816104ed3660046129c4565b61160f565b6102db600c5481565b61050e610509366004612c2b565b6116a6565b6040516102b29190612fff565b6102816105293660046129c4565b61172d565b61028161053c366004612c2b565b6117a9565b61029e611806565b60075461029e906001600160a01b031681565b61028161056a366004612c2b565b61181a565b61035161057d366004612d36565b611877565b610281610590366004612d57565b611893565b60105461029e906001600160a01b031681565b6103b46105b6366004612a0b565b611987565b6103b46105c9366004612a0b565b6119f5565b6103516105dc366004612d36565b611a63565b6102816105ef3660046129c4565b611a7f565b6105fc611af5565b6007546040516334d2a49760e11b8152600481018590526001600160a01b03909116906369a5492e9060240160206040518083038186803b15801561064057600080fd5b505afa158015610654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106789190612c0b565b61069d5760405162461bcd60e51b815260040161069490613116565b60405180910390fd5b60006106b1853063c7f7007960e01b611b42565b6040805180820190915260048152636461746560e01b60208201529091506106db90829085611b69565b6040805180820190915260078152661cdc1bdc9d125960ca1b602082015261070590829086611b69565b8151156107365760408051808201909152600781526667616d6549647360c81b602082015261073690829084611b8c565b61074233600d54611c12565b600061075082600d54611c2a565b600090815260096020908152604080832097909755600a9052949094209290925550505050565b61077f611af5565b6010546001600160a01b031633146107e85760405162461bcd60e51b815260206004820152602660248201527f4f6e6c792053706f72747320414d4d2063616e2063616c6c20746869732066756044820152653731ba34b7b760d11b6064820152608401610694565b600d54600e546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561082e57600080fd5b505afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190612e86565b10610a60576007546040516356e4194d60e01b81526001600160a01b03838116600483015260009283929116906356e4194d9060240160606040518083038186803b1580156108b457600080fd5b505afa1580156108c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ec9190612e9e565b5060075460405163a50267a560e01b815260048101849052602481018390529294509092506000916001600160a01b039091169063a50267a59060440160006040518083038186803b15801561094157600080fd5b505afa158015610955573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261097d9190810190612a9d565b600f54600854604051630574513160e11b8152929350610a1492869186916001600160a01b0390911690630ae8a262906109bb908890600401612fff565b60006040518083038186803b1580156109d357600080fd5b505afa1580156109e7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a0f9190810190612b23565b611c44565b60408051848152602081018490526001600160a01b0386168183015290517f7c7905e4aa6d903c8f8e60c93891dbf754e35cae604e0fecb08d8ca45ffb91fa9181900360600190a15050505b50565b6000610a776002546001600160a01b031690565b905090565b610a84611af5565b60085460405163645de6cb60e11b8152849184916001600160a01b039091169063c8bbcd9690610ab89085906004016130b1565b60206040518083038186803b158015610ad057600080fd5b505afa158015610ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b089190612c0b565b610b4e5760405162461bcd60e51b815260206004820152601760248201527613585c9ad95d081a5cc81b9bdd081cdd5c1c1bdc9d1959604a1b6044820152606401610694565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b158015610b9257600080fd5b505afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bca9190612c0b565b610be65760405162461bcd60e51b815260040161069490613116565b610bee612757565b6040516563726561746560d01b60208201526000906026016040516020818303038152906040528051906020012087604051602001610c2d9190612f4b565b604051602081830303815290604052805190602001201415610c6757610c5b883063073f457b60e41b611b42565b9150600b549050610c81565b610c7988306301fdbf4560e61b611b42565b9150600c5490505b6040805180820190915260048152636461746560e01b6020820152610ca890839087611b69565b6040805180820190915260068152651b585c9ad95d60d21b6020820152610cd190839089611cdd565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152610cfb90839088611b69565b610d053382611c12565b6000610d118383611c2a565b600090815260096020908152604080832099909955600a9052969096209490945550505050505050565b610d43611af5565b60085460405163645de6cb60e11b8152869186916001600160a01b039091169063c8bbcd9690610d779085906004016130b1565b60206040518083038186803b158015610d8f57600080fd5b505afa158015610da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc79190612c0b565b610e0d5760405162461bcd60e51b815260206004820152601760248201527613585c9ad95d081a5cc81b9bdd081cdd5c1c1bdc9d1959604a1b6044820152606401610694565b6007546040516334d2a49760e11b8152600481018390526001600160a01b03909116906369a5492e9060240160206040518083038186803b158015610e5157600080fd5b505afa158015610e65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e899190612c0b565b610ea55760405162461bcd60e51b815260040161069490613116565b610ead612757565b6040516563726561746560d01b60208201526000906026016040516020818303038152906040528051906020012089604051602001610eec9190612f4b565b604051602081830303815290604052805190602001201415610f2657610f1a8a3063073f457b60e41b611b42565b9150600b549050610f40565b610f388a306301fdbf4560e61b611b42565b9150600c5490505b6040805180820190915260048152636461746560e01b6020820152610f6790839089611b69565b6040805180820190915260068152651b585c9ad95d60d21b6020820152610f909083908b611cdd565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152610fba9083908a611b69565b60408051808201909152600981526873746174757349647360b81b6020820152610fe690839088611b8c565b60408051808201909152600781526667616d6549647360c81b602082015261101090839087611b8c565b61101a3382611c12565b60006110268383611c2a565b60009081526009602090815260408083209b909b55600a90529890982096909655505050505050505050565b61105a611cfb565b6000811161107a5760405162461bcd60e51b8152600401610694906130ed565b600d8190556040518181527f523e038e803877ea42acb6426444bcd23d2bbf31ad9f41ea0991762c20ee6d14906020015b60405180910390a150565b601260205281600052604060002081815481106110d257600080fd5b906000526020600020016000915091505080546110ee90613374565b80601f016020809104026020016040519081016040528092919081815260200182805461111a90613374565b80156111675780601f1061113c57610100808354040283529160200191611167565b820191906000526020600020905b81548152906001019060200180831161114a57829003601f168201915b505050505081565b611177611cfb565b6001600160a01b03811661119d5760405162461bcd60e51b8152600401610694906130c4565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527fa1fd6a6669acb930bae242943bb9fa08ddcba665c707261e9730ee0305fb85e5906020016110ab565b6111f3611cfb565b600e5461120a906001600160a01b03168383611d55565b5050565b611216611cfb565b6001600160a01b03811661123c5760405162461bcd60e51b8152600401610694906130c4565b600780546001600160a01b0319166001600160a01b0383169081179091556040519081527f96e60d35957ee680a1536282a3d7e57e96e55cf15f3fc5997088c2b07f411f94906020016110ab565b611292611cfb565b61129c6000611db8565b565b60008381526005602052604090205483906001600160a01b031633146112d65760405162461bcd60e51b81526004016106949061314d565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a26000848152601160209081526040909120835161133892850190612792565b506000848152601560209081526040808320805460ff19166001179055601482528083208690556007546009835281842054600a9093529281902054905163a400a89160e01b81526001600160a01b039093169263a400a891926113a492899288929190600401613085565b600060405180830381600087803b1580156113be57600080fd5b505af11580156113d2573d6000803e3d6000fd5b5050505050505050565b6113e4611cfb565b6001600160a01b03811661140a5760405162461bcd60e51b8152600401610694906130c4565b600380546001600160a01b0319166001600160a01b0383161790556040516001600160a01b03821681527f83b00e25c000adada62072ff4992b6702b635a6e3d57e135bbd60a01be113ead906020016110ab565b60008381526005602052604090205483906001600160a01b031633146114965760405162461bcd60e51b81526004016106949061314d565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a2600084815260126020908152604090912083516114f892850190612792565b506000848152601660209081526040808320805460ff1916600117905560148252808320869055600754600990925291829020549151632f73199d60e01b81526001600160a01b0390911691632f73199d916113a491889187919060040161305c565b611563611cfb565b600f8190556040518181527fa9654d85422e4e0fb6544086f22f928d2d39fe8ab1c13ee9636c64cbdcf99fcb906020016110ab565b6000805b825181101561160657601760008483815181106115c957634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166115f45750600092915050565b806115fe816133a9565b91505061159c565b50600192915050565b611617611cfb565b6001600160a01b03811661163d5760405162461bcd60e51b8152600401610694906130c4565b600280546001600160a01b0319166001600160a01b038316179055600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f0a79df54a5f0809c9853241a307e8bf1dfe87ad5323398cc566df6e3470599906020016110ab565b6008546040516399d9f2b960e01b8152600481018390526060916001600160a01b0316906399d9f2b99060240160006040518083038186803b1580156116eb57600080fd5b505afa1580156116ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117279190810190612a9d565b92915050565b611735611cfb565b6001600160a01b03811661175b5760405162461bcd60e51b8152600401610694906130c4565b601080546001600160a01b0319166001600160a01b0383169081179091556040519081527f3a310361002138b9ae7ac040259a1e871d3263696335223ddf2dc1af218a222b906020016110ab565b6117b1611cfb565b600081116117d15760405162461bcd60e51b8152600401610694906130ed565b600b8190556040518181527f29a88aaedea4371894af2af86b4d24f2cfcbb494532f46b5b761cbc4cc5ff2a3906020016110ab565b6000610a776003546001600160a01b031690565b611822611cfb565b600081116118425760405162461bcd60e51b8152600401610694906130ed565b600c8190556040518181527f2e959719b856a4dda43c92d8d13eb48b37668b25366584f6167cf86b653df9f6906020016110ab565b601160205281600052604060002081815481106110d257600080fd5b60008381526005602052604090205483906001600160a01b031633146118cb5760405162461bcd60e51b81526004016106949061314d565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a26000848152601360209081526040909120835161192d92850190612792565b506000848152601460209081526040808320869055601790915290819020805460ff191660011790556007549051631ecbaea760e11b81526001600160a01b0390911690633d975d4e906113a49087908690600401613043565b6000805b825181101561160657601560008483815181106119b857634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff166119e35750600092915050565b806119ed816133a9565b91505061198b565b6000805b82518110156116065760166000848381518110611a2657634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16611a515750600092915050565b80611a5b816133a9565b9150506119f9565b601360205281600052604060002081815481106110d257600080fd5b611a87611cfb565b6001600160a01b038116611aec5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610694565b610a6081611db8565b600654600160a01b900460ff161561129c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610694565b611b4a612757565b611b52612757565b611b5e81868686611e0a565b9150505b9392505050565b6080830151611b789083611e50565b6080830151611b879082611e67565b505050565b6080830151611b9b9083611e50565b611ba88360800151611e8c565b60005b8151811015611c0457611bf2828281518110611bd757634e487b7160e01b600052603260045260246000fd5b60200260200101518560800151611e5090919063ffffffff16565b80611bfc816133a9565b915050611bab565b50611b878360800151611e97565b600e5461120a906001600160a01b0316833084611ea2565b600354600090611b62906001600160a01b03168484611ee0565b6000611c58853063c7f7007960e01b611b42565b6040805180820190915260048152636461746560e01b6020820152909150611c8290829085611b69565b6040805180820190915260078152661cdc1bdc9d125960ca1b6020820152611cac90829086611b69565b8151156107425760408051808201909152600781526667616d6549647360c81b602082015261074290829084611b8c565b6080830151611cec9083611e50565b6080830151611b879082611e50565b6006546001600160a01b0316331461129c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610694565b6040516001600160a01b038316602482015260448101829052611b8790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611f73565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611e12612757565b611e228560800151610100612045565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b611e5d82600383516120aa565b611b8782826121b1565b6001600160401b03811115611e805761120a82826121d8565b61120a826000836120aa565b610a6081600461220f565b610a6081600761220f565b6040516001600160a01b0380851660248301528316604482015260648101829052611eda9085906323b872dd60e01b90608401611d81565b50505050565b600454600090611ef181600161320f565b600455835160408086015160808701515191516000936320214ca360e11b93611f299386938493923092918a91600191602401612f67565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050611f6986838684612224565b9695505050505050565b6000611fc8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166123919092919063ffffffff16565b805190915015611b875780806020019051810190611fe69190612c0b565b611b875760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610694565b6040805180820190915260608152600060208201526120656020836133c4565b1561208d576120756020836133c4565b612080906020613331565b61208a908361320f565b91505b506020828101829052604080518085526000815290920101905290565b6017816001600160401b0316116120ce57611eda8360e0600585901b1683176123a0565b60ff816001600160401b03161161210a576120f4836018611fe0600586901b16176123a0565b50611eda836001600160401b03831660016123c5565b61ffff816001600160401b03161161214757612131836019611fe0600586901b16176123a0565b50611eda836001600160401b03831660026123c5565b63ffffffff816001600160401b0316116121865761217083601a611fe0600586901b16176123a0565b50611eda836001600160401b03831660046123c5565b61219b83601b611fe0600586901b16176123a0565b50611eda836001600160401b03831660086123c5565b604080518082019091526060815260006020820152611b62838460000151518485516123eb565b6121e38260c26123a0565b5061120a82826040516020016121fb91815260200190565b6040516020818303038152906040526124d5565b611b8782601f611fe0600585901b16176123a0565b6040516bffffffffffffffffffffffff193060601b1660208201526034810184905260009060540160408051808303601f1901815282825280516020918201206000818152600590925291812080546001600160a01b0319166001600160a01b038a1617905590925082917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af99190a2600254604051630200057560e51b81526001600160a01b0390911690634000aea0906122e790889087908790600401612fcf565b602060405180830381600087803b15801561230157600080fd5b505af1158015612315573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123399190612c0b565b611e485760405162461bcd60e51b815260206004820152602360248201527f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261604482015262636c6560e81b6064820152608401610694565b6060611e4884846000856124e2565b604080518082019091526060815260006020820152611b628384600001515184612613565b604080518082019091526060815260006020820152611e4884856000015151858561266f565b604080518082019091526060815260006020820152825182111561240e57600080fd5b602085015161241d838661320f565b111561245057612450856124408760200151878661243b919061320f565b6126f0565b61244b906002613312565b612707565b60008086518051876020830101935080888701111561246f5787860182525b505050602084015b602084106124af578051825261248e60208361320f565b915061249b60208261320f565b90506124a8602085613331565b9350612477565b51815160001960208690036101000a019081169019919091161790525083949350505050565b611e5d82600283516120aa565b6060824710156125435760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610694565b6001600160a01b0385163b61259a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610694565b600080866001600160a01b031685876040516125b69190612f4b565b60006040518083038185875af1925050503d80600081146125f3576040519150601f19603f3d011682016040523d82523d6000602084013e6125f8565b606091505b509150915061260882828661271e565b979650505050505050565b6040805180820190915260608152600060208201528360200151831061264857612648848560200151600261244b9190613312565b835180516020858301018481535080851415612665576001810182525b5093949350505050565b6040805180820190915260608152600060208201526020850151612693858461320f565b11156126a7576126a785612440868561320f565b600060016126b78461010061326a565b6126c19190613331565b90508551838682010185831982511617815250805184870111156126e55783860181525b509495945050505050565b600081831115612701575081611727565b50919050565b81516127138383612045565b50611eda83826121b1565b6060831561272d575081611b62565b82511561273d5782518084602001fd5b8160405162461bcd60e51b815260040161069491906130b1565b6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b8280548282559060005260206000209081019282156127df579160200282015b828111156127df57825180516127cf9184916020909101906127ef565b50916020019190600101906127b2565b506127eb92915061286f565b5090565b8280546127fb90613374565b90600052602060002090601f01602090048101928261281d5760008555612863565b82601f1061283657805160ff1916838001178555612863565b82800160010185558215612863579182015b82811115612863578251825591602001919060010190612848565b506127eb92915061288c565b808211156127eb57600061288382826128a1565b5060010161286f565b5b808211156127eb576000815560010161288d565b5080546128ad90613374565b6000825580601f106128bd575050565b601f016020900490600052602060002090810190610a60919061288c565b60006128ee6128e9846131e8565b613195565b905082815283838301111561290257600080fd5b828260208301376000602084830101529392505050565b600082601f830112612929578081fd5b813560206129396128e9836131c5565b80838252828201915082860187848660051b8901011115612958578586fd5b855b858110156129985781356001600160401b03811115612977578788fd5b6129858a87838c01016129a5565b855250928401929084019060010161295a565b5090979650505050505050565b600082601f8301126129b5578081fd5b611b62838335602085016128db565b6000602082840312156129d5578081fd5b8135611b6281613410565b600080604083850312156129f2578081fd5b82356129fd81613410565b946020939093013593505050565b60006020808385031215612a1d578182fd5b82356001600160401b03811115612a32578283fd5b8301601f81018513612a42578283fd5b8035612a506128e9826131c5565b80828252848201915084840188868560051b8701011115612a6f578687fd5b8694505b83851015612a91578035835260019490940193918501918501612a73565b50979650505050505050565b60006020808385031215612aaf578182fd5b82516001600160401b03811115612ac4578283fd5b8301601f81018513612ad4578283fd5b8051612ae26128e9826131c5565b80828252848201915084840188868560051b8701011115612b01578687fd5b8694505b83851015612a91578051835260019490940193918501918501612b05565b60006020808385031215612b35578182fd5b82516001600160401b0380821115612b4b578384fd5b818501915085601f830112612b5e578384fd5b8151612b6c6128e9826131c5565b80828252858201915085850189878560051b8801011115612b8b578788fd5b875b84811015612bfc57815186811115612ba357898afd5b8701603f81018c13612bb357898afd5b888101516040612bc56128e9836131e8565b8281528e82848601011115612bd8578c8dfd5b612be7838d8301848701613348565b87525050509287019290870190600101612b8d565b50909998505050505050505050565b600060208284031215612c1c578081fd5b81518015158114611b62578182fd5b600060208284031215612c3c578081fd5b5035919050565b60008060008060808587031215612c58578182fd5b8435935060208501356001600160401b03811115612c74578283fd5b612c80878288016129a5565b949794965050505060408301359260600135919050565b60008060008060008060c08789031215612caf578384fd5b8635955060208701356001600160401b0380821115612ccc578586fd5b612cd88a838b016129a5565b965060408901359550606089013594506080890135915080821115612cfb578384fd5b612d078a838b01612919565b935060a0890135915080821115612d1c578283fd5b50612d2989828a01612919565b9150509295509295509295565b60008060408385031215612d48578182fd5b50508035926020909101359150565b600080600060608486031215612d6b578081fd5b8335925060208085013592506040808601356001600160401b0380821115612d91578485fd5b818801915088601f830112612da4578485fd5b8135612db26128e9826131c5565b8082825286820191508685018c888560051b8801011115612dd1578889fd5b885b84811015612e1c57813586811115612de9578a8bfd5b8701603f81018f13612df9578a8bfd5b612e098f8b8301358b84016128db565b8552509288019290880190600101612dd3565b5050809750505050505050509250925092565b60008060008060808587031215612e44578182fd5b84359350602085013592506040850135915060608501356001600160401b03811115612e6e578182fd5b612e7a87828801612919565b91505092959194509250565b600060208284031215612e97578081fd5b5051919050565b600080600060608486031215612eb2578081fd5b8351925060208401519150604084015190509250925092565b600081518084526020808501808196508360051b81019150828601855b85811015612f12578284038952612f00848351612f1f565b98850198935090840190600101612ee8565b5091979650505050505050565b60008151808452612f37816020860160208601613348565b601f01601f19169290920160200192915050565b60008251612f5d818460208701613348565b9190910192915050565b6001600160a01b0389811682526020820189905260408201889052861660608201526001600160e01b03198516608082015260a0810184905260c0810183905261010060e08201819052600090612fc083820185612f1f565b9b9a5050505050505050505050565b60018060a01b0384168152826020820152606060408201526000612ff66060830184612f1f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156130375783518352928401929184019160010161301b565b50909695505050505050565b828152604060208201526000611e486040830184612ecb565b8381526060602082015260006130756060830185612ecb565b9050826040830152949350505050565b84815260806020820152600061309e6080830186612ecb565b6040830194909452506060015292915050565b602081526000611b626020830184612f1f565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b6020808252600f908201526e43616e206e6f74206265207a65726f60881b604082015260600190565b60208082526018908201527f53706f72744964206973206e6f7420737570706f727465640000000000000000604082015260600190565b60208082526028908201527f536f75726365206d75737420626520746865206f7261636c65206f6620746865604082015267081c995c5d595cdd60c21b606082015260800190565b604051601f8201601f191681016001600160401b03811182821017156131bd576131bd6133fa565b604052919050565b60006001600160401b038211156131de576131de6133fa565b5060051b60200190565b60006001600160401b03821115613201576132016133fa565b50601f01601f191660200190565b60008219821115613222576132226133e4565b500190565b600181815b80851115613262578160001904821115613248576132486133e4565b8085161561325557918102915b93841c939080029061322c565b509250929050565b6000611b62838360008261328057506001611727565b8161328d57506000611727565b81600181146132a357600281146132ad576132c9565b6001915050611727565b60ff8411156132be576132be6133e4565b50506001821b611727565b5060208310610133831016604e8410600b84101617156132ec575081810a611727565b6132f68383613227565b806000190482111561330a5761330a6133e4565b029392505050565b600081600019048311821515161561332c5761332c6133e4565b500290565b600082821015613343576133436133e4565b500390565b60005b8381101561336357818101518382015260200161334b565b83811115611eda5750506000910152565b600181811c9082168061338857607f821691505b6020821081141561270157634e487b7160e01b600052602260045260246000fd5b60006000198214156133bd576133bd6133e4565b5060010190565b6000826133df57634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a6057600080fdfea26469706673582212208932709a31fbc334667459d5b69e3ee789acc3a6d6c76d77c5ac971524c0684764736f6c63430008040033

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

000000000000000000000000dc2cc710e42857672e7907cf474a69b63b93089f000000000000000000000000e7b1e93b6e79970b699a4daeb40dcd709ac876ea000000000000000000000000db6eb989127d0c33bc630d7b5b53f87ceced3ce1000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc1000032306464386137383732653434363038623864383232396365663336666236380000000000000000000000007465c5d60d3d095443cf9991da03304a30d42eae00000000000000000000000086991efb34b0cf55af38e9dace3f82cd8b70188f

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

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000dc2cc710e42857672e7907cf474a69b63b93089f
Arg [1] : 000000000000000000000000e7b1e93b6e79970b699a4daeb40dcd709ac876ea
Arg [2] : 000000000000000000000000db6eb989127d0c33bc630d7b5b53f87ceced3ce1
Arg [3] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [4] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [5] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [6] : 3230646438613738373265343436303862386438323239636566333666623638
Arg [7] : 0000000000000000000000007465c5d60d3d095443cf9991da03304a30d42eae
Arg [8] : 00000000000000000000000086991efb34b0cf55af38e9dace3f82cd8b70188f


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