false
false

Contract Address Details

0x111a9bba0cE975A818AAa079926e986eCc2D572E

Contract Name
AccessControlledOffchai..regator
Creator
0x7b11d3–9d29aa at 0x50472f–aca6b8
Balance
0 KCS
Tokens
Fetching tokens...
Transactions
637,717 Transactions
Transfers
0 Transfers
Gas Used
60,846,087,610
Last Balance Update
44722916
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify.
Contract name:
AccessControlledOffchainAggregator




Optimization enabled
true
Compiler version
v0.7.6+commit.7338295f




Optimization runs
1000000
EVM Version
default




Verified at
2024-01-27T16:55:07.374713Z

Constructor Arguments

0x000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000010000000000000000000000000009515646b5833526dff12fae9b03754c7f0e0a8f000000000000000000000000e0d0e68297772dd5a1f1d99897c581e2082dba5b000000000000000000000000d39d4d972c7e166856c4eb29e54d3548b4597f5300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000009455448202f205553440000000000000000000000000000000000000000000000

Arg [0] (uint8) : 95
Arg [1] (uint8) : 105
Arg [2] (uint8) : 8
Arg [3] (string) : ETH / USD
Arg [4] (address) : 0x09515646b5833526dff12fae9b03754c7f0e0a8f
Arg [5] (address) : 0xe0d0e68297772dd5a1f1d99897c581e2082dba5b
Arg [6] (address) : 0xd39d4d972c7e166856c4eb29e54d3548b4597f53
Arg [7] (bool) : true

              

Contract source code

// Sources flattened with hardhat v2.12.7 https://hardhat.org

// File contracts/v0.7/interfaces/IERC2362.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;

/**
 * @dev EIP2362 Interface for pull oracles
 * https://github.com/adoracles/EIPs/blob/erc-2362/EIPS/eip-2362.md
 */
interface IERC2362 {
  /**
   * @dev Exposed function pertaining to EIP standards
   * @param _id bytes32 ID of the query
   * @return int,uint,uint returns the value, timestamp, and status code of query
   */
  function valueFor(bytes32 _id)
    external
    view
    returns (
      int256,
      uint256,
      uint256
    );
}


// File contracts/v0.7/interfaces/IMojitoOracle.sol





interface IMojitoOracle {
  function getMojitoTwap(bytes32 pairId) external view returns (uint256);

  function currencyPairId(string memory) external view returns (bytes32);

  function lookupERC2362ID(bytes32 _erc2362id) external view returns (string memory _caption);
}


// File contracts/v0.7/interfaces/IPythOracle.sol


contract PythStructs {
  // A price with a degree of uncertainty, represented as a price +- a confidence interval.
  //
  // The confidence interval roughly corresponds to the standard error of a normal distribution.
  // Both the price and confidence are stored in a fixed-point numeric representation,
  // `x * (10^expo)`, where `expo` is the exponent.
  //
  // Please refer to the documentation at https://docs.pyth.network/consumers/best-practices for how
  // to how this price safely.
  struct Price {
    // Price
    int64 price;
    // Confidence interval around the price
    uint64 conf;
    // Price exponent
    int32 expo;
    // Unix timestamp describing when the price was published
    uint256 publishTime;
  }

  // PriceFeed represents a current aggregate price from pyth publisher feeds.
  struct PriceFeed {
    // The price ID.
    bytes32 id;
    // Latest available price
    Price price;
    // Latest available exponentially-weighted moving average price
    Price emaPrice;
  }
}

interface IPythOracle {
  function getPriceUnsafe(bytes32 id) external view returns (PythStructs.Price memory price);
}


// File contracts/v0.7/interfaces/OwnableInterface.sol




interface OwnableInterface {
  function owner() external returns (address);

  function transferOwnership(address recipient) external;

  function acceptOwnership() external;
}


// File contracts/v0.7/ConfirmedOwnerWithProposal.sol




/**
 * @title The ConfirmedOwner contract
 * @notice A contract with helpers for basic contract ownership.
 */
contract ConfirmedOwnerWithProposal is OwnableInterface {
  address private s_owner;
  address private s_pendingOwner;

  event OwnershipTransferRequested(address indexed from, address indexed to);
  event OwnershipTransferred(address indexed from, address indexed to);

  constructor(address newOwner, address pendingOwner) {
    require(newOwner != address(0), "Cannot set owner to zero");

    s_owner = newOwner;
    if (pendingOwner != address(0)) {
      _transferOwnership(pendingOwner);
    }
  }

  /**
   * @notice Allows an owner to begin transferring ownership to a new address,
   * pending.
   */
  function transferOwnership(address to) public override onlyOwner {
    _transferOwnership(to);
  }

  /**
   * @notice Allows an ownership transfer to be completed by the recipient.
   */
  function acceptOwnership() external override {
    require(msg.sender == s_pendingOwner, "Must be proposed owner");

    address oldOwner = s_owner;
    s_owner = msg.sender;
    s_pendingOwner = address(0);

    emit OwnershipTransferred(oldOwner, msg.sender);
  }

  /**
   * @notice Get the current owner
   */
  function owner() public view override returns (address) {
    return s_owner;
  }

  /**
   * @notice validate, transfer ownership, and emit relevant events
   */
  function _transferOwnership(address to) private {
    require(to != msg.sender, "Cannot transfer to self");

    s_pendingOwner = to;

    emit OwnershipTransferRequested(s_owner, to);
  }

  /**
   * @notice validate access
   */
  function _validateOwnership() internal view {
    require(msg.sender == s_owner, "Only callable by owner");
  }

  /**
   * @notice Reverts if called by anyone other than the contract owner.
   */
  modifier onlyOwner() {
    _validateOwnership();
    _;
  }
}


// File contracts/v0.7/ConfirmedOwner.sol




/**
 * @title The ConfirmedOwner contract
 * @notice A contract with helpers for basic contract ownership.
 */
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
  constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}


// File contracts/v0.7/OwnerIsCreator.sol




/**
 * @title The OwnerIsCreator contract
 * @notice A contract with helpers for basic contract ownership.
 */
contract OwnerIsCreator is ConfirmedOwner {
  constructor() ConfirmedOwner(msg.sender) {}
}


// File contracts/v0.7/SafeMath.sol




/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
  /**
   * @dev Returns the multiplication of two unsigned integers, reverting on
   * overflow.
   *
   * Counterpart to Solidity's `*` operator.
   *
   * Requirements:
   * - Multiplication cannot overflow.
   */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b, "SafeMath: multiplication overflow");

    return c;
  }

  /**
   * @dev Returns the integer division of two unsigned integers. Reverts on
   * division by zero. The result is rounded towards zero.
   *
   * Counterpart to Solidity's `/` operator. Note: this function uses a
   * `revert` opcode (which leaves remaining gas untouched) while Solidity
   * uses an invalid opcode to revert (consuming all remaining gas).
   *
   * Requirements:
   * - The divisor cannot be zero.
   */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // Solidity only automatically asserts when dividing by 0
    require(b > 0, "SafeMath: division by zero");
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }
}


contract AnchoredView is OwnerIsCreator {
  using SafeMath for uint256;

  bool public validateAnswerEnabled;
  /// @notice how many digits of precision to retain, in 1e-decimals token units
  uint256 public immutable answerBaseUnit;

  struct MojitoConfig {
    bool available;
    bytes32 pairA;
    uint256 pairABaseUnit;
  }

  MojitoConfig internal mojitoConfig;

  /// @notice emitted when mojito config are set
  event MojitoConfigSet(bool available, bytes32 pairA, uint256 pairABaseUnit);

  struct PythConfig {
    bool available;
    uint256 stalenessSeconds;
    bytes32 priceFeedId;
    uint256 decimals;
  }

  PythConfig internal pythConfig;

  /// @notice emitted when pyth config are set
  event PythConfigSet(bool available, uint256 stalenessSeconds, bytes32 priceFeedId, uint256 decimals);

  struct WitnetConfig {
    bool available;
    bytes32 pairA;
    bytes32 pairB;
    uint256 pairABaseUnit;
    uint256 pairBBaseUnit;
  }

  WitnetConfig internal witnetConfig;

  /// @notice emitted when witnet config are set
  event WitnetConfigSet(bool available, bytes32 pairA, bytes32 pairB, uint256 pairABaseUnit, uint256 pairBBaseUnit);

  // The price oracle
  IMojitoOracle public mojitoOracle;
  IPythOracle public pythOracle;
  IERC2362 public witnetOracle;

  /**
   * @notice emitted when a new mojito oracle contract is set
   * @param old the address prior to the current setting
   * @param current the address of the new mojito oracle contract
   */
  event MojitoOracleSet(IMojitoOracle old, IMojitoOracle current);

  /**
   * @notice emitted when a new pyth oracle contract is set
   * @param old the address prior to the current setting
   * @param current the address of the new witnet oracle contract
   */
  event PythOracleSet(IPythOracle old, IPythOracle current);

  /**
   * @notice emitted when a new witnet oracle contract is set
   * @param old the address prior to the current setting
   * @param current the address of the new witnet oracle contract
   */
  event WitnetOracleSet(IERC2362 old, IERC2362 current);

  event ValidateAnswerEnabled();
  event ValidateAnswerDisabled();

  /*
   * @param _mojitoOracle address of the mojito oracle contract
   * @param _pythOracle address of the pyth oracle contract
   * @param _witnetOracle address of the witnet oracle contract
   * @param _decimals answers are stored in fixed-point format, with this many digits of precision
   * @param _validateAnswerEnabled whether to enable the switch for validate answer
   */
  constructor(
    address _mojitoOracle,
    address _pythOracle,
    address _witnetOracle,
    uint8 _decimals,
    bool _validateAnswerEnabled
  ) {
    _setMojitoOracle(IMojitoOracle(_mojitoOracle));
    _setPythOracle(IPythOracle(_pythOracle));
    _setWitnetOracle(IERC2362(_witnetOracle));
    // pow(10, _decimals)
    answerBaseUnit = 10**_decimals;
    validateAnswerEnabled = _validateAnswerEnabled;
  }

  /**
   * @notice sets the mojito twap oracle
   * @param _oracle the address of the mojito oracle contract
   */
  function setMojitoOracle(IMojitoOracle _oracle) external onlyOwner {
    _setMojitoOracle(_oracle);
  }

  function _setMojitoOracle(IMojitoOracle _oracle) internal {
    IMojitoOracle oldOracle = mojitoOracle;
    if (_oracle != oldOracle) {
      mojitoOracle = _oracle;
      emit MojitoOracleSet(oldOracle, _oracle);
    }
  }

  /**
   * @notice sets the mojito twap oracle
   * @param _oracle the address of the mojito oracle contract
   */
  function setPythOracle(IPythOracle _oracle) external onlyOwner {
    _setPythOracle(_oracle);
  }

  function _setPythOracle(IPythOracle _oracle) internal {
    IPythOracle oldOracle = pythOracle;
    if (_oracle != oldOracle) {
      pythOracle = _oracle;
      emit PythOracleSet(oldOracle, _oracle);
    }
  }

  /**
   * @notice sets the witnet oracle
   * @param _oracle the address of the witnet oracle contract
   */
  function setWitnetOracle(IERC2362 _oracle) external onlyOwner {
    _setWitnetOracle(_oracle);
  }

  function _setWitnetOracle(IERC2362 _oracle) internal {
    IERC2362 oldOracle = witnetOracle;
    if (_oracle != oldOracle) {
      witnetOracle = _oracle;
      emit WitnetOracleSet(oldOracle, _oracle);
    }
  }

  function _getMojitoPriceInternal() internal view returns (uint256) {
    if (mojitoConfig.available) {
      uint256 twapPrice = mojitoOracle.getMojitoTwap(mojitoConfig.pairA);
      return twapPrice.mul(answerBaseUnit).div(mojitoConfig.pairABaseUnit);
    }
    return 0;
  }

  function _getPythPriceInternal() internal view returns (uint256) {
    if (pythConfig.available) {
      PythStructs.Price memory retrievedPrice = pythOracle.getPriceUnsafe(pythConfig.priceFeedId);
      uint256 stalenessSeconds = pythConfig.stalenessSeconds;
      if (diff(block.timestamp, retrievedPrice.publishTime) <= stalenessSeconds) {
        uint256 baseConvertion = 10**uint256(int256(pythConfig.decimals) + retrievedPrice.expo);
        return uint256(retrievedPrice.price * int256(baseConvertion));
      }
      return 0;
    }
    return 0;
  }

  function _getWitnetPriceInternal() internal view returns (uint256) {
    if (witnetConfig.available) {
      int256 pairAPrice;
      (pairAPrice, , ) = witnetOracle.valueFor(witnetConfig.pairA);
      if (witnetConfig.pairB == "") {
        return uint256(pairAPrice).mul(answerBaseUnit).div(witnetConfig.pairABaseUnit);
      } else {
        int256 pairBPrice;
        (pairBPrice, , ) = witnetOracle.valueFor(witnetConfig.pairB);
        return
          uint256(pairAPrice).mul(uint256(pairBPrice)).mul(answerBaseUnit).div(witnetConfig.pairABaseUnit).div(
            witnetConfig.pairBBaseUnit
          );
      }
    }
    return 0;
  }

  /**
   * @notice sets mojito parameters
   * @param _available is the price available
   * @param _pairA pairA erc2362 asset id
   * @param _pairABaseUnit pairA decimals
   * @dev must be called by owner
   */
  function setMojitoConfig(
    bool _available,
    bytes32 _pairA,
    uint256 _pairABaseUnit
  ) external onlyOwner {
    mojitoConfig.available = _available;
    mojitoConfig.pairA = _pairA;
    mojitoConfig.pairABaseUnit = _pairABaseUnit;
    emit MojitoConfigSet(_available, _pairA, _pairABaseUnit);
  }

  /*
   * @notice gets the mojito config
   * @return The config object
   */
  function getMojitoConfig()
    external
    view
    returns (
      bool available,
      bytes32 pairA,
      uint256 pairABaseUnit
    )
  {
    return (mojitoConfig.available, mojitoConfig.pairA, mojitoConfig.pairABaseUnit);
  }

  /**
   * @notice sets pyth parameters
   * @param _available is the price available
   * @param _stalenessSeconds is how long before we consider the feed price to be stale
   * @param _priceFeedId the price feed ids for evm chains differs depending on whether they are a mainnet or testnet
   * @param _decimals converted price decimal
   * @dev must be called by owner
   */
  function setPythConfig(
    bool _available,
    uint256 _stalenessSeconds,
    bytes32 _priceFeedId,
    uint256 _decimals
  ) external onlyOwner {
    pythConfig.available = _available;
    pythConfig.stalenessSeconds = _stalenessSeconds;
    pythConfig.priceFeedId = _priceFeedId;
    pythConfig.decimals = _decimals;
    emit PythConfigSet(_available, _stalenessSeconds, _priceFeedId, _decimals);
  }

  /*
   * @notice gets the pyth config
   * @return The config object
   */
  function getPythConfig()
    external
    view
    returns (
      bool available,
      uint256 stalenessSeconds,
      bytes32 priceFeedId,
      uint256 decimals
    )
  {
    return (pythConfig.available, pythConfig.stalenessSeconds, pythConfig.priceFeedId, pythConfig.decimals);
  }

  /**
   * @notice sets winet parameters
   * @param _available is the price available
   * @param _pairA pairA erc2362 asset id
   * @param _pairB pairB erc2362 asset id, optimal exchange rate when used
   * @param _pairABaseUnit pairA decimals
   * @param _pairBBaseUnit pairB decimals
   * @dev must be called by owner
   */
  function setWitnetConfig(
    bool _available,
    bytes32 _pairA,
    bytes32 _pairB,
    uint256 _pairABaseUnit,
    uint256 _pairBBaseUnit
  ) external onlyOwner {
    witnetConfig.available = _available;
    witnetConfig.pairA = _pairA;
    witnetConfig.pairB = _pairB;
    witnetConfig.pairABaseUnit = _pairABaseUnit;
    witnetConfig.pairBBaseUnit = _pairBBaseUnit;
    emit WitnetConfigSet(_available, _pairA, _pairB, _pairABaseUnit, _pairBBaseUnit);
  }

  /*
   * @notice gets the witnet config
   * @return The config object
   */
  function getWitnetConfig()
    external
    view
    returns (
      bool available,
      bytes32 pairA,
      bytes32 pairB,
      uint256 pairABaseUnit,
      uint256 pairBBaseUnit
    )
  {
    return (
      witnetConfig.available,
      witnetConfig.pairA,
      witnetConfig.pairB,
      witnetConfig.pairABaseUnit,
      witnetConfig.pairBBaseUnit
    );
  }

  /**
   * @notice Get the mojito oracle twap for a underlying
   * @return Price denominated in USD, with 8 decimals
   */
  function getMojitoPrice() external view returns (uint256) {
    return _getMojitoPriceInternal();
  }

  /**
   * @notice Get the pyth oracle price for a underlying
   * @return Price denominated in USD, with 8 decimals
   */
  function getPythPrice() external view returns (uint256) {
    return _getPythPriceInternal();
  }

  /**
   * @notice Get the witnet oracle price for a underlying
   * @return Price denominated in USD, with 8 decimals
   */
  function getWitnetPrice() external view returns (uint256) {
    return _getWitnetPriceInternal();
  }

  /**
   * @notice makes the answer validate enforced
   */
  function enableAnswerValidate() external onlyOwner {
    if (!validateAnswerEnabled) {
      validateAnswerEnabled = true;

      emit ValidateAnswerEnabled();
    }
  }

  /**
   * @notice makes the answer validate unenforced
   */
  function disableAnswerValidate() external onlyOwner {
    if (validateAnswerEnabled) {
      validateAnswerEnabled = false;

      emit ValidateAnswerDisabled();
    }
  }

  function diff(uint256 x, uint256 y) internal pure returns (uint256) {
    if (x > y) {
      return x - y;
    } else {
      return y - x;
    }
  }
}


// File contracts/v0.7/interfaces/AccessControllerInterface.sol




interface AccessControllerInterface {
  function hasAccess(address user, bytes calldata data) external view returns (bool);
}


// File contracts/v0.7/interfaces/AggregatorInterface.sol




interface AggregatorInterface {
  function latestAnswer() external view returns (int256);

  function latestTimestamp() external view returns (uint256);

  function latestRound() external view returns (uint256);

  function getAnswer(uint256 roundId) external view returns (int256);

  function getTimestamp(uint256 roundId) external view returns (uint256);

  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);
  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);
}


// File contracts/v0.7/interfaces/AggregatorV3Interface.sol




interface AggregatorV3Interface {
  function decimals() external view returns (uint8);

  function description() external view returns (string memory);

  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}


// File contracts/v0.7/interfaces/AggregatorV2V3Interface.sol





interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}


// File contracts/v0.7/interfaces/TypeAndVersionInterface.sol




abstract contract TypeAndVersionInterface {
  function typeAndVersion() external pure virtual returns (string memory);
}


// File contracts/v0.7/OffchainAggregator.sol









/**
  * @notice Onchain verification of reports from the offchain reporting protocol

  * @dev For details on its operation, see the offchain reporting protocol design
  * @dev doc, which refers to this contract as simply the "contract".
*/
contract OffchainAggregator is OwnerIsCreator, AggregatorV2V3Interface, TypeAndVersionInterface, AnchoredView {
  using SafeMath for uint256;
  // Storing these fields used on the hot path in a HotVars variable reduces the
  // retrieval of all of them to a single SLOAD. If any further fields are
  // added, make sure that storage of the struct still takes at most 32 bytes.
  struct HotVars {
    // Oracle Aggregators expose a roundId to consumers. The offchain reporting
    // protocol does not use this id anywhere. We increment it whenever a new
    // transmission is made to provide callers with contiguous ids for successive
    // reports.
    uint32 latestAggregatorRoundId;
  }
  HotVars internal s_hotVars;

  // Transmission records the median answer from the transmit transaction at time timestamp
  struct Transmission {
    int192 answer; // 192 bits ought to be enough for anyone
    uint32 observationsTimestamp; // when were observations made offchain
    uint32 transmissionTimestamp; // when was report received onchain
  }
  mapping(uint32 => Transmission) /* aggregator round ID */
    internal s_transmissions;

  // incremented each time a new config is posted. This count is incorporated
  // into the config digest to prevent replay attacks.
  uint32 internal s_configCount;

  // makes it easier for offchain systems to extract config from logs
  uint32 internal s_latestConfigBlockNumber;

  // makes it easier for offchain systems to extract config from logs
  address internal s_latestTransmitter;

  // lowest answers for calculating the old price or the anchor price
  uint8 public lowerBoundAnchorRatio; //0.8e2
  // highest answers for calculating the old price or the anchor price
  uint8 public upperBoundAnchorRatio; //1.2e2

  uint8 internal constant minLowerBoundAnchorRatio = 0.8e2;
  uint8 internal constant maxUpperBoundAnchorRatio = 1.2e2;

  struct Transmitter {
    bool active;
    // Index of oracle in s_signersList/s_transmittersList
    uint8 index;
  }
  mapping(address => Transmitter) /* transmitter address */
    internal s_transmitters;

  struct Signer {
    bool active;
    // Index of oracle in s_signersList/s_transmittersList
    uint8 index;
  }
  mapping(address => Signer) /* signer address */
    internal s_signers;

  // s_signersList contains the signing address of each oracle
  address[] internal s_signersList;

  // s_transmittersList contains the transmission address of each oracle,
  // i.e. the address the oracle actually sends transactions to the contract from
  address[] internal s_transmittersList;

  /*
   * @param _lowerBoundAnchorRatio lowest answers for calculating the old price or the anchor price
   * @param _upperBoundAnchorRatio highest answers for calculating the old price or the anchor price
   * @param _decimals answers are stored in fixed-point format, with this many digits of precision
   * @param _description short human-readable description of observable this contract's answers pertain to
   * @param _mojitoOracle address of the mojito oracle contract
   * @param _pythOracle address of the pyth oracle contract
   * @param _witnetOracle address of the witnet oracle contract
   * @param _validateAnswerEnabled whether to enable the switch for validate answer
   */
  constructor(
    uint8 _lowerBoundAnchorRatio,
    uint8 _upperBoundAnchorRatio,
    uint8 _decimals,
    string memory _description,
    address _mojitoOracle,
    address _pythOracle,
    address _witnetOracle,
    bool _validateAnswerEnabled
  ) AnchoredView(_mojitoOracle, _pythOracle, _witnetOracle, _decimals, _validateAnswerEnabled) {
    lowerBoundAnchorRatio = _lowerBoundAnchorRatio;
    upperBoundAnchorRatio = _upperBoundAnchorRatio;
    decimals = _decimals;
    s_description = _description;
  }

  /*
   * Versioning
   */
  function typeAndVersion() external pure virtual override returns (string memory) {
    return "OffchainAggregator 2.0.0";
  }

  /*
   * AnchorRatio logic
   */

  event AnchorRatioUpdated(uint8 lowerBoundAnchorRatio, uint8 upperBoundAnchorRatio);

  function setAnchorRatio(uint8 _lowerBoundAnchorRatio, uint8 _upperBoundAnchorRatio) external onlyOwner {
    require(
      minLowerBoundAnchorRatio <= _lowerBoundAnchorRatio,
      "lowerBoundAnchorRatio must greater than or equal to minLowerBoundAnchorRatio"
    );
    require(
      maxUpperBoundAnchorRatio >= _upperBoundAnchorRatio,
      "upperBoundAnchorRatio must less than or equal to maxUpperBoundAnchorRatio"
    );
    require(
      _upperBoundAnchorRatio > _lowerBoundAnchorRatio,
      "upperBoundAnchorRatio must less than lowerBoundAnchorRatio"
    );

    lowerBoundAnchorRatio = _lowerBoundAnchorRatio;
    upperBoundAnchorRatio = _upperBoundAnchorRatio;

    emit AnchorRatioUpdated(lowerBoundAnchorRatio, upperBoundAnchorRatio);
  }

  /*
   * Config logic
   */

  /**
   * @notice triggers a new run of the offchain reporting protocol
   * @param previousConfigBlockNumber block in which the previous config was set, to simplify historic analysis
   * @param configCount ordinal number of this config setting among all config settings over the life of this contract
   * @param signers ith element is address ith oracle uses to sign a report
   * @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method
   */
  event ConfigSet(uint32 previousConfigBlockNumber, uint64 configCount, address[] signers, address[] transmitters);

  /**
   * @notice sets offchain reporting protocol configuration incl. participating oracles
   * @param _transmitters addresses oracles use to transmit the reports
   */
  function setConfig(address[] calldata _signers, address[] calldata _transmitters) external onlyOwner {
    require(_signers.length == _transmitters.length, "oracle length mismatch");

    // remove any old signer/transmitter addresses
    uint256 oldLength = s_signersList.length;
    for (uint256 i = 0; i < oldLength; i++) {
      address signer = s_signersList[i];
      address transmitter = s_transmittersList[i];
      delete s_signers[signer];
      delete s_transmitters[transmitter];
    }
    delete s_signersList;
    delete s_transmittersList;

    // add new signer/transmitter addresses
    for (uint256 i = 0; i < _signers.length; i++) {
      require(!s_signers[_signers[i]].active, "repeated signer address");
      s_signers[_signers[i]] = Signer({active: true, index: uint8(i)});
      require(!s_transmitters[_transmitters[i]].active, "repeated transmitter address");
      s_transmitters[_transmitters[i]] = Transmitter({active: true, index: uint8(i)});
    }
    s_signersList = _signers;
    s_transmittersList = _transmitters;

    uint32 previousConfigBlockNumber = s_latestConfigBlockNumber;
    s_latestConfigBlockNumber = uint32(block.number);
    s_configCount += 1;

    emit ConfigSet(previousConfigBlockNumber, s_configCount, _signers, _transmitters);
  }

  /**
   * @notice information about current offchain reporting protocol configuration
   * @return configCount ordinal number of current config, out of all configs applied to this contract so far
   * @return blockNumber block at which this config was set
   */
  function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber) {
    return (s_configCount, s_latestConfigBlockNumber);
  }

  /**
   * @return list of addresses permitted to transmit reports to this contract
   * @dev The list will match the order used to specify the transmitter during setConfig
   */
  function getTransmitters() external view returns (address[] memory) {
    return s_transmittersList;
  }

  /*
   * Transmission logic
   */

  /**
   * @notice indicates that a new report was transmitted
   * @param aggregatorRoundId the round to which this report was assigned
   * @param answer median of the observations attached this report
   * @param transmitter address from which the report was transmitted
   * @param observationsTimestamp when were observations made offchain
   */
  event NewTransmission(
    uint32 indexed aggregatorRoundId,
    int192 answer,
    address transmitter,
    uint32 observationsTimestamp
  );

  /*
   * @notice details about the most transmission details
   * @return nextTransmitter who will be next to transmit the report
   * @return afterNextTransmitter who will transmit the report next afterwards
   * @return nextIndex the index of the next transmitter
   * @return length the length of the s_transmittersList
   * @return roundId aggregator round of latest report
   * @return answer median value from latest report
   * @return startedAt when the latest report was transmitted
   * @return updatedAt when the latest report was transmitted
   */
  function latestTransmissionDetails()
    external
    view
    returns (
      address nextTransmitter,
      address afterNextTransmitter,
      uint8 nextIndex,
      uint256 transmittersLength,
      uint80 roundId,
      int192 answer,
      uint256 startedAt,
      uint256 updatedAt
    )
  {
    require(msg.sender == tx.origin, "Only callable by EOA");

    nextIndex = 0;
    uint8 afterNextIndex = 0;

    // Calculating the index of the next transmitter
    uint256 s_length = s_transmittersList.length;
    if (s_length > 0) {
      // the index of the current transmitter
      Transmitter memory s_transmitter;
      s_transmitter = s_transmitters[s_latestTransmitter];
      if (s_transmitter.active) {
        nextIndex = s_transmitter.index;
        nextIndex++;
        if (s_length == nextIndex) {
          nextIndex = 0;
        }
      }

      afterNextIndex = nextIndex;
      afterNextIndex++;
      if (s_length == afterNextIndex) {
        afterNextIndex = 0;
      }

      nextTransmitter = s_transmittersList[nextIndex];
      afterNextTransmitter = s_transmittersList[afterNextIndex];
    }

    roundId = s_hotVars.latestAggregatorRoundId;
    Transmission memory transmission = s_transmissions[uint32(roundId)];
    return (
      nextTransmitter,
      afterNextTransmitter,
      nextIndex,
      s_length,
      roundId,
      transmission.answer,
      transmission.observationsTimestamp,
      transmission.transmissionTimestamp
    );
  }

  // The constant-length components of the msg.data sent to transmit.
  // See the "If we wanted to call sam" example on for example reasoning
  // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html
  uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT =
    4 + // function selector
      32 + // word containing start location of abiencoded _report value
      32 + // _rs value
      32 + // _ss value
      32 + // _vs value
      32 + // word containing length of _report
      0; // placeholder

  function expectedMsgDataLength() private pure returns (uint256 length) {
    // calldata will never be big enough to make this overflow
    return
      uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) +
      64 + // one byte pure entry in _report
      0; // placeholder
  }

  /**
   * @notice transmit is called to post a new report to the contract
   * @param _report serialized report, which the signatures are signing. See parsing code below for format.
   * @param _rs the R components of the signature on report.
   * @param _ss the S components of the signature on report.
   * @param _vs the V component of the signature on report.
   */
  function transmit(
    // NOTE: If these parameters are changed, expectedMsgDataLength and/or
    // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly
    bytes calldata _report,
    // ECDSA signature
    bytes32 _rs,
    bytes32 _ss,
    uint8 _vs
  ) external {
    require(s_transmitters[msg.sender].active, "unauthorized transmitter");

    require(msg.data.length == expectedMsgDataLength(), "transmit message length mismatch");

    uint192 median;
    uint32 observationsTimestamp;
    (median, observationsTimestamp) = abi.decode(_report, (uint192, uint32));

    uint32 s_latestTimestamp = s_transmissions[s_hotVars.latestAggregatorRoundId].transmissionTimestamp;
    require(observationsTimestamp > s_latestTimestamp, "invalid observations timestamp");

    // Verify signatures attached to report
    {
      bytes32 h = keccak256(_report);

      Signer memory signer;
      address signerAddress = ecrecover(h, _vs + 27, _rs, _ss);
      signer = s_signers[signerAddress];
      require(signer.active, "signature error");
    }

    if (validateAnswerEnabled) {
      if (_validateAnswer(uint256(median))) {
        _transmit(int192(median), observationsTimestamp);
      }
    } else {
      uint256 previousAnswer = uint192(s_transmissions[s_hotVars.latestAggregatorRoundId].answer);
      if (previousAnswer > 0) {
        require(isWithinAnchor(median, previousAnswer), "median is out of min-max range");
      }
      _transmit(int192(median), observationsTimestamp);
    }
  }

  function transmitWithForce(uint192 median) external onlyOwner {
    _transmit(int192(median), uint32(block.timestamp));
  }

  function _transmit(int192 median, uint32 observationsTimestamp) internal {
    HotVars memory hotVars = s_hotVars; // cache read from storage
    hotVars.latestAggregatorRoundId++;
    s_transmissions[hotVars.latestAggregatorRoundId] = Transmission({
      answer: median,
      observationsTimestamp: observationsTimestamp,
      transmissionTimestamp: uint32(block.timestamp)
    });

    s_latestTransmitter = msg.sender;
    emit NewTransmission(hotVars.latestAggregatorRoundId, median, msg.sender, observationsTimestamp);
    // Emit these for backwards compatability with offchain consumers
    // that only support legacy events
    emit NewRound(
      hotVars.latestAggregatorRoundId,
      address(0x0), // use zero address since we don't have anybody "starting" the round here
      observationsTimestamp
    );
    emit AnswerUpdated(median, hotVars.latestAggregatorRoundId, block.timestamp);

    // persist updates to hotVars
    s_hotVars = hotVars;
  }

  /// @notice The event emitted when new prices are posted but the stored price is not updated due to the anchor
  event AnswerGuarded(
    uint32 indexed aggregatorRoundId,
    uint256 reporterPrice,
    uint256 anchorMojitoPrice,
    uint256 anchorPythPrice,
    uint256 anchorWitnetPrice,
    uint256 updatedAt
  );

  /**
   * @notice This is called by the reporter whenever a new price is posted on-chain
   * @param reporterPrice the price from the reporter
   * @return valid bool
   */
  function _validateAnswer(uint256 reporterPrice) internal returns (bool) {
    uint256 anchorMojitoPrice = _getMojitoPriceInternal();

    if (isWithinAnchor(reporterPrice, anchorMojitoPrice)) {
      return true;
    } else {
      uint256 anchorPythPrice = _getPythPriceInternal();
      if (isWithinAnchor(reporterPrice, anchorPythPrice)) {
        return true;
      } else {
        uint256 anchorWitnetPrice = _getWitnetPriceInternal();
        if (isWithinAnchor(reporterPrice, anchorWitnetPrice)) {
          return true;
        } else {
          emit AnswerGuarded(
            s_hotVars.latestAggregatorRoundId + 1,
            reporterPrice,
            anchorMojitoPrice,
            anchorPythPrice,
            anchorWitnetPrice,
            block.timestamp
          );
          return false;
        }
      }
    }
  }

  /**
   * @notice This is called by the reporter whenever a new price is posted on-chain
   * @param reporterPrice the price from the reporter
   * @param anchorPrice the price from the other contract
   * @return valid bool
   */
  function isWithinAnchor(uint256 reporterPrice, uint256 anchorPrice) internal view returns (bool) {
    if (reporterPrice > 0 && anchorPrice > 0) {
      uint256 minAnswer = anchorPrice.mul(lowerBoundAnchorRatio).div(1e2);
      uint256 maxAnswer = anchorPrice.mul(upperBoundAnchorRatio).div(1e2);
      return minAnswer <= reporterPrice && reporterPrice <= maxAnswer;
    }
    return false;
  }

  /*
   * v2 Aggregator interface
   */

  /**
   * @notice median from the most recent report
   */
  function latestAnswer() public view virtual override returns (int256) {
    return s_transmissions[s_hotVars.latestAggregatorRoundId].answer;
  }

  /**
   * @notice timestamp of block in which last report was transmitted
   */
  function latestTimestamp() public view virtual override returns (uint256) {
    return s_transmissions[s_hotVars.latestAggregatorRoundId].transmissionTimestamp;
  }

  /**
   * @notice Aggregator round (NOT OCR round) in which last report was transmitted
   */
  function latestRound() public view virtual override returns (uint256) {
    return s_hotVars.latestAggregatorRoundId;
  }

  /**
   * @notice median of report from given aggregator round (NOT OCR round)
   * @param _roundId the aggregator round of the target report
   */
  function getAnswer(uint256 _roundId) public view virtual override returns (int256) {
    if (_roundId > 0xFFFFFFFF) {
      return 0;
    }
    return s_transmissions[uint32(_roundId)].answer;
  }

  /**
   * @notice timestamp of block in which report from given aggregator round was transmitted
   * @param _roundId aggregator round (NOT OCR round) of target report
   */
  function getTimestamp(uint256 _roundId) public view virtual override returns (uint256) {
    if (_roundId > 0xFFFFFFFF) {
      return 0;
    }
    return s_transmissions[uint32(_roundId)].transmissionTimestamp;
  }

  /*
   * v3 Aggregator interface
   */

  string private constant V3_NO_DATA_ERROR = "No data present";

  /**
   * @return answers are stored in fixed-point format, with this many digits of precision
   */
  uint8 public immutable override decimals;

  /**
   * @notice aggregator contract version
   */
  uint256 public constant override version = 2;

  string internal s_description;

  /**
   * @notice human-readable description of observable this contract is reporting on
   */
  function description() public view virtual override returns (string memory) {
    return s_description;
  }

  /**
   * @notice details for the given aggregator round
   * @param _roundId target aggregator round (NOT OCR round). Must fit in uint32
   * @return roundId _roundId
   * @return answer median of report from given _roundId
   * @return startedAt timestamp of block in which report from given _roundId was transmitted
   * @return updatedAt timestamp of block in which report from given _roundId was transmitted
   * @return answeredInRound _roundId
   */
  function getRoundData(uint80 _roundId)
    public
    view
    virtual
    override
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    require(_roundId <= 0xFFFFFFFF, V3_NO_DATA_ERROR);
    Transmission memory transmission = s_transmissions[uint32(_roundId)];
    return (
      _roundId,
      transmission.answer,
      transmission.observationsTimestamp,
      transmission.transmissionTimestamp,
      _roundId
    );
  }

  /**
   * @notice aggregator details for the most recently transmitted report
   * @return roundId aggregator round of latest report (NOT OCR round)
   * @return answer median of latest report
   * @return startedAt timestamp of block containing latest report
   * @return updatedAt timestamp of block containing latest report
   * @return answeredInRound aggregator round of latest report
   */
  function latestRoundData()
    public
    view
    virtual
    override
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    roundId = s_hotVars.latestAggregatorRoundId;

    // Skipped for compatability with existing FluxAggregator in which latestRoundData never reverts.
    // require(roundId != 0, V3_NO_DATA_ERROR);

    Transmission memory transmission = s_transmissions[uint32(roundId)];
    return (
      roundId,
      transmission.answer,
      transmission.observationsTimestamp,
      transmission.transmissionTimestamp,
      roundId
    );
  }
}


// File contracts/v0.7/SimpleWriteAccessController.sol





/**
 * @title SimpleWriteAccessController
 * @notice Gives access to accounts explicitly added to an access list by the
 * controller's owner.
 * @dev does not make any special permissions for externally, see
 * SimpleReadAccessController for that.
 */
contract SimpleWriteAccessController is AccessControllerInterface, OwnerIsCreator {
  bool public checkEnabled;
  mapping(address => bool) internal accessList;

  event AddedAccess(address user);
  event RemovedAccess(address user);
  event CheckAccessEnabled();
  event CheckAccessDisabled();

  constructor() {
    checkEnabled = true;
  }

  /**
   * @notice Returns the access of an address
   * @param _user The address to query
   */
  function hasAccess(address _user, bytes memory) public view virtual override returns (bool) {
    return accessList[_user] || !checkEnabled;
  }

  /**
   * @notice Adds an address to the access list
   * @param _user The address to add
   */
  function addAccess(address _user) external onlyOwner {
    if (!accessList[_user]) {
      accessList[_user] = true;

      emit AddedAccess(_user);
    }
  }

  /**
   * @notice Removes an address from the access list
   * @param _user The address to remove
   */
  function removeAccess(address _user) external onlyOwner {
    if (accessList[_user]) {
      accessList[_user] = false;

      emit RemovedAccess(_user);
    }
  }

  /**
   * @notice makes the access check enforced
   */
  function enableAccessCheck() external onlyOwner {
    if (!checkEnabled) {
      checkEnabled = true;

      emit CheckAccessEnabled();
    }
  }

  /**
   * @notice makes the access check unenforced
   */
  function disableAccessCheck() external onlyOwner {
    if (checkEnabled) {
      checkEnabled = false;

      emit CheckAccessDisabled();
    }
  }

  /**
   * @dev reverts if the caller does not have access
   */
  modifier checkAccess() {
    require(hasAccess(msg.sender, msg.data), "No access");
    _;
  }
}


// File contracts/v0.7/SimpleReadAccessController.sol




/**
 * @title SimpleReadAccessController
 * @notice Gives access to:
 * - any externally owned account (note that offchain actors can always read
 * any contract storage regardless of onchain access control measures, so this
 * does not weaken the access control while improving usability)
 * - accounts explicitly added to an access list
 * @dev SimpleReadAccessController is not suitable for access controlling writes
 * since it grants any externally owned account access! See
 * SimpleWriteAccessController for that.
 */
contract SimpleReadAccessController is SimpleWriteAccessController {
  /**
   * @notice Returns the access of an address
   * @param _user The address to query
   */
  function hasAccess(address _user, bytes memory _calldata) public view virtual override returns (bool) {
    return super.hasAccess(_user, _calldata) || _user == tx.origin;
  }
}


// File contracts/v0.7/AccessControlledOffchainAggregator.sol





/**
 * @notice Wrapper of OffchainAggregator which checks read access on Aggregator-interface methods
 */
contract AccessControlledOffchainAggregator is OffchainAggregator, SimpleReadAccessController {
  constructor(
    uint8 _lowerBoundAnchorRatio,
    uint8 _upperBoundAnchorRatio,
    uint8 _decimals,
    string memory _description,
    address _mojitoOracle,
    address _pythOracle,
    address _witnetOracle,
    bool _validateAnswerEnabled
  )
    OffchainAggregator(
      _lowerBoundAnchorRatio,
      _upperBoundAnchorRatio,
      _decimals,
      _description,
      _mojitoOracle,
      _pythOracle,
      _witnetOracle,
      _validateAnswerEnabled
    )
  {}

  /*
   * Versioning
   */

  function typeAndVersion() external pure virtual override returns (string memory) {
    return "AccessControlledOffchainAggregator 2.0.0";
  }

  /*
   * v2 Aggregator interface
   */

  /// @inheritdoc OffchainAggregator
  function latestAnswer() public view override checkAccess returns (int256) {
    return super.latestAnswer();
  }

  /// @inheritdoc OffchainAggregator
  function latestTimestamp() public view override checkAccess returns (uint256) {
    return super.latestTimestamp();
  }

  /// @inheritdoc OffchainAggregator
  function latestRound() public view override checkAccess returns (uint256) {
    return super.latestRound();
  }

  /// @inheritdoc OffchainAggregator
  function getAnswer(uint256 _roundId) public view override checkAccess returns (int256) {
    return super.getAnswer(_roundId);
  }

  /// @inheritdoc OffchainAggregator
  function getTimestamp(uint256 _roundId) public view override checkAccess returns (uint256) {
    return super.getTimestamp(_roundId);
  }

  /*
   * v3 Aggregator interface
   */

  /// @inheritdoc OffchainAggregator
  function description() public view override checkAccess returns (string memory) {
    return super.description();
  }

  /// @inheritdoc OffchainAggregator
  function getRoundData(uint80 _roundId)
    public
    view
    override
    checkAccess
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    return super.getRoundData(_roundId);
  }

  /// @inheritdoc OffchainAggregator
  function latestRoundData()
    public
    view
    override
    checkAccess
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    return super.latestRoundData();
  }
}
        

Contract ABI

[{"type":"constructor","inputs":[{"type":"uint8","name":"_lowerBoundAnchorRatio","internalType":"uint8"},{"type":"uint8","name":"_upperBoundAnchorRatio","internalType":"uint8"},{"type":"uint8","name":"_decimals","internalType":"uint8"},{"type":"string","name":"_description","internalType":"string"},{"type":"address","name":"_mojitoOracle","internalType":"address"},{"type":"address","name":"_pythOracle","internalType":"address"},{"type":"address","name":"_witnetOracle","internalType":"address"},{"type":"bool","name":"_validateAnswerEnabled","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addAccess","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"answerBaseUnit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"checkEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"description","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disableAccessCheck","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disableAnswerValidate","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableAccessCheck","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableAnswerValidate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"getAnswer","inputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"available","internalType":"bool"},{"type":"bytes32","name":"pairA","internalType":"bytes32"},{"type":"uint256","name":"pairABaseUnit","internalType":"uint256"}],"name":"getMojitoConfig","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMojitoPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"available","internalType":"bool"},{"type":"uint256","name":"stalenessSeconds","internalType":"uint256"},{"type":"bytes32","name":"priceFeedId","internalType":"bytes32"},{"type":"uint256","name":"decimals","internalType":"uint256"}],"name":"getPythConfig","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPythPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int256","name":"answer","internalType":"int256"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"},{"type":"uint80","name":"answeredInRound","internalType":"uint80"}],"name":"getRoundData","inputs":[{"type":"uint80","name":"_roundId","internalType":"uint80"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTimestamp","inputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getTransmitters","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"available","internalType":"bool"},{"type":"bytes32","name":"pairA","internalType":"bytes32"},{"type":"bytes32","name":"pairB","internalType":"bytes32"},{"type":"uint256","name":"pairABaseUnit","internalType":"uint256"},{"type":"uint256","name":"pairBBaseUnit","internalType":"uint256"}],"name":"getWitnetConfig","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getWitnetPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasAccess","inputs":[{"type":"address","name":"_user","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"latestAnswer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"configCount","internalType":"uint32"},{"type":"uint32","name":"blockNumber","internalType":"uint32"}],"name":"latestConfigDetails","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestRound","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int256","name":"answer","internalType":"int256"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"},{"type":"uint80","name":"answeredInRound","internalType":"uint80"}],"name":"latestRoundData","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"nextTransmitter","internalType":"address"},{"type":"address","name":"afterNextTransmitter","internalType":"address"},{"type":"uint8","name":"nextIndex","internalType":"uint8"},{"type":"uint256","name":"transmittersLength","internalType":"uint256"},{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int192","name":"answer","internalType":"int192"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"}],"name":"latestTransmissionDetails","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"lowerBoundAnchorRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IMojitoOracle"}],"name":"mojitoOracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPythOracle"}],"name":"pythOracle","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeAccess","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAnchorRatio","inputs":[{"type":"uint8","name":"_lowerBoundAnchorRatio","internalType":"uint8"},{"type":"uint8","name":"_upperBoundAnchorRatio","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setConfig","inputs":[{"type":"address[]","name":"_signers","internalType":"address[]"},{"type":"address[]","name":"_transmitters","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMojitoConfig","inputs":[{"type":"bool","name":"_available","internalType":"bool"},{"type":"bytes32","name":"_pairA","internalType":"bytes32"},{"type":"uint256","name":"_pairABaseUnit","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMojitoOracle","inputs":[{"type":"address","name":"_oracle","internalType":"contract IMojitoOracle"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPythConfig","inputs":[{"type":"bool","name":"_available","internalType":"bool"},{"type":"uint256","name":"_stalenessSeconds","internalType":"uint256"},{"type":"bytes32","name":"_priceFeedId","internalType":"bytes32"},{"type":"uint256","name":"_decimals","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPythOracle","inputs":[{"type":"address","name":"_oracle","internalType":"contract IPythOracle"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWitnetConfig","inputs":[{"type":"bool","name":"_available","internalType":"bool"},{"type":"bytes32","name":"_pairA","internalType":"bytes32"},{"type":"bytes32","name":"_pairB","internalType":"bytes32"},{"type":"uint256","name":"_pairABaseUnit","internalType":"uint256"},{"type":"uint256","name":"_pairBBaseUnit","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWitnetOracle","inputs":[{"type":"address","name":"_oracle","internalType":"contract IERC2362"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"to","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transmit","inputs":[{"type":"bytes","name":"_report","internalType":"bytes"},{"type":"bytes32","name":"_rs","internalType":"bytes32"},{"type":"bytes32","name":"_ss","internalType":"bytes32"},{"type":"uint8","name":"_vs","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transmitWithForce","inputs":[{"type":"uint192","name":"median","internalType":"uint192"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"typeAndVersion","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"upperBoundAnchorRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"validateAnswerEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"version","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC2362"}],"name":"witnetOracle","inputs":[]},{"type":"event","name":"AddedAccess","inputs":[{"type":"address","name":"user","indexed":false}],"anonymous":false},{"type":"event","name":"AnchorRatioUpdated","inputs":[{"type":"uint8","name":"lowerBoundAnchorRatio","indexed":false},{"type":"uint8","name":"upperBoundAnchorRatio","indexed":false}],"anonymous":false},{"type":"event","name":"AnswerGuarded","inputs":[{"type":"uint32","name":"aggregatorRoundId","indexed":true},{"type":"uint256","name":"reporterPrice","indexed":false},{"type":"uint256","name":"anchorMojitoPrice","indexed":false},{"type":"uint256","name":"anchorPythPrice","indexed":false},{"type":"uint256","name":"anchorWitnetPrice","indexed":false},{"type":"uint256","name":"updatedAt","indexed":false}],"anonymous":false},{"type":"event","name":"AnswerUpdated","inputs":[{"type":"int256","name":"current","indexed":true},{"type":"uint256","name":"roundId","indexed":true},{"type":"uint256","name":"updatedAt","indexed":false}],"anonymous":false},{"type":"event","name":"CheckAccessDisabled","inputs":[],"anonymous":false},{"type":"event","name":"CheckAccessEnabled","inputs":[],"anonymous":false},{"type":"event","name":"ConfigSet","inputs":[{"type":"uint32","name":"previousConfigBlockNumber","indexed":false},{"type":"uint64","name":"configCount","indexed":false},{"type":"address[]","name":"signers","indexed":false},{"type":"address[]","name":"transmitters","indexed":false}],"anonymous":false},{"type":"event","name":"MojitoConfigSet","inputs":[{"type":"bool","name":"available","indexed":false},{"type":"bytes32","name":"pairA","indexed":false},{"type":"uint256","name":"pairABaseUnit","indexed":false}],"anonymous":false},{"type":"event","name":"MojitoOracleSet","inputs":[{"type":"address","name":"old","indexed":false},{"type":"address","name":"current","indexed":false}],"anonymous":false},{"type":"event","name":"NewRound","inputs":[{"type":"uint256","name":"roundId","indexed":true},{"type":"address","name":"startedBy","indexed":true},{"type":"uint256","name":"startedAt","indexed":false}],"anonymous":false},{"type":"event","name":"NewTransmission","inputs":[{"type":"uint32","name":"aggregatorRoundId","indexed":true},{"type":"int192","name":"answer","indexed":false},{"type":"address","name":"transmitter","indexed":false},{"type":"uint32","name":"observationsTimestamp","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferRequested","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true}],"anonymous":false},{"type":"event","name":"PythConfigSet","inputs":[{"type":"bool","name":"available","indexed":false},{"type":"uint256","name":"stalenessSeconds","indexed":false},{"type":"bytes32","name":"priceFeedId","indexed":false},{"type":"uint256","name":"decimals","indexed":false}],"anonymous":false},{"type":"event","name":"PythOracleSet","inputs":[{"type":"address","name":"old","indexed":false},{"type":"address","name":"current","indexed":false}],"anonymous":false},{"type":"event","name":"RemovedAccess","inputs":[{"type":"address","name":"user","indexed":false}],"anonymous":false},{"type":"event","name":"ValidateAnswerDisabled","inputs":[],"anonymous":false},{"type":"event","name":"ValidateAnswerEnabled","inputs":[],"anonymous":false},{"type":"event","name":"WitnetConfigSet","inputs":[{"type":"bool","name":"available","indexed":false},{"type":"bytes32","name":"pairA","indexed":false},{"type":"bytes32","name":"pairB","indexed":false},{"type":"uint256","name":"pairABaseUnit","indexed":false},{"type":"uint256","name":"pairBBaseUnit","indexed":false}],"anonymous":false},{"type":"event","name":"WitnetOracleSet","inputs":[{"type":"address","name":"old","indexed":false},{"type":"address","name":"current","indexed":false}],"anonymous":false}]
              

Contract Creation Code

Verify & Publish
0x60c06040523480156200001157600080fd5b506040516200421c3803806200421c833981016040819052620000349162000432565b8787878787878787838383888433806000816200006e5760405162461bcd60e51b8152600401620000659062000591565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000a157620000a18162000188565b505050620000b5856200020560201b60201c565b620000c08462000279565b620000cb83620002df565b60ff918216600a0a6080526001805460ff60a01b1916600160a01b921515929092029190911790556013805460ff60e01b1916600160e01b8e8416021760ff60e81b1916600160e81b928d169290920291909117905550505060f886901b7fff000000000000000000000000000000000000000000000000000000000000001660a05284516200016390601890602088019062000346565b50506019805460ff1916600117905550620005ff9d5050505050505050505050505050565b6001600160a01b038116331415620001b45760405162461bcd60e51b81526004016200006590620005c8565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600e546001600160a01b0390811690821681146200027557600e80546001600160a01b0319166001600160a01b0384161790556040517f9d835f4731b75b6c2365317484d718ea9ba2102b89b5547092f7fe1c6fea5c29906200026c908390859062000577565b60405180910390a15b5050565b600f546001600160a01b0390811690821681146200027557600f80546001600160a01b0319166001600160a01b0384161790556040517e4e195fa31ccc70d4b5113711cee69b9f2059118d18832686a27d19e62a953f906200026c908390859062000577565b6010546001600160a01b0390811690821681146200027557601080546001600160a01b0319166001600160a01b0384161790556040517f5308b9ec263489f989284cee03c20f22af06d25e5758670c809795165997ea83906200026c908390859062000577565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200037e5760008555620003c9565b82601f106200039957805160ff1916838001178555620003c9565b82800160010185558215620003c9579182015b82811115620003c9578251825591602001919060010190620003ac565b50620003d7929150620003db565b5090565b5b80821115620003d75760008155600101620003dc565b80516001600160a01b03811681146200040a57600080fd5b919050565b805180151581146200040a57600080fd5b805160ff811681146200040a57600080fd5b600080600080600080600080610100898b0312156200044f578384fd5b6200045a8962000420565b975060206200046b818b0162000420565b97506200047b60408b0162000420565b60608b01519097506001600160401b038082111562000498578687fd5b818c0191508c601f830112620004ac578687fd5b815181811115620004b957fe5b604051601f8201601f1916810185018381118282101715620004d757fe5b60405281815283820185018f1015620004ee578889fd5b8892505b81831015620005115783830185015181840186015291840191620004f2565b818311156200052257888583830101525b80995050505050506200053860808a01620003f2565b93506200054860a08a01620003f2565b92506200055860c08a01620003f2565b91506200056860e08a016200040f565b90509295985092959890939650565b6001600160a01b0392831681529116602082015260400190565b60208082526018908201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604082015260600190565b60208082526017908201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604082015260600190565b60805160a05160f81c613be7620006356000398061081d5250806111725280611f8d528061207e5280612b3e5250613be76000f3fe608060405234801561001057600080fd5b50600436106103205760003560e01c80638038e4a1116101a7578063b5ab58dc116100ee578063e48d7d1611610097578063f2fde38b11610071578063f2fde38b146105f9578063f5d6ac901461060c578063feaf968c1461061457610320565b8063e48d7d16146105b2578063e5fe4577146105ca578063f27f55c0146105e657610320565b8063d2266a4d116100c8578063d2266a4d1461058b578063dc7f012414610593578063dd76c8e11461059b57610320565b8063b5ab58dc1461055d578063b633620c14610570578063c76995211461058357610320565b80639795358511610150578063a5db36ed1161012a578063a5db36ed1461052f578063af8477c614610542578063b2310a401461054a57610320565b806397953585146104e55780639a6fc8f5146104f8578063a118f2491461051c57610320565b80638823da6c116101815780638823da6c146104c25780638da5cb5b146104d557806392b84357146104dd57610320565b80638038e4a11461049c57806381ff7048146104a45780638205bf6a146104ba57610320565b80635106257e1161026b578063666cab8d116102145780637284e416116101ee5780637284e41614610479578063789a0e611461048157806379ba50971461049457610320565b8063666cab8d14610449578063668a0f021461045e5780636b14daf81461046657610320565b8063622bd11811610245578063622bd1181461041b578063632042b41461042e5780636659d9201461044157610320565b80635106257e146103f657806352c48571146103fe57806354fd4d501461041357610320565b806324105209116102cd578063420d2d63116102a7578063420d2d63146103d357806343c417a2146103db57806350d25bcd146103ee57610320565b806324105209146103a157806326300a3b146103b6578063313ce567146103cb57610320565b8063181f5a77116102fe578063181f5a7714610360578063194d4d9a146103755780631f7674821461038e57610320565b80630490fd1d146103255780630a7569831461033a57806311b36ce514610342575b600080fd5b61033861033336600461306c565b61061c565b005b61033861069b565b61034a610702565b60405161035791906134a3565b60405180910390f35b610368610712565b6040516103579190613528565b61037d610732565b604051610357959493929190613449565b61033861039c36600461309e565b61074e565b6103a96107d5565b6040516103579190613b21565b6103be6107ff565b6040516103579190613360565b6103a961081b565b61033861083f565b6103386103e93660046130d6565b6108bd565b61034a610c01565b61034a610c82565b610406610c8c565b604051610357919061343e565b61034a610cad565b610338610429366004612eec565b610cb2565b61033861043c366004612fc2565b610cc6565b61034a611170565b610451611194565b60405161035791906133e4565b61034a611203565b610406610474366004612f08565b611284565b6103686112b9565b61033861048f366004612eec565b61133a565b61033861134b565b610338611418565b6104ac611480565b604051610357929190613a8d565b61034a611499565b6103386104d0366004612eec565b61151a565b6103be6115d6565b6103a96115f2565b6103386104f33660046132c9565b61161b565b61050b61050636600461329f565b6117c2565b604051610357959493929190613aee565b61033861052a366004612eec565b61185c565b61033861053d366004612eec565b61190f565b610338611920565b61033861055836600461302b565b6119b4565b61034a61056b36600461326f565b611a43565b61034a61057e36600461326f565b611acd565b61034a611b4f565b6103be611b59565b610406611b75565b6105a3611b7e565b6040516103579392919061346e565b6105ba611b92565b6040516103579493929190613486565b6105d2611baa565b604051610357989796959493929190613381565b6103386105f4366004613217565b611d95565b610338610607366004612eec565b611da7565b6103be611db8565b61050b611dd4565b610624611e6c565b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841515179055600382905560048190556040517f2978888affaf766022740d128cfc5375b42a4cdf47a49fd773497210645f8fbf9061068e9085908590859061346e565b60405180910390a1505050565b6106a3611e6c565b60195460ff161561070057601980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b600061070c611ebd565b90505b90565b6060604051806060016040528060288152602001613b8a60289139905090565b600954600a54600b54600c54600d5460ff909416939091929394565b610756611e6c565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515151790556006839055600782905560088190556040517f7047d35996c62dbdf1fc1a1f806c94faa41a95ec10bb837a161bc44836de2e62906107c7908690869086908690613486565b60405180910390a150505050565b6013547d010000000000000000000000000000000000000000000000000000000000900460ff1681565b600e5473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b610847611e6c565b60015474010000000000000000000000000000000000000000900460ff161561070057600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f625848e8e55631f99209e68ae0f6cbe04c01ee090e7addf3b54e93756c58aa9c90600090a1565b3360009081526014602052604090205460ff1661090f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061397f565b60405180910390fd5b6109176120bc565b361461094f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613a24565b60008061095e86880188613231565b60115463ffffffff9081166000908152601260205260409020549294509092507c0100000000000000000000000000000000000000000000000000000000909104811690821681106109dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613607565b600088886040516109ee929190613350565b60405180910390209050610a00612d76565b600060018388601b018b8b60405160008152602001604052604051610a2894939291906134ac565b6020604051602081039080840390855afa158015610a4a573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526015602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290945092509050610af8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906139b6565b505060015474010000000000000000000000000000000000000000900460ff16159050610b5657610b428377ffffffffffffffffffffffffffffffffffffffffffffffff166120c1565b15610b5157610b518383612192565b610bf7565b60115463ffffffff1660009081526012602052604090205460170b77ffffffffffffffffffffffffffffffffffffffffffffffff168015610beb57610bb58477ffffffffffffffffffffffffffffffffffffffffffffffff16826123ff565b610beb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613831565b610bf58484612192565b505b5050505050505050565b6000610c44336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b610c7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c6124b3565b600061070c6124d5565b60015474010000000000000000000000000000000000000000900460ff1681565b600281565b610cba611e6c565b610cc3816125da565b50565b610cce611e6c565b828114610d07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906136f8565b60165460005b81811015610dd057600060168281548110610d2457fe5b60009182526020822001546017805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110610d5857fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff948516835260158252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915595909116835260149091529020805490921690915550600101610d0d565b50610ddd60166000612d8d565b610de960176000612d8d565b60005b8481101561109b5760156000878784818110610e0457fe5b9050602002016020810190610e199190612eec565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205460ff1615610e7a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061379d565b604080518082019091526001815260ff8216602082015260156000888885818110610ea157fe5b9050602002016020810190610eb69190612eec565b73ffffffffffffffffffffffffffffffffffffffff168152602080820192909252604001600090812083518154949093015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009095169490941792909216929092179055601490858584818110610f5457fe5b9050602002016020810190610f699190612eec565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205460ff1615610fca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906135d0565b604080518082019091526001815260ff8216602082015260146000868685818110610ff157fe5b90506020020160208101906110069190612eec565b73ffffffffffffffffffffffffffffffffffffffff16815260208082019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009094169390931791909116919091179055600101610dec565b506110a860168686612dab565b506110b560178484612dab565b50601380544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff84161780831660010183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909116179384905560405192048116927fe8d070a65cc69d4aaeb20e8cdc65fdd7a656a77ee34614d6758ffd9eac3d1cd09261116092859216908a908a908a908a90613aa4565b60405180910390a1505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606060178054806020026020016040519081016040528092919081815260200182805480156111f957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116111ce575b5050505050905090565b6000611246336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b61127c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c612673565b6000611290838361267f565b806112b0575073ffffffffffffffffffffffffffffffffffffffff831632145b90505b92915050565b60606112fc336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611332576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c6126bc565b611342611e6c565b610cc381612767565b60015473ffffffffffffffffffffffffffffffffffffffff16331461139c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613599565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611420611e6c565b60195460ff1661070057601980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b60135463ffffffff808216916401000000009004169091565b60006114dc336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611512576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c6127fd565b611522611e6c565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601a602052604090205460ff1615610cc35773ffffffffffffffffffffffffffffffffffffffff81166000908152601a60205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d1906115cb908390613360565b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6013547c0100000000000000000000000000000000000000000000000000000000900460ff1681565b611623611e6c565b60ff821660501115611661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613868565b60ff81166078101561169f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613675565b8160ff168160ff16116116de576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906137d4565b6013805460ff8381167d0100000000000000000000000000000000000000000000000000000000009081027fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8388167c01000000000000000000000000000000000000000000000000000000009081027fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff909616959095171617938490556040517ff899e0ea4845aabbeda4bd108029c91ecfd7e0afa5a1eefbdbf436d15a6ffb3c946117b694810484169392900490911690613b2f565b60405180910390a15050565b600080600080600061180b336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611841576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61184a8661283b565b939a9299509097509550909350915050565b611864611e6c565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601a602052604090205460ff16610cc35773ffffffffffffffffffffffffffffffffffffffff81166000908152601a60205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db4906115cb908390613360565b611917611e6c565b610cc381612959565b611928611e6c565b60015474010000000000000000000000000000000000000000900460ff1661070057600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f0b3307cc46a1592167f2a25f93a31437772754c8517ffb3c78ab9d254183300590600090a1565b6119bc611e6c565b600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515179055600a849055600b839055600c829055600d8190556040517fb5e4346584d07c27736121a2e37073a71bed9243ef9c7fed5e18520cda3a859190611a349087908790879087908790613449565b60405180910390a15050505050565b6000611a86336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611abc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b611ac5826129ef565b90505b919050565b6000611b10336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b611ac582612a25565b600061070c612a77565b60105473ffffffffffffffffffffffffffffffffffffffff1681565b60195460ff1681565b60025460035460045460ff90921691909192565b60055460065460075460085460ff9093169290919293565b600080808080808080333214611bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613766565b6017546000965086908015611cfe57611c03612d76565b5060135468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526014602090815260409182902082518084019093525460ff80821615801585526101009092041691830191909152611c7a576020810151600101985060ff8916821415611c7a57600098505b60018901925060ff8316821415611c9057600092505b60178960ff1681548110611ca057fe5b6000918252602090912001546017805473ffffffffffffffffffffffffffffffffffffffff9092169c509060ff8516908110611cd857fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169950505b60115463ffffffff90811660008181526012602090815260409182902082516060810184529054601781810b810b900b8083527801000000000000000000000000000000000000000000000000820487169383018490527c010000000000000000000000000000000000000000000000000000000090910490951692018290529c9d9b9c9a9b939a91995091975095509350915050565b611d9d611e6c565b610cc38142612192565b611daf611e6c565b610cc381612b62565b600f5473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000611e1d336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611e53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b611e5b612c28565b945094509450945094509091929394565b60005473ffffffffffffffffffffffffffffffffffffffff163314610700576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061363e565b60095460009060ff16156120b657601054600a546040517ff78eea8300000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff169163f78eea8391611f2491906004016134a3565b60606040518083038186803b158015611f3c57600080fd5b505afa158015611f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f749190613164565b5050600b54909150611fbf57600c54611fb790611fb1837f0000000000000000000000000000000000000000000000000000000000000000612cb7565b90612d0b565b91505061070f565b601054600b546040517ff78eea8300000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff169163f78eea839161201891906004016134a3565b60606040518083038186803b15801561203057600080fd5b505afa158015612044573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120689190613164565b5050600d54600c549192506120ad91611fb190817f00000000000000000000000000000000000000000000000000000000000000006120a78888612cb7565b90612cb7565b9250505061070f565b50600090565b60e490565b6000806120cc612a77565b90506120d883826123ff565b156120e7576001915050611ac8565b60006120f16124d5565b90506120fd84826123ff565b1561210d57600192505050611ac8565b6000612117611ebd565b905061212385826123ff565b156121345760019350505050611ac8565b60115460405163ffffffff918216600101909116907fe05b0b0de121051cc17d6526f37a1f811848e7e7c61784ff18980391e87f5c119061217e9088908790879087904290613a59565b60405180910390a260009350505050611ac8565b604080516020808201835260115463ffffffff908116600101811683528351606081018552601787810b8252868316828501908152428416838801908152865185166000908152601290965294879020925183549151955185167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9686167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9290940b77ffffffffffffffffffffffffffffffffffffffffffffffff167fffffffffffffffff00000000000000000000000000000000000000000000000090931692909217169190911793909316929092179091556013805468010000000000000000339081027fffffffff0000000000000000000000000000000000000000ffffffffffffffff90921691909117909155825193519293909116917f38567aa999bdbf56a2a0e536f6d3420a6befcc0d5a443f686e3bded71d09157e916123349187919087906134f1565b60405180910390a2805160405160009163ffffffff16907f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac6027190612378908690613a7c565b60405180910390a3806000015163ffffffff168360170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040516123be91906134a3565b60405180910390a351601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790555050565b600080831180156124105750600082115b156124aa5760135460009061245090606490611fb19086907c0100000000000000000000000000000000000000000000000000000000900460ff16612cb7565b60135490915060009061248f90606490611fb19087907d010000000000000000000000000000000000000000000000000000000000900460ff16612cb7565b90508482111580156124a15750808511155b925050506112b3565b50600092915050565b60115463ffffffff16600090815260126020526040902054601790810b900b90565b60055460009060ff16156120b657600f546007546040517f96834ad300000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff16916396834ad39161253c91906004016134a3565b60806040518083038186803b15801561255457600080fd5b505afa158015612568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258c9190613191565b905060006005600101549050806125a7428460600151612d5a565b116125cf57506040810151600854915160070b60039190910b91909101600a0a02905061070f565b60009250505061070f565b600f5473ffffffffffffffffffffffffffffffffffffffff908116908216811461266f57600f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556040517e4e195fa31ccc70d4b5113711cee69b9f2059118d18832686a27d19e62a953f906117b690839085906134ca565b5050565b60115463ffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604081205460ff16806112b057505060195460ff161592915050565b60188054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111f95780601f1061273b576101008083540402835291602001916111f9565b820191906000526020600020905b81548152906001019060200180831161274957509395945050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff908116908216811461266f57600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556040517f9d835f4731b75b6c2365317484d718ea9ba2102b89b5547092f7fe1c6fea5c29906117b690839085906134ca565b60115463ffffffff9081166000908152601260205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b600080600080600063ffffffff8669ffffffffffffffffffff1611156040518060400160405280600f81526020017f4e6f20646174612070726573656e740000000000000000000000000000000000815250906128c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069190613528565b5050505063ffffffff83811660009081526012602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830487169484018590527c01000000000000000000000000000000000000000000000000000000009092049095169190930181905295969190920b949193509091508490565b60105473ffffffffffffffffffffffffffffffffffffffff908116908216811461266f57601080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556040517f5308b9ec263489f989284cee03c20f22af06d25e5758670c809795165997ea83906117b690839085906134ca565b600063ffffffff821115612a0557506000611ac8565b5063ffffffff16600090815260126020526040902054601790810b900b90565b600063ffffffff821115612a3b57506000611ac8565b5063ffffffff9081166000908152601260205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b60025460009060ff16156120b657600e546003546040517f0ca55a8e00000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff1691630ca55a8e91612ade91906004016134a3565b60206040518083038186803b158015612af657600080fd5b505afa158015612b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2e9190613287565b600454909150611fb790611fb1837f0000000000000000000000000000000000000000000000000000000000000000612cb7565b73ffffffffffffffffffffffffffffffffffffffff8116331415612bb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906139ed565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60115463ffffffff90811660008181526012602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830488169484018590527c01000000000000000000000000000000000000000000000000000000009092049096169190930181905292949190930b9291908490565b600082612cc6575060006112b3565b82820282848281612cd357fe5b04146112b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613922565b6000808211612d46576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061372f565b6000828481612d5157fe5b04949350505050565b600081831115612d6d57508082036112b3565b508181036112b3565b604080518082019091526000808252602082015290565b5080546000825590600052602060002090810190610cc39190612e33565b828054828255906000526020600020908101928215612e23579160200282015b82811115612e235781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190612dcb565b50612e2f929150612e33565b5090565b5b80821115612e2f5760008155600101612e34565b60008083601f840112612e59578081fd5b50813567ffffffffffffffff811115612e70578182fd5b6020830191508360208083028501011115612e8a57600080fd5b9250929050565b80358015158114611ac857600080fd5b8051600381900b8114611ac857600080fd5b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611ac857600080fd5b803560ff81168114611ac857600080fd5b600060208284031215612efd578081fd5b81356112b081613b67565b60008060408385031215612f1a578081fd5b8235612f2581613b67565b915060208381013567ffffffffffffffff80821115612f42578384fd5b818601915086601f830112612f55578384fd5b813581811115612f6157fe5b612f91847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613b43565b91508082528784828501011115612fa6578485fd5b8084840185840137810190920192909252919491935090915050565b60008060008060408587031215612fd7578182fd5b843567ffffffffffffffff80821115612fee578384fd5b612ffa88838901612e48565b90965094506020870135915080821115613012578384fd5b5061301f87828801612e48565b95989497509550505050565b600080600080600060a08688031215613042578081fd5b61304b86612e91565b97602087013597506040870135966060810135965060800135945092505050565b600080600060608486031215613080578283fd5b61308984612e91565b95602085013595506040909401359392505050565b600080600080608085870312156130b3578182fd5b6130bc85612e91565b966020860135965060408601359560600135945092505050565b6000806000806000608086880312156130ed578283fd5b853567ffffffffffffffff80821115613104578485fd5b818801915088601f830112613117578485fd5b813581811115613125578586fd5b896020828501011115613136578586fd5b6020928301975095505086013592506040860135915061315860608701612edb565b90509295509295909350565b600080600060608486031215613178578081fd5b8351925060208401519150604084015190509250925092565b6000608082840312156131a2578081fd5b6040516080810167ffffffffffffffff82821081831117156131c057fe5b81604052845191508160070b82146131d6578384fd5b90825260208401519080821682146131ec578384fd5b5060208201526131fe60408401612ea1565b6040820152606083015160608201528091505092915050565b600060208284031215613228578081fd5b6112b082612eb3565b60008060408385031215613243578182fd5b61324c83612eb3565b9150602083013563ffffffff81168114613264578182fd5b809150509250929050565b600060208284031215613280578081fd5b5035919050565b600060208284031215613298578081fd5b5051919050565b6000602082840312156132b0578081fd5b813569ffffffffffffffffffff811681146112b0578182fd5b600080604083850312156132db578182fd5b6132e483612edb565b91506132f260208401612edb565b90509250929050565b60008284526020808501945082825b8581101561334557813561331d81613b67565b73ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161330a565b509495945050505050565b6000828483379101908152919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff988916815296909716602087015260ff949094166040860152606085019290925269ffffffffffffffffffff16608084015260170b60a083015260c082015260e08101919091526101000190565b6020808252825182820181905260009190848201906040850190845b8181101561343257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613400565b50909695505050505050565b901515815260200190565b9415158552602085019390935260408401919091526060830152608082015260a00190565b92151583526020830191909152604082015260600190565b931515845260208401929092526040830152606082015260800190565b90815260200190565b93845260ff9290921660208401526040830152606082015260800190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b60179390930b835273ffffffffffffffffffffffffffffffffffffffff91909116602083015263ffffffff16604082015260600190565b6000602080835283518082850152825b8181101561355457858101830151858201604001528201613538565b818111156135655783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526016908201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604082015260600190565b6020808252601c908201527f7265706561746564207472616e736d6974746572206164647265737300000000604082015260600190565b6020808252601e908201527f696e76616c6964206f62736572766174696f6e732074696d657374616d700000604082015260600190565b60208082526016908201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604082015260600190565b60208082526049908201527f7570706572426f756e64416e63686f72526174696f206d757374206c6573732060408201527f7468616e206f7220657175616c20746f206d61785570706572426f756e64416e60608201527f63686f72526174696f0000000000000000000000000000000000000000000000608082015260a00190565b60208082526016908201527f6f7261636c65206c656e677468206d69736d6174636800000000000000000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526014908201527f4f6e6c792063616c6c61626c6520627920454f41000000000000000000000000604082015260600190565b60208082526017908201527f7265706561746564207369676e65722061646472657373000000000000000000604082015260600190565b6020808252603a908201527f7570706572426f756e64416e63686f72526174696f206d757374206c6573732060408201527f7468616e206c6f776572426f756e64416e63686f72526174696f000000000000606082015260800190565b6020808252601e908201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e67650000604082015260600190565b6020808252604c908201527f6c6f776572426f756e64416e63686f72526174696f206d75737420677265617460408201527f6572207468616e206f7220657175616c20746f206d696e4c6f776572426f756e60608201527f64416e63686f72526174696f0000000000000000000000000000000000000000608082015260a00190565b60208082526009908201527f4e6f206163636573730000000000000000000000000000000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526018908201527f756e617574686f72697a6564207472616e736d69747465720000000000000000604082015260600190565b6020808252600f908201527f7369676e6174757265206572726f720000000000000000000000000000000000604082015260600190565b60208082526017908201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604082015260600190565b6020808252818101527f7472616e736d6974206d657373616765206c656e677468206d69736d61746368604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b63ffffffff91909116815260200190565b63ffffffff92831681529116602082015260400190565b600063ffffffff808916835280881660208401525060806040830152613ace6080830186886132fb565b8281036060840152613ae18185876132fb565b9998505050505050505050565b69ffffffffffffffffffff9586168152602081019490945260408401929092526060830152909116608082015260a00190565b60ff91909116815260200190565b60ff92831681529116602082015260400190565b60405181810167ffffffffffffffff81118282101715613b5f57fe5b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc357600080fdfe416363657373436f6e74726f6c6c65644f6666636861696e41676772656761746f7220322e302e30a2646970667358221220e4b71953822e3578b50a31ee2b3d8da7208c277a8d4affe9b37ef0c8b89b466164736f6c63430007060033000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000010000000000000000000000000009515646b5833526dff12fae9b03754c7f0e0a8f000000000000000000000000e0d0e68297772dd5a1f1d99897c581e2082dba5b000000000000000000000000d39d4d972c7e166856c4eb29e54d3548b4597f5300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000009455448202f205553440000000000000000000000000000000000000000000000

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106103205760003560e01c80638038e4a1116101a7578063b5ab58dc116100ee578063e48d7d1611610097578063f2fde38b11610071578063f2fde38b146105f9578063f5d6ac901461060c578063feaf968c1461061457610320565b8063e48d7d16146105b2578063e5fe4577146105ca578063f27f55c0146105e657610320565b8063d2266a4d116100c8578063d2266a4d1461058b578063dc7f012414610593578063dd76c8e11461059b57610320565b8063b5ab58dc1461055d578063b633620c14610570578063c76995211461058357610320565b80639795358511610150578063a5db36ed1161012a578063a5db36ed1461052f578063af8477c614610542578063b2310a401461054a57610320565b806397953585146104e55780639a6fc8f5146104f8578063a118f2491461051c57610320565b80638823da6c116101815780638823da6c146104c25780638da5cb5b146104d557806392b84357146104dd57610320565b80638038e4a11461049c57806381ff7048146104a45780638205bf6a146104ba57610320565b80635106257e1161026b578063666cab8d116102145780637284e416116101ee5780637284e41614610479578063789a0e611461048157806379ba50971461049457610320565b8063666cab8d14610449578063668a0f021461045e5780636b14daf81461046657610320565b8063622bd11811610245578063622bd1181461041b578063632042b41461042e5780636659d9201461044157610320565b80635106257e146103f657806352c48571146103fe57806354fd4d501461041357610320565b806324105209116102cd578063420d2d63116102a7578063420d2d63146103d357806343c417a2146103db57806350d25bcd146103ee57610320565b806324105209146103a157806326300a3b146103b6578063313ce567146103cb57610320565b8063181f5a77116102fe578063181f5a7714610360578063194d4d9a146103755780631f7674821461038e57610320565b80630490fd1d146103255780630a7569831461033a57806311b36ce514610342575b600080fd5b61033861033336600461306c565b61061c565b005b61033861069b565b61034a610702565b60405161035791906134a3565b60405180910390f35b610368610712565b6040516103579190613528565b61037d610732565b604051610357959493929190613449565b61033861039c36600461309e565b61074e565b6103a96107d5565b6040516103579190613b21565b6103be6107ff565b6040516103579190613360565b6103a961081b565b61033861083f565b6103386103e93660046130d6565b6108bd565b61034a610c01565b61034a610c82565b610406610c8c565b604051610357919061343e565b61034a610cad565b610338610429366004612eec565b610cb2565b61033861043c366004612fc2565b610cc6565b61034a611170565b610451611194565b60405161035791906133e4565b61034a611203565b610406610474366004612f08565b611284565b6103686112b9565b61033861048f366004612eec565b61133a565b61033861134b565b610338611418565b6104ac611480565b604051610357929190613a8d565b61034a611499565b6103386104d0366004612eec565b61151a565b6103be6115d6565b6103a96115f2565b6103386104f33660046132c9565b61161b565b61050b61050636600461329f565b6117c2565b604051610357959493929190613aee565b61033861052a366004612eec565b61185c565b61033861053d366004612eec565b61190f565b610338611920565b61033861055836600461302b565b6119b4565b61034a61056b36600461326f565b611a43565b61034a61057e36600461326f565b611acd565b61034a611b4f565b6103be611b59565b610406611b75565b6105a3611b7e565b6040516103579392919061346e565b6105ba611b92565b6040516103579493929190613486565b6105d2611baa565b604051610357989796959493929190613381565b6103386105f4366004613217565b611d95565b610338610607366004612eec565b611da7565b6103be611db8565b61050b611dd4565b610624611e6c565b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841515179055600382905560048190556040517f2978888affaf766022740d128cfc5375b42a4cdf47a49fd773497210645f8fbf9061068e9085908590859061346e565b60405180910390a1505050565b6106a3611e6c565b60195460ff161561070057601980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b600061070c611ebd565b90505b90565b6060604051806060016040528060288152602001613b8a60289139905090565b600954600a54600b54600c54600d5460ff909416939091929394565b610756611e6c565b600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515151790556006839055600782905560088190556040517f7047d35996c62dbdf1fc1a1f806c94faa41a95ec10bb837a161bc44836de2e62906107c7908690869086908690613486565b60405180910390a150505050565b6013547d010000000000000000000000000000000000000000000000000000000000900460ff1681565b600e5473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000881565b610847611e6c565b60015474010000000000000000000000000000000000000000900460ff161561070057600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f625848e8e55631f99209e68ae0f6cbe04c01ee090e7addf3b54e93756c58aa9c90600090a1565b3360009081526014602052604090205460ff1661090f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061397f565b60405180910390fd5b6109176120bc565b361461094f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613a24565b60008061095e86880188613231565b60115463ffffffff9081166000908152601260205260409020549294509092507c0100000000000000000000000000000000000000000000000000000000909104811690821681106109dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613607565b600088886040516109ee929190613350565b60405180910390209050610a00612d76565b600060018388601b018b8b60405160008152602001604052604051610a2894939291906134ac565b6020604051602081039080840390855afa158015610a4a573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526015602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290945092509050610af8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906139b6565b505060015474010000000000000000000000000000000000000000900460ff16159050610b5657610b428377ffffffffffffffffffffffffffffffffffffffffffffffff166120c1565b15610b5157610b518383612192565b610bf7565b60115463ffffffff1660009081526012602052604090205460170b77ffffffffffffffffffffffffffffffffffffffffffffffff168015610beb57610bb58477ffffffffffffffffffffffffffffffffffffffffffffffff16826123ff565b610beb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613831565b610bf58484612192565b505b5050505050505050565b6000610c44336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b610c7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c6124b3565b600061070c6124d5565b60015474010000000000000000000000000000000000000000900460ff1681565b600281565b610cba611e6c565b610cc3816125da565b50565b610cce611e6c565b828114610d07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906136f8565b60165460005b81811015610dd057600060168281548110610d2457fe5b60009182526020822001546017805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110610d5857fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff948516835260158252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915595909116835260149091529020805490921690915550600101610d0d565b50610ddd60166000612d8d565b610de960176000612d8d565b60005b8481101561109b5760156000878784818110610e0457fe5b9050602002016020810190610e199190612eec565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205460ff1615610e7a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061379d565b604080518082019091526001815260ff8216602082015260156000888885818110610ea157fe5b9050602002016020810190610eb69190612eec565b73ffffffffffffffffffffffffffffffffffffffff168152602080820192909252604001600090812083518154949093015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009095169490941792909216929092179055601490858584818110610f5457fe5b9050602002016020810190610f699190612eec565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205460ff1615610fca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906135d0565b604080518082019091526001815260ff8216602082015260146000868685818110610ff157fe5b90506020020160208101906110069190612eec565b73ffffffffffffffffffffffffffffffffffffffff16815260208082019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009094169390931791909116919091179055600101610dec565b506110a860168686612dab565b506110b560178484612dab565b50601380544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff84161780831660010183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909116179384905560405192048116927fe8d070a65cc69d4aaeb20e8cdc65fdd7a656a77ee34614d6758ffd9eac3d1cd09261116092859216908a908a908a908a90613aa4565b60405180910390a1505050505050565b7f0000000000000000000000000000000000000000000000000000000005f5e10081565b606060178054806020026020016040519081016040528092919081815260200182805480156111f957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116111ce575b5050505050905090565b6000611246336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b61127c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c612673565b6000611290838361267f565b806112b0575073ffffffffffffffffffffffffffffffffffffffff831632145b90505b92915050565b60606112fc336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611332576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c6126bc565b611342611e6c565b610cc381612767565b60015473ffffffffffffffffffffffffffffffffffffffff16331461139c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613599565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611420611e6c565b60195460ff1661070057601980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b60135463ffffffff808216916401000000009004169091565b60006114dc336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611512576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61070c6127fd565b611522611e6c565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601a602052604090205460ff1615610cc35773ffffffffffffffffffffffffffffffffffffffff81166000908152601a60205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d1906115cb908390613360565b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6013547c0100000000000000000000000000000000000000000000000000000000900460ff1681565b611623611e6c565b60ff821660501115611661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613868565b60ff81166078101561169f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613675565b8160ff168160ff16116116de576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906137d4565b6013805460ff8381167d0100000000000000000000000000000000000000000000000000000000009081027fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8388167c01000000000000000000000000000000000000000000000000000000009081027fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff909616959095171617938490556040517ff899e0ea4845aabbeda4bd108029c91ecfd7e0afa5a1eefbdbf436d15a6ffb3c946117b694810484169392900490911690613b2f565b60405180910390a15050565b600080600080600061180b336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611841576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b61184a8661283b565b939a9299509097509550909350915050565b611864611e6c565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601a602052604090205460ff16610cc35773ffffffffffffffffffffffffffffffffffffffff81166000908152601a60205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db4906115cb908390613360565b611917611e6c565b610cc381612959565b611928611e6c565b60015474010000000000000000000000000000000000000000900460ff1661070057600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f0b3307cc46a1592167f2a25f93a31437772754c8517ffb3c78ab9d254183300590600090a1565b6119bc611e6c565b600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515179055600a849055600b839055600c829055600d8190556040517fb5e4346584d07c27736121a2e37073a71bed9243ef9c7fed5e18520cda3a859190611a349087908790879087908790613449565b60405180910390a15050505050565b6000611a86336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611abc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b611ac5826129ef565b90505b919050565b6000611b10336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b611ac582612a25565b600061070c612a77565b60105473ffffffffffffffffffffffffffffffffffffffff1681565b60195460ff1681565b60025460035460045460ff90921691909192565b60055460065460075460085460ff9093169290919293565b600080808080808080333214611bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613766565b6017546000965086908015611cfe57611c03612d76565b5060135468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526014602090815260409182902082518084019093525460ff80821615801585526101009092041691830191909152611c7a576020810151600101985060ff8916821415611c7a57600098505b60018901925060ff8316821415611c9057600092505b60178960ff1681548110611ca057fe5b6000918252602090912001546017805473ffffffffffffffffffffffffffffffffffffffff9092169c509060ff8516908110611cd857fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169950505b60115463ffffffff90811660008181526012602090815260409182902082516060810184529054601781810b810b900b8083527801000000000000000000000000000000000000000000000000820487169383018490527c010000000000000000000000000000000000000000000000000000000090910490951692018290529c9d9b9c9a9b939a91995091975095509350915050565b611d9d611e6c565b610cc38142612192565b611daf611e6c565b610cc381612b62565b600f5473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000611e1d336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061128492505050565b611e53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906138eb565b611e5b612c28565b945094509450945094509091929394565b60005473ffffffffffffffffffffffffffffffffffffffff163314610700576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061363e565b60095460009060ff16156120b657601054600a546040517ff78eea8300000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff169163f78eea8391611f2491906004016134a3565b60606040518083038186803b158015611f3c57600080fd5b505afa158015611f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f749190613164565b5050600b54909150611fbf57600c54611fb790611fb1837f0000000000000000000000000000000000000000000000000000000005f5e100612cb7565b90612d0b565b91505061070f565b601054600b546040517ff78eea8300000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff169163f78eea839161201891906004016134a3565b60606040518083038186803b15801561203057600080fd5b505afa158015612044573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120689190613164565b5050600d54600c549192506120ad91611fb190817f0000000000000000000000000000000000000000000000000000000005f5e1006120a78888612cb7565b90612cb7565b9250505061070f565b50600090565b60e490565b6000806120cc612a77565b90506120d883826123ff565b156120e7576001915050611ac8565b60006120f16124d5565b90506120fd84826123ff565b1561210d57600192505050611ac8565b6000612117611ebd565b905061212385826123ff565b156121345760019350505050611ac8565b60115460405163ffffffff918216600101909116907fe05b0b0de121051cc17d6526f37a1f811848e7e7c61784ff18980391e87f5c119061217e9088908790879087904290613a59565b60405180910390a260009350505050611ac8565b604080516020808201835260115463ffffffff908116600101811683528351606081018552601787810b8252868316828501908152428416838801908152865185166000908152601290965294879020925183549151955185167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9686167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9290940b77ffffffffffffffffffffffffffffffffffffffffffffffff167fffffffffffffffff00000000000000000000000000000000000000000000000090931692909217169190911793909316929092179091556013805468010000000000000000339081027fffffffff0000000000000000000000000000000000000000ffffffffffffffff90921691909117909155825193519293909116917f38567aa999bdbf56a2a0e536f6d3420a6befcc0d5a443f686e3bded71d09157e916123349187919087906134f1565b60405180910390a2805160405160009163ffffffff16907f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac6027190612378908690613a7c565b60405180910390a3806000015163ffffffff168360170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040516123be91906134a3565b60405180910390a351601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790555050565b600080831180156124105750600082115b156124aa5760135460009061245090606490611fb19086907c0100000000000000000000000000000000000000000000000000000000900460ff16612cb7565b60135490915060009061248f90606490611fb19087907d010000000000000000000000000000000000000000000000000000000000900460ff16612cb7565b90508482111580156124a15750808511155b925050506112b3565b50600092915050565b60115463ffffffff16600090815260126020526040902054601790810b900b90565b60055460009060ff16156120b657600f546007546040517f96834ad300000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff16916396834ad39161253c91906004016134a3565b60806040518083038186803b15801561255457600080fd5b505afa158015612568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258c9190613191565b905060006005600101549050806125a7428460600151612d5a565b116125cf57506040810151600854915160070b60039190910b91909101600a0a02905061070f565b60009250505061070f565b600f5473ffffffffffffffffffffffffffffffffffffffff908116908216811461266f57600f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556040517e4e195fa31ccc70d4b5113711cee69b9f2059118d18832686a27d19e62a953f906117b690839085906134ca565b5050565b60115463ffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604081205460ff16806112b057505060195460ff161592915050565b60188054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111f95780601f1061273b576101008083540402835291602001916111f9565b820191906000526020600020905b81548152906001019060200180831161274957509395945050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff908116908216811461266f57600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556040517f9d835f4731b75b6c2365317484d718ea9ba2102b89b5547092f7fe1c6fea5c29906117b690839085906134ca565b60115463ffffffff9081166000908152601260205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b600080600080600063ffffffff8669ffffffffffffffffffff1611156040518060400160405280600f81526020017f4e6f20646174612070726573656e740000000000000000000000000000000000815250906128c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069190613528565b5050505063ffffffff83811660009081526012602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830487169484018590527c01000000000000000000000000000000000000000000000000000000009092049095169190930181905295969190920b949193509091508490565b60105473ffffffffffffffffffffffffffffffffffffffff908116908216811461266f57601080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556040517f5308b9ec263489f989284cee03c20f22af06d25e5758670c809795165997ea83906117b690839085906134ca565b600063ffffffff821115612a0557506000611ac8565b5063ffffffff16600090815260126020526040902054601790810b900b90565b600063ffffffff821115612a3b57506000611ac8565b5063ffffffff9081166000908152601260205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b60025460009060ff16156120b657600e546003546040517f0ca55a8e00000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff1691630ca55a8e91612ade91906004016134a3565b60206040518083038186803b158015612af657600080fd5b505afa158015612b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2e9190613287565b600454909150611fb790611fb1837f0000000000000000000000000000000000000000000000000000000005f5e100612cb7565b73ffffffffffffffffffffffffffffffffffffffff8116331415612bb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610906906139ed565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60115463ffffffff90811660008181526012602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830488169484018590527c01000000000000000000000000000000000000000000000000000000009092049096169190930181905292949190930b9291908490565b600082612cc6575060006112b3565b82820282848281612cd357fe5b04146112b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690613922565b6000808211612d46576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109069061372f565b6000828481612d5157fe5b04949350505050565b600081831115612d6d57508082036112b3565b508181036112b3565b604080518082019091526000808252602082015290565b5080546000825590600052602060002090810190610cc39190612e33565b828054828255906000526020600020908101928215612e23579160200282015b82811115612e235781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190612dcb565b50612e2f929150612e33565b5090565b5b80821115612e2f5760008155600101612e34565b60008083601f840112612e59578081fd5b50813567ffffffffffffffff811115612e70578182fd5b6020830191508360208083028501011115612e8a57600080fd5b9250929050565b80358015158114611ac857600080fd5b8051600381900b8114611ac857600080fd5b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611ac857600080fd5b803560ff81168114611ac857600080fd5b600060208284031215612efd578081fd5b81356112b081613b67565b60008060408385031215612f1a578081fd5b8235612f2581613b67565b915060208381013567ffffffffffffffff80821115612f42578384fd5b818601915086601f830112612f55578384fd5b813581811115612f6157fe5b612f91847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613b43565b91508082528784828501011115612fa6578485fd5b8084840185840137810190920192909252919491935090915050565b60008060008060408587031215612fd7578182fd5b843567ffffffffffffffff80821115612fee578384fd5b612ffa88838901612e48565b90965094506020870135915080821115613012578384fd5b5061301f87828801612e48565b95989497509550505050565b600080600080600060a08688031215613042578081fd5b61304b86612e91565b97602087013597506040870135966060810135965060800135945092505050565b600080600060608486031215613080578283fd5b61308984612e91565b95602085013595506040909401359392505050565b600080600080608085870312156130b3578182fd5b6130bc85612e91565b966020860135965060408601359560600135945092505050565b6000806000806000608086880312156130ed578283fd5b853567ffffffffffffffff80821115613104578485fd5b818801915088601f830112613117578485fd5b813581811115613125578586fd5b896020828501011115613136578586fd5b6020928301975095505086013592506040860135915061315860608701612edb565b90509295509295909350565b600080600060608486031215613178578081fd5b8351925060208401519150604084015190509250925092565b6000608082840312156131a2578081fd5b6040516080810167ffffffffffffffff82821081831117156131c057fe5b81604052845191508160070b82146131d6578384fd5b90825260208401519080821682146131ec578384fd5b5060208201526131fe60408401612ea1565b6040820152606083015160608201528091505092915050565b600060208284031215613228578081fd5b6112b082612eb3565b60008060408385031215613243578182fd5b61324c83612eb3565b9150602083013563ffffffff81168114613264578182fd5b809150509250929050565b600060208284031215613280578081fd5b5035919050565b600060208284031215613298578081fd5b5051919050565b6000602082840312156132b0578081fd5b813569ffffffffffffffffffff811681146112b0578182fd5b600080604083850312156132db578182fd5b6132e483612edb565b91506132f260208401612edb565b90509250929050565b60008284526020808501945082825b8581101561334557813561331d81613b67565b73ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161330a565b509495945050505050565b6000828483379101908152919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff988916815296909716602087015260ff949094166040860152606085019290925269ffffffffffffffffffff16608084015260170b60a083015260c082015260e08101919091526101000190565b6020808252825182820181905260009190848201906040850190845b8181101561343257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613400565b50909695505050505050565b901515815260200190565b9415158552602085019390935260408401919091526060830152608082015260a00190565b92151583526020830191909152604082015260600190565b931515845260208401929092526040830152606082015260800190565b90815260200190565b93845260ff9290921660208401526040830152606082015260800190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b60179390930b835273ffffffffffffffffffffffffffffffffffffffff91909116602083015263ffffffff16604082015260600190565b6000602080835283518082850152825b8181101561355457858101830151858201604001528201613538565b818111156135655783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526016908201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604082015260600190565b6020808252601c908201527f7265706561746564207472616e736d6974746572206164647265737300000000604082015260600190565b6020808252601e908201527f696e76616c6964206f62736572766174696f6e732074696d657374616d700000604082015260600190565b60208082526016908201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604082015260600190565b60208082526049908201527f7570706572426f756e64416e63686f72526174696f206d757374206c6573732060408201527f7468616e206f7220657175616c20746f206d61785570706572426f756e64416e60608201527f63686f72526174696f0000000000000000000000000000000000000000000000608082015260a00190565b60208082526016908201527f6f7261636c65206c656e677468206d69736d6174636800000000000000000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526014908201527f4f6e6c792063616c6c61626c6520627920454f41000000000000000000000000604082015260600190565b60208082526017908201527f7265706561746564207369676e65722061646472657373000000000000000000604082015260600190565b6020808252603a908201527f7570706572426f756e64416e63686f72526174696f206d757374206c6573732060408201527f7468616e206c6f776572426f756e64416e63686f72526174696f000000000000606082015260800190565b6020808252601e908201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e67650000604082015260600190565b6020808252604c908201527f6c6f776572426f756e64416e63686f72526174696f206d75737420677265617460408201527f6572207468616e206f7220657175616c20746f206d696e4c6f776572426f756e60608201527f64416e63686f72526174696f0000000000000000000000000000000000000000608082015260a00190565b60208082526009908201527f4e6f206163636573730000000000000000000000000000000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526018908201527f756e617574686f72697a6564207472616e736d69747465720000000000000000604082015260600190565b6020808252600f908201527f7369676e6174757265206572726f720000000000000000000000000000000000604082015260600190565b60208082526017908201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604082015260600190565b6020808252818101527f7472616e736d6974206d657373616765206c656e677468206d69736d61746368604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b63ffffffff91909116815260200190565b63ffffffff92831681529116602082015260400190565b600063ffffffff808916835280881660208401525060806040830152613ace6080830186886132fb565b8281036060840152613ae18185876132fb565b9998505050505050505050565b69ffffffffffffffffffff9586168152602081019490945260408401929092526060830152909116608082015260a00190565b60ff91909116815260200190565b60ff92831681529116602082015260400190565b60405181810167ffffffffffffffff81118282101715613b5f57fe5b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc357600080fdfe416363657373436f6e74726f6c6c65644f6666636861696e41676772656761746f7220322e302e30a2646970667358221220e4b71953822e3578b50a31ee2b3d8da7208c277a8d4affe9b37ef0c8b89b466164736f6c63430007060033