Contract 0x51aa283a37771B33101e88658C440951ee0AE02d

 
 
Txn Hash
Method
Block
From
To
Value
0x6293374eb2a9b271523f23d7bc157037a9a2d971096471fd2d45533d777415b0Transmit156816242022-10-05 11:32:2323 hrs 53 mins ago0xcc29be4ca92d4ecc43c8451fba94c200b83991f6 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00103744 5.9223551
0x4d0ac1306aad5991d84132371c1859f0a16877acd25b07335acf9ae02aed2048Transmit156744942022-10-04 11:32:111 day 23 hrs ago0x70bc61658615725a82d5e78ff0066bfcb1b98988 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00130725 7.39617933
0xfc94b9769dd9c1dcb35b5cf709d9355e02c93a58f7120773d3a5692743218120Transmit156673422022-10-03 11:31:232 days 23 hrs ago0xedbed9f5dea03dd0ec484577c41502af68b7c46a IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00142504 8.06316599
0x8e9a00238b4d4c9668243190348c951d8b8001c9b758dba150c4c82c1051f46fTransmit156601732022-10-02 11:30:353 days 23 hrs ago0xf07131f578a5f708ae2ccb9faf98458099e0ffb4 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00117587 6.65153578
0xef7d361597fc12172a6523c5bf6c46cf65fa562a9845e87da94a15b324548766Transmit156530222022-10-01 11:29:594 days 23 hrs ago0xc61a7e5a04a5d32ffe8e01f77cb39253bf21d2ac IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00099974 5.65715795
0x53b49d75af9f51bf42cba60006329dd50600da19db75cc93c1ebf6b176abe81fTransmit156459052022-09-30 11:38:355 days 23 hrs ago0xf07131f578a5f708ae2ccb9faf98458099e0ffb4 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00198547 11.22887385
0x5562d7ce1f0de89adf73b932b7b0a30337bbd4338ddd053bcc8275b430c755d9Transmit156387542022-09-29 11:38:236 days 23 hrs ago0x8f3ab0e87b70a57bd4980111a99a1b2c4b8334f4 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00198173 11.21760987
0x8248f0e59cae592782776abe7eefabee2f46cf62efc94b0cb78a5e0138b9f415Transmit156328932022-09-28 16:00:357 days 19 hrs ago0xf34ac04a28f7cb5324a167c96b24ade9c742b44f IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00322951 18.26947062
0x736af8be9f71db60bb75a714cbeef26cefcee0f6c3b5234ac648094deefb14caTransmit156257432022-09-27 16:00:118 days 19 hrs ago0xedbed9f5dea03dd0ec484577c41502af68b7c46a IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00517979 29.30823815
0xcae75a5953cde781f7a96cc8368837bd29d36343d03884e75919eaf164d3924dTransmit156257082022-09-27 15:53:118 days 19 hrs ago0x64c735d72eab90c04da523b6b9895773acb60f5d IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00415308 23.5037087
0x6cd2441dc0d51c45977ae7cb388fcd496c182593d9fb3cb8b2e9fdde08d0b2d4Transmit156220192022-09-27 3:30:119 days 7 hrs ago0xcf4be57aa078dc7568c631be7a73adc1cda992f8 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00219654 12.42844975
0x001f9ca86724e40303568ac440b80dac095014103934c2ca4830fd165af84dbbTransmit156217522022-09-27 2:36:359 days 8 hrs ago0xd22c87dc7a3f12dcbb75cebda2e96f6766ae114f IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00218995 12.39538499
0xecb6b7bd146008986372c718095e70ae3707ee810981be5e460bb4de338200b2Transmit156196672022-09-26 19:36:479 days 15 hrs ago0xc61a7e5a04a5d32ffe8e01f77cb39253bf21d2ac IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00267471 15.14019728
0xac955f9bf576b8279274cf22f2f23cdb80733f41bd1eaa8da406a96e28e650f6Transmit156155172022-09-26 5:39:5910 days 5 hrs ago0xd22c87dc7a3f12dcbb75cebda2e96f6766ae114f IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00023115 6.32967199
0x3097b6378b67e8713a763326c069905f3913767689ca89fbca200fce12394fdbTransmit156154922022-09-26 5:34:4710 days 5 hrs ago0x5a6fcc02d8c50ea58a22115a7c4608b723030016 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00109769 6.20971412
0x52ed009d0ff58a9dee81dbcc660e171e7f09c070c21987f8521394aab2937197Transmit156117522022-09-25 17:02:2310 days 18 hrs ago0xd22c87dc7a3f12dcbb75cebda2e96f6766ae114f IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00332877 18.83102749
0xa72bc527396a13d179bd87b41a79d60265d5b0d10168cd36112a679dbcc8f4b0Transmit156055582022-09-24 20:19:1111 days 15 hrs ago0x7663c5790e1ebf04197245d541279d13f3c2f362 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00084974 4.80767198
0x662fc3bb6db9b0e7dfdfffdac9a2c093ca023b47391bb3d292f9f0909a8d4965Transmit156036122022-09-24 13:47:2311 days 21 hrs ago0x8f3ab0e87b70a57bd4980111a99a1b2c4b8334f4 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00188221 10.65139949
0xec6d6ac5d006cde608c616e31763b323ca905fbe89f6abbbfcb79cb2fb36fde7Transmit156001762022-09-24 2:17:3512 days 9 hrs ago0x8f3ab0e87b70a57bd4980111a99a1b2c4b8334f4 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00112232 6.35161973
0x16b4602e6c2e5b01cc6674e76522d01e2dc718f918466dfa649364a0362718dbTransmit155993002022-09-23 23:21:4712 days 12 hrs ago0x5a6fcc02d8c50ea58a22115a7c4608b723030016 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00109039 6.16922675
0x38e7f3f6b1afe2b2772f459b2ed72b100c5c9604df680a40fb1913326ce44a37Transmit155991892022-09-23 22:59:3512 days 12 hrs ago0xf34ac04a28f7cb5324a167c96b24ade9c742b44f IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00096318 5.45246829
0x163e1e91f08699e2f94fa5c9ebbe57c6baf0b77926e234692e8919d18004bb0fTransmit155991382022-09-23 22:49:2312 days 12 hrs ago0x8f3ab0e87b70a57bd4980111a99a1b2c4b8334f4 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00176984 10.01411381
0x2e5f2f07c15b43d053b962d97a9507df473e3ca148921fd977d6cf9a1baf85eaTransmit155983882022-09-23 20:18:5912 days 15 hrs ago0xdbfea8d5822141c13f92caa06eb94d0f3d67c243 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00116929 6.61652211
0x9230e863160b3df37532104ebe1edc4b220d45bc5363efd49c08ec1d702cd43aTransmit155912192022-09-22 20:18:1113 days 15 hrs ago0x5a6fcc02d8c50ea58a22115a7c4608b723030016 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00175743 9.94459307
0x384d130545c5e8280c0dea93ad1715da6ff02effc591875edee9d53508b5942dTransmit155868202022-09-22 5:33:2314 days 5 hrs ago0x8f3ab0e87b70a57bd4980111a99a1b2c4b8334f4 IN  0x51aa283a37771b33101e88658c440951ee0ae02d0 Ether0.00114613 6.48504142
[ Download CSV Export 
View more zero value Internal Transactions in Advanced View mode
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AccessControlledOffchainAggregator

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 20000 runs

Other Settings:
default evmVersion, MIT license
File 1 of 12 : AccessControlledOffchainAggregator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.1;

import "./OffchainAggregator.sol";
import "./SimpleReadAccessController.sol";

/**
 * @notice Wrapper of OffchainAggregator which checks read access on Aggregator-interface methods
 */
contract AccessControlledOffchainAggregator is OffchainAggregator, SimpleReadAccessController {

  constructor(
    uint32 _maximumGasPrice,
    uint32 _reasonableGasPrice,
    uint32 _microLinkPerEth,
    uint32 _linkGweiPerObservation,
    uint32 _linkGweiPerTransmission,
    address _link,
    address _validator,
    int192 _minAnswer,
    int192 _maxAnswer,
    AccessControllerInterface _billingAccessController,
    AccessControllerInterface _requesterAccessController,
    uint8 _decimals,
    string memory description
  )
    OffchainAggregator(
      _maximumGasPrice,
      _reasonableGasPrice,
      _microLinkPerEth,
      _linkGweiPerObservation,
      _linkGweiPerTransmission,
      _link,
      _validator,
      _minAnswer,
      _maxAnswer,
      _billingAccessController,
      _requesterAccessController,
      _decimals,
      description
    ) {
    }

  /*
   * v2 Aggregator interface
   */

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

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

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

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

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

  /*
   * v3 Aggregator interface
   */

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

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

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

}

File 2 of 12 : OffchainAggregator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./AccessControllerInterface.sol";
import "./AggregatorV2V3Interface.sol";
import "./AggregatorValidatorInterface.sol";
import "./LinkTokenInterface.sol";
import "./Owned.sol";
import "./OffchainAggregatorBilling.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 Owned, OffchainAggregatorBilling, AggregatorV2V3Interface {

  uint256 constant private maxUint32 = (1 << 32) - 1;

  // 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 {
    // Provides 128 bits of security against 2nd pre-image attacks, but only
    // 64 bits against collisions. This is acceptable, since a malicious owner has
    // easier way of messing up the protocol than to find hash collisions.
    bytes16 latestConfigDigest;
    uint40 latestEpochAndRound; // 32 most sig bits for epoch, 8 least sig bits for round
    // Current bound assumed on number of faulty/dishonest oracles participating
    // in the protocol, this value is referred to as f in the design
    uint8 threshold;
    // Chainlink 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
    uint64 timestamp;
  }
  mapping(uint32 /* aggregator round ID */ => Transmission) 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;
  uint32 internal s_latestConfigBlockNumber; // makes it easier for offchain systems
                                             // to extract config from logs.

  // Lowest answer the system is allowed to report in response to transmissions
  int192 immutable public minAnswer;
  // Highest answer the system is allowed to report in response to transmissions
  int192 immutable public maxAnswer;

  /*
   * @param _maximumGasPrice highest gas price for which transmitter will be compensated
   * @param _reasonableGasPrice transmitter will receive reward for gas prices under this value
   * @param _microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units
   * @param _linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units
   * @param _linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units
   * @param _link address of the LINK contract
   * @param _validator address of validator contract (must satisfy AggregatorValidatorInterface)
   * @param _minAnswer lowest answer the median of a report is allowed to be
   * @param _maxAnswer highest answer the median of a report is allowed to be
   * @param _billingAccessController access controller for billing admin functions
   * @param _requesterAccessController access controller for requesting new rounds
   * @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
   */
  constructor(
    uint32 _maximumGasPrice,
    uint32 _reasonableGasPrice,
    uint32 _microLinkPerEth,
    uint32 _linkGweiPerObservation,
    uint32 _linkGweiPerTransmission,
    address _link,
    address _validator,
    int192 _minAnswer,
    int192 _maxAnswer,
    AccessControllerInterface _billingAccessController,
    AccessControllerInterface _requesterAccessController,
    uint8 _decimals,
    string memory _description
  )
    OffchainAggregatorBilling(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth,
      _linkGweiPerObservation, _linkGweiPerTransmission, _link,
      _billingAccessController
    )
  {
    decimals = _decimals;
    s_description = _description;
    setRequesterAccessController(_requesterAccessController);
    setValidator(_validator);
    minAnswer = _minAnswer;
    maxAnswer = _maxAnswer;
  }

  /*
   * 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
   * @param threshold maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly
   * @param encodedConfigVersion version of the serialization format used for "encoded" parameter
   * @param encoded serialized data used by oracles to configure their offchain operation
   */
  event ConfigSet(
    uint32 previousConfigBlockNumber,
    uint64 configCount,
    address[] signers,
    address[] transmitters,
    uint8 threshold,
    uint64 encodedConfigVersion,
    bytes encoded
  );

  // Reverts transaction if config args are invalid
  modifier checkConfigValid (
    uint256 _numSigners, uint256 _numTransmitters, uint256 _threshold
  ) {
    require(_numSigners <= maxNumOracles, "too many signers");
    require(_threshold > 0, "threshold must be positive");
    require(
      _numSigners == _numTransmitters,
      "oracle addresses out of registration"
    );
    require(_numSigners > 3*_threshold, "faulty-oracle threshold too high");
    _;
  }

  /**
   * @notice sets offchain reporting protocol configuration incl. participating oracles
   * @param _signers addresses with which oracles sign the reports
   * @param _transmitters addresses oracles use to transmit the reports
   * @param _threshold number of faulty oracles the system can tolerate
   * @param _encodedConfigVersion version number for offchainEncoding schema
   * @param _encoded encoded off-chain oracle configuration
   */
  function setConfig(
    address[] calldata _signers,
    address[] calldata _transmitters,
    uint8 _threshold,
    uint64 _encodedConfigVersion,
    bytes calldata _encoded
  )
    external
    checkConfigValid(_signers.length, _transmitters.length, _threshold)
    onlyOwner()
  {
    while (s_signers.length != 0) { // remove any old signer/transmitter addresses
      uint lastIdx = s_signers.length - 1;
      address signer = s_signers[lastIdx];
      address transmitter = s_transmitters[lastIdx];
      payOracle(transmitter);
      delete s_oracles[signer];
      delete s_oracles[transmitter];
      s_signers.pop();
      s_transmitters.pop();
    }

    for (uint i = 0; i < _signers.length; i++) { // add new signer/transmitter addresses
      require(
        s_oracles[_signers[i]].role == Role.Unset,
        "repeated signer address"
      );
      s_oracles[_signers[i]] = Oracle(uint8(i), Role.Signer);
      require(s_payees[_transmitters[i]] != address(0), "payee must be set");
      require(
        s_oracles[_transmitters[i]].role == Role.Unset,
        "repeated transmitter address"
      );
      s_oracles[_transmitters[i]] = Oracle(uint8(i), Role.Transmitter);
      s_signers.push(_signers[i]);
      s_transmitters.push(_transmitters[i]);
    }
    s_hotVars.threshold = _threshold;
    uint32 previousConfigBlockNumber = s_latestConfigBlockNumber;
    s_latestConfigBlockNumber = uint32(block.number);
    s_configCount += 1;
    uint64 configCount = s_configCount;
    {
      s_hotVars.latestConfigDigest = configDigestFromConfigData(
        address(this),
        configCount,
        _signers,
        _transmitters,
        _threshold,
        _encodedConfigVersion,
        _encoded
      );
      s_hotVars.latestEpochAndRound = 0;
    }
    emit ConfigSet(
      previousConfigBlockNumber,
      configCount,
      _signers,
      _transmitters,
      _threshold,
      _encodedConfigVersion,
      _encoded
    );
  }

  function configDigestFromConfigData(
    address _contractAddress,
    uint64 _configCount,
    address[] calldata _signers,
    address[] calldata _transmitters,
    uint8 _threshold,
    uint64 _encodedConfigVersion,
    bytes calldata _encodedConfig
  ) internal pure returns (bytes16) {
    return bytes16(keccak256(abi.encode(_contractAddress, _configCount,
      _signers, _transmitters, _threshold, _encodedConfigVersion, _encodedConfig
    )));
  }

  /**
   * @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
   * @return configDigest domain-separation tag for current config (see configDigestFromConfigData)
   */
  function latestConfigDetails()
    external
    view
    returns (
      uint32 configCount,
      uint32 blockNumber,
      bytes16 configDigest
    )
  {
    return (s_configCount, s_latestConfigBlockNumber, s_hotVars.latestConfigDigest);
  }

  /**
   * @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 transmitters()
    external
    view
    returns(address[] memory)
  {
      return s_transmitters;
  }

  /*
   * On-chain validation logc
   */

  // Maximum gas the validation logic can use
  uint256 private constant VALIDATOR_GAS_LIMIT = 100000;

  // Contract containing the validation logic
  AggregatorValidatorInterface private s_validator;

  /**
   * @notice indicates that the address of the validator contract has been set
   * @param previous setting of the address prior to this event
   * @param current the new value for the address
   */
  event ValidatorUpdated(
    address indexed previous,
    address indexed current
  );

  /**
   * @notice address of the contract which does external data validation
   * @return validator address
   */
  function validator()
    external
    view
    returns (AggregatorValidatorInterface)
  {
    return s_validator;
  }

  /**
   * @notice sets the address which does external data validation
   * @param _newValidator designates the address of the new validation contract
   */
  function setValidator(address _newValidator)
    public
    onlyOwner()
  {
    address previous = address(s_validator);

    if (previous != _newValidator) {
      s_validator = AggregatorValidatorInterface(_newValidator);

      emit ValidatorUpdated(previous, _newValidator);
    }
  }

  function validateAnswer(
    uint32 _aggregatorRoundId,
    int256 _answer
  )
    private
  {
    AggregatorValidatorInterface av = s_validator; // cache storage reads
    if (address(av) == address(0)) return;

    uint32 prevAggregatorRoundId = _aggregatorRoundId - 1;
    int256 prevAggregatorRoundAnswer = s_transmissions[prevAggregatorRoundId].answer;
    // We do not want the validator to ever prevent reporting, so we limit its
    // gas usage and catch any errors that may arise.
    try av.validate{gas: VALIDATOR_GAS_LIMIT}(
      prevAggregatorRoundId,
      prevAggregatorRoundAnswer,
      _aggregatorRoundId,
      _answer
    ) {} catch {}
  }

  /*
   * requestNewRound logic
   */

  AccessControllerInterface internal s_requesterAccessController;

  /**
   * @notice emitted when a new requester access controller contract is set
   * @param old the address prior to the current setting
   * @param current the address of the new access controller contract
   */
  event RequesterAccessControllerSet(AccessControllerInterface old, AccessControllerInterface current);

  /**
   * @notice emitted to immediately request a new round
   * @param requester the address of the requester
   * @param configDigest the latest transmission's configDigest
   * @param epoch the latest transmission's epoch
   * @param round the latest transmission's round
   */
  event RoundRequested(address indexed requester, bytes16 configDigest, uint32 epoch, uint8 round);

  /**
   * @notice address of the requester access controller contract
   * @return requester access controller address
   */
  function requesterAccessController()
    external
    view
    returns (AccessControllerInterface)
  {
    return s_requesterAccessController;
  }

  /**
   * @notice sets the requester access controller
   * @param _requesterAccessController designates the address of the new requester access controller
   */
  function setRequesterAccessController(AccessControllerInterface _requesterAccessController)
    public
    onlyOwner()
  {
    AccessControllerInterface oldController = s_requesterAccessController;
    if (_requesterAccessController != oldController) {
      s_requesterAccessController = AccessControllerInterface(_requesterAccessController);
      emit RequesterAccessControllerSet(oldController, _requesterAccessController);
    }
  }

  /**
   * @notice immediately requests a new round
   * @return the aggregatorRoundId of the next round. Note: The report for this round may have been
   * transmitted (but not yet mined) *before* requestNewRound() was even called. There is *no*
   * guarantee of causality between the request and the report at aggregatorRoundId.
   */
  function requestNewRound() external returns (uint80) {
    require(msg.sender == owner || s_requesterAccessController.hasAccess(msg.sender, msg.data),
      "Only owner&requester can call");

    HotVars memory hotVars = s_hotVars;

    emit RoundRequested(
      msg.sender,
      hotVars.latestConfigDigest,
      uint32(s_hotVars.latestEpochAndRound >> 8),
      uint8(s_hotVars.latestEpochAndRound)
    );
    return hotVars.latestAggregatorRoundId + 1;
  }

  /*
   * 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 observations observations transmitted with this report
   * @param rawReportContext signature-replay-prevention domain-separation tag
   */
  event NewTransmission(
    uint32 indexed aggregatorRoundId,
    int192 answer,
    address transmitter,
    int192[] observations,
    bytes observers,
    bytes32 rawReportContext
  );

  // decodeReport is used to check that the solidity and go code are using the
  // same format. See TestOffchainAggregator.testDecodeReport and TestReportParsing
  function decodeReport(bytes memory _report)
    internal
    pure
    returns (
      bytes32 rawReportContext,
      bytes32 rawObservers,
      int192[] memory observations
    )
  {
    (rawReportContext, rawObservers, observations) = abi.decode(_report,
      (bytes32, bytes32, int192[]));
  }

  // Used to relieve stack pressure in transmit
  struct ReportData {
    HotVars hotVars; // Only read from storage once
    bytes observers; // ith element is the index of the ith observer
    int192[] observations; // ith element is the ith observation
    bytes vs; // jth element is the v component of the jth signature
    bytes32 rawReportContext;
  }

  /*
   * @notice details about the most recent report

   * @return configDigest domain separation tag for the latest report
   * @return epoch epoch in which the latest report was generated
   * @return round OCR round in which the latest report was generated
   * @return latestAnswer median value from latest report
   * @return latestTimestamp when the latest report was transmitted
   */
  function latestTransmissionDetails()
    external
    view
    returns (
      bytes16 configDigest,
      uint32 epoch,
      uint8 round,
      int192 latestAnswer,
      uint64 latestTimestamp
    )
  {
    require(msg.sender == tx.origin, "Only callable by EOA");
    return (
      s_hotVars.latestConfigDigest,
      uint32(s_hotVars.latestEpochAndRound >> 8),
      uint8(s_hotVars.latestEpochAndRound),
      s_transmissions[s_hotVars.latestAggregatorRoundId].answer,
      s_transmissions[s_hotVars.latestAggregatorRoundId].timestamp
    );
  }

  // 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 + // word containing location start of abiencoded  _rs value
    32 + // word containing start location of abiencoded _ss value
    32 + // _rawVs value
    32 + // word containing length of _report
    32 + // word containing length _rs
    32 + // word containing length of _ss
    0; // placeholder

  function expectedMsgDataLength(
    bytes calldata _report, bytes32[] calldata _rs, bytes32[] calldata _ss
  ) private pure returns (uint256 length)
  {
    // calldata will never be big enough to make this overflow
    return uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) +
      _report.length + // one byte pure entry in _report
      _rs.length * 32 + // 32 bytes per entry in _rs
      _ss.length * 32 + // 32 bytes per entry in _ss
      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. The ith element of the observers component must be the index in s_signers of the address for the ith signature
   * @param _rs ith element is the R components of the ith signature on report. Must have at most maxNumOracles entries
   * @param _ss ith element is the S components of the ith signature on report. Must have at most maxNumOracles entries
   * @param _rawVs ith element is the the V component of the ith signature
   */
  function transmit(
    // NOTE: If these parameters are changed, expectedMsgDataLength and/or
    // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly
    bytes calldata _report,
    bytes32[] calldata _rs, bytes32[] calldata _ss, bytes32 _rawVs // signatures
  )
    external
  {
    uint256 initialGas = gasleft(); // This line must come first
    // Make sure the transmit message-length matches the inputs. Otherwise, the
    // transmitter could append an arbitrarily long (up to gas-block limit)
    // string of 0 bytes, which we would reimburse at a rate of 16 gas/byte, but
    // which would only cost the transmitter 4 gas/byte. (Appendix G of the
    // yellow paper, p. 25, for G_txdatazero and EIP 2028 for G_txdatanonzero.)
    // This could amount to reimbursement profit of 36 million gas, given a 3MB
    // zero tail.
    require(msg.data.length == expectedMsgDataLength(_report, _rs, _ss),
      "transmit message too long");
    ReportData memory r; // Relieves stack pressure
    {
      r.hotVars = s_hotVars; // cache read from storage

      bytes32 rawObservers;
      (r.rawReportContext, rawObservers, r.observations) = abi.decode(
        _report, (bytes32, bytes32, int192[])
      );

      // rawReportContext consists of:
      // 11-byte zero padding
      // 16-byte configDigest
      // 4-byte epoch
      // 1-byte round

      bytes16 configDigest = bytes16(r.rawReportContext << 88);
      require(
        r.hotVars.latestConfigDigest == configDigest,
        "configDigest mismatch"
      );

      uint40 epochAndRound = uint40(uint256(r.rawReportContext));

      // direct numerical comparison works here, because
      //
      //   ((e,r) <= (e',r')) implies (epochAndRound <= epochAndRound')
      //
      // because alphabetic ordering implies e <= e', and if e = e', then r<=r',
      // so e*256+r <= e'*256+r', because r, r' < 256
      require(r.hotVars.latestEpochAndRound < epochAndRound, "stale report");

      require(_rs.length > r.hotVars.threshold, "not enough signatures");
      require(_rs.length <= maxNumOracles, "too many signatures");
      require(_ss.length == _rs.length, "signatures out of registration");
      require(r.observations.length <= maxNumOracles,
              "num observations out of bounds");
      require(r.observations.length > 2 * r.hotVars.threshold,
              "too few values to trust median");

      // Copy signature parities in bytes32 _rawVs to bytes r.v
      r.vs = new bytes(_rs.length);
      for (uint8 i = 0; i < _rs.length; i++) {
        r.vs[i] = _rawVs[i];
      }

      // Copy observer identities in bytes32 rawObservers to bytes r.observers
      r.observers = new bytes(r.observations.length);
      bool[maxNumOracles] memory seen;
      for (uint8 i = 0; i < r.observations.length; i++) {
        uint8 observerIdx = uint8(rawObservers[i]);
        require(!seen[observerIdx], "observer index repeated");
        seen[observerIdx] = true;
        r.observers[i] = rawObservers[i];
      }

      Oracle memory transmitter = s_oracles[msg.sender];
      require( // Check that sender is authorized to report
        transmitter.role == Role.Transmitter &&
        msg.sender == s_transmitters[transmitter.index],
        "unauthorized transmitter"
      );
      // record epochAndRound here, so that we don't have to carry the local
      // variable in transmit. The change is reverted if something fails later.
      r.hotVars.latestEpochAndRound = epochAndRound;
    }

    { // Verify signatures attached to report
      bytes32 h = keccak256(_report);
      bool[maxNumOracles] memory signed;

      Oracle memory o;
      for (uint i = 0; i < _rs.length; i++) {
        address signer = ecrecover(h, uint8(r.vs[i])+27, _rs[i], _ss[i]);
        o = s_oracles[signer];
        require(o.role == Role.Signer, "address not authorized to sign");
        require(!signed[o.index], "non-unique signature");
        signed[o.index] = true;
      }
    }

    { // Check the report contents, and record the result
      for (uint i = 0; i < r.observations.length - 1; i++) {
        bool inOrder = r.observations[i] <= r.observations[i+1];
        require(inOrder, "observations not sorted");
      }

      int192 median = r.observations[r.observations.length/2];
      require(minAnswer <= median && median <= maxAnswer, "median is out of min-max range");
      r.hotVars.latestAggregatorRoundId++;
      s_transmissions[r.hotVars.latestAggregatorRoundId] =
        Transmission(median, uint64(block.timestamp));

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

      validateAnswer(r.hotVars.latestAggregatorRoundId, median);
    }
    s_hotVars = r.hotVars;
    assert(initialGas < maxUint32);
    reimburseAndRewardOracles(uint32(initialGas), r.observers);
  }

  /*
   * v2 Aggregator interface
   */

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

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

  /**
   * @notice Aggregator round (NOT OCR round) in which last report was transmitted
   */
  function latestRound()
    public
    override
    view
    virtual
    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
    override
    view
    virtual
    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
    override
    view
    virtual
    returns (uint256)
  {
    if (_roundId > 0xFFFFFFFF) { return 0; }
    return s_transmissions[uint32(_roundId)].timestamp;
  }

  /*
   * v3 Aggregator interface
   */

  string constant private V3_NO_DATA_ERROR = "No data present";

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

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

  string internal s_description;

  /**
   * @notice human-readable description of observable this contract is reporting on
   */
  function description()
    public
    override
    view
    virtual
    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
    override
    view
    virtual
    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.timestamp,
      transmission.timestamp,
      _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
    override
    view
    virtual
    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.timestamp,
      transmission.timestamp,
      roundId
    );
  }
}

File 3 of 12 : AccessControllerInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

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

File 4 of 12 : AggregatorV2V3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./AggregatorInterface.sol";
import "./AggregatorV3Interface.sol";

interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface
{
}

File 5 of 12 : AggregatorInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

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 6 of 12 : AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

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 7 of 12 : AggregatorValidatorInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

interface AggregatorValidatorInterface {
  function validate(
    uint256 previousRoundId,
    int256 previousAnswer,
    uint256 currentRoundId,
    int256 currentAnswer
  ) external returns (bool);
}

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

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);
  function approve(address spender, uint256 value) external returns (bool success);
  function balanceOf(address owner) external view returns (uint256 balance);
  function decimals() external view returns (uint8 decimalPlaces);
  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);
  function increaseApproval(address spender, uint256 subtractedValue) external;
  function name() external view returns (string memory tokenName);
  function symbol() external view returns (string memory tokenSymbol);
  function totalSupply() external view returns (uint256 totalTokensIssued);
  function transfer(address to, uint256 value) external returns (bool success);
  function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success);
  function transferFrom(address from, address to, uint256 value) external returns (bool success);
}

File 9 of 12 : Owned.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

/**
 * @title The Owned contract
 * @notice A contract with helpers for basic contract ownership.
 */
contract Owned {

  address payable public owner;
  address private pendingOwner;

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

  constructor() {
    owner = msg.sender;
  }

  /**
   * @dev Allows an owner to begin transferring ownership to a new address,
   * pending.
   */
  function transferOwnership(address _to)
    external
    onlyOwner()
  {
    pendingOwner = _to;

    emit OwnershipTransferRequested(owner, _to);
  }

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

    address oldOwner = owner;
    owner = msg.sender;
    pendingOwner = address(0);

    emit OwnershipTransferred(oldOwner, msg.sender);
  }

  /**
   * @dev Reverts if called by anyone other than the contract owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner, "Only callable by owner");
    _;
  }

}

File 10 of 12 : OffchainAggregatorBilling.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./AccessControllerInterface.sol";
import "./LinkTokenInterface.sol";
import "./Owned.sol";

/**
 * @notice tracks administration of oracle-reward and gas-reimbursement parameters.

 * @dev
 * If you read or change this, be sure to read or adjust the comments. They
 * track the units of the values under consideration, and are crucial to
 * the readability of the operations it specifies.

 * @notice
 * Trust Model:

 * Nothing in this contract prevents a billing admin from setting insane
 * values for the billing parameters in setBilling. Oracles
 * participating in this contract should regularly check that the
 * parameters make sense. Similarly, the outstanding obligations of this
 * contract to the oracles can exceed the funds held by the contract.
 * Oracles participating in this contract should regularly check that it
 * holds sufficient funds and stop interacting with it if funding runs
 * out.

 * This still leaves oracles with some risk due to TOCTOU issues.
 * However, since the sums involved are pretty small (Ethereum
 * transactions aren't that expensive in the end) and an oracle would
 * likely stop participating in a contract it repeatedly lost money on,
 * this risk is deemed acceptable. Oracles should also regularly
 * withdraw any funds in the contract to prevent issues where the
 * contract becomes underfunded at a later time, and different oracles
 * are competing for the left-over funds.

 * Finally, note that any change to the set of oracles or to the billing
 * parameters will trigger payout of all oracles first (using the old
 * parameters), a billing admin cannot take away funds that are already
 * marked for payment.
*/
contract OffchainAggregatorBilling is Owned {

  // Maximum number of oracles the offchain reporting protocol is designed for
  uint256 constant internal maxNumOracles = 31;

  // Parameters for oracle payments
  struct Billing {

    // Highest compensated gas price, in ETH-gwei uints
    uint32 maximumGasPrice;

    // If gas price is less (in ETH-gwei units), transmitter gets half the savings
    uint32 reasonableGasPrice;

    // Pay transmitter back this much LINK per unit eth spent on gas
    // (1e-6LINK/ETH units)
    uint32 microLinkPerEth;

    // Fixed LINK reward for each observer, in LINK-gwei units
    uint32 linkGweiPerObservation;

    // Fixed reward for transmitter, in linkGweiPerObservation units
    uint32 linkGweiPerTransmission;
  }
  Billing internal s_billing;

  /**
  * @return LINK token contract used for billing
  */
  LinkTokenInterface immutable public LINK;

  AccessControllerInterface internal s_billingAccessController;

  // ith element is number of observation rewards due to ith process, plus one.
  // This is expected to saturate after an oracle has submitted 65,535
  // observations, or about 65535/(3*24*20) = 45 days, given a transmission
  // every 3 minutes.
  //
  // This is always one greater than the actual value, so that when the value is
  // reset to zero, we don't end up with a zero value in storage (which would
  // result in a higher gas cost, the next time the value is incremented.)
  // Calculations using this variable need to take that offset into account.
  uint16[maxNumOracles] internal s_oracleObservationsCounts;

  // Addresses at which oracles want to receive payments, by transmitter address
  mapping (address /* transmitter */ => address /* payment address */)
    internal
    s_payees;

  // Payee addresses which must be approved by the owner
  mapping (address /* transmitter */ => address /* payment address */)
    internal
    s_proposedPayees;

  // LINK-wei-denominated reimbursements for gas used by transmitters.
  //
  // This is always one greater than the actual value, so that when the value is
  // reset to zero, we don't end up with a zero value in storage (which would
  // result in a higher gas cost, the next time the value is incremented.)
  // Calculations using this variable need to take that offset into account.
  //
  // Argument for overflow safety:
  // We have the following maximum intermediate values:
  // - 2**40 additions to this variable (epochAndRound is a uint40)
  // - 2**32 gas price in ethgwei/gas
  // - 1e9 ethwei/ethgwei
  // - 2**32 gas since the block gas limit is at ~20 million
  // - 2**32 (microlink/eth)
  // And we have 2**40 * 2**32 * 1e9 * 2**32 * 2**32 < 2**166
  // (we also divide in some places, but that only makes the value smaller)
  // We can thus safely use uint256 intermediate values for the computation
  // updating this variable.
  uint256[maxNumOracles] internal s_gasReimbursementsLinkWei;

  // Used for s_oracles[a].role, where a is an address, to track the purpose
  // of the address, or to indicate that the address is unset.
  enum Role {
    // No oracle role has been set for address a
    Unset,
    // Signing address for the s_oracles[a].index'th oracle. I.e., report
    // signatures from this oracle should ecrecover back to address a.
    Signer,
    // Transmission address for the s_oracles[a].index'th oracle. I.e., if a
    // report is received by OffchainAggregator.transmit in which msg.sender is
    // a, it is attributed to the s_oracles[a].index'th oracle.
    Transmitter
  }

  struct Oracle {
    uint8 index; // Index of oracle in s_signers/s_transmitters
    Role role;   // Role of the address which mapped to this struct
  }

  mapping (address /* signer OR transmitter address */ => Oracle)
    internal s_oracles;

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

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

  uint256 constant private  maxUint16 = (1 << 16) - 1;
  uint256 constant internal maxUint128 = (1 << 128) - 1;

  constructor(
    uint32 _maximumGasPrice,
    uint32 _reasonableGasPrice,
    uint32 _microLinkPerEth,
    uint32 _linkGweiPerObservation,
    uint32 _linkGweiPerTransmission,
    address _link,
    AccessControllerInterface _billingAccessController
  )
  {
    setBillingInternal(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth,
      _linkGweiPerObservation, _linkGweiPerTransmission);
    setBillingAccessControllerInternal(_billingAccessController);
    LINK = LinkTokenInterface(_link);
    uint16[maxNumOracles] memory counts; // See s_oracleObservationsCounts docstring
    uint256[maxNumOracles] memory gas; // see s_gasReimbursementsLinkWei docstring
    for (uint8 i = 0; i < maxNumOracles; i++) {
      counts[i] = 1;
      gas[i] = 1;
    }
    s_oracleObservationsCounts = counts;
    s_gasReimbursementsLinkWei = gas;

  }

  /**
   * @notice emitted when billing parameters are set
   * @param maximumGasPrice highest gas price for which transmitter will be compensated
   * @param reasonableGasPrice transmitter will receive reward for gas prices under this value
   * @param microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units
   * @param linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units
   * @param linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units
   */
  event BillingSet(
    uint32 maximumGasPrice,
    uint32 reasonableGasPrice,
    uint32 microLinkPerEth,
    uint32 linkGweiPerObservation,
    uint32 linkGweiPerTransmission
  );

  function setBillingInternal(
    uint32 _maximumGasPrice,
    uint32 _reasonableGasPrice,
    uint32 _microLinkPerEth,
    uint32 _linkGweiPerObservation,
    uint32 _linkGweiPerTransmission
  )
    internal
  {
    s_billing = Billing(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth,
      _linkGweiPerObservation, _linkGweiPerTransmission);
    emit BillingSet(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth,
      _linkGweiPerObservation, _linkGweiPerTransmission);
  }

  /**
   * @notice sets billing parameters
   * @param _maximumGasPrice highest gas price for which transmitter will be compensated
   * @param _reasonableGasPrice transmitter will receive reward for gas prices under this value
   * @param _microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units
   * @param _linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units
   * @param _linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units
   * @dev access control provided by billingAccessController
   */
  function setBilling(
    uint32 _maximumGasPrice,
    uint32 _reasonableGasPrice,
    uint32 _microLinkPerEth,
    uint32 _linkGweiPerObservation,
    uint32 _linkGweiPerTransmission
  )
    external
  {
    AccessControllerInterface access = s_billingAccessController;
    require(msg.sender == owner || access.hasAccess(msg.sender, msg.data),
      "Only owner&billingAdmin can call");
    payOracles();
    setBillingInternal(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth,
      _linkGweiPerObservation, _linkGweiPerTransmission);
  }

  /**
   * @notice gets billing parameters
   * @param maximumGasPrice highest gas price for which transmitter will be compensated
   * @param reasonableGasPrice transmitter will receive reward for gas prices under this value
   * @param microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units
   * @param linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units
   * @param linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units
   */
  function getBilling()
    external
    view
    returns (
      uint32 maximumGasPrice,
      uint32 reasonableGasPrice,
      uint32 microLinkPerEth,
      uint32 linkGweiPerObservation,
      uint32 linkGweiPerTransmission
    )
  {
    Billing memory billing = s_billing;
    return (
      billing.maximumGasPrice,
      billing.reasonableGasPrice,
      billing.microLinkPerEth,
      billing.linkGweiPerObservation,
      billing.linkGweiPerTransmission
    );
  }

  /**
   * @notice emitted when a new access-control contract is set
   * @param old the address prior to the current setting
   * @param current the address of the new access-control contract
   */
  event BillingAccessControllerSet(AccessControllerInterface old, AccessControllerInterface current);

  function setBillingAccessControllerInternal(AccessControllerInterface _billingAccessController)
    internal
  {
    AccessControllerInterface oldController = s_billingAccessController;
    if (_billingAccessController != oldController) {
      s_billingAccessController = _billingAccessController;
      emit BillingAccessControllerSet(
        oldController,
        _billingAccessController
      );
    }
  }

  /**
   * @notice sets billingAccessController
   * @param _billingAccessController new billingAccessController contract address
   * @dev only owner can call this
   */
  function setBillingAccessController(AccessControllerInterface _billingAccessController)
    external
    onlyOwner
  {
    setBillingAccessControllerInternal(_billingAccessController);
  }

  /**
   * @notice gets billingAccessController
   * @return address of billingAccessController contract
   */
  function billingAccessController()
    external
    view
    returns (AccessControllerInterface)
  {
    return s_billingAccessController;
  }

  /**
   * @notice withdraws an oracle's payment from the contract
   * @param _transmitter the transmitter address of the oracle
   * @dev must be called by oracle's payee address
   */
  function withdrawPayment(address _transmitter)
    external
  {
    require(msg.sender == s_payees[_transmitter], "Only payee can withdraw");
    payOracle(_transmitter);
  }

  /**
   * @notice query an oracle's payment amount
   * @param _transmitter the transmitter address of the oracle
   */
  function owedPayment(address _transmitter)
    public
    view
    returns (uint256)
  {
    Oracle memory oracle = s_oracles[_transmitter];
    if (oracle.role == Role.Unset) { return 0; }
    Billing memory billing = s_billing;
    uint256 linkWeiAmount =
      uint256(s_oracleObservationsCounts[oracle.index] - 1) *
      uint256(billing.linkGweiPerObservation) *
      (1 gwei);
    linkWeiAmount += s_gasReimbursementsLinkWei[oracle.index] - 1;
    return linkWeiAmount;
  }

  /**
   * @notice emitted when an oracle has been paid LINK
   * @param transmitter address from which the oracle sends reports to the transmit method
   * @param payee address to which the payment is sent
   * @param amount amount of LINK sent
   */
  event OraclePaid(address transmitter, address payee, uint256 amount);

  // payOracle pays out _transmitter's balance to the corresponding payee, and zeros it out
  function payOracle(address _transmitter)
    internal
  {
    Oracle memory oracle = s_oracles[_transmitter];
    uint256 linkWeiAmount = owedPayment(_transmitter);
    if (linkWeiAmount > 0) {
      address payee = s_payees[_transmitter];
      // Poses no re-entrancy issues, because LINK.transfer does not yield
      // control flow.
      require(LINK.transfer(payee, linkWeiAmount), "insufficient funds");
      s_oracleObservationsCounts[oracle.index] = 1; // "zero" the counts. see var's docstring
      s_gasReimbursementsLinkWei[oracle.index] = 1; // "zero" the counts. see var's docstring
      emit OraclePaid(_transmitter, payee, linkWeiAmount);
    }
  }

  // payOracles pays out all transmitters, and zeros out their balances.
  //
  // It's much more gas-efficient to do this as a single operation, to avoid
  // hitting storage too much.
  function payOracles()
    internal
  {
    Billing memory billing = s_billing;
    uint16[maxNumOracles] memory observationsCounts = s_oracleObservationsCounts;
    uint256[maxNumOracles] memory gasReimbursementsLinkWei =
      s_gasReimbursementsLinkWei;
    address[] memory transmitters = s_transmitters;
    for (uint transmitteridx = 0; transmitteridx < transmitters.length; transmitteridx++) {
      uint256 reimbursementAmountLinkWei = gasReimbursementsLinkWei[transmitteridx] - 1;
      uint256 obsCount = observationsCounts[transmitteridx] - 1;
      uint256 linkWeiAmount =
        obsCount * uint256(billing.linkGweiPerObservation) * (1 gwei) + reimbursementAmountLinkWei;
      if (linkWeiAmount > 0) {
          address payee = s_payees[transmitters[transmitteridx]];
          // Poses no re-entrancy issues, because LINK.transfer does not yield
          // control flow.
          require(LINK.transfer(payee, linkWeiAmount), "insufficient funds");
          observationsCounts[transmitteridx] = 1;       // "zero" the counts.
          gasReimbursementsLinkWei[transmitteridx] = 1; // "zero" the counts.
          emit OraclePaid(transmitters[transmitteridx], payee, linkWeiAmount);
        }
    }
    // "Zero" the accounting storage variables
    s_oracleObservationsCounts = observationsCounts;
    s_gasReimbursementsLinkWei = gasReimbursementsLinkWei;
  }

  function oracleRewards(
    bytes memory observers,
    uint16[maxNumOracles] memory observations
  )
    internal
    pure
    returns (uint16[maxNumOracles] memory)
  {
    // reward each observer-participant with the observer reward
    for (uint obsIdx = 0; obsIdx < observers.length; obsIdx++) {
      uint8 observer = uint8(observers[obsIdx]);
      observations[observer] = saturatingAddUint16(observations[observer], 1);
    }
    return observations;
  }

  // This value needs to change if maxNumOracles is increased, or the accounting
  // calculations at the bottom of reimburseAndRewardOracles change.
  //
  // To recalculate it, run the profiler as described in
  // ../../profile/README.md, and add up the gas-usage values reported for the
  // lines in reimburseAndRewardOracles following the "gasLeft = gasleft()"
  // line. E.g., you will see output like this:
  //
  //      7        uint256 gasLeft = gasleft();
  //     29        uint256 gasCostEthWei = transmitterGasCostEthWei(
  //      9          uint256(initialGas),
  //      3          gasPrice,
  //      3          callDataGasCost,
  //      3          gasLeft
  //      .
  //      .
  //      .
  //     59        uint256 gasCostLinkWei = (gasCostEthWei * billing.microLinkPerEth)/ 1e6;
  //      .
  //      .
  //      .
  //   5047        s_gasReimbursementsLinkWei[txOracle.index] =
  //    856          s_gasReimbursementsLinkWei[txOracle.index] + gasCostLinkWei +
  //     26          uint256(billing.linkGweiPerTransmission) * (1 gwei);
  //
  // If those were the only lines to be accounted for, you would add up
  // 29+9+3+3+3+59+5047+856+26=6035.
  uint256 internal constant accountingGasCost = 6035;

  // Uncomment the following declaration to compute the remaining gas cost after
  // above gasleft(). (This must exist in a base class to OffchainAggregator, so
  // it can't go in TestOffchainAggregator.)
  //
  // uint256 public gasUsedInAccounting;

  // Gas price at which the transmitter should be reimbursed, in ETH-gwei/gas
  function impliedGasPrice(
    uint256 txGasPrice,         // ETH-gwei/gas units
    uint256 reasonableGasPrice, // ETH-gwei/gas units
    uint256 maximumGasPrice     // ETH-gwei/gas units
  )
    internal
    pure
    returns (uint256)
  {
    // Reward the transmitter for choosing an efficient gas price: if they manage
    // to come in lower than considered reasonable, give them half the savings.
    //
    // The following calculations are all in units of gwei/gas, i.e. 1e-9ETH/gas
    uint256 gasPrice = txGasPrice;
    if (txGasPrice < reasonableGasPrice) {
      // Give transmitter half the savings for coming in under the reasonable gas price
      gasPrice += (reasonableGasPrice - txGasPrice) / 2;
    }
    // Don't reimburse a gas price higher than maximumGasPrice
    return min(gasPrice, maximumGasPrice);
  }

  // gas reimbursement due the transmitter, in ETH-wei
  //
  // If this function is changed, accountingGasCost needs to change, too. See
  // its docstring
  function transmitterGasCostEthWei(
    uint256 initialGas,
    uint256 gasPrice, // ETH-gwei/gas units
    uint256 callDataCost, // gas units
    uint256 gasLeft
  )
    internal
    pure
    returns (uint128 gasCostEthWei)
  {
    require(initialGas >= gasLeft, "gasLeft cannot exceed initialGas");
    uint256 gasUsed = // gas units
      initialGas - gasLeft + // observed gas usage
      callDataCost + accountingGasCost; // estimated gas usage
    // gasUsed is in gas units, gasPrice is in ETH-gwei/gas units; convert to ETH-wei
    uint256 fullGasCostEthWei = gasUsed * gasPrice * (1 gwei);
    assert(fullGasCostEthWei < maxUint128); // the entire ETH supply fits in a uint128...
    return uint128(fullGasCostEthWei);
  }

  /**
   * @notice withdraw any available funds left in the contract, up to _amount, after accounting for the funds due to participants in past reports
   * @param _recipient address to send funds to
   * @param _amount maximum amount to withdraw, denominated in LINK-wei.
   * @dev access control provided by billingAccessController
   */
  function withdrawFunds(address _recipient, uint256 _amount)
    external
  {
    require(msg.sender == owner || s_billingAccessController.hasAccess(msg.sender, msg.data),
      "Only owner&billingAdmin can call");
    uint256 linkDue = totalLINKDue();
    uint256 linkBalance = LINK.balanceOf(address(this));
    require(linkBalance >= linkDue, "insufficient balance");
    require(LINK.transfer(_recipient, min(linkBalance - linkDue, _amount)), "insufficient funds");
  }

  // Total LINK due to participants in past reports.
  function totalLINKDue()
    internal
    view
    returns (uint256 linkDue)
  {
    // Argument for overflow safety: We do all computations in
    // uint256s. The inputs to linkDue are:
    // - the <= 31 observation rewards each of which has less than
    //   64 bits (32 bits for billing.linkGweiPerObservation, 32 bits
    //   for wei/gwei conversion). Hence 69 bits are sufficient for this part.
    // - the <= 31 gas reimbursements, each of which consists of at most 166
    //   bits (see s_gasReimbursementsLinkWei docstring). Hence 171 bits are
    //   sufficient for this part
    // In total, 172 bits are enough.
    uint16[maxNumOracles] memory observationCounts = s_oracleObservationsCounts;
    for (uint i = 0; i < maxNumOracles; i++) {
      linkDue += observationCounts[i] - 1; // Stored value is one greater than actual value
    }
    Billing memory billing = s_billing;
    // Convert linkGweiPerObservation to uint256, or this overflows!
    linkDue *= uint256(billing.linkGweiPerObservation) * (1 gwei);
    address[] memory transmitters = s_transmitters;
    uint256[maxNumOracles] memory gasReimbursementsLinkWei =
      s_gasReimbursementsLinkWei;
    for (uint i = 0; i < transmitters.length; i++) {
      linkDue += uint256(gasReimbursementsLinkWei[i]-1); // Stored value is one greater than actual value
    }
  }

  /**
   * @notice allows oracles to check that sufficient LINK balance is available
   * @return availableBalance LINK available on this contract, after accounting for outstanding obligations. can become negative
   */
  function linkAvailableForPayment()
    external
    view
    returns (int256 availableBalance)
  {
    // there are at most one billion LINK, so this cast is safe
    int256 balance = int256(LINK.balanceOf(address(this)));
    // according to the argument in the definition of totalLINKDue,
    // totalLINKDue is never greater than 2**172, so this cast is safe
    int256 due = int256(totalLINKDue());
    // safe from overflow according to above sizes
    return int256(balance) - int256(due);
  }

  /**
   * @notice number of observations oracle is due to be reimbursed for
   * @param _signerOrTransmitter address used by oracle for signing or transmitting reports
   */
  function oracleObservationCount(address _signerOrTransmitter)
    external
    view
    returns (uint16)
  {
    Oracle memory oracle = s_oracles[_signerOrTransmitter];
    if (oracle.role == Role.Unset) { return 0; }
    return s_oracleObservationsCounts[oracle.index] - 1;
  }


  function reimburseAndRewardOracles(
    uint32 initialGas,
    bytes memory observers
  )
    internal
  {
    Oracle memory txOracle = s_oracles[msg.sender];
    Billing memory billing = s_billing;
    // Reward oracles for providing observations. Oracles are not rewarded
    // for providing signatures, because signing is essentially free.
    s_oracleObservationsCounts =
      oracleRewards(observers, s_oracleObservationsCounts);
    // Reimburse transmitter of the report for gas usage
    require(txOracle.role == Role.Transmitter,
      "sent by undesignated transmitter"
    );
    uint256 gasPrice = impliedGasPrice(
      tx.gasprice / (1 gwei), // convert to ETH-gwei units
      billing.reasonableGasPrice,
      billing.maximumGasPrice
    );
    // The following is only an upper bound, as it ignores the cheaper cost for
    // 0 bytes. Safe from overflow, because calldata just isn't that long.
    uint256 callDataGasCost = 16 * msg.data.length;
    // If any changes are made to subsequent calculations, accountingGasCost
    // needs to change, too.
    uint256 gasLeft = gasleft();
    uint256 gasCostEthWei = transmitterGasCostEthWei(
      uint256(initialGas),
      gasPrice,
      callDataGasCost,
      gasLeft
    );

    // microLinkPerEth is 1e-6LINK/ETH units, gasCostEthWei is 1e-18ETH units
    // (ETH-wei), product is 1e-24LINK-wei units, dividing by 1e6 gives
    // 1e-18LINK units, i.e. LINK-wei units
    // Safe from over/underflow, since all components are non-negative,
    // gasCostEthWei will always fit into uint128 and microLinkPerEth is a
    // uint32 (128+32 < 256!).
    uint256 gasCostLinkWei = (gasCostEthWei * billing.microLinkPerEth)/ 1e6;

    // Safe from overflow, because gasCostLinkWei < 2**160 and
    // billing.linkGweiPerTransmission * (1 gwei) < 2**64 and we increment
    // s_gasReimbursementsLinkWei[txOracle.index] at most 2**40 times.
    s_gasReimbursementsLinkWei[txOracle.index] =
      s_gasReimbursementsLinkWei[txOracle.index] + gasCostLinkWei +
      uint256(billing.linkGweiPerTransmission) * (1 gwei); // convert from linkGwei to linkWei

    // Uncomment next line to compute the remaining gas cost after above gasleft().
    // See OffchainAggregatorBilling.accountingGasCost docstring for more information.
    //
    // gasUsedInAccounting = gasLeft - gasleft();
  }

  /*
   * Payee management
   */

  /**
   * @notice emitted when a transfer of an oracle's payee address has been initiated
   * @param transmitter address from which the oracle sends reports to the transmit method
   * @param current the payeee address for the oracle, prior to this setting
   * @param proposed the proposed new payee address for the oracle
   */
  event PayeeshipTransferRequested(
    address indexed transmitter,
    address indexed current,
    address indexed proposed
  );

  /**
   * @notice emitted when a transfer of an oracle's payee address has been completed
   * @param transmitter address from which the oracle sends reports to the transmit method
   * @param current the payeee address for the oracle, prior to this setting
   */
  event PayeeshipTransferred(
    address indexed transmitter,
    address indexed previous,
    address indexed current
  );

  /**
   * @notice sets the payees for transmitting addresses
   * @param _transmitters addresses oracles use to transmit the reports
   * @param _payees addresses of payees corresponding to list of transmitters
   * @dev must be called by owner
   * @dev cannot be used to change payee addresses, only to initially populate them
   */
  function setPayees(
    address[] calldata _transmitters,
    address[] calldata _payees
  )
    external
    onlyOwner()
  {
    require(_transmitters.length == _payees.length, "transmitters.size != payees.size");

    for (uint i = 0; i < _transmitters.length; i++) {
      address transmitter = _transmitters[i];
      address payee = _payees[i];
      address currentPayee = s_payees[transmitter];
      bool zeroedOut = currentPayee == address(0);
      require(zeroedOut || currentPayee == payee, "payee already set");
      s_payees[transmitter] = payee;

      if (currentPayee != payee) {
        emit PayeeshipTransferred(transmitter, currentPayee, payee);
      }
    }
  }

  /**
   * @notice first step of payeeship transfer (safe transfer pattern)
   * @param _transmitter transmitter address of oracle whose payee is changing
   * @param _proposed new payee address
   * @dev can only be called by payee address
   */
  function transferPayeeship(
    address _transmitter,
    address _proposed
  )
    external
  {
      require(msg.sender == s_payees[_transmitter], "only current payee can update");
      require(msg.sender != _proposed, "cannot transfer to self");

      address previousProposed = s_proposedPayees[_transmitter];
      s_proposedPayees[_transmitter] = _proposed;

      if (previousProposed != _proposed) {
        emit PayeeshipTransferRequested(_transmitter, msg.sender, _proposed);
      }
  }

  /**
   * @notice second step of payeeship transfer (safe transfer pattern)
   * @param _transmitter transmitter address of oracle whose payee is changing
   * @dev can only be called by proposed new payee address
   */
  function acceptPayeeship(
    address _transmitter
  )
    external
  {
    require(msg.sender == s_proposedPayees[_transmitter], "only proposed payees can accept");

    address currentPayee = s_payees[_transmitter];
    s_payees[_transmitter] = msg.sender;
    s_proposedPayees[_transmitter] = address(0);

    emit PayeeshipTransferred(_transmitter, currentPayee, msg.sender);
  }

  /*
   * Helper functions
   */

  function saturatingAddUint16(uint16 _x, uint16 _y)
    internal
    pure
    returns (uint16)
  {
    return uint16(min(uint256(_x)+uint256(_y), maxUint16));
  }

  function min(uint256 a, uint256 b)
    internal
    pure
    returns (uint256)
  {
    if (a < b) { return a; }
    return b;
  }
}

File 11 of 12 : SimpleReadAccessController.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.1;

import "./SimpleWriteAccessController.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 12 of 12 : SimpleWriteAccessController.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./Owned.sol";
import "./AccessControllerInterface.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, Owned {

  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() {
    addAccessInternal(_user);
  }

  function addAccessInternal(address _user) internal {
    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");
    _;
  }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 20000
  },
  "evmVersion": "istanbul",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint32","name":"_maximumGasPrice","type":"uint32"},{"internalType":"uint32","name":"_reasonableGasPrice","type":"uint32"},{"internalType":"uint32","name":"_microLinkPerEth","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerObservation","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerTransmission","type":"uint32"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"address","name":"_validator","type":"address"},{"internalType":"int192","name":"_minAnswer","type":"int192"},{"internalType":"int192","name":"_maxAnswer","type":"int192"},{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"},{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"string","name":"description","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"AddedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"current","type":"int256"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"updatedAt","type":"uint256"}],"name":"AnswerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","name":"current","type":"address"}],"name":"BillingAccessControllerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"maximumGasPrice","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"reasonableGasPrice","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"microLinkPerEth","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"linkGweiPerObservation","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"linkGweiPerTransmission","type":"uint32"}],"name":"BillingSet","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessDisabled","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"threshold","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"encodedConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":true,"internalType":"address","name":"startedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"startedAt","type":"uint256"}],"name":"NewRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"aggregatorRoundId","type":"uint32"},{"indexed":false,"internalType":"int192","name":"answer","type":"int192"},{"indexed":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"int192[]","name":"observations","type":"int192[]"},{"indexed":false,"internalType":"bytes","name":"observers","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"rawReportContext","type":"bytes32"}],"name":"NewTransmission","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OraclePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"},{"indexed":true,"internalType":"address","name":"proposed","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"RemovedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","name":"current","type":"address"}],"name":"RequesterAccessControllerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"bytes16","name":"configDigest","type":"bytes16"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"round","type":"uint8"}],"name":"RoundRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"ValidatorUpdated","type":"event"},{"inputs":[],"name":"LINK","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"addAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"billingAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBilling","outputs":[{"internalType":"uint32","name":"maximumGasPrice","type":"uint32"},{"internalType":"uint32","name":"reasonableGasPrice","type":"uint32"},{"internalType":"uint32","name":"microLinkPerEth","type":"uint32"},{"internalType":"uint32","name":"linkGweiPerObservation","type":"uint32"},{"internalType":"uint32","name":"linkGweiPerTransmission","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"hasAccess","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes16","name":"configDigest","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTransmissionDetails","outputs":[{"internalType":"bytes16","name":"configDigest","type":"bytes16"},{"internalType":"uint32","name":"epoch","type":"uint32"},{"internalType":"uint8","name":"round","type":"uint8"},{"internalType":"int192","name":"latestAnswer","type":"int192"},{"internalType":"uint64","name":"latestTimestamp","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"availableBalance","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_signerOrTransmitter","type":"address"}],"name":"oracleObservationCount","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"owedPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"removeAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestNewRound","outputs":[{"internalType":"uint80","name":"","type":"uint80"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requesterAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_maximumGasPrice","type":"uint32"},{"internalType":"uint32","name":"_reasonableGasPrice","type":"uint32"},{"internalType":"uint32","name":"_microLinkPerEth","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerObservation","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerTransmission","type":"uint32"}],"name":"setBilling","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"}],"name":"setBillingAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_signers","type":"address[]"},{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"uint8","name":"_threshold","type":"uint8"},{"internalType":"uint64","name":"_encodedConfigVersion","type":"uint64"},{"internalType":"bytes","name":"_encoded","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"address[]","name":"_payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"}],"name":"setRequesterAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newValidator","type":"address"}],"name":"setValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"},{"internalType":"address","name":"_proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_report","type":"bytes"},{"internalType":"bytes32[]","name":"_rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_ss","type":"bytes32[]"},{"internalType":"bytes32","name":"_rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transmitters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validator","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101006040523480156200001257600080fd5b50604051620061083803806200610883398181016040526101a08110156200003957600080fd5b815160208301516040808501516060860151608087015160a088015160c089015160e08a01516101008b01516101208c01516101408d01516101608e01516101808f0180519b519d9f9c9e9a9d999c989b979a96999598949793969295919491939282019284640100000000821115620000b257600080fd5b908301906020820185811115620000c857600080fd5b8251640100000000811182820188101715620000e357600080fd5b82525081516020918201929091019080838360005b8381101562000112578181015183820152602001620000f8565b50505050905090810190601f168015620001405780820380516001836020036101000a031916815260200191505b506040525050600080546001600160a01b03191633179055508c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c896200017c8787878787620002da565b6200018781620003cc565b6001600160601b0319606083901b16608052620001a362000602565b620001ad62000602565b60005b601f8160ff161015620001fd576001838260ff16601f8110620001cf57fe5b61ffff909216602092909202015260018260ff8316601f8110620001ef57fe5b6020020152600101620001b0565b506200020d600483601f62000621565b506200021d600882601f620006be565b505050505060f887901b7fff000000000000000000000000000000000000000000000000000000000000001660e05250508351620002669350602e9250602085019150620006ef565b50620002728362000445565b6200027d876200051d565b8560170b60a08160170b60401b815250508460170b60c08160170b60401b81525050505050505050505050505050506001602f60006101000a81548160ff0219169083151502179055505050505050505050505050505062000788565b6040805160a0808201835263ffffffff88811680845288821660208086018290528984168688018190528985166060808901829052958a1660809889018190526002805463ffffffff1916871763ffffffff60201b191664010000000087021763ffffffff60401b19166801000000000000000085021763ffffffff60601b19166c0100000000000000000000000084021763ffffffff60801b1916600160801b830217905589519586529285019390935283880152928201529283015291517fd0d9486a2c673e2a4b57fc82e4c8a556b3e2b82dd5db07e2c04a920ca0f469b6929181900390910190a15050505050565b6003546001600160a01b0390811690821681146200044157600380546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d489129281900390910190a15b5050565b6000546001600160a01b03163314620004a5576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602d546001600160a01b0390811690821681146200044157602d80546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae6349281900390910190a15050565b6000546001600160a01b031633146200057d576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602c546001600160a01b0368010000000000000000909104811690821681146200044157602c8054600160401b600160e01b031916680100000000000000006001600160a01b0385811691820292909217909255604051908316907fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d90600090a35050565b604051806103e00160405280601f906020820280368337509192915050565b600283019183908215620006ac5791602002820160005b838211156200067a57835183826101000a81548161ffff021916908361ffff160217905550926020019260020160208160010104928301926001030262000638565b8015620006aa5782816101000a81549061ffff02191690556002016020816001010492830192600103026200067a565b505b50620006ba92915062000771565b5090565b82601f8101928215620006ac579160200282015b82811115620006ac578251825591602001919060010190620006d2565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620007275760008555620006ac565b82601f106200074257805160ff1916838001178555620006ac565b82800160010185558215620006ac5791820182811115620006ac578251825591602001919060010190620006d2565b5b80821115620006ba576000815560010162000772565b60805160601c60a05160401c60c05160401c60e05160f81c61591b620007ed60003980611053525080611bd7528061392e525080610fb25280613901525080610f8e5280612c675280612d575280613d6852806143f65280614c75525061591b6000f3fe608060405234801561001057600080fd5b50600436106102f45760003560e01c80638ac28d5a11610191578063bd824706116100e3578063e4902f8211610097578063f2fde38b11610071578063f2fde38b14610c36578063fbffd2c114610c5c578063feaf968c14610c82576102f4565b8063e4902f8214610b61578063e5fe457714610b9e578063eb5dcd6c14610c08576102f4565b8063c9807539116100c8578063c980753914610a3d578063d09dc33914610b51578063dc7f012414610b59576102f4565b8063bd824706146109cc578063c107532914610a11576102f4565b80639c849b3011610145578063b121e1471161011f578063b121e1471461096c578063b5ab58dc14610992578063b633620c146109af576102f4565b80639c849b301461085e5780639e3ceeab14610920578063a118f24914610946576102f4565b806398e5b12a1161017657806398e5b12a146107bc578063996e8298146107e35780639a6fc8f5146107eb576102f4565b80638ac28d5a1461078e5780638da5cb5b146107b4576102f4565b8063668a0f021161024a57806379ba5097116101fe57806381ff7048116101d857806381ff70481461070f5780638205bf6a146107605780638823da6c14610768576102f4565b806379ba5097146106a75780638038e4a1146106af57806381411834146106b7576102f4565b806370da2f671161022f57806370da2f671461061a57806370efdf2d146106225780637284e4161461062a576102f4565b8063668a0f02146105485780636b14daf814610550576102f4565b806329937268116102ac57806350d25bcd1161028657806350d25bcd1461040b57806354fd4d5014610413578063585aa7de1461041b576102f4565b806329937268146103a4578063313ce567146103e55780633a5381b514610403576102f4565b80631327d3d8116102dd5780631327d3d81461033b5780631b6b6d231461036157806322adbc7814610385576102f4565b80630a756983146102f95780630eafb25b14610303575b600080fd5b610301610c8a565b005b6103296004803603602081101561031957600080fd5b50356001600160a01b0316610d48565b60408051918252519081900360200190f35b6103016004803603602081101561035157600080fd5b50356001600160a01b0316610e93565b610369610f8c565b604080516001600160a01b039092168252519081900360200190f35b61038d610fb0565b6040805160179290920b8252519081900360200190f35b6103ac610fd4565b6040805163ffffffff96871681529486166020860152928516848401529084166060840152909216608082015290519081900360a00190f35b6103ed611051565b6040805160ff9092168252519081900360200190f35b610369611075565b610329611090565b610329611131565b610301600480360360a081101561043157600080fd5b81019060208101813564010000000081111561044c57600080fd5b82018360208201111561045e57600080fd5b8035906020019184602083028401116401000000008311171561048057600080fd5b91939092909160208101903564010000000081111561049e57600080fd5b8201836020820111156104b057600080fd5b803590602001918460208302840111640100000000831117156104d257600080fd5b9193909260ff8335169267ffffffffffffffff60208201351692919060608101906040013564010000000081111561050957600080fd5b82018360208201111561051b57600080fd5b8035906020019184600183028401116401000000008311171561053d57600080fd5b509092509050611136565b610329611b11565b6106066004803603604081101561056657600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561059157600080fd5b8201836020820111156105a357600080fd5b803590602001918460018302840111640100000000831117156105c557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bad945050505050565b604080519115158252519081900360200190f35b61038d611bd5565b610369611bf9565b610632611c08565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561066c578181015183820152602001610654565b50505050905090810190601f1680156106995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610301611ca4565b610301611d72565b6106bf611e31565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106fb5781810151838201526020016106e3565b505050509050019250505060405180910390f35b610717611e93565b6040805163ffffffff94851681529290931660208301527fffffffffffffffffffffffffffffffff00000000000000000000000000000000168183015290519081900360600190f35b610329611eb4565b6103016004803603602081101561077e57600080fd5b50356001600160a01b0316611f50565b610301600480360360208110156107a457600080fd5b50356001600160a01b0316612047565b6103696120be565b6107c46120cd565b6040805169ffffffffffffffffffff9092168252519081900360200190f35b610369612321565b6108146004803603602081101561080157600080fd5b503569ffffffffffffffffffff16612330565b604051808669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1681526020019550505050505060405180910390f35b6103016004803603604081101561087457600080fd5b81019060208101813564010000000081111561088f57600080fd5b8201836020820111156108a157600080fd5b803590602001918460208302840111640100000000831117156108c357600080fd5b9193909290916020810190356401000000008111156108e157600080fd5b8201836020820111156108f357600080fd5b8035906020019184602083028401116401000000008311171561091557600080fd5b5090925090506123e5565b6103016004803603602081101561093657600080fd5b50356001600160a01b031661261e565b6103016004803603602081101561095c57600080fd5b50356001600160a01b031661270c565b6103016004803603602081101561098257600080fd5b50356001600160a01b0316612774565b610329600480360360208110156109a857600080fd5b503561286d565b610329600480360360208110156109c557600080fd5b503561290a565b610301600480360360a08110156109e257600080fd5b5063ffffffff8135811691602081013582169160408201358116916060810135821691608090910135166129a7565b61030160048036036040811015610a2757600080fd5b506001600160a01b038135169060200135612b0d565b61030160048036036080811015610a5357600080fd5b810190602081018135640100000000811115610a6e57600080fd5b820183602082011115610a8057600080fd5b80359060200191846001830284011164010000000083111715610aa257600080fd5b919390929091602081019035640100000000811115610ac057600080fd5b820183602082011115610ad257600080fd5b80359060200191846020830284011164010000000083111715610af457600080fd5b919390929091602081019035640100000000811115610b1257600080fd5b820183602082011115610b2457600080fd5b80359060200191846020830284011164010000000083111715610b4657600080fd5b919350915035612e5a565b610329613d63565b610606613e14565b610b8760048036036020811015610b7757600080fd5b50356001600160a01b0316613e1d565b6040805161ffff9092168252519081900360200190f35b610ba6613eca565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909616865263ffffffff909416602086015260ff9092168484015260170b606084015267ffffffffffffffff166080830152519081900360a00190f35b61030160048036036040811015610c1e57600080fd5b506001600160a01b0381358116916020013516613fb9565b61030160048036036020811015610c4c57600080fd5b50356001600160a01b0316614115565b61030160048036036020811015610c7257600080fd5b50356001600160a01b03166141dd565b610814614245565b6000546001600160a01b03163314610ce9576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602f5460ff1615610d4657602f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b6001600160a01b03811660009081526027602090815260408083208151808301909252805460ff808216845285948401916101009004166002811115610d8a57fe5b6002811115610d9557fe5b9052509050600081602001516002811115610dac57fe5b1415610dbc576000915050610e8e565b6040805160a08101825260025463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830181905270010000000000000000000000000000000090910490921660808201528251909160009160019060049060ff16601f8110610e4757fe5b601091828204019190066002029054906101000a900461ffff160361ffff1602633b9aca0002905060016008846000015160ff16601f8110610e8557fe5b01540301925050505b919050565b6000546001600160a01b03163314610ef2576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602c546001600160a01b036801000000000000000090910481169082168114610f8857602c80547fffffffff0000000000000000000000000000000000000000ffffffffffffffff16680100000000000000006001600160a01b0385811691820292909217909255604051908316907fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d90600090a35b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6040805160a08101825260025463ffffffff808216808452640100000000830482166020850181905268010000000000000000840483169585018690526c01000000000000000000000000840483166060860181905270010000000000000000000000000000000090940490921660809094018490529490939290565b7f000000000000000000000000000000000000000000000000000000000000000081565b602c546801000000000000000090046001600160a01b031690565b60006110d3336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b611124576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61112c6142f8565b905090565b600481565b868560ff8616601f831115611192576040805162461bcd60e51b815260206004820152601060248201527f746f6f206d616e79207369676e65727300000000000000000000000000000000604482015290519081900360640190fd5b600081116111e7576040805162461bcd60e51b815260206004820152601a60248201527f7468726573686f6c64206d75737420626520706f736974697665000000000000604482015290519081900360640190fd5b8183146112255760405162461bcd60e51b81526004018080602001828103825260248152602001806158c26024913960400191505060405180910390fd5b80600302831161127c576040805162461bcd60e51b815260206004820181905260248201527f6661756c74792d6f7261636c65207468726573686f6c6420746f6f2068696768604482015290519081900360640190fd5b6000546001600160a01b031633146112db576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6028541561147f57602880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101916000918390811061131857fe5b6000918252602082200154602980546001600160a01b039092169350908490811061133f57fe5b6000918252602090912001546001600160a01b0316905061135f81614334565b6001600160a01b0380831660009081526027602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000908116909155928416825290208054909116905560288054806113bb57fe5b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055602980548061141e57fe5b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055506112db915050565b60005b8a81101561188d576000602760008e8e8581811061149c57fe5b602090810292909201356001600160a01b031683525081019190915260400160002054610100900460ff1660028111156114d257fe5b14611524576040805162461bcd60e51b815260206004820152601760248201527f7265706561746564207369676e65722061646472657373000000000000000000604482015290519081900360640190fd5b6040805180820190915260ff8216815260016020820152602760008e8e8581811061154b57fe5b602090810292909201356001600160a01b031683525081810192909252604001600020825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff9091161780825591830151909182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360028111156115d657fe5b02179055506000915060069050818c8c858181106115f057fe5b6001600160a01b036020918202939093013583168452830193909352604090910160002054169190911415905061166e576040805162461bcd60e51b815260206004820152601160248201527f7061796565206d75737420626520736574000000000000000000000000000000604482015290519081900360640190fd5b6000602760008c8c8581811061168057fe5b602090810292909201356001600160a01b031683525081019190915260400160002054610100900460ff1660028111156116b657fe5b14611708576040805162461bcd60e51b815260206004820152601c60248201527f7265706561746564207472616e736d6974746572206164647265737300000000604482015290519081900360640190fd5b6040805180820190915260ff8216815260026020820152602760008c8c8581811061172f57fe5b602090810292909201356001600160a01b031683525081810192909252604001600020825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff9091161780825591830151909182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360028111156117ba57fe5b021790555090505060288c8c838181106117d057fe5b835460018101855560009485526020948590200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03959092029390930135939093169290921790555060298a8a8381811061183257fe5b835460018181018655600095865260209586902090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0396909302949094013594909416179091555001611482565b50602a805460ff89167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff909116179055602c80544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff84161780831660010183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000090911617938490559091048116911661195930828f8f8f8f8f8f8f8f61455e565b602a60000160006101000a8154816fffffffffffffffffffffffffffffffff021916908360801c02179055506000602a60000160106101000a81548164ffffffffff021916908364ffffffffff1602179055507f25d719d88a4512dd76c7442b910a83360845505894eb444ef299409e180f8fb982828f8f8f8f8f8f8f8f604051808b63ffffffff1681526020018a67ffffffffffffffff16815260200180602001806020018760ff1681526020018667ffffffffffffffff1681526020018060200184810384528c8c82818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810384528a8152602090810191508b908b0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810383528681526020019050868680828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039f50909d5050505050505050505050505050a150505050505050505050505050565b6000611b54336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b611ba5576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61112c61469e565b6000611bb983836146c4565b80611bcc57506001600160a01b03831632145b90505b92915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b602d546001600160a01b031690565b6060611c4b336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b611c9c576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61112c6146f4565b6001546001600160a01b03163314611d03576040805162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000546001600160a01b03163314611dd1576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602f5460ff16610d4657602f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b60606029805480602002602001604051908101604052809291908181526020018280548015611e8957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611e6b575b5050505050905090565b602c54602a5463ffffffff808316926401000000009004169060801b909192565b6000611ef7336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b611f48576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61112c61479f565b6000546001600160a01b03163314611faf576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6001600160a01b03811660009081526030602052604090205460ff1615612044576001600160a01b03811660008181526030602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055815192835290517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d19281900390910190a15b50565b6001600160a01b038181166000908152600660205260409020541633146120b5576040805162461bcd60e51b815260206004820152601760248201527f4f6e6c792070617965652063616e207769746864726177000000000000000000604482015290519081900360640190fd5b61204481614334565b6000546001600160a01b031681565b600080546001600160a01b03163314806121c75750602d54604080517f6b14daf800000000000000000000000000000000000000000000000000000000815233600482018181526024830193845236604484018190526001600160a01b0390951694636b14daf894929360009391929190606401848480828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201965060209550909350505081840390508186803b15801561219a57600080fd5b505afa1580156121ae573d6000803e3d6000fd5b505050506040513d60208110156121c457600080fd5b50515b612218576040805162461bcd60e51b815260206004820152601d60248201527f4f6e6c79206f776e6572267265717565737465722063616e2063616c6c000000604482015290519081900360640190fd5b6040805160808082018352602a549081901b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016808352700100000000000000000000000000000000820464ffffffffff81166020808601919091527501000000000000000000000000000000000000000000840460ff9081168688015276010000000000000000000000000000000000000000000090940463ffffffff9081166060808801919091528751948552600884901c909116918401919091529216818501529251919233927f3ea16a923ff4b1df6526e854c9e3a995c43385d70e73359e10623c74f0b52037929181900390910190a2806060015160010163ffffffff1691505090565b6003546001600160a01b031690565b6000806000806000612379336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b6123ca576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6123d3866147fa565b939a9299509097509550909350915050565b6000546001600160a01b03163314612444576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b828114612498576040805162461bcd60e51b815260206004820181905260248201527f7472616e736d6974746572732e73697a6520213d207061796565732e73697a65604482015290519081900360640190fd5b60005b838110156126175760008585838181106124b157fe5b905060200201356001600160a01b0316905060008484848181106124d157fe5b6001600160a01b03858116600090815260066020908152604090912054920293909301358316935090911690508015808061251d5750826001600160a01b0316826001600160a01b0316145b61256e576040805162461bcd60e51b815260206004820152601160248201527f706179656520616c726561647920736574000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b03848116600090815260066020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168583169081179091559083161461260757826001600160a01b0316826001600160a01b0316856001600160a01b03167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a45b50506001909201915061249b9050565b5050505050565b6000546001600160a01b0316331461267d576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602d546001600160a01b039081169082168114610f8857602d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03848116918217909255604080519284168352602083019190915280517f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae6349281900390910190a15050565b6000546001600160a01b0316331461276b576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b61204481614945565b6001600160a01b038181166000908152600760205260409020541633146127e2576040805162461bcd60e51b815260206004820152601f60248201527f6f6e6c792070726f706f736564207061796565732063616e2061636365707400604482015290519081900360640190fd5b6001600160a01b0381811660008181526006602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556007909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b60006128b0336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b612901576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611bcf826149de565b600061294d336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b61299e576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611bcf82614a14565b6003546000546001600160a01b039182169116331480612a9f5750604080517f6b14daf800000000000000000000000000000000000000000000000000000000815233600482018181526024830193845236604484018190526001600160a01b03861694636b14daf8946000939190606401848480828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201965060209550909350505081840390508186803b158015612a7257600080fd5b505afa158015612a86573d6000803e3d6000fd5b505050506040513d6020811015612a9c57600080fd5b50515b612af0576040805162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c604482015290519081900360640190fd5b612af8614a69565b612b058686868686614e2e565b505050505050565b6000546001600160a01b0316331480612c065750600354604080517f6b14daf800000000000000000000000000000000000000000000000000000000815233600482018181526024830193845236604484018190526001600160a01b0390951694636b14daf894929360009391929190606401848480828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201965060209550909350505081840390508186803b158015612bd957600080fd5b505afa158015612bed573d6000803e3d6000fd5b505050506040513d6020811015612c0357600080fd5b50515b612c57576040805162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c604482015290519081900360640190fd5b6000612c61614fa8565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612cd257600080fd5b505afa158015612ce6573d6000803e3d6000fd5b505050506040513d6020811015612cfc57600080fd5b5051905081811015612d55576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb85612d9185850387615178565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612dd757600080fd5b505af1158015612deb573d6000803e3d6000fd5b505050506040513d6020811015612e0157600080fd5b5051612e54576040805162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b50505050565b60005a9050612e6d88888888888861518f565b3614612ec0576040805162461bcd60e51b815260206004820152601960248201527f7472616e736d6974206d65737361676520746f6f206c6f6e6700000000000000604482015290519081900360640190fd5b612ec8615757565b6040805160808082018352602a549081901b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252700100000000000000000000000000000000810464ffffffffff1660208301527501000000000000000000000000000000000000000000810460ff169282019290925276010000000000000000000000000000000000000000000090910463ffffffff166060808301919091529082526000908a908a90811015612f8157600080fd5b813591602081013591810190606081016040820135640100000000811115612fa857600080fd5b820183602082011115612fba57600080fd5b80359060200191846020830284011164010000000083111715612fdc57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050505060408801525050506080840182905283515190925060589190911b907fffffffffffffffffffffffffffffffff000000000000000000000000000000008083169116146130a3576040805162461bcd60e51b815260206004820152601560248201527f636f6e666967446967657374206d69736d617463680000000000000000000000604482015290519081900360640190fd5b608083015183516020015164ffffffffff80831691161061310b576040805162461bcd60e51b815260206004820152600c60248201527f7374616c65207265706f72740000000000000000000000000000000000000000604482015290519081900360640190fd5b83516040015160ff168911613167576040805162461bcd60e51b815260206004820152601560248201527f6e6f7420656e6f756768207369676e6174757265730000000000000000000000604482015290519081900360640190fd5b601f8911156131bd576040805162461bcd60e51b815260206004820152601360248201527f746f6f206d616e79207369676e61747572657300000000000000000000000000604482015290519081900360640190fd5b868914613211576040805162461bcd60e51b815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e0000604482015290519081900360640190fd5b601f846040015151111561326c576040805162461bcd60e51b815260206004820152601e60248201527f6e756d206f62736572766174696f6e73206f7574206f6620626f756e64730000604482015290519081900360640190fd5b83600001516040015160020260ff16846040015151116132d3576040805162461bcd60e51b815260206004820152601e60248201527f746f6f206665772076616c75657320746f207472757374206d656469616e0000604482015290519081900360640190fd5b8867ffffffffffffffff811180156132ea57600080fd5b506040519080825280601f01601f191660200182016040528015613315576020820181803683370190505b50606085015260005b60ff81168a111561338657868160ff166020811061333857fe5b1a60f81b85606001518260ff168151811061334f57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161331e565b5083604001515167ffffffffffffffff811180156133a357600080fd5b506040519080825280601f01601f1916602001820160405280156133ce576020820181803683370190505b5060208501526133dc61578b565b60005b8560400151518160ff1610156134e2576000858260ff166020811061340057fe5b1a90508281601f811061340f57fe5b602002015115613466576040805162461bcd60e51b815260206004820152601760248201527f6f6273657276657220696e646578207265706561746564000000000000000000604482015290519081900360640190fd5b6001838260ff16601f811061347757fe5b91151560209283029190910152869060ff841690811061349357fe5b1a60f81b87602001518360ff16815181106134aa57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350506001016133df565b503360009081526027602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561352057fe5b600281111561352b57fe5b905250905060028160200151600281111561354257fe5b14801561357657506029816000015160ff168154811061355e57fe5b6000918252602090912001546001600160a01b031633145b6135c7576040805162461bcd60e51b815260206004820152601860248201527f756e617574686f72697a6564207472616e736d69747465720000000000000000604482015290519081900360640190fd5b5050835164ffffffffff90911660209091015250506040516000908a908a908083838082843760405192018290039091209450613608935061578b92505050565b6136106157aa565b60005b898110156138275760006001858760600151848151811061363057fe5b60209101015160f81c601b018e8e8681811061364857fe5b905060200201358d8d8781811061365b57fe5b9050602002013560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156136b6573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101516001600160a01b03811660009081526027602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561372357fe5b600281111561372e57fe5b905250925060018360200151600281111561374557fe5b14613797576040805162461bcd60e51b815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e0000604482015290519081900360640190fd5b8251849060ff16601f81106137a857fe5b6020020151156137ff576040805162461bcd60e51b815260206004820152601460248201527f6e6f6e2d756e69717565207369676e6174757265000000000000000000000000604482015290519081900360640190fd5b600184846000015160ff16601f811061381457fe5b9115156020909202015250600101613613565b5050505060005b6001826040015151038110156138d85760008260400151826001018151811061385357fe5b602002602001015160170b8360400151838151811061386e57fe5b602002602001015160170b13159050806138cf576040805162461bcd60e51b815260206004820152601760248201527f6f62736572766174696f6e73206e6f7420736f72746564000000000000000000604482015290519081900360640190fd5b5060010161382e565b506040810151805160009190600281049081106138f157fe5b602002602001015190508060170b7f000000000000000000000000000000000000000000000000000000000000000060170b1315801561395757507f000000000000000000000000000000000000000000000000000000000000000060170b8160170b13155b6139a8576040805162461bcd60e51b815260206004820152601e60248201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e67650000604482015290519081900360640190fd5b81516060908101805163ffffffff60019091018116909152604080518082018252601785810b80835267ffffffffffffffff42811660208086019182528a5189015188166000908152602b82528781209651875493519094167801000000000000000000000000000000000000000000000000029390950b77ffffffffffffffffffffffffffffffffffffffffffffffff9081167fffffffffffffffff0000000000000000000000000000000000000000000000009093169290921790911691909117909355875186015184890151848a01516080808c015188519586523386890181905291860181905260a0988601898152845199870199909952835194909916997ff6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451998c999298949793969095909492939185019260c086019289820192909102908190849084905b83811015613b0b578181015183820152602001613af3565b50505050905001838103825285818151815260200191508051906020019080838360005b83811015613b47578181015183820152602001613b2f565b50505050905090810190601f168015613b745780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a281516060015160408051428152905160009263ffffffff16917f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271919081900360200190a381600001516060015163ffffffff168160170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a3613c298260000151606001518260170b6151a7565b5080518051602a8054602084015160408501516060909501517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921660809490941c939093177fffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000064ffffffffff90941693909302929092177fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000060ff90941693909302929092177fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000063ffffffff92831602179091558210613d4a57fe5b613d588282602001516152b8565b505050505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613dd357600080fd5b505afa158015613de7573d6000803e3d6000fd5b505050506040513d6020811015613dfd57600080fd5b505190506000613e0b614fa8565b90910391505090565b602f5460ff1681565b6001600160a01b03811660009081526027602090815260408083208151808301909252805460ff808216845285948401916101009004166002811115613e5f57fe5b6002811115613e6a57fe5b9052509050600081602001516002811115613e8157fe5b1415613e91576000915050610e8e565b60016004826000015160ff16601f8110613ea757fe5b601091828204019190066002029054906101000a900461ffff1603915050919050565b600080808080333214613f24576040805162461bcd60e51b815260206004820152601460248201527f4f6e6c792063616c6c61626c6520627920454f41000000000000000000000000604482015290519081900360640190fd5b5050602a5463ffffffff760100000000000000000000000000000000000000000000820481166000908152602b6020526040902054608083901b96700100000000000000000000000000000000909304600881901c909216955064ffffffffff9091169350601781900b92507801000000000000000000000000000000000000000000000000900467ffffffffffffffff1690565b6001600160a01b03828116600090815260066020526040902054163314614027576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792063757272656e742070617965652063616e20757064617465000000604482015290519081900360640190fd5b336001600160a01b0382161415614085576040805162461bcd60e51b815260206004820152601760248201527f63616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b6001600160a01b03808316600090815260076020526040902080548383167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117909255909116908114614110576040516001600160a01b038084169133918616907f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836790600090a45b505050565b6000546001600160a01b03163314614174576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000546001600160a01b0316331461423c576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b61204481615505565b600080600080600061428e336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bad92505050565b6142df576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6142e7615594565b945094509450945094509091929394565b602a54760100000000000000000000000000000000000000000000900463ffffffff166000908152602b6020526040902054601790810b900b90565b6001600160a01b03811660009081526027602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561437a57fe5b600281111561438557fe5b9052509050600061439583610d48565b90508015614110576001600160a01b0380841660009081526006602090815260408083205481517fa9059cbb0000000000000000000000000000000000000000000000000000000081529085166004820181905260248201879052915191947f0000000000000000000000000000000000000000000000000000000000000000169363a9059cbb9360448084019491939192918390030190829087803b15801561443e57600080fd5b505af1158015614452573d6000803e3d6000fd5b505050506040513d602081101561446857600080fd5b50516144bb576040805162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b60016004846000015160ff16601f81106144d157fe5b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060016008846000015160ff16601f811061450c57fe5b0155604080516001600160a01b0380871682528316602082015280820184905290517fe8ec50e5150ae28ae37e493ff389ffab7ffaec2dc4dccfca03f12a3de29d12b29181900360600190a150505050565b60008a8a8a8a8a8a8a8a8a8a604051602001808b6001600160a01b031681526020018a67ffffffffffffffff16815260200180602001806020018760ff1681526020018667ffffffffffffffff1681526020018060200184810384528c8c82818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810384528a8152602090810191508b908b0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810383528681526020019050868680828437600081840152601f19601f8201169050808301925050509d50505050505050505050505050506040516020818303038152906040528051906020012090509a9950505050505050505050565b602a54760100000000000000000000000000000000000000000000900463ffffffff1690565b6001600160a01b03821660009081526030602052604081205460ff1680611bcc575050602f5460ff161592915050565b602e8054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015611e895780601f1061477357610100808354040283529160200191611e89565b820191906000526020600020905b81548152906001019060200180831161478157509395945050505050565b602a54760100000000000000000000000000000000000000000000900463ffffffff166000908152602b60205260409020547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1690565b600080600080600063ffffffff8669ffffffffffffffffffff1611156040518060400160405280600f81526020017f4e6f20646174612070726573656e740000000000000000000000000000000000815250906148d55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561489a578181015183820152602001614882565b50505050905090810190601f1680156148c75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5050505063ffffffff83166000908152602b6020908152604091829020825180840190935254601781810b810b810b808552780100000000000000000000000000000000000000000000000090920467ffffffffffffffff1693909201839052949594900b939092508291508490565b6001600160a01b03811660009081526030602052604090205460ff16612044576001600160a01b03811660008181526030602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055815192835290517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49281900390910190a150565b600063ffffffff8211156149f457506000610e8e565b5063ffffffff166000908152602b6020526040902054601790810b900b90565b600063ffffffff821115614a2a57506000610e8e565b5063ffffffff166000908152602b60205260409020547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1690565b6040805160a08101825260025463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000082048116606084015270010000000000000000000000000000000090910416608082015281516103e0810192839052909160009190600490601f908285855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411614aee575050604080516103e0810191829052959650600095945060089350601f9250905082845b815481526020019060010190808311614b48575050505050905060006029805480602002602001604051908101604052809291908181526020018280548015614bba57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614b9c575b5050505050905060005b8151811015614e1257600060018483601f8110614bdd57fe5b6020020151039050600060018684601f8110614bf557fe5b60200201510361ffff169050600082886060015163ffffffff168302633b9aca00020190506000811115614e0757600060066000878781518110614c3557fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031690507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb82846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015614cea57600080fd5b505af1158015614cfe573d6000803e3d6000fd5b505050506040513d6020811015614d1457600080fd5b5051614d67576040805162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b60018886601f8110614d7557fe5b61ffff909216602092909202015260018786601f8110614d9157fe5b602002015285517fe8ec50e5150ae28ae37e493ff389ffab7ffaec2dc4dccfca03f12a3de29d12b290879087908110614dc657fe5b6020026020010151828460405180846001600160a01b03168152602001836001600160a01b03168152602001828152602001935050505060405180910390a1505b505050600101614bc4565b50614e20600484601f6157c1565b50612617600883601f615857565b6040805160a0808201835263ffffffff88811680845288821660208086018290528984168688018190528985166060808901829052958a166080988901819052600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001687177fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff166401000000008702177fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff16680100000000000000008502177fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c010000000000000000000000008402177fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000830217905589519586529285019390935283880152928201529283015291517fd0d9486a2c673e2a4b57fc82e4c8a556b3e2b82dd5db07e2c04a920ca0f469b6929181900390910190a15050505050565b604080516103e0810191829052600091829190600490601f908285855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411614fc55790505050505050905060005b601f8110156150355760018282601f811061501e57fe5b60200201510361ffff169290920191600101615007565b506040805160a08101825260025463ffffffff8082168352640100000000820481166020808501919091526801000000000000000083048216848601526c01000000000000000000000000830482166060850181905270010000000000000000000000000000000090930490911660808401526029805485518184028101840190965280865296909202633b9aca000295929360009390929183018282801561510757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116150e9575b5050604080516103e0810191829052949550600094935060089250601f915082845b815481526020019060010190808311615129575050505050905060005b82518110156151705760018282601f811061515d57fe5b6020020151039590950194600101615146565b505050505090565b600081831015615189575081611bcf565b50919050565b602083810286019082020160e4019695505050505050565b602c546801000000000000000090046001600160a01b0316806151ca5750610f88565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830163ffffffff8181166000818152602b602090815260408083205481517fbeed9b510000000000000000000000000000000000000000000000000000000081526004810195909552601790810b900b60248501819052948916604485015260648401889052516001600160a01b0387169363beed9b5193620186a09360848084019491939192918390030190829088803b15801561528957600080fd5b5087f1935050505080156152af57506040513d60208110156152aa57600080fd5b505160015b612b0557612617565b3360009081526027602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156152f557fe5b600281111561530057fe5b9052506040805160a08101825260025463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000082048116606084015270010000000000000000000000000000000090910416608082015281516103e0810192839052929350916153d091859190600490601f90826000855b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161538e5790505050505050615618565b6153de90600490601f6157c1565b506002826020015160028111156153f157fe5b14615443576040805162461bcd60e51b815260206004820181905260248201527f73656e7420627920756e64657369676e61746564207472616e736d6974746572604482015290519081900360640190fd5b600061546a633b9aca003a04836020015163ffffffff16846000015163ffffffff1661568d565b90506010360260005a905060006154898863ffffffff168585856156b3565b6fffffffffffffffffffffffffffffffff1690506000620f4240866040015163ffffffff168302816154b757fe5b049050856080015163ffffffff16633b9aca0002816008896000015160ff16601f81106154e057fe5b015401016008886000015160ff16601f81106154f857fe5b0155505050505050505050565b6003546001600160a01b039081169082168114610f8857600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03848116918217909255604080519284168352602083019190915280517f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d489129281900390910190a15050565b602a54760100000000000000000000000000000000000000000000900463ffffffff166000818152602b6020908152604091829020825180840190935254601781810b810b810b808552780100000000000000000000000000000000000000000000000090920467ffffffffffffffff1693909201839052929392900b9181908490565b61562061578b565b60005b835181101561568557600084828151811061563a57fe5b016020015160f81c905061565f8482601f811061565357fe5b6020020151600161573f565b848260ff16601f811061566e57fe5b61ffff909216602092909202015250600101615623565b509092915050565b600083838110156156a057600285850304015b6156aa8184615178565b95945050505050565b60008185101561570a576040805162461bcd60e51b815260206004820181905260248201527f6761734c6566742063616e6e6f742065786365656420696e697469616c476173604482015290519081900360640190fd5b818503830161179301633b9aca00858202026fffffffffffffffffffffffffffffffff811061573557fe5b9695505050505050565b6000611bcc8261ffff168461ffff160161ffff615178565b6040518060a0016040528061576a615885565b81526060602082018190526040820181905280820152600060809091015290565b604051806103e00160405280601f906020820280368337509192915050565b604080518082019091526000808252602082015290565b6002830191839082156158475791602002820160005b8382111561581757835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026157d7565b80156158455782816101000a81549061ffff0219169055600201602081600101049283019260010302615817565b505b506158539291506158ac565b5090565b82601f8101928215615847579160200282015b8281111561584757825182559160200191906001019061586a565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b8082111561585357600081556001016158ad56fe6f7261636c6520616464726573736573206f7574206f6620726567697374726174696f6ea26469706673582212209de1ed4c0c937db6dc21106b5273d66a62faef1e2c8c840253ab946e0a7191d264736f6c6343000706003300000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000003dfd24000000000000000000000000000000000000000000000000000000000039387000000000000000000000000000000000000000000000000000000000011e1a300000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174876e8000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009db83cef9f68b63989e4e82d65d549e7ff2acda9000000000000000000000000641b698ad1c6e503470520b0eecb472c0589dfe6000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000094f474e202f204554480000000000000000000000000000000000000000000000

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

00000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000003dfd24000000000000000000000000000000000000000000000000000000000039387000000000000000000000000000000000000000000000000000000000011e1a300000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174876e8000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009db83cef9f68b63989e4e82d65d549e7ff2acda9000000000000000000000000641b698ad1c6e503470520b0eecb472c0589dfe6000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000094f474e202f204554480000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _maximumGasPrice (uint32): 1000
Arg [1] : _reasonableGasPrice (uint32): 100
Arg [2] : _microLinkPerEth (uint32): 65000000
Arg [3] : _linkGweiPerObservation (uint32): 60000000
Arg [4] : _linkGweiPerTransmission (uint32): 300000000
Arg [5] : _link (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [6] : _validator (address): 0x0000000000000000000000000000000000000000
Arg [7] : _minAnswer (int192): 100000000000
Arg [8] : _maxAnswer (int192): 1000000000000000000
Arg [9] : _billingAccessController (address): 0x9db83CEf9f68b63989E4E82D65D549e7fF2aCda9
Arg [10] : _requesterAccessController (address): 0x641B698aD1C6E503470520B0EeCb472c0589dfE6
Arg [11] : _decimals (uint8): 18
Arg [12] : description (string): OGN / ETH

-----Encoded View---------------
15 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [2] : 0000000000000000000000000000000000000000000000000000000003dfd240
Arg [3] : 0000000000000000000000000000000000000000000000000000000003938700
Arg [4] : 0000000000000000000000000000000000000000000000000000000011e1a300
Arg [5] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 000000000000000000000000000000000000000000000000000000174876e800
Arg [8] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [9] : 0000000000000000000000009db83cef9f68b63989e4e82d65d549e7ff2acda9
Arg [10] : 000000000000000000000000641b698ad1c6e503470520b0eecb472c0589dfe6
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [12] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [14] : 4f474e202f204554480000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.