Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 13,770 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transmit | 3553266 | 1 hr ago | IN | 0 ETH | 0.00009236 | ||||
Transmit | 3553131 | 1 hr ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3553048 | 2 hrs ago | IN | 0 ETH | 0.00009231 | ||||
Transmit | 3552845 | 2 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3552788 | 3 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3552651 | 3 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3552618 | 3 hrs ago | IN | 0 ETH | 0.00009233 | ||||
Transmit | 3552601 | 3 hrs ago | IN | 0 ETH | 0.00009231 | ||||
Transmit | 3552566 | 4 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3552471 | 4 hrs ago | IN | 0 ETH | 0.00009231 | ||||
Transmit | 3552319 | 5 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3552226 | 5 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3552098 | 5 hrs ago | IN | 0 ETH | 0.00009232 | ||||
Transmit | 3551802 | 7 hrs ago | IN | 0 ETH | 0.00016919 | ||||
Transmit | 3550956 | 10 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3550766 | 11 hrs ago | IN | 0 ETH | 0.00009233 | ||||
Transmit | 3550611 | 11 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3550530 | 12 hrs ago | IN | 0 ETH | 0.00009233 | ||||
Transmit | 3550398 | 12 hrs ago | IN | 0 ETH | 0.00009232 | ||||
Transmit | 3550334 | 13 hrs ago | IN | 0 ETH | 0.00009233 | ||||
Transmit | 3550277 | 13 hrs ago | IN | 0 ETH | 0.00009233 | ||||
Transmit | 3550250 | 13 hrs ago | IN | 0 ETH | 0.00009232 | ||||
Transmit | 3549895 | 14 hrs ago | IN | 0 ETH | 0.00009233 | ||||
Transmit | 3549878 | 14 hrs ago | IN | 0 ETH | 0.00009235 | ||||
Transmit | 3549807 | 15 hrs ago | IN | 0 ETH | 0.00009232 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AccessControlledOCR2Aggregator
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity =0.8.19; import "./OCR2Aggregator.sol"; import "./SimpleReadAccessController.sol"; /** * @notice Wrapper of OCR2Aggregator which checks read access on Aggregator-interface methods */ contract AccessControlledOCR2Aggregator is OCR2Aggregator, SimpleReadAccessController { constructor( LinkTokenInterface _link, int192 _minAnswer, int192 _maxAnswer, AccessControllerInterface _billingAccessController, AccessControllerInterface _requesterAccessController, uint8 _decimals, string memory description ) OCR2Aggregator( _link, _minAnswer, _maxAnswer, _billingAccessController, _requesterAccessController, _decimals, description ) { } /* * Versioning */ function typeAndVersion() external override pure virtual returns (string memory) { return "AccessControlledOCR2Aggregator 1.0.0"; } /* * v2 Aggregator interface */ /// @inheritdoc OCR2Aggregator function latestAnswer() public override view checkAccess() returns (int256) { return super.latestAnswer(); } /// @inheritdoc OCR2Aggregator function latestTimestamp() public override view checkAccess() returns (uint256) { return super.latestTimestamp(); } /// @inheritdoc OCR2Aggregator function latestRound() public override view checkAccess() returns (uint256) { return super.latestRound(); } /// @inheritdoc OCR2Aggregator function getAnswer(uint256 _roundId) public override view checkAccess() returns (int256) { return super.getAnswer(_roundId); } /// @inheritdoc OCR2Aggregator function getTimestamp(uint256 _roundId) public override view checkAccess() returns (uint256) { return super.getTimestamp(_roundId); } /* * v3 Aggregator interface */ /// @inheritdoc OCR2Aggregator function description() public override view checkAccess() returns (string memory) { return super.description(); } /// @inheritdoc OCR2Aggregator function getRoundData(uint80 _roundId) public override view checkAccess() returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return super.getRoundData(_roundId); } /// @inheritdoc OCR2Aggregator function latestRoundData() public override view checkAccess() returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return super.latestRoundData(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ConfirmedOwnerWithProposal.sol"; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ contract ConfirmedOwner is ConfirmedOwnerWithProposal { constructor( address newOwner ) ConfirmedOwnerWithProposal( newOwner, address(0) ) { } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/OwnableInterface.sol"; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ contract ConfirmedOwnerWithProposal is OwnableInterface { address private s_owner; address private s_pendingOwner; event OwnershipTransferRequested( address indexed from, address indexed to ); event OwnershipTransferred( address indexed from, address indexed to ); constructor( address newOwner, address pendingOwner ) { require(newOwner != address(0), "Cannot set owner to zero"); s_owner = newOwner; if (pendingOwner != address(0)) { _transferOwnership(pendingOwner); } } /** * @notice Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership( address to ) public override onlyOwner() { _transferOwnership(to); } /** * @notice Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external override { require(msg.sender == s_pendingOwner, "Must be proposed owner"); address oldOwner = s_owner; s_owner = msg.sender; s_pendingOwner = address(0); emit OwnershipTransferred(oldOwner, msg.sender); } /** * @notice Get the current owner */ function owner() public view override returns ( address ) { return s_owner; } /** * @notice validate, transfer ownership, and emit relevant events */ function _transferOwnership( address to ) private { require(to != msg.sender, "Cannot transfer to self"); s_pendingOwner = to; emit OwnershipTransferRequested(s_owner, to); } /** * @notice validate access */ function _validateOwnership() internal view { require(msg.sender == s_owner, "Only callable by owner"); } /** * @notice Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { _validateOwnership(); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/TypeAndVersionInterface.sol"; abstract contract OCR2Abstract is TypeAndVersionInterface { // Maximum number of oracles the offchain reporting protocol is designed for uint256 constant internal maxNumOracles = 31; /** * @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 configDigest configDigest of this configuration * @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 f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly * @param onchainConfig serialized configuration used by the contract (and possibly oracles) * @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract */ event ConfigSet( uint32 previousConfigBlockNumber, bytes32 configDigest, uint64 configCount, address[] signers, address[] transmitters, uint8 f, bytes onchainConfig, uint64 offchainConfigVersion, bytes offchainConfig ); /** * @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 f number of faulty oracles the system can tolerate * @param onchainConfig serialized configuration used by the contract (and possibly oracles) * @param offchainConfigVersion version number for offchainEncoding schema * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract */ function setConfig( address[] memory signers, address[] memory transmitters, uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, bytes memory offchainConfig ) external virtual; /** * @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 virtual returns ( uint32 configCount, uint32 blockNumber, bytes32 configDigest ); function _configDigestFromConfigData( uint256 chainId, address contractAddress, uint64 configCount, address[] memory signers, address[] memory transmitters, uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, bytes memory offchainConfig ) internal pure returns (bytes32) { uint256 h = uint256(keccak256(abi.encode(chainId, contractAddress, configCount, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig ))); uint256 prefixMask = type(uint256).max << (256-16); // 0xFFFF00..00 uint256 prefix = 0x0001 << (256-16); // 0x000100..00 return bytes32((prefix & prefixMask) | (h & ~prefixMask)); } /** * @notice optionally emitted to indicate the latest configDigest and epoch for which a report was successfully transmitted. Alternatively, the contract may use latestConfigDigestAndEpoch with scanLogs set to false. */ event Transmitted( bytes32 configDigest, uint32 epoch ); /** * @notice optionally returns the latest configDigest and epoch for which a report was successfully transmitted. Alternatively, the contract may return scanLogs set to true and use Transmitted events to provide this information to offchain watchers. * @return scanLogs indicates whether to rely on the configDigest and epoch returned or whether to scan logs for the Transmitted event instead. * @return configDigest * @return epoch */ function latestConfigDigestAndEpoch() external view virtual returns( bool scanLogs, bytes32 configDigest, uint32 epoch ); /** * @notice transmit is called to post a new report to the contract * @param reportContext serialized report context containing configDigest, epoch, round, extraHash * @param report serialized report, which the signatures are signing * @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 bytes32[3] calldata reportContext, bytes calldata report, bytes32[] calldata rs, bytes32[] calldata ss, bytes32 rawVs // signatures ) external virtual; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.19; import "./interfaces/AccessControllerInterface.sol"; import "./interfaces/AggregatorV2V3Interface.sol"; import "./interfaces/AggregatorValidatorInterface.sol"; import "./interfaces/LinkTokenInterface.sol"; import "./interfaces/TypeAndVersionInterface.sol"; import "./OCR2Abstract.sol"; import "./OwnerIsCreator.sol"; /** * @notice OCR2Aggregator for numerical data with billing support. * @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 * Billing 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 OCR2Aggregator is OCR2Abstract, OwnerIsCreator, AggregatorV2V3Interface { // This contract is divided into sections. Each section defines a set of // variables, events, and functions that belong together. /*************************************************************************** * Section: Variables used in multiple other sections **************************************************************************/ struct Transmitter { bool active; // Index of oracle in s_signersList/s_transmittersList uint8 index; // juels-denominated payment for transmitters, covering gas costs incurred // by the transmitter plus additional rewards. The entire LINK supply (1e9 // LINK = 1e27 Juels) will always fit into a uint96. uint96 paymentJuels; } mapping (address /* transmitter address */ => Transmitter) internal s_transmitters; struct Signer { bool active; // Index of oracle in s_signersList/s_transmittersList uint8 index; } mapping (address /* signer address */ => Signer) internal s_signers; // s_signersList contains the signing address of each oracle address[] internal s_signersList; // s_transmittersList contains the transmission address of each oracle, // i.e. the address the oracle actually sends transactions to the contract from address[] internal s_transmittersList; // We assume that all oracles contribute observations to all rounds. this // variable tracks (per-oracle) from what round an oracle should be rewarded, // i.e. the oracle gets (latestAggregatorRoundId - // rewardFromAggregatorRoundId) * reward uint32[maxNumOracles] internal s_rewardFromAggregatorRoundId; bytes32 s_latestConfigDigest; // Storing these fields used on the hot path in a HotVars variable reduces the // retrieval of all of them to a single SLOAD. struct HotVars { // maximum number of faulty oracles uint8 f; // epoch and round from OCR protocol. // 32 most sig bits for epoch, 8 least sig bits for round uint40 latestEpochAndRound; // 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; // Highest compensated gas price, in gwei uints uint32 maximumGasPriceGwei; // If gas price is less (in gwei units), transmitter gets half the savings uint32 reasonableGasPriceGwei; // Fixed LINK reward for each observer uint32 observationPaymentGjuels; // Fixed reward for transmitter uint32 transmissionPaymentGjuels; // Overhead incurred by accounting logic uint24 accountingGas; } HotVars internal s_hotVars; // Transmission records the median answer from the transmit transaction at // time timestamp struct Transmission { int192 answer; // 192 bits ought to be enough for anyone uint32 observationsTimestamp; // when were observations made offchain uint32 transmissionTimestamp; // when was report received onchain } mapping(uint32 /* aggregator round ID */ => Transmission) internal s_transmissions; // 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; /*************************************************************************** * Section: Constructor **************************************************************************/ /** * @param link address of the LINK contract * @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 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( LinkTokenInterface link, int192 minAnswer_, int192 maxAnswer_, AccessControllerInterface billingAccessController, AccessControllerInterface requesterAccessController, uint8 decimals_, string memory description_ ) { s_linkToken = link; emit LinkTokenSet(LinkTokenInterface(address(0)), link); _setBillingAccessController(billingAccessController); decimals = decimals_; s_description = description_; setRequesterAccessController(requesterAccessController); setValidatorConfig(AggregatorValidatorInterface(address(0x0)), 0); minAnswer = minAnswer_; maxAnswer = maxAnswer_; } /*************************************************************************** * Section: OCR2Abstract Configuration **************************************************************************/ // incremented each time a new config is posted. This count is incorporated // into the config digest to prevent replay attacks. uint32 internal s_configCount; // makes it easier for offchain systems to extract config from logs uint32 internal s_latestConfigBlockNumber; // left as a function so this check can be disabled in derived contracts function _requirePositiveF ( uint256 f ) internal pure virtual { require(0 < f, "f must be positive"); } struct SetConfigArgs { address[] signers; address[] transmitters; uint8 f; bytes onchainConfig; uint64 offchainConfigVersion; bytes offchainConfig; } /// @inheritdoc OCR2Abstract function setConfig( address[] memory signers, address[] memory transmitters, uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, bytes memory offchainConfig ) external override onlyOwner() { require(signers.length <= maxNumOracles, "too many oracles"); require(signers.length == transmitters.length, "oracle length mismatch"); require(3*f < signers.length, "faulty-oracle f too high"); _requirePositiveF(f); require(keccak256(onchainConfig) == keccak256(abi.encodePacked(uint8(1) /*version*/, minAnswer, maxAnswer)), "invalid onchainConfig"); SetConfigArgs memory args = SetConfigArgs({ signers: signers, transmitters: transmitters, f: f, onchainConfig: onchainConfig, offchainConfigVersion: offchainConfigVersion, offchainConfig: offchainConfig }); s_hotVars.latestEpochAndRound = 0; _payOracles(); // remove any old signer/transmitter addresses uint256 oldLength = s_signersList.length; for (uint256 i = 0; i < oldLength; i++) { address signer = s_signersList[i]; address transmitter = s_transmittersList[i]; delete s_signers[signer]; delete s_transmitters[transmitter]; } delete s_signersList; delete s_transmittersList; // add new signer/transmitter addresses for (uint i = 0; i < args.signers.length; i++) { require( !s_signers[args.signers[i]].active, "repeated signer address" ); s_signers[args.signers[i]] = Signer({ active: true, index: uint8(i) }); require( !s_transmitters[args.transmitters[i]].active, "repeated transmitter address" ); s_transmitters[args.transmitters[i]] = Transmitter({ active: true, index: uint8(i), paymentJuels: 0 }); } s_signersList = args.signers; s_transmittersList = args.transmitters; s_hotVars.f = args.f; uint32 previousConfigBlockNumber = s_latestConfigBlockNumber; s_latestConfigBlockNumber = uint32(block.number); s_configCount += 1; s_latestConfigDigest = _configDigestFromConfigData( block.chainid, address(this), s_configCount, args.signers, args.transmitters, args.f, args.onchainConfig, args.offchainConfigVersion, args.offchainConfig ); emit ConfigSet( previousConfigBlockNumber, s_latestConfigDigest, s_configCount, args.signers, args.transmitters, args.f, args.onchainConfig, args.offchainConfigVersion, args.offchainConfig ); uint32 latestAggregatorRoundId = s_hotVars.latestAggregatorRoundId; for (uint256 i = 0; i < args.signers.length; i++) { s_rewardFromAggregatorRoundId[i] = latestAggregatorRoundId; } } /// @inheritdoc OCR2Abstract function latestConfigDetails() external override view returns ( uint32 configCount, uint32 blockNumber, bytes32 configDigest ) { return (s_configCount, s_latestConfigBlockNumber, s_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 getTransmitters() external view returns(address[] memory) { return s_transmittersList; } /*************************************************************************** * Section: Onchain Validation **************************************************************************/ // Configuration for validator struct ValidatorConfig { AggregatorValidatorInterface validator; uint32 gasLimit; } ValidatorConfig private s_validatorConfig; /** * @notice indicates that the validator configuration has been set * @param previousValidator previous validator contract * @param previousGasLimit previous gas limit for validate calls * @param currentValidator current validator contract * @param currentGasLimit current gas limit for validate calls */ event ValidatorConfigSet( AggregatorValidatorInterface indexed previousValidator, uint32 previousGasLimit, AggregatorValidatorInterface indexed currentValidator, uint32 currentGasLimit ); /** * @notice validator configuration * @return validator validator contract * @return gasLimit gas limit for validate calls */ function getValidatorConfig() external view returns (AggregatorValidatorInterface validator, uint32 gasLimit) { ValidatorConfig memory vc = s_validatorConfig; return (vc.validator, vc.gasLimit); } /** * @notice sets validator configuration * @dev set newValidator to 0x0 to disable validate calls * @param newValidator address of the new validator contract * @param newGasLimit new gas limit for validate calls */ function setValidatorConfig( AggregatorValidatorInterface newValidator, uint32 newGasLimit ) public onlyOwner() { ValidatorConfig memory previous = s_validatorConfig; if (previous.validator != newValidator || previous.gasLimit != newGasLimit) { s_validatorConfig = ValidatorConfig({ validator: newValidator, gasLimit: newGasLimit }); emit ValidatorConfigSet(previous.validator, previous.gasLimit, newValidator, newGasLimit); } } function _validateAnswer( uint32 aggregatorRoundId, int256 answer ) private { ValidatorConfig memory vc = s_validatorConfig; if (address(vc.validator) == address(0)) { return; } uint32 prevAggregatorRoundId = aggregatorRoundId - 1; int256 prevAggregatorRoundAnswer = s_transmissions[prevAggregatorRoundId].answer; require( _callWithExactGasEvenIfTargetIsNoContract( vc.gasLimit, address(vc.validator), abi.encodeWithSignature( "validate(uint256,int256,uint256,int256)", uint256(prevAggregatorRoundId), prevAggregatorRoundAnswer, uint256(aggregatorRoundId), answer ) ), "insufficient gas" ); } uint256 private constant CALL_WITH_EXACT_GAS_CUSHION = 5_000; /** * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available. */ function _callWithExactGasEvenIfTargetIsNoContract( uint256 gasAmount, address target, bytes memory data ) private returns (bool sufficientGas) { // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // Compute g -= CALL_WITH_EXACT_GAS_CUSHION and check for underflow. We // need the cushion since the logic following the above call to gas also // costs gas which we cannot account for exactly. So cushion is a // conservative upper bound for the cost of this logic. if iszero(lt(g, CALL_WITH_EXACT_GAS_CUSHION)) { g := sub(g, CALL_WITH_EXACT_GAS_CUSHION) // If g - g//64 <= gasAmount, we don't have enough gas. (We subtract g//64 // because of EIP-150.) if gt(sub(g, div(g, 64)), gasAmount) { // Call and ignore success/return data. Note that we did not check // whether a contract actually exists at the target address. pop(call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0)) sufficientGas := true } } } } /*************************************************************************** * Section: RequestNewRound **************************************************************************/ 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, bytes32 configDigest, uint32 epoch, uint8 round); /** * @notice address of the requester access controller contract * @return requester access controller address */ function getRequesterAccessController() 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"); uint40 latestEpochAndRound = s_hotVars.latestEpochAndRound; uint32 latestAggregatorRoundId = s_hotVars.latestAggregatorRoundId; emit RoundRequested( msg.sender, s_latestConfigDigest, uint32(latestEpochAndRound >> 8), uint8(latestEpochAndRound) ); return latestAggregatorRoundId + 1; } /*************************************************************************** * Section: Transmission **************************************************************************/ /** * @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 to this report * @param transmitter address from which the report was transmitted * @param observationsTimestamp when were observations made offchain * @param observations observations transmitted with this report * @param observers i-th element is the oracle id of the oracle that made the i-th observation * @param juelsPerFeeCoin exchange rate between feeCoin (e.g. ETH on Ethereum) and LINK, denominated in juels * @param configDigest configDigest of transmission * @param epochAndRound least-significant byte is the OCR protocol round number, the other bytes give the big-endian OCR protocol epoch number */ event NewTransmission( uint32 indexed aggregatorRoundId, int192 answer, address transmitter, uint32 observationsTimestamp, int192[] observations, bytes observers, int192 juelsPerFeeCoin, bytes32 configDigest, uint40 epochAndRound ); // Used to relieve stack pressure in transmit struct Report { uint32 observationsTimestamp; bytes observers; // ith element is the index of the ith observer int192[] observations; // ith element is the ith observation int192 juelsPerFeeCoin; } // _decodeReport decodes a serialized report into a Report struct function _decodeReport(bytes memory rawReport) internal pure returns ( Report memory ) { uint32 observationsTimestamp; bytes32 rawObservers; int192[] memory observations; int192 juelsPerFeeCoin; (observationsTimestamp, rawObservers, observations, juelsPerFeeCoin) = abi.decode(rawReport, (uint32, bytes32, int192[], int192)); _requireExpectedReportLength(rawReport, observations); uint256 numObservations = observations.length; bytes memory observers = abi.encodePacked(rawObservers); assembly { // we truncate observers from length 32 to the number of observations mstore(observers, numObservations) } return Report({ observationsTimestamp: observationsTimestamp, observers: observers, observations: observations, juelsPerFeeCoin: juelsPerFeeCoin }); } // 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 uint256 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT = 4 + // function selector 32 * 3 + // 3 words containing reportContext 32 + // word containing start location of abiencoded report value 32 + // word containing start location 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 // Make sure the calldata 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. function _requireExpectedMsgDataLength( bytes calldata report, bytes32[] calldata rs, bytes32[] calldata ss ) private pure { // calldata will never be big enough to make this overflow uint256 expected = TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT + report.length + // one byte per entry in report rs.length * 32 + // 32 bytes per entry in rs ss.length * 32 + // 32 bytes per entry in ss 0; // placeholder require(msg.data.length == expected, "calldata length mismatch"); } /// @inheritdoc OCR2Abstract function transmit( // reportContext consists of: // reportContext[0]: ConfigDigest // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round // reportContext[2]: ExtraHash bytes32[3] calldata reportContext, bytes calldata report, // ECDSA signatures bytes32[] calldata rs, bytes32[] calldata ss, bytes32 rawVs ) external override { // NOTE: If the arguments to this function are changed, _requireExpectedMsgDataLength and/or // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly uint256 initialGas = gasleft(); // This line must come first HotVars memory hotVars = s_hotVars; uint40 epochAndRound = uint40(uint256(reportContext[1])); require(hotVars.latestEpochAndRound < epochAndRound, "stale report"); require(s_transmitters[msg.sender].active, "unauthorized transmitter"); require(s_latestConfigDigest == reportContext[0], "configDigest mismatch"); _requireExpectedMsgDataLength(report, rs, ss); require(rs.length == hotVars.f + 1, "wrong number of signatures"); require(rs.length == ss.length, "signatures out of registration"); // Verify signatures attached to report { bytes32 h = keccak256(abi.encode(keccak256(report), reportContext)); // i-th byte counts number of sigs made by i-th signer uint256 signedCount = 0; Signer memory signer; for (uint i = 0; i < rs.length; i++) { address signerAddress = ecrecover(h, uint8(rawVs[i])+27, rs[i], ss[i]); signer = s_signers[signerAddress]; require(signer.active, "signature error"); unchecked{ signedCount += 1 << (8 * signer.index); } } // The first byte of the mask can be 0, because we only ever have 31 oracles require(signedCount & 0x0001010101010101010101010101010101010101010101010101010101010101 == signedCount, "duplicate signer"); } int192 juelsPerFeeCoin = _report(hotVars, reportContext[0], epochAndRound, report); _payTransmitter(hotVars, juelsPerFeeCoin, uint32(initialGas), msg.sender); } /** * @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 ( bytes32 configDigest, uint32 epoch, uint8 round, int192 latestAnswer_, uint64 latestTimestamp_ ) { require(msg.sender == tx.origin, "Only callable by EOA"); return ( s_latestConfigDigest, uint32(s_hotVars.latestEpochAndRound >> 8), uint8(s_hotVars.latestEpochAndRound), s_transmissions[s_hotVars.latestAggregatorRoundId].answer, s_transmissions[s_hotVars.latestAggregatorRoundId].transmissionTimestamp ); } /// @inheritdoc OCR2Abstract function latestConfigDigestAndEpoch() external override view virtual returns( bool scanLogs, bytes32 configDigest, uint32 epoch ) { return (false, s_latestConfigDigest, uint32(s_hotVars.latestEpochAndRound >> 8)); } function _requireExpectedReportLength( bytes memory report, int192[] memory observations ) private pure { uint256 expected = 32 + // observationsTimestamp 32 + // rawObservers 32 + // observations offset 32 + // juelsPerFeeCoin 32 + // observations length 32 * observations.length + // observations payload 0; require(report.length == expected, "report length mismatch"); } function _report( HotVars memory hotVars, bytes32 configDigest, uint40 epochAndRound, bytes memory rawReport ) internal returns (int192 juelsPerFeeCoin) { Report memory report = _decodeReport(rawReport); require(report.observations.length <= maxNumOracles, "num observations out of bounds"); // Offchain logic ensures that a quorum of oracles is operating on a matching set of at least // 2f+1 observations. By assumption, up to f of those can be faulty, which includes being // malformed. Conversely, more than f observations have to be well-formed and sent on chain. require(hotVars.f < report.observations.length, "too few values to trust median"); hotVars.latestEpochAndRound = epochAndRound; // get median, validate its range, store it in new aggregator round int192 median = report.observations[report.observations.length/2]; require(minAnswer <= median && median <= maxAnswer, "median is out of min-max range"); hotVars.latestAggregatorRoundId++; s_transmissions[hotVars.latestAggregatorRoundId] = Transmission({ answer: median, observationsTimestamp: report.observationsTimestamp, transmissionTimestamp: uint32(block.timestamp) }); // persist updates to hotVars s_hotVars = hotVars; emit NewTransmission( hotVars.latestAggregatorRoundId, median, msg.sender, report.observationsTimestamp, report.observations, report.observers, report.juelsPerFeeCoin, configDigest, epochAndRound ); // Emit these for backwards compatibility with offchain consumers // that only support legacy events emit NewRound( hotVars.latestAggregatorRoundId, address(0x0), // use zero address since we don't have anybody "starting" the round here report.observationsTimestamp ); emit AnswerUpdated( median, hotVars.latestAggregatorRoundId, block.timestamp ); _validateAnswer(hotVars.latestAggregatorRoundId, median); return report.juelsPerFeeCoin; } /*************************************************************************** * Section: v2 AggregatorInterface **************************************************************************/ /** * @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].transmissionTimestamp; } /** * @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)].transmissionTimestamp; } /*************************************************************************** * Section: v3 AggregatorInterface **************************************************************************/ /** * @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 = 6; 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 when observations were made offchain * @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 ) { if(roundId > type(uint32).max) { return (0, 0, 0, 0, 0); } Transmission memory transmission = s_transmissions[uint32(roundId)]; return ( roundId, transmission.answer, transmission.observationsTimestamp, transmission.transmissionTimestamp, roundId ); } /** * @notice aggregator details for the most recently transmitted report * @return roundId aggregator round of latest report (NOT OCR round) * @return answer median of latest report * @return startedAt timestamp of when observations were made offchain * @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 ) { uint32 latestAggregatorRoundId = s_hotVars.latestAggregatorRoundId; Transmission memory transmission = s_transmissions[latestAggregatorRoundId]; return ( latestAggregatorRoundId, transmission.answer, transmission.observationsTimestamp, transmission.transmissionTimestamp, latestAggregatorRoundId ); } /*************************************************************************** * Section: Configurable LINK Token **************************************************************************/ // We assume that the token contract is correct. This contract is not written // to handle misbehaving ERC20 tokens! LinkTokenInterface internal s_linkToken; /* * @notice emitted when the LINK token contract is set * @param oldLinkToken the address of the old LINK token contract * @param newLinkToken the address of the new LINK token contract */ event LinkTokenSet( LinkTokenInterface indexed oldLinkToken, LinkTokenInterface indexed newLinkToken ); /** * @notice sets the LINK token contract used for paying oracles * @param linkToken the address of the LINK token contract * @param recipient remaining funds from the previous token contract are transferred * here * @dev this function will return early (without an error) without changing any state * if linkToken equals getLinkToken(). * @dev this will trigger a payout so that a malicious owner cannot take from oracles * what is already owed to them. * @dev we assume that the token contract is correct. This contract is not written * to handle misbehaving ERC20 tokens! */ function setLinkToken( LinkTokenInterface linkToken, address recipient ) external onlyOwner() { LinkTokenInterface oldLinkToken = s_linkToken; if (linkToken == oldLinkToken) { // No change, nothing to be done return; } // call balanceOf as a sanity check on whether we're talking to a token // contract linkToken.balanceOf(address(this)); // we break CEI here, but that's okay because we're dealing with a correct // token contract (by assumption). _payOracles(); uint256 remainingBalance = oldLinkToken.balanceOf(address(this)); require(oldLinkToken.transfer(recipient, remainingBalance), "transfer remaining funds failed"); s_linkToken = linkToken; emit LinkTokenSet(oldLinkToken, linkToken); } /* * @notice gets the LINK token contract used for paying oracles * @return linkToken the address of the LINK token contract */ function getLinkToken() external view returns(LinkTokenInterface linkToken) { return s_linkToken; } /*************************************************************************** * Section: BillingAccessController Management **************************************************************************/ // Controls who can change billing parameters. A billingAdmin is not able to // affect any OCR protocol settings and therefore cannot tamper with the // liveness or integrity of a data feed. However, a billingAdmin can set // faulty billing parameters causing oracles to be underpaid, or causing them // to be paid so much that further calls to setConfig, setBilling, // setLinkToken will always fail due to the contract being underfunded. AccessControllerInterface internal s_billingAccessController; /** * @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 _setBillingAccessController(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 { _setBillingAccessController(_billingAccessController); } /** * @notice gets billingAccessController * @return address of billingAccessController contract */ function getBillingAccessController() external view returns (AccessControllerInterface) { return s_billingAccessController; } /*************************************************************************** * Section: Billing Configuration **************************************************************************/ /** * @notice emitted when billing parameters are set * @param maximumGasPriceGwei highest gas price for which transmitter will be compensated * @param reasonableGasPriceGwei transmitter will receive reward for gas prices under this value * @param observationPaymentGjuels reward to oracle for contributing an observation to a successfully transmitted report * @param transmissionPaymentGjuels reward to transmitter of a successful report * @param accountingGas gas overhead incurred by accounting logic */ event BillingSet( uint32 maximumGasPriceGwei, uint32 reasonableGasPriceGwei, uint32 observationPaymentGjuels, uint32 transmissionPaymentGjuels, uint24 accountingGas ); /** * @notice sets billing parameters * @param maximumGasPriceGwei highest gas price for which transmitter will be compensated * @param reasonableGasPriceGwei transmitter will receive reward for gas prices under this value * @param observationPaymentGjuels reward to oracle for contributing an observation to a successfully transmitted report * @param transmissionPaymentGjuels reward to transmitter of a successful report * @param accountingGas gas overhead incurred by accounting logic * @dev access control provided by billingAccessController */ function setBilling( uint32 maximumGasPriceGwei, uint32 reasonableGasPriceGwei, uint32 observationPaymentGjuels, uint32 transmissionPaymentGjuels, uint24 accountingGas ) external { AccessControllerInterface access = s_billingAccessController; require(msg.sender == owner() || access.hasAccess(msg.sender, msg.data), "Only owner&billingAdmin can call"); _payOracles(); s_hotVars.maximumGasPriceGwei = maximumGasPriceGwei; s_hotVars.reasonableGasPriceGwei = reasonableGasPriceGwei; s_hotVars.observationPaymentGjuels = observationPaymentGjuels; s_hotVars.transmissionPaymentGjuels = transmissionPaymentGjuels; s_hotVars.accountingGas = accountingGas; emit BillingSet(maximumGasPriceGwei, reasonableGasPriceGwei, observationPaymentGjuels, transmissionPaymentGjuels, accountingGas); } /** * @notice gets billing parameters * @param maximumGasPriceGwei highest gas price for which transmitter will be compensated * @param reasonableGasPriceGwei transmitter will receive reward for gas prices under this value * @param observationPaymentGjuels reward to oracle for contributing an observation to a successfully transmitted report * @param transmissionPaymentGjuels reward to transmitter of a successful report * @param accountingGas gas overhead of the accounting logic */ function getBilling() external view returns ( uint32 maximumGasPriceGwei, uint32 reasonableGasPriceGwei, uint32 observationPaymentGjuels, uint32 transmissionPaymentGjuels, uint24 accountingGas ) { return ( s_hotVars.maximumGasPriceGwei, s_hotVars.reasonableGasPriceGwei, s_hotVars.observationPaymentGjuels, s_hotVars.transmissionPaymentGjuels, s_hotVars.accountingGas ); } /*************************************************************************** * Section: Payments and Withdrawals **************************************************************************/ /** * @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, denominated in juels * @param transmitterAddress the transmitter address of the oracle */ function owedPayment(address transmitterAddress) public view returns (uint256) { Transmitter memory transmitter = s_transmitters[transmitterAddress]; if (!transmitter.active) { return 0; } // safe from overflow: // s_hotVars.latestAggregatorRoundId - s_rewardFromAggregatorRoundId[transmitter.index] <= 2**32 // s_hotVars.observationPaymentGjuels <= 2**32 // 1 gwei <= 2**32 // hence juelsAmount <= 2**96 uint256 juelsAmount = uint256(s_hotVars.latestAggregatorRoundId - s_rewardFromAggregatorRoundId[transmitter.index]) * uint256(s_hotVars.observationPaymentGjuels) * (1 gwei); juelsAmount += transmitter.paymentJuels; return juelsAmount; } /** * @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 * @param linkToken address of the LINK token contract */ event OraclePaid( address indexed transmitter, address indexed payee, uint256 amount, LinkTokenInterface indexed linkToken ); // _payOracle pays out transmitter's balance to the corresponding payee, and zeros it out function _payOracle(address transmitterAddress) internal { Transmitter memory transmitter = s_transmitters[transmitterAddress]; if (!transmitter.active) { return; } uint256 juelsAmount = owedPayment(transmitterAddress); if (juelsAmount > 0) { address payee = s_payees[transmitterAddress]; // Poses no re-entrancy issues, because LINK.transfer does not yield // control flow. require(s_linkToken.transfer(payee, juelsAmount), "insufficient funds"); s_rewardFromAggregatorRoundId[transmitter.index] = s_hotVars.latestAggregatorRoundId; s_transmitters[transmitterAddress].paymentJuels = 0; emit OraclePaid(transmitterAddress, payee, juelsAmount, s_linkToken); } } // _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 { unchecked { LinkTokenInterface linkToken = s_linkToken; uint32 latestAggregatorRoundId = s_hotVars.latestAggregatorRoundId; uint32[maxNumOracles] memory rewardFromAggregatorRoundId = s_rewardFromAggregatorRoundId; address[] memory transmitters = s_transmittersList; for (uint transmitteridx = 0; transmitteridx < transmitters.length; transmitteridx++) { uint256 reimbursementAmountJuels = s_transmitters[transmitters[transmitteridx]].paymentJuels; s_transmitters[transmitters[transmitteridx]].paymentJuels = 0; uint256 obsCount = latestAggregatorRoundId - rewardFromAggregatorRoundId[transmitteridx]; uint256 juelsAmount = obsCount * uint256(s_hotVars.observationPaymentGjuels) * (1 gwei) + reimbursementAmountJuels; if (juelsAmount > 0) { address payee = s_payees[transmitters[transmitteridx]]; // Poses no re-entrancy issues, because LINK.transfer does not yield // control flow. require(linkToken.transfer(payee, juelsAmount), "insufficient funds"); rewardFromAggregatorRoundId[transmitteridx] = latestAggregatorRoundId; emit OraclePaid(transmitters[transmitteridx], payee, juelsAmount, linkToken); } } // "Zero" the accounting storage variables s_rewardFromAggregatorRoundId = rewardFromAggregatorRoundId; } } /** * @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 = s_linkToken.balanceOf(address(this)); require(linkBalance >= linkDue, "insufficient balance"); require(s_linkToken.transfer(recipient, _min(linkBalance - linkDue, amount)), "insufficient funds"); } // Total LINK due to participants in past reports (denominated in Juels). 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 observationPaymentGjuels, 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 96 // bits. Hence 101 bits are sufficient for this part. // So we never need more than 102 bits. address[] memory transmitters = s_transmittersList; uint256 n = transmitters.length; uint32 latestAggregatorRoundId = s_hotVars.latestAggregatorRoundId; uint32[maxNumOracles] memory rewardFromAggregatorRoundId = s_rewardFromAggregatorRoundId; for (uint i = 0; i < n; i++) { linkDue += latestAggregatorRoundId - rewardFromAggregatorRoundId[i]; } // Convert observationPaymentGjuels to uint256, or this overflows! linkDue *= uint256(s_hotVars.observationPaymentGjuels) * (1 gwei); for (uint i = 0; i < n; i++) { linkDue += uint256(s_transmitters[transmitters[i]].paymentJuels); } } /** * @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(s_linkToken.balanceOf(address(this))); // according to the argument in the definition of _totalLinkDue, // _totalLinkDue is never greater than 2**102, 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 transmitterAddress address used by oracle for signing or transmitting reports */ function oracleObservationCount(address transmitterAddress) external view returns (uint32) { Transmitter memory transmitter = s_transmitters[transmitterAddress]; if (!transmitter.active) { return 0; } return s_hotVars.latestAggregatorRoundId - s_rewardFromAggregatorRoundId[transmitter.index]; } /*************************************************************************** * Section: Transmitter Payment **************************************************************************/ // Gas price at which the transmitter should be reimbursed, in gwei/gas function _reimbursementGasPriceGwei( uint256 txGasPriceGwei, uint256 reasonableGasPriceGwei, uint256 maximumGasPriceGwei ) internal pure returns (uint256) { // this happens on the path for transmissions. we'd rather pay out // a wrong reward than risk a liveness failure due to a revert. unchecked { // Reward the transmitter for choosing an efficient gas price: if they manage // to come in lower than considered reasonable, give them half the savings. uint256 gasPriceGwei = txGasPriceGwei; if (txGasPriceGwei < reasonableGasPriceGwei) { // Give transmitter half the savings for coming in under the reasonable gas price gasPriceGwei += (reasonableGasPriceGwei - txGasPriceGwei) / 2; } // Don't reimburse a gas price higher than maximumGasPriceGwei return _min(gasPriceGwei, maximumGasPriceGwei); } } // gas reimbursement due the transmitter, in wei function _transmitterGasCostWei( uint256 initialGas, uint256 gasPriceGwei, uint256 callDataGas, uint256 accountingGas, uint256 leftGas ) internal pure returns (uint256) { // this happens on the path for transmissions. we'd rather pay out // a wrong reward than risk a liveness failure due to a revert. unchecked { require(initialGas >= leftGas, "leftGas cannot exceed initialGas"); uint256 usedGas = initialGas - leftGas + // observed gas usage callDataGas + accountingGas; // estimated gas usage uint256 fullGasCostWei = usedGas * gasPriceGwei * (1 gwei); return fullGasCostWei; } } function _payTransmitter( HotVars memory hotVars, int192 juelsPerFeeCoin, uint32 initialGas, address transmitter ) internal virtual { // this happens on the path for transmissions. we'd rather pay out // a wrong reward than risk a liveness failure due to a revert. unchecked { // we can't deal with negative juelsPerFeeCoin, better to just not pay if (juelsPerFeeCoin < 0) { return; } // Reimburse transmitter of the report for gas usage uint256 gasPriceGwei = _reimbursementGasPriceGwei( tx.gasprice / (1 gwei), // convert to ETH-gwei units hotVars.reasonableGasPriceGwei, hotVars.maximumGasPriceGwei ); // 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; uint256 gasLeft = gasleft(); uint256 gasCostEthWei = _transmitterGasCostWei( uint256(initialGas), gasPriceGwei, callDataGasCost, hotVars.accountingGas, gasLeft ); // Even if we assume absurdly large values, this still does not overflow. With // - usedGas <= 1'000'000 gas <= 2**20 gas // - weiPerGas <= 1'000'000 gwei <= 2**50 wei // - hence gasCostEthWei <= 2**70 // - juelsPerFeeCoin <= 2**96 (more than the entire supply) // we still fit into 166 bits uint256 gasCostJuels = (gasCostEthWei * uint192(juelsPerFeeCoin))/1e18; uint96 oldTransmitterPaymentJuels = s_transmitters[transmitter].paymentJuels; uint96 newTransmitterPaymentJuels = uint96(uint256(oldTransmitterPaymentJuels) + gasCostJuels + uint256(hotVars.transmissionPaymentGjuels) * (1 gwei)); // overflow *should* never happen, but if it does, let's not persist it. if (newTransmitterPaymentJuels < oldTransmitterPaymentJuels) { return; } s_transmitters[transmitter].paymentJuels = newTransmitterPaymentJuels; } } /*************************************************************************** * Section: Payee Management **************************************************************************/ // 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; /** * @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 payee 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 payee 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); } /*************************************************************************** * Section: TypeAndVersionInterface **************************************************************************/ function typeAndVersion() external override pure virtual returns (string memory) { return "OCR2Aggregator 1.0.0"; } /*************************************************************************** * Section: Helper Functions **************************************************************************/ function _min( uint256 a, uint256 b ) internal pure returns (uint256) { unchecked { if (a < b) { return a; } return b; } } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.19; import "./interfaces/TypeAndVersionInterface.sol"; import "./lib/ConfigDigestUtilEVMSimple.sol"; import "./OwnerIsCreator.sol"; import "./OCR2Abstract.sol"; /// @title OCRConfigurationStoreEVMSimple /// @notice This contract stores configurations for protocol versions OCR2 and /// above in contract storage. It uses the "EVMSimple" config digester. contract OCRConfigurationStoreEVMSimple is TypeAndVersionInterface { struct ConfigurationEVMSimple { address[] signers; address[] transmitters; bytes onchainConfig; bytes offchainConfig; address contractAddress; uint64 offchainConfigVersion; uint32 configCount; uint8 f; } /// @notice a list of configurations keyed by their digest mapping(bytes32 => ConfigurationEVMSimple) internal s_configurations; /// @notice emitted when a new configuration is added event NewConfiguration(bytes32 indexed configDigest); /// @notice adds a new configuration to the store function addConfig(ConfigurationEVMSimple calldata configuration) external returns (bytes32) { bytes32 configDigest = ConfigDigestUtilEVMSimple.configDigestFromConfigData( block.chainid, configuration.contractAddress, configuration.configCount, configuration.signers, configuration.transmitters, configuration.f, configuration.onchainConfig, configuration.offchainConfigVersion, configuration.offchainConfig ); s_configurations[configDigest] = configuration; emit NewConfiguration(configDigest); return configDigest; } /// @notice reads a configuration from the store function readConfig(bytes32 configDigest) external view returns (ConfigurationEVMSimple memory) { return s_configurations[configDigest]; } /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external override pure virtual returns (string memory) { return "OCRConfigurationStoreEVMSimple 1.0.0"; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ConfirmedOwner.sol"; /** * @title The OwnerIsCreator contract * @notice A contract with helpers for basic contract ownership. */ contract OwnerIsCreator is ConfirmedOwner { constructor( ) ConfirmedOwner( msg.sender ) { } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; 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; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./OwnerIsCreator.sol"; import "./interfaces/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, OwnerIsCreator { bool public checkEnabled; mapping(address => bool) internal accessList; event AddedAccess(address user); event RemovedAccess(address user); event CheckAccessEnabled(); event CheckAccessDisabled(); constructor() // TODO // this is modified from the version in the Chainlink monorepo // OwnerIsCreator() { checkEnabled = true; } /** * @notice Returns the access of an address * @param _user The address to query */ function hasAccess( address _user, bytes memory ) public view virtual override returns (bool) { return accessList[_user] || !checkEnabled; } /** * @notice Adds an address to the access list * @param _user The address to add */ function addAccess(address _user) external onlyOwner() { if (!accessList[_user]) { accessList[_user] = true; emit AddedAccess(_user); } } /** * @notice Removes an address from the access list * @param _user The address to remove */ function removeAccess(address _user) external onlyOwner() { if (accessList[_user]) { accessList[_user] = false; emit RemovedAccess(_user); } } /** * @notice makes the access check enforced */ function enableAccessCheck() external onlyOwner() { if (!checkEnabled) { checkEnabled = true; emit CheckAccessEnabled(); } } /** * @notice makes the access check unenforced */ function disableAccessCheck() external onlyOwner() { if (checkEnabled) { checkEnabled = false; emit CheckAccessDisabled(); } } /** * @dev reverts if the caller does not have access */ modifier checkAccess() { require(hasAccess(msg.sender, msg.data), "No access"); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AccessControllerInterface { function hasAccess(address user, bytes calldata data) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./AggregatorInterface.sol"; import "./AggregatorV3Interface.sol"; interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface { }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); 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 ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorValidatorInterface { function validate( uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface LinkTokenInterface { function allowance(address owner, address spender) external view returns (uint256 remaining); function approve(address spender, uint256 value) external returns (bool success); function balanceOf(address owner) external view returns (uint256 balance); function decimals() external view returns (uint8 decimalPlaces); function decreaseApproval(address spender, uint256 addedValue) external returns (bool success); function increaseApproval(address spender, uint256 subtractedValue) external; function name() external view returns (string memory tokenName); function symbol() external view returns (string memory tokenSymbol); function totalSupply() external view returns (uint256 totalTokensIssued); function transfer(address to, uint256 value) external returns (bool success); function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success); function transferFrom(address from, address to, uint256 value) external returns (bool success); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface OwnableInterface { function owner() external returns ( address ); function transferOwnership( address recipient ) external; function acceptOwnership() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface TypeAndVersionInterface{ function typeAndVersion() external pure returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title ConfigDigestUtilEVMSimple /// @notice ConfigDigest related utility functions for "EVMSimple" config /// digester library ConfigDigestUtilEVMSimple { function configDigestFromConfigData( uint256 chainId, address contractAddress, uint64 configCount, address[] memory signers, address[] memory transmitters, uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, bytes memory offchainConfig ) internal pure returns (bytes32) { uint256 hash = uint256( keccak256( abi.encode( chainId, contractAddress, configCount, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig ))); uint256 prefixMask = type(uint256).max << (256-16); // 0xFFFF00..00 uint256 prefix = 0x0001 << (256-16); // 0x000100..00 return bytes32((prefix & prefixMask) | (hash & ~prefixMask)); } }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/" ], "optimizer": { "enabled": true, "runs": 10000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract ABI
API[{"inputs":[{"internalType":"contract LinkTokenInterface","name":"_link","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":"maximumGasPriceGwei","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"reasonableGasPriceGwei","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"observationPaymentGjuels","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"transmissionPaymentGjuels","type":"uint32"},{"indexed":false,"internalType":"uint24","name":"accountingGas","type":"uint24"}],"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":"bytes32","name":"configDigest","type":"bytes32"},{"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":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract LinkTokenInterface","name":"oldLinkToken","type":"address"},{"indexed":true,"internalType":"contract LinkTokenInterface","name":"newLinkToken","type":"address"}],"name":"LinkTokenSet","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":"uint32","name":"observationsTimestamp","type":"uint32"},{"indexed":false,"internalType":"int192[]","name":"observations","type":"int192[]"},{"indexed":false,"internalType":"bytes","name":"observers","type":"bytes"},{"indexed":false,"internalType":"int192","name":"juelsPerFeeCoin","type":"int192"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint40","name":"epochAndRound","type":"uint40"}],"name":"NewTransmission","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"payee","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"contract LinkTokenInterface","name":"linkToken","type":"address"}],"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":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"round","type":"uint8"}],"name":"RoundRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract AggregatorValidatorInterface","name":"previousValidator","type":"address"},{"indexed":false,"internalType":"uint32","name":"previousGasLimit","type":"uint32"},{"indexed":true,"internalType":"contract AggregatorValidatorInterface","name":"currentValidator","type":"address"},{"indexed":false,"internalType":"uint32","name":"currentGasLimit","type":"uint32"}],"name":"ValidatorConfigSet","type":"event"},{"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":"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":"maximumGasPriceGwei","type":"uint32"},{"internalType":"uint32","name":"reasonableGasPriceGwei","type":"uint32"},{"internalType":"uint32","name":"observationPaymentGjuels","type":"uint32"},{"internalType":"uint32","name":"transmissionPaymentGjuels","type":"uint32"},{"internalType":"uint24","name":"accountingGas","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBillingAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkToken","outputs":[{"internalType":"contract LinkTokenInterface","name":"linkToken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRequesterAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"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":[],"name":"getTransmitters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidatorConfig","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"validator","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"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":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"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":"bytes32","name":"configDigest","type":"bytes32"},{"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":"transmitterAddress","type":"address"}],"name":"oracleObservationCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transmitterAddress","type":"address"}],"name":"owedPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","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":[{"internalType":"uint32","name":"maximumGasPriceGwei","type":"uint32"},{"internalType":"uint32","name":"reasonableGasPriceGwei","type":"uint32"},{"internalType":"uint32","name":"observationPaymentGjuels","type":"uint32"},{"internalType":"uint32","name":"transmissionPaymentGjuels","type":"uint32"},{"internalType":"uint24","name":"accountingGas","type":"uint24"}],"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":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract LinkTokenInterface","name":"linkToken","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"setLinkToken","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":"contract AggregatorValidatorInterface","name":"newValidator","type":"address"},{"internalType":"uint32","name":"newGasLimit","type":"uint32"}],"name":"setValidatorConfig","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":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"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":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","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"}]
Contract Creation Code
60e06040523480156200001157600080fd5b5060405162005edf38038062005edf8339810160408190526200003491620004a4565b868686868686863380600081620000925760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c557620000c58162000179565b5050601180546001600160a01b0319166001600160a01b038a169081179091556040519091506000907f4966a50c93f855342ccf6c5c0d358b85b91335b2acedc7da0932f691f351711a908290a36200011e8462000224565b60ff821660c052601062000133828262000686565b506200013f836200029d565b6200014c60008062000318565b50505050601791820b608052900b60a05250506015805460ff191660011790555062000752945050505050565b336001600160a01b03821603620001d35760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000089565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6012546001600160a01b0390811690821681146200029957601280546001600160a01b0319166001600160a01b0384811691821790925560408051928416835260208301919091527f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d4891291015b60405180910390a15b5050565b620002a7620003ff565b600f546001600160a01b0390811690821681146200029957600f80546001600160a01b0319166001600160a01b0384811691821790925560408051928416835260208301919091527f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae634910162000290565b62000322620003ff565b60408051808201909152600e546001600160a01b03808216808452600160a01b90920463ffffffff16602084015284161415806200037057508163ffffffff16816020015163ffffffff1614155b15620003fa576040805180820182526001600160a01b0385811680835263ffffffff8681166020948501819052600e80546001600160c01b0319168417600160a01b830217905586518786015187519316835294820152909392909116917fb04e3a37abe9c0fcdfebdeae019a8e2b12ddf53f5d55ffb0caccc1bedaca1541910160405180910390a35b505050565b6000546001600160a01b031633146200045b5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000089565b565b6001600160a01b03811681146200047357600080fd5b50565b8051601781900b81146200048957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600060e0888a031215620004c057600080fd5b8751620004cd816200045d565b96506020620004de89820162000476565b9650620004ee60408a0162000476565b9550606089015162000500816200045d565b60808a015190955062000513816200045d565b60a08a015190945060ff811681146200052b57600080fd5b60c08a01519093506001600160401b03808211156200054957600080fd5b818b0191508b601f8301126200055e57600080fd5b8151818111156200057357620005736200048e565b604051601f8201601f19908116603f011681019083821181831017156200059e576200059e6200048e565b816040528281528e86848701011115620005b757600080fd5b600093505b82841015620005db5784840186015181850187015292850192620005bc565b600086848301015280965050505050505092959891949750929550565b600181811c908216806200060d57607f821691505b6020821081036200062e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003fa57600081815260208120601f850160051c810160208610156200065d5750805b601f850160051c820191505b818110156200067e5782815560010162000669565b505050505050565b81516001600160401b03811115620006a257620006a26200048e565b620006ba81620006b38454620005f8565b8462000634565b602080601f831160018114620006f25760008415620006d95750858301515b600019600386901b1c1916600185901b1785556200067e565b600085815260208120601f198616915b82811015620007235788860151825594840194600190910190840162000702565b5085821015620007425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516157416200079e6000396000610468015260008181610517015281816126ad0152613ccf015260008181610364015281816126850152613ca201526157416000f3fe608060405234801561001057600080fd5b50600436106103155760003560e01c80639a6fc8f5116101a7578063d09dc339116100ee578063e76d516811610097578063f2fde38b11610071578063f2fde38b1461084f578063fbffd2c114610862578063feaf968c1461087557600080fd5b8063e76d516814610818578063eb45716314610829578063eb5dcd6c1461083c57600080fd5b8063e3d0e712116100c8578063e3d0e71214610793578063e4902f82146107a6578063e5fe4577146107ce57600080fd5b8063d09dc3391461076d578063daffc4b514610775578063dc7f01241461078657600080fd5b8063b121e14711610150578063b633620c1161012a578063b633620c14610736578063c107532914610749578063c4c92b371461075c57600080fd5b8063b121e147146106fd578063b1dc65a414610710578063b5ab58dc1461072357600080fd5b80639e3ceeab116101815780639e3ceeab146106a6578063a118f249146106b9578063afcb95d7146106cc57600080fd5b80639a6fc8f5146105f75780639bd2c0b1146106415780639c849b301461069357600080fd5b8063668a0f021161026b57806381ff7048116102145780638ac28d5a116101ee5780638ac28d5a1461059c5780638da5cb5b146105af57806398e5b12a146105d457600080fd5b806381ff7048146105515780638205bf6a146105815780638823da6c1461058957600080fd5b80637284e416116102455780637284e4161461053957806379ba5097146105415780638038e4a11461054957600080fd5b8063668a0f02146104e75780636b14daf8146104ef57806370da2f671461051257600080fd5b8063313ce567116102cd57806354fd4d50116102a757806354fd4d50146104b7578063643dc105146104bf578063666cab8d146104d257600080fd5b8063313ce567146104635780634fb174701461049c57806350d25bcd146104af57600080fd5b8063181f5a77116102fe578063181f5a771461034a57806322adbc781461035f578063299372681461039957600080fd5b80630a7569831461031a5780630eafb25b14610324575b600080fd5b61032261087d565b005b610337610332366004614b17565b6108e4565b6040519081526020015b60405180910390f35b610352610a05565b6040516103419190614b7a565b6103867f000000000000000000000000000000000000000000000000000000000000000081565b60405160179190910b8152602001610341565b610427600b546a0100000000000000000000810463ffffffff908116926e010000000000000000000000000000830482169272010000000000000000000000000000000000008104831692760100000000000000000000000000000000000000000000820416917a01000000000000000000000000000000000000000000000000000090910462ffffff1690565b6040805163ffffffff9687168152948616602086015292851692840192909252909216606082015262ffffff909116608082015260a001610341565b61048a7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610341565b6103226104aa366004614b8d565b610a25565b610337610ca5565b610337600681565b6103226104cd366004614bd8565b610d63565b6104da61101e565b6040516103419190614c95565b610337611080565b6105026104fd366004614d78565b611127565b6040519015158152602001610341565b6103867f000000000000000000000000000000000000000000000000000000000000000081565b61035261114f565b6103226111e6565b6103226112af565b600d54600a546040805163ffffffff80851682526401000000009094049093166020840152820152606001610341565b610337611317565b610322610597366004614b17565b6113ef565b6103226105aa366004614b17565b61148f565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610341565b6105dc611501565b60405169ffffffffffffffffffff9091168152602001610341565b61060a610605366004614dc8565b611678565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a001610341565b604080518082018252600e546001600160a01b0381168083527401000000000000000000000000000000000000000090910463ffffffff16602092830181905283519182529181019190915201610341565b6103226106a1366004614e40565b61172a565b6103226106b4366004614b17565b611920565b6103226106c7366004614b17565b6119b7565b600a54600b546040805160008152602081019390935261010090910460081c63ffffffff1690820152606001610341565b61032261070b366004614b17565b611a51565b61032261071e366004614eac565b611b45565b610337610731366004614f91565b612090565b610337610744366004614f91565b612130565b610322610757366004614faa565b6121c8565b6012546001600160a01b03166105bc565b61033761249c565b600f546001600160a01b03166105bc565b6015546105029060ff1681565b6103226107a1366004615097565b612545565b6107b96107b4366004614b17565b612dc1565b60405163ffffffff9091168152602001610341565b6107d6612e7f565b6040805195865263ffffffff909416602086015260ff9092169284019290925260179190910b606083015267ffffffffffffffff16608082015260a001610341565b6011546001600160a01b03166105bc565b610322610837366004615164565b612f44565b61032261084a366004614b8d565b613061565b61032261085d366004614b17565b6131b1565b610322610870366004614b17565b6131c2565b61060a6131d3565b610885613308565b60155460ff16156108e257601580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b6001600160a01b03811660009081526002602090815260408083208151606081018352905460ff80821615158084526101008304909116948301949094526201000090046bffffffffffffffffffffffff16918101919091529061094b5750600092915050565b600b5460208201516000917201000000000000000000000000000000000000900463ffffffff169060069060ff16601f811061098957610989615192565b600881049190910154600b546109bf926007166004026101000a90910463ffffffff9081169166010000000000009004166151f0565b63ffffffff166109cf9190615214565b6109dd90633b9aca00615214565b905081604001516bffffffffffffffffffffffff16816109fd919061522b565b949350505050565b60606040518060600160405280602481526020016156e860249139905090565b610a2d613308565b6011546001600160a01b03908116908316819003610a4a57505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa158015610aa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acb919061523e565b50610ad4613362565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b58919061523e565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482018390529192509083169063a9059cbb906044016020604051808303816000875af1158015610bc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be89190615257565b610c395760405162461bcd60e51b815260206004820152601f60248201527f7472616e736665722072656d61696e696e672066756e6473206661696c65640060448201526064015b60405180910390fd5b601180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925560405190918416907f4966a50c93f855342ccf6c5c0d358b85b91335b2acedc7da0932f691f351711a90600090a350505b5050565b6000610ce8336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b610d345760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b600b546601000000000000900463ffffffff166000908152600c602052604090205460170b905090565b905090565b6012546001600160a01b0316610d816000546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480610e2657506040517f6b14daf80000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636b14daf890610de59033906000903690600401615279565b602060405180830381865afa158015610e02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e269190615257565b610e725760405162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c6044820152606401610c30565b610e7a613362565b600b80547fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a010000000000000000000063ffffffff8981169182027fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff16929092176e010000000000000000000000000000898416908102919091177fffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000008985169081027fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff1691909117760100000000000000000000000000000000000000000000948916948502177fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff167a01000000000000000000000000000000000000000000000000000062ffffff89169081029190911790955560408051938452602084019290925290820152606081019190915260808101919091527f0bf184bf1bba9699114bdceddaf338a1b364252c5e497cc01918dde92031713f9060a00160405180910390a1505050505050565b6060600580548060200260200160405190810160405280929190818152602001828054801561107657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611058575b5050505050905090565b60006110c3336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b61110f5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b600b546601000000000000900463ffffffff16905090565b60006111338383613746565b8061114657506001600160a01b03831632145b90505b92915050565b6060611192336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6111de5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b610d5e613776565b6001546001600160a01b031633146112405760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c30565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6112b7613308565b60155460ff166108e257601580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b600061135a336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6113a65760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b50600b5463ffffffff660100000000000090910481166000908152600c60205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b6113f7613308565b6001600160a01b03811660009081526016602052604090205460ff161561148c576001600160a01b03811660008181526016602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d191015b60405180910390a15b50565b6001600160a01b038181166000908152601360205260409020541633146114f85760405162461bcd60e51b815260206004820152601760248201527f4f6e6c792070617965652063616e2077697468647261770000000000000000006044820152606401610c30565b61148c816137ff565b600080546001600160a01b03163314806115a55750600f546040517f6b14daf80000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690636b14daf8906115649033906000903690600401615279565b602060405180830381865afa158015611581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a59190615257565b6115f15760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c79206f776e6572267265717565737465722063616e2063616c6c0000006044820152606401610c30565b600b54600a546040805191825263ffffffff6101008404600881901c8216602085015260ff811684840152915164ffffffffff9092169366010000000000009004169133917f41e3990591fd372502daa15842da15bc7f41c75309ab3ff4f56f1848c178825c9181900360600190a261166b8160016152b8565b63ffffffff169250505090565b60008060008060006116c1336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b61170d5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b61171686613a4b565b945094509450945094505b91939590929450565b611732613308565b8281146117815760405162461bcd60e51b815260206004820181905260248201527f7472616e736d6974746572732e73697a6520213d207061796565732e73697a656044820152606401610c30565b60005b838110156119195760008585838181106117a0576117a0615192565b90506020020160208101906117b59190614b17565b905060008484848181106117cb576117cb615192565b90506020020160208101906117e09190614b17565b6001600160a01b03808416600090815260136020526040902054919250168015808061181d5750826001600160a01b0316826001600160a01b0316145b6118695760405162461bcd60e51b815260206004820152601160248201527f706179656520616c7265616479207365740000000000000000000000000000006044820152606401610c30565b6001600160a01b03848116600090815260136020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168583169081179091559083161461190257826001600160a01b0316826001600160a01b0316856001600160a01b03167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a45b505050508080611911906152d5565b915050611784565b5050505050565b611928613308565b600f546001600160a01b039081169082168114610ca157600f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691821790925560408051928416835260208301919091527f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae63491015b60405180910390a15050565b6119bf613308565b6001600160a01b03811660009081526016602052604090205460ff1661148c576001600160a01b03811660008181526016602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49101611483565b6001600160a01b03818116600090815260146020526040902054163314611aba5760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792070726f706f736564207061796565732063616e20616363657074006044820152606401610c30565b6001600160a01b0381811660008181526013602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556014909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b60005a604080516101008082018352600b5460ff8116835290810464ffffffffff90811660208085018290526601000000000000840463ffffffff908116968601969096526a01000000000000000000008404861660608601526e01000000000000000000000000000084048616608086015272010000000000000000000000000000000000008404861660a0860152760100000000000000000000000000000000000000000000840490951660c08501527a01000000000000000000000000000000000000000000000000000090920462ffffff1660e08401529394509092918c013591821611611c795760405162461bcd60e51b815260206004820152600c60248201527f7374616c65207265706f727400000000000000000000000000000000000000006044820152606401610c30565b3360009081526002602052604090205460ff16611cd85760405162461bcd60e51b815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610c30565b600a548b3514611d2a5760405162461bcd60e51b815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610c30565b611d388a8a8a8a8a8a613b05565b8151611d4590600161530d565b60ff168714611d965760405162461bcd60e51b815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610c30565b868514611de55760405162461bcd60e51b815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610c30565b60008a8a604051611df7929190615326565b604051908190038120611e0e918e90602001615336565b60408051601f19818403018152828252805160209182012083830190925260008084529083018190529092509060005b8a811015611fb45760006001858a8460208110611e5d57611e5d615192565b611e6a91901a601b61530d565b8f8f86818110611e7c57611e7c615192565b905060200201358e8e87818110611e9557611e95615192565b9050602002013560405160008152602001604052604051611ed2949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611ef4573d6000803e3d6000fd5b505060408051601f198101516001600160a01b03811660009081526003602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955092509050611f8d5760405162461bcd60e51b815260206004820152600f60248201527f7369676e6174757265206572726f7200000000000000000000000000000000006044820152606401610c30565b826020015160080260ff166001901b84019350508080611fac906152d5565b915050611e3e565b5081827e0101010101010101010101010101010101010101010101010101010101010116146120255760405162461bcd60e51b815260206004820152601060248201527f6475706c6963617465207369676e6572000000000000000000000000000000006044820152606401610c30565b50600091506120749050838d836020020135848e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613ba292505050565b90506120828382863361409f565b505050505050505050505050565b60006120d3336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b61211f5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b612128826141ea565b90505b919050565b6000612173336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6121bf5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b6121288261421c565b6000546001600160a01b031633148061226b57506012546040517f6b14daf80000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690636b14daf89061222a9033906000903690600401615279565b602060405180830381865afa158015612247573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226b9190615257565b6122b75760405162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c6044820152606401610c30565b60006122c161426e565b6011546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612328573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234c919061523e565b90508181101561239e5760405162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e63650000000000000000000000006044820152606401610c30565b6011546001600160a01b031663a9059cbb856123c36123bd868661534c565b8761444f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015612426573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244a9190615257565b6124965760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c30565b50505050565b6011546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612502573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612526919061523e565b9050600061253261426e565b905061253e818361535f565b9250505090565b61254d613308565b601f8651111561259f5760405162461bcd60e51b815260206004820152601060248201527f746f6f206d616e79206f7261636c6573000000000000000000000000000000006044820152606401610c30565b84518651146125f05760405162461bcd60e51b815260206004820152601660248201527f6f7261636c65206c656e677468206d69736d61746368000000000000000000006044820152606401610c30565b85516125fd85600361537f565b60ff161061264d5760405162461bcd60e51b815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610c30565b6126598460ff16614466565b604080517f010000000000000000000000000000000000000000000000000000000000000060208201527f0000000000000000000000000000000000000000000000000000000000000000821b60218201527f000000000000000000000000000000000000000000000000000000000000000090911b6039820152605101604051602081830303815290604052805190602001208380519060200120146127425760405162461bcd60e51b815260206004820152601560248201527f696e76616c6964206f6e636861696e436f6e66696700000000000000000000006044820152606401610c30565b6040805160c0810182528781526020810187905260ff8616918101919091526060810184905267ffffffffffffffff8316608082015260a08101829052600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ff1690556127af613362565b60045460005b8181101561288e576000600482815481106127d2576127d2615192565b6000918252602082200154600580546001600160a01b03909216935090849081106127ff576127ff615192565b60009182526020808320909101546001600160a01b03948516835260038252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905594168252600290529190912080547fffffffffffffffffffffffffffffffffffff00000000000000000000000000001690555080612886816152d5565b9150506127b5565b5061289b600460006149bf565b6128a7600560006149bf565b60005b825151811015612bb45760036000846000015183815181106128ce576128ce615192565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16156129425760405162461bcd60e51b815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610c30565b604080518082019091526001815260ff82166020820152835180516003916000918590811061297357612973615192565b6020908102919091018101516001600160a01b0316825281810192909252604001600090812083518154948401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff161761010060ff90951694909402939093179092558401518051600292919084908110612a1857612a18615192565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615612a8c5760405162461bcd60e51b815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610c30565b60405180606001604052806001151581526020018260ff16815260200160006bffffffffffffffffffffffff168152506002600085602001518481518110612ad657612ad6615192565b6020908102919091018101516001600160a01b03168252818101929092526040908101600020835181549385015194909201516bffffffffffffffffffffffff1662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff931515939093167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090941693909317919091179290921617905580612bac816152d5565b9150506128aa565b5081518051612bcb916004916020909101906149dd565b506020808301518051612be29260059201906149dd565b506040820151600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600d80547fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff811664010000000063ffffffff438116820292831785559083048116936001939092600092612c749286929082169116176152b8565b92506101000a81548163ffffffff021916908363ffffffff160217905550612cd34630600d60009054906101000a900463ffffffff1663ffffffff1686600001518760200151886040015189606001518a608001518b60a001516144b6565b600a819055600d5484516020860151604080880151606089015160808a015160a08b015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612d3c988b98919763ffffffff90911696919590949093909290919061539b565b60405180910390a1600b546601000000000000900463ffffffff1660005b845151811015612db45781600682601f8110612d7857612d78615192565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508080612dac906152d5565b915050612d5a565b5050505050505050505050565b6001600160a01b03811660009081526002602090815260408083208151606081018352905460ff80821615158084526101008304909116948301949094526201000090046bffffffffffffffffffffffff169181019190915290612e285750600092915050565b6006816020015160ff16601f8110612e4257612e42615192565b600881049190910154600b54612e78926007166004026101000a90910463ffffffff9081169166010000000000009004166151f0565b9392505050565b600080808080333214612ed45760405162461bcd60e51b815260206004820152601460248201527f4f6e6c792063616c6c61626c6520627920454f410000000000000000000000006044820152606401610c30565b5050600a54600b5463ffffffff6601000000000000820481166000908152600c60205260409020549296610100909204600881901c8216965064ffffffffff169450601783900b93507c010000000000000000000000000000000000000000000000000000000090920490911690565b612f4c613308565b60408051808201909152600e546001600160a01b038082168084527401000000000000000000000000000000000000000090920463ffffffff1660208401528416141580612faa57508163ffffffff16816020015163ffffffff1614155b1561305c576040805180820182526001600160a01b0385811680835263ffffffff8681166020948501819052600e80547fffffffffffffffff00000000000000000000000000000000000000000000000016841774010000000000000000000000000000000000000000830217905586518786015187519316835294820152909392909116917fb04e3a37abe9c0fcdfebdeae019a8e2b12ddf53f5d55ffb0caccc1bedaca1541910160405180910390a35b505050565b6001600160a01b038281166000908152601360205260409020541633146130ca5760405162461bcd60e51b815260206004820152601d60248201527f6f6e6c792063757272656e742070617965652063616e207570646174650000006044820152606401610c30565b6001600160a01b03811633036131225760405162461bcd60e51b815260206004820152601760248201527f63616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c30565b6001600160a01b03808316600090815260146020526040902080548383167fffffffffffffffffffffffff00000000000000000000000000000000000000008216811790925590911690811461305c576040516001600160a01b038084169133918616907f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836790600090a4505050565b6131b9613308565b61148c81614544565b6131ca613308565b61148c81614605565b600080600080600061321c336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6132685760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b6132f7600b546601000000000000900463ffffffff9081166000818152600c602090815260409182902082516060810184529054601781900b8083527801000000000000000000000000000000000000000000000000820487169383018490527c0100000000000000000000000000000000000000000000000000000000909104909516920182905291938490565b945094509450945094509091929394565b6000546001600160a01b031633146108e25760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c30565b601154600b54604080516103e08101918290526001600160a01b0390931692660100000000000090920463ffffffff1691600091600690601f908285855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116133a0579050505050505090506000600580548060200260200160405190810160405280929190818152602001828054801561343b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161341d575b5050505050905060005b81518110156137385760006002600084848151811061346657613466615192565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160029054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1690506000600260008585815181106134d2576134d2615192565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160026101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008483601f811061353f5761353f615192565b6020020151600b5490870363ffffffff90811692507201000000000000000000000000000000000000909104168102633b9aca00028201801561372d5760006013600087878151811061359457613594615192565b6020908102919091018101516001600160a01b0390811683529082019290925260409081016000205490517fa9059cbb00000000000000000000000000000000000000000000000000000000815290821660048201819052602482018590529250908a169063a9059cbb906044016020604051808303816000875af1158015613621573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136459190615257565b6136915760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c30565b878786601f81106136a4576136a4615192565b602002019063ffffffff16908163ffffffff1681525050886001600160a01b0316816001600160a01b03168787815181106136e1576136e1615192565b60200260200101516001600160a01b03167fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c8560405161372391815260200190565b60405180910390a4505b505050600101613445565b50611919600683601f614a5a565b6001600160a01b03821660009081526016602052604081205460ff168061114657505060155460ff161592915050565b60606010805461378590615431565b80601f01602080910402602001604051908101604052809291908181526020018280546137b190615431565b80156110765780601f106137d357610100808354040283529160200191611076565b820191906000526020600020905b8154815290600101906020018083116137e157509395945050505050565b6001600160a01b0381166000908152600260209081526040918290208251606081018452905460ff80821615158084526101008304909116938301939093526201000090046bffffffffffffffffffffffff1692810192909252613861575050565b600061386c836108e4565b9050801561305c576001600160a01b03838116600090815260136020526040908190205460115491517fa9059cbb000000000000000000000000000000000000000000000000000000008152908316600482018190526024820185905292919091169063a9059cbb906044016020604051808303816000875af11580156138f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391b9190615257565b6139675760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c30565b600b60000160069054906101000a900463ffffffff166006846020015160ff16601f811061399757613997615192565b6008810491909101805460079092166004026101000a63ffffffff8181021990931693909216919091029190911790556001600160a01b0384811660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff169055601154915186815291841693851692917fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c910160405180910390a450505050565b60008080808063ffffffff69ffffffffffffffffffff87161115613a7d57506000935083925082915081905080611721565b5050505063ffffffff8281166000908152600c602090815260409182902082516060810184529054601781900b8083527801000000000000000000000000000000000000000000000000820486169383018490527c01000000000000000000000000000000000000000000000000000000009091049094169201829052939491939250908490565b6000613b12826020615214565b613b1d856020615214565b613b298861014461522b565b613b33919061522b565b613b3d919061522b565b613b4890600061522b565b9050368114613b995760405162461bcd60e51b815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610c30565b50505050505050565b600080613bae8361468c565b9050601f8160400151511115613c065760405162461bcd60e51b815260206004820152601e60248201527f6e756d206f62736572766174696f6e73206f7574206f6620626f756e647300006044820152606401610c30565b604081015151865160ff1610613c5e5760405162461bcd60e51b815260206004820152601e60248201527f746f6f206665772076616c75657320746f207472757374206d656469616e00006044820152606401610c30565b64ffffffffff841660208701526040810151805160009190613c829060029061547e565b81518110613c9257613c92615192565b602002602001015190508060170b7f000000000000000000000000000000000000000000000000000000000000000060170b13158015613cf857507f000000000000000000000000000000000000000000000000000000000000000060170b8160170b13155b613d445760405162461bcd60e51b815260206004820152601e60248201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e676500006044820152606401610c30565b60408701805190613d54826154b9565b63ffffffff1663ffffffff168152505060405180606001604052808260170b8152602001836000015163ffffffff1681526020014263ffffffff16815250600c6000896040015163ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548177ffffffffffffffffffffffffffffffffffffffffffffffff021916908360170b77ffffffffffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555090505086600b60008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548164ffffffffff021916908364ffffffffff16021790555060408201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001600a6101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600e6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160000160126101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160000160166101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600001601a6101000a81548162ffffff021916908362ffffff160217905550905050866040015163ffffffff167fc797025feeeaf2cd924c99e9205acb8ec04d5cad21c41ce637a38fb6dee6016a823385600001518660400151876020015188606001518d8d604051613fe89897969594939291906154dc565b60405180910390a26040808801518351915163ffffffff9283168152600092909116907f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac602719060200160405180910390a3866040015163ffffffff168160170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f4260405161407891815260200190565b60405180910390a361409187604001518260170b614731565b506060015195945050505050565b60008360170b126124965760006140d1633b9aca003a04866080015163ffffffff16876060015163ffffffff16614881565b90506010360260005a905060006140fa8663ffffffff1685858b60e0015162ffffff16866148a7565b90506000670de0b6b3a764000077ffffffffffffffffffffffffffffffffffffffffffffffff891683026001600160a01b03881660009081526002602052604090205460c08c01519290910492506201000090046bffffffffffffffffffffffff9081169163ffffffff16633b9aca0002828401019081168211156141855750505050505050612496565b6001600160a01b038816600090815260026020526040902080546bffffffffffffffffffffffff90921662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff90921691909117905550505050505050505050565b600063ffffffff82111561420057506000919050565b5063ffffffff166000908152600c602052604090205460170b90565b600063ffffffff82111561423257506000919050565b5063ffffffff9081166000908152600c60205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b60008060058054806020026020016040519081016040528092919081815260200182805480156142c757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116142a9575b50508351600b54604080516103e08101918290529697509195660100000000000090910463ffffffff169450600093509150600690601f908285855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116143035790505050505050905060005b83811015614396578181601f811061436357614363615192565b602002015161437290846151f0565b6143829063ffffffff168761522b565b95508061438e816152d5565b915050614349565b50600b546143c4907201000000000000000000000000000000000000900463ffffffff16633b9aca00615214565b6143ce9086615214565b945060005b8381101561444757600260008683815181106143f1576143f1615192565b6020908102919091018101516001600160a01b0316825281019190915260400160002054614433906201000090046bffffffffffffffffffffffff168761522b565b95508061443f816152d5565b9150506143d3565b505050505090565b600081831015614460575081611149565b50919050565b8060001061148c5760405162461bcd60e51b815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610c30565b6000808a8a8a8a8a8a8a8a8a6040516020016144da99989796959493929190615584565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150505b9998505050505050505050565b336001600160a01b0382160361459c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c30565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6012546001600160a01b039081169082168114610ca157601280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691821790925560408051928416835260208301919091527f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d4891291016119ab565b6146c06040518060800160405280600063ffffffff1681526020016060815260200160608152602001600060170b81525090565b60008060606000858060200190518101906146db919061561e565b929650909450925090506146ef868361490b565b81516040805160208082019690965281519082018252918252805160808101825263ffffffff969096168652938501529183015260170b606082015292915050565b60408051808201909152600e546001600160a01b0381168083527401000000000000000000000000000000000000000090910463ffffffff16602083015261477857505050565b60006147856001856151f0565b63ffffffff8181166000818152600c6020908152604091829020549087015187519251602481019490945260179190910b6044840181905289851660648501526084840189905294955061483593169160a40160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fbeed9b5100000000000000000000000000000000000000000000000000000000179052614983565b6119195760405162461bcd60e51b815260206004820152601060248201527f696e73756666696369656e7420676173000000000000000000000000000000006044820152606401610c30565b6000838381101561489457600285850304015b61489e818461444f565b95945050505050565b6000818610156148f95760405162461bcd60e51b815260206004820181905260248201527f6c6566744761732063616e6e6f742065786365656420696e697469616c4761736044820152606401610c30565b50633b9aca0094039190910101020290565b60008151602061491b9190615214565b6149269060a061522b565b61493190600061522b565b90508083511461305c5760405162461bcd60e51b815260206004820152601660248201527f7265706f7274206c656e677468206d69736d61746368000000000000000000006044820152606401610c30565b60005a61138881106149b757611388810390508460408204820311156149b7576000808451602086016000888af150600191505b509392505050565b508054600082559060005260206000209081019061148c9190614aed565b828054828255906000526020600020908101928215614a4a579160200282015b82811115614a4a57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039091161782556020909201916001909101906149fd565b50614a56929150614aed565b5090565b600483019183908215614a4a5791602002820160005b83821115614ab457835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614a70565b8015614ae45782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614ab4565b5050614a569291505b5b80821115614a565760008155600101614aee565b6001600160a01b038116811461148c57600080fd5b600060208284031215614b2957600080fd5b8135612e7881614b02565b6000815180845260005b81811015614b5a57602081850181015186830182015201614b3e565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006111466020830184614b34565b60008060408385031215614ba057600080fd5b8235614bab81614b02565b91506020830135614bbb81614b02565b809150509250929050565b63ffffffff8116811461148c57600080fd5b600080600080600060a08688031215614bf057600080fd5b8535614bfb81614bc6565b94506020860135614c0b81614bc6565b93506040860135614c1b81614bc6565b92506060860135614c2b81614bc6565b9150608086013562ffffff81168114614c4357600080fd5b809150509295509295909350565b600081518084526020808501945080840160005b83811015614c8a5781516001600160a01b031687529582019590820190600101614c65565b509495945050505050565b6020815260006111466020830184614c51565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614d0057614d00614ca8565b604052919050565b600082601f830112614d1957600080fd5b813567ffffffffffffffff811115614d3357614d33614ca8565b614d466020601f19601f84011601614cd7565b818152846020838601011115614d5b57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215614d8b57600080fd5b8235614d9681614b02565b9150602083013567ffffffffffffffff811115614db257600080fd5b614dbe85828601614d08565b9150509250929050565b600060208284031215614dda57600080fd5b813569ffffffffffffffffffff81168114612e7857600080fd5b60008083601f840112614e0657600080fd5b50813567ffffffffffffffff811115614e1e57600080fd5b6020830191508360208260051b8501011115614e3957600080fd5b9250929050565b60008060008060408587031215614e5657600080fd5b843567ffffffffffffffff80821115614e6e57600080fd5b614e7a88838901614df4565b90965094506020870135915080821115614e9357600080fd5b50614ea087828801614df4565b95989497509550505050565b60008060008060008060008060e0898b031215614ec857600080fd5b606089018a811115614ed957600080fd5b8998503567ffffffffffffffff80821115614ef357600080fd5b818b0191508b601f830112614f0757600080fd5b813581811115614f1657600080fd5b8c6020828501011115614f2857600080fd5b6020830199508098505060808b0135915080821115614f4657600080fd5b614f528c838d01614df4565b909750955060a08b0135915080821115614f6b57600080fd5b50614f788b828c01614df4565b999c989b50969995989497949560c00135949350505050565b600060208284031215614fa357600080fd5b5035919050565b60008060408385031215614fbd57600080fd5b8235614fc881614b02565b946020939093013593505050565b600067ffffffffffffffff821115614ff057614ff0614ca8565b5060051b60200190565b600082601f83011261500b57600080fd5b8135602061502061501b83614fd6565b614cd7565b82815260059290921b8401810191818101908684111561503f57600080fd5b8286015b8481101561506357803561505681614b02565b8352918301918301615043565b509695505050505050565b803560ff8116811461212b57600080fd5b803567ffffffffffffffff8116811461212b57600080fd5b60008060008060008060c087890312156150b057600080fd5b863567ffffffffffffffff808211156150c857600080fd5b6150d48a838b01614ffa565b975060208901359150808211156150ea57600080fd5b6150f68a838b01614ffa565b965061510460408a0161506e565b9550606089013591508082111561511a57600080fd5b6151268a838b01614d08565b945061513460808a0161507f565b935060a089013591508082111561514a57600080fd5b5061515789828a01614d08565b9150509295509295509295565b6000806040838503121561517757600080fd5b823561518281614b02565b91506020830135614bbb81614bc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff82811682821603908082111561520d5761520d6151c1565b5092915050565b8082028115828204841417611149576111496151c1565b80820180821115611149576111496151c1565b60006020828403121561525057600080fd5b5051919050565b60006020828403121561526957600080fd5b81518015158114612e7857600080fd5b6001600160a01b038416815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b63ffffffff81811683821601908082111561520d5761520d6151c1565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615306576153066151c1565b5060010190565b60ff8181168382160190811115611149576111496151c1565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b81810381811115611149576111496151c1565b818103600083128015838313168383128216171561520d5761520d6151c1565b60ff818116838216029081169081811461520d5761520d6151c1565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153cb8184018a614c51565b905082810360808401526153df8189614c51565b905060ff871660a084015282810360c08401526153fc8187614b34565b905067ffffffffffffffff851660e08401528281036101008401526154218185614b34565b9c9b505050505050505050505050565b600181811c9082168061544557607f821691505b602082108103614460577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000826154b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600063ffffffff8083168181036154d2576154d26151c1565b6001019392505050565b600061010080830160178c810b855260206001600160a01b038d168187015263ffffffff8c1660408701528360608701528293508a5180845261012087019450818c01935060005b81811015615542578451840b86529482019493820193600101615524565b505050505082810360808401526155598188614b34565b91505061556b60a083018660170b9052565b8360c083015261453760e083018464ffffffffff169052565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526155be8285018b614c51565b915083820360808501526155d2828a614c51565b915060ff881660a085015283820360c08501526155ef8288614b34565b90861660e085015283810361010085015290506154218185614b34565b8051601781900b811461212b57600080fd5b6000806000806080858703121561563457600080fd5b845161563f81614bc6565b809450506020808601519350604086015167ffffffffffffffff81111561566557600080fd5b8601601f8101881361567657600080fd5b805161568461501b82614fd6565b81815260059190911b8201830190838101908a8311156156a357600080fd5b928401925b828410156156c8576156b98461560c565b825292840192908401906156a8565b80965050505050506156dc6060860161560c565b90509295919450925056fe416363657373436f6e74726f6c6c65644f43523241676772656761746f7220312e302e30a2646970667358221220fed0cd68c5bfb721dbfe295c92e43bb48a83a2d5f53ba8e3528a83638fb3c6ad64736f6c63430008130033000000000000000000000000685ce6742351ae9b618f383883d6d1e0c5a31b4b000000000000000000000000000000000000000000000000000000000000000100000000000000000000ffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d8382f542373cc25c2ef526699f88177713b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000a4c494e4b202f2055534400000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103155760003560e01c80639a6fc8f5116101a7578063d09dc339116100ee578063e76d516811610097578063f2fde38b11610071578063f2fde38b1461084f578063fbffd2c114610862578063feaf968c1461087557600080fd5b8063e76d516814610818578063eb45716314610829578063eb5dcd6c1461083c57600080fd5b8063e3d0e712116100c8578063e3d0e71214610793578063e4902f82146107a6578063e5fe4577146107ce57600080fd5b8063d09dc3391461076d578063daffc4b514610775578063dc7f01241461078657600080fd5b8063b121e14711610150578063b633620c1161012a578063b633620c14610736578063c107532914610749578063c4c92b371461075c57600080fd5b8063b121e147146106fd578063b1dc65a414610710578063b5ab58dc1461072357600080fd5b80639e3ceeab116101815780639e3ceeab146106a6578063a118f249146106b9578063afcb95d7146106cc57600080fd5b80639a6fc8f5146105f75780639bd2c0b1146106415780639c849b301461069357600080fd5b8063668a0f021161026b57806381ff7048116102145780638ac28d5a116101ee5780638ac28d5a1461059c5780638da5cb5b146105af57806398e5b12a146105d457600080fd5b806381ff7048146105515780638205bf6a146105815780638823da6c1461058957600080fd5b80637284e416116102455780637284e4161461053957806379ba5097146105415780638038e4a11461054957600080fd5b8063668a0f02146104e75780636b14daf8146104ef57806370da2f671461051257600080fd5b8063313ce567116102cd57806354fd4d50116102a757806354fd4d50146104b7578063643dc105146104bf578063666cab8d146104d257600080fd5b8063313ce567146104635780634fb174701461049c57806350d25bcd146104af57600080fd5b8063181f5a77116102fe578063181f5a771461034a57806322adbc781461035f578063299372681461039957600080fd5b80630a7569831461031a5780630eafb25b14610324575b600080fd5b61032261087d565b005b610337610332366004614b17565b6108e4565b6040519081526020015b60405180910390f35b610352610a05565b6040516103419190614b7a565b6103867f000000000000000000000000000000000000000000000000000000000000000181565b60405160179190910b8152602001610341565b610427600b546a0100000000000000000000810463ffffffff908116926e010000000000000000000000000000830482169272010000000000000000000000000000000000008104831692760100000000000000000000000000000000000000000000820416917a01000000000000000000000000000000000000000000000000000090910462ffffff1690565b6040805163ffffffff9687168152948616602086015292851692840192909252909216606082015262ffffff909116608082015260a001610341565b61048a7f000000000000000000000000000000000000000000000000000000000000000881565b60405160ff9091168152602001610341565b6103226104aa366004614b8d565b610a25565b610337610ca5565b610337600681565b6103226104cd366004614bd8565b610d63565b6104da61101e565b6040516103419190614c95565b610337611080565b6105026104fd366004614d78565b611127565b6040519015158152602001610341565b6103867f00000000000000000000ffffffffffffffffffffffffffffffffffffffffffff81565b61035261114f565b6103226111e6565b6103226112af565b600d54600a546040805163ffffffff80851682526401000000009094049093166020840152820152606001610341565b610337611317565b610322610597366004614b17565b6113ef565b6103226105aa366004614b17565b61148f565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610341565b6105dc611501565b60405169ffffffffffffffffffff9091168152602001610341565b61060a610605366004614dc8565b611678565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a001610341565b604080518082018252600e546001600160a01b0381168083527401000000000000000000000000000000000000000090910463ffffffff16602092830181905283519182529181019190915201610341565b6103226106a1366004614e40565b61172a565b6103226106b4366004614b17565b611920565b6103226106c7366004614b17565b6119b7565b600a54600b546040805160008152602081019390935261010090910460081c63ffffffff1690820152606001610341565b61032261070b366004614b17565b611a51565b61032261071e366004614eac565b611b45565b610337610731366004614f91565b612090565b610337610744366004614f91565b612130565b610322610757366004614faa565b6121c8565b6012546001600160a01b03166105bc565b61033761249c565b600f546001600160a01b03166105bc565b6015546105029060ff1681565b6103226107a1366004615097565b612545565b6107b96107b4366004614b17565b612dc1565b60405163ffffffff9091168152602001610341565b6107d6612e7f565b6040805195865263ffffffff909416602086015260ff9092169284019290925260179190910b606083015267ffffffffffffffff16608082015260a001610341565b6011546001600160a01b03166105bc565b610322610837366004615164565b612f44565b61032261084a366004614b8d565b613061565b61032261085d366004614b17565b6131b1565b610322610870366004614b17565b6131c2565b61060a6131d3565b610885613308565b60155460ff16156108e257601580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b6001600160a01b03811660009081526002602090815260408083208151606081018352905460ff80821615158084526101008304909116948301949094526201000090046bffffffffffffffffffffffff16918101919091529061094b5750600092915050565b600b5460208201516000917201000000000000000000000000000000000000900463ffffffff169060069060ff16601f811061098957610989615192565b600881049190910154600b546109bf926007166004026101000a90910463ffffffff9081169166010000000000009004166151f0565b63ffffffff166109cf9190615214565b6109dd90633b9aca00615214565b905081604001516bffffffffffffffffffffffff16816109fd919061522b565b949350505050565b60606040518060600160405280602481526020016156e860249139905090565b610a2d613308565b6011546001600160a01b03908116908316819003610a4a57505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa158015610aa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acb919061523e565b50610ad4613362565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b58919061523e565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482018390529192509083169063a9059cbb906044016020604051808303816000875af1158015610bc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be89190615257565b610c395760405162461bcd60e51b815260206004820152601f60248201527f7472616e736665722072656d61696e696e672066756e6473206661696c65640060448201526064015b60405180910390fd5b601180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925560405190918416907f4966a50c93f855342ccf6c5c0d358b85b91335b2acedc7da0932f691f351711a90600090a350505b5050565b6000610ce8336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b610d345760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b600b546601000000000000900463ffffffff166000908152600c602052604090205460170b905090565b905090565b6012546001600160a01b0316610d816000546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480610e2657506040517f6b14daf80000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636b14daf890610de59033906000903690600401615279565b602060405180830381865afa158015610e02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e269190615257565b610e725760405162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c6044820152606401610c30565b610e7a613362565b600b80547fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a010000000000000000000063ffffffff8981169182027fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff16929092176e010000000000000000000000000000898416908102919091177fffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000008985169081027fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff1691909117760100000000000000000000000000000000000000000000948916948502177fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff167a01000000000000000000000000000000000000000000000000000062ffffff89169081029190911790955560408051938452602084019290925290820152606081019190915260808101919091527f0bf184bf1bba9699114bdceddaf338a1b364252c5e497cc01918dde92031713f9060a00160405180910390a1505050505050565b6060600580548060200260200160405190810160405280929190818152602001828054801561107657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611058575b5050505050905090565b60006110c3336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b61110f5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b600b546601000000000000900463ffffffff16905090565b60006111338383613746565b8061114657506001600160a01b03831632145b90505b92915050565b6060611192336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6111de5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b610d5e613776565b6001546001600160a01b031633146112405760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c30565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6112b7613308565b60155460ff166108e257601580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b600061135a336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6113a65760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b50600b5463ffffffff660100000000000090910481166000908152600c60205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b6113f7613308565b6001600160a01b03811660009081526016602052604090205460ff161561148c576001600160a01b03811660008181526016602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d191015b60405180910390a15b50565b6001600160a01b038181166000908152601360205260409020541633146114f85760405162461bcd60e51b815260206004820152601760248201527f4f6e6c792070617965652063616e2077697468647261770000000000000000006044820152606401610c30565b61148c816137ff565b600080546001600160a01b03163314806115a55750600f546040517f6b14daf80000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690636b14daf8906115649033906000903690600401615279565b602060405180830381865afa158015611581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a59190615257565b6115f15760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c79206f776e6572267265717565737465722063616e2063616c6c0000006044820152606401610c30565b600b54600a546040805191825263ffffffff6101008404600881901c8216602085015260ff811684840152915164ffffffffff9092169366010000000000009004169133917f41e3990591fd372502daa15842da15bc7f41c75309ab3ff4f56f1848c178825c9181900360600190a261166b8160016152b8565b63ffffffff169250505090565b60008060008060006116c1336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b61170d5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b61171686613a4b565b945094509450945094505b91939590929450565b611732613308565b8281146117815760405162461bcd60e51b815260206004820181905260248201527f7472616e736d6974746572732e73697a6520213d207061796565732e73697a656044820152606401610c30565b60005b838110156119195760008585838181106117a0576117a0615192565b90506020020160208101906117b59190614b17565b905060008484848181106117cb576117cb615192565b90506020020160208101906117e09190614b17565b6001600160a01b03808416600090815260136020526040902054919250168015808061181d5750826001600160a01b0316826001600160a01b0316145b6118695760405162461bcd60e51b815260206004820152601160248201527f706179656520616c7265616479207365740000000000000000000000000000006044820152606401610c30565b6001600160a01b03848116600090815260136020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168583169081179091559083161461190257826001600160a01b0316826001600160a01b0316856001600160a01b03167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a45b505050508080611911906152d5565b915050611784565b5050505050565b611928613308565b600f546001600160a01b039081169082168114610ca157600f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691821790925560408051928416835260208301919091527f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae63491015b60405180910390a15050565b6119bf613308565b6001600160a01b03811660009081526016602052604090205460ff1661148c576001600160a01b03811660008181526016602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49101611483565b6001600160a01b03818116600090815260146020526040902054163314611aba5760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792070726f706f736564207061796565732063616e20616363657074006044820152606401610c30565b6001600160a01b0381811660008181526013602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556014909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b60005a604080516101008082018352600b5460ff8116835290810464ffffffffff90811660208085018290526601000000000000840463ffffffff908116968601969096526a01000000000000000000008404861660608601526e01000000000000000000000000000084048616608086015272010000000000000000000000000000000000008404861660a0860152760100000000000000000000000000000000000000000000840490951660c08501527a01000000000000000000000000000000000000000000000000000090920462ffffff1660e08401529394509092918c013591821611611c795760405162461bcd60e51b815260206004820152600c60248201527f7374616c65207265706f727400000000000000000000000000000000000000006044820152606401610c30565b3360009081526002602052604090205460ff16611cd85760405162461bcd60e51b815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610c30565b600a548b3514611d2a5760405162461bcd60e51b815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610c30565b611d388a8a8a8a8a8a613b05565b8151611d4590600161530d565b60ff168714611d965760405162461bcd60e51b815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610c30565b868514611de55760405162461bcd60e51b815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610c30565b60008a8a604051611df7929190615326565b604051908190038120611e0e918e90602001615336565b60408051601f19818403018152828252805160209182012083830190925260008084529083018190529092509060005b8a811015611fb45760006001858a8460208110611e5d57611e5d615192565b611e6a91901a601b61530d565b8f8f86818110611e7c57611e7c615192565b905060200201358e8e87818110611e9557611e95615192565b9050602002013560405160008152602001604052604051611ed2949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611ef4573d6000803e3d6000fd5b505060408051601f198101516001600160a01b03811660009081526003602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955092509050611f8d5760405162461bcd60e51b815260206004820152600f60248201527f7369676e6174757265206572726f7200000000000000000000000000000000006044820152606401610c30565b826020015160080260ff166001901b84019350508080611fac906152d5565b915050611e3e565b5081827e0101010101010101010101010101010101010101010101010101010101010116146120255760405162461bcd60e51b815260206004820152601060248201527f6475706c6963617465207369676e6572000000000000000000000000000000006044820152606401610c30565b50600091506120749050838d836020020135848e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613ba292505050565b90506120828382863361409f565b505050505050505050505050565b60006120d3336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b61211f5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b612128826141ea565b90505b919050565b6000612173336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6121bf5760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b6121288261421c565b6000546001600160a01b031633148061226b57506012546040517f6b14daf80000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690636b14daf89061222a9033906000903690600401615279565b602060405180830381865afa158015612247573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226b9190615257565b6122b75760405162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c6044820152606401610c30565b60006122c161426e565b6011546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612328573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234c919061523e565b90508181101561239e5760405162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e63650000000000000000000000006044820152606401610c30565b6011546001600160a01b031663a9059cbb856123c36123bd868661534c565b8761444f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015612426573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244a9190615257565b6124965760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c30565b50505050565b6011546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612502573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612526919061523e565b9050600061253261426e565b905061253e818361535f565b9250505090565b61254d613308565b601f8651111561259f5760405162461bcd60e51b815260206004820152601060248201527f746f6f206d616e79206f7261636c6573000000000000000000000000000000006044820152606401610c30565b84518651146125f05760405162461bcd60e51b815260206004820152601660248201527f6f7261636c65206c656e677468206d69736d61746368000000000000000000006044820152606401610c30565b85516125fd85600361537f565b60ff161061264d5760405162461bcd60e51b815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610c30565b6126598460ff16614466565b604080517f010000000000000000000000000000000000000000000000000000000000000060208201527f0000000000000000000000000000000000000000000000000000000000000001821b60218201527f00000000000000000000ffffffffffffffffffffffffffffffffffffffffffff90911b6039820152605101604051602081830303815290604052805190602001208380519060200120146127425760405162461bcd60e51b815260206004820152601560248201527f696e76616c6964206f6e636861696e436f6e66696700000000000000000000006044820152606401610c30565b6040805160c0810182528781526020810187905260ff8616918101919091526060810184905267ffffffffffffffff8316608082015260a08101829052600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ff1690556127af613362565b60045460005b8181101561288e576000600482815481106127d2576127d2615192565b6000918252602082200154600580546001600160a01b03909216935090849081106127ff576127ff615192565b60009182526020808320909101546001600160a01b03948516835260038252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905594168252600290529190912080547fffffffffffffffffffffffffffffffffffff00000000000000000000000000001690555080612886816152d5565b9150506127b5565b5061289b600460006149bf565b6128a7600560006149bf565b60005b825151811015612bb45760036000846000015183815181106128ce576128ce615192565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16156129425760405162461bcd60e51b815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610c30565b604080518082019091526001815260ff82166020820152835180516003916000918590811061297357612973615192565b6020908102919091018101516001600160a01b0316825281810192909252604001600090812083518154948401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff161761010060ff90951694909402939093179092558401518051600292919084908110612a1857612a18615192565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615612a8c5760405162461bcd60e51b815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610c30565b60405180606001604052806001151581526020018260ff16815260200160006bffffffffffffffffffffffff168152506002600085602001518481518110612ad657612ad6615192565b6020908102919091018101516001600160a01b03168252818101929092526040908101600020835181549385015194909201516bffffffffffffffffffffffff1662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff931515939093167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090941693909317919091179290921617905580612bac816152d5565b9150506128aa565b5081518051612bcb916004916020909101906149dd565b506020808301518051612be29260059201906149dd565b506040820151600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600d80547fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff811664010000000063ffffffff438116820292831785559083048116936001939092600092612c749286929082169116176152b8565b92506101000a81548163ffffffff021916908363ffffffff160217905550612cd34630600d60009054906101000a900463ffffffff1663ffffffff1686600001518760200151886040015189606001518a608001518b60a001516144b6565b600a819055600d5484516020860151604080880151606089015160808a015160a08b015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612d3c988b98919763ffffffff90911696919590949093909290919061539b565b60405180910390a1600b546601000000000000900463ffffffff1660005b845151811015612db45781600682601f8110612d7857612d78615192565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508080612dac906152d5565b915050612d5a565b5050505050505050505050565b6001600160a01b03811660009081526002602090815260408083208151606081018352905460ff80821615158084526101008304909116948301949094526201000090046bffffffffffffffffffffffff169181019190915290612e285750600092915050565b6006816020015160ff16601f8110612e4257612e42615192565b600881049190910154600b54612e78926007166004026101000a90910463ffffffff9081169166010000000000009004166151f0565b9392505050565b600080808080333214612ed45760405162461bcd60e51b815260206004820152601460248201527f4f6e6c792063616c6c61626c6520627920454f410000000000000000000000006044820152606401610c30565b5050600a54600b5463ffffffff6601000000000000820481166000908152600c60205260409020549296610100909204600881901c8216965064ffffffffff169450601783900b93507c010000000000000000000000000000000000000000000000000000000090920490911690565b612f4c613308565b60408051808201909152600e546001600160a01b038082168084527401000000000000000000000000000000000000000090920463ffffffff1660208401528416141580612faa57508163ffffffff16816020015163ffffffff1614155b1561305c576040805180820182526001600160a01b0385811680835263ffffffff8681166020948501819052600e80547fffffffffffffffff00000000000000000000000000000000000000000000000016841774010000000000000000000000000000000000000000830217905586518786015187519316835294820152909392909116917fb04e3a37abe9c0fcdfebdeae019a8e2b12ddf53f5d55ffb0caccc1bedaca1541910160405180910390a35b505050565b6001600160a01b038281166000908152601360205260409020541633146130ca5760405162461bcd60e51b815260206004820152601d60248201527f6f6e6c792063757272656e742070617965652063616e207570646174650000006044820152606401610c30565b6001600160a01b03811633036131225760405162461bcd60e51b815260206004820152601760248201527f63616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c30565b6001600160a01b03808316600090815260146020526040902080548383167fffffffffffffffffffffffff00000000000000000000000000000000000000008216811790925590911690811461305c576040516001600160a01b038084169133918616907f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836790600090a4505050565b6131b9613308565b61148c81614544565b6131ca613308565b61148c81614605565b600080600080600061321c336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b6132685760405162461bcd60e51b815260206004820152600960248201527f4e6f2061636365737300000000000000000000000000000000000000000000006044820152606401610c30565b6132f7600b546601000000000000900463ffffffff9081166000818152600c602090815260409182902082516060810184529054601781900b8083527801000000000000000000000000000000000000000000000000820487169383018490527c0100000000000000000000000000000000000000000000000000000000909104909516920182905291938490565b945094509450945094509091929394565b6000546001600160a01b031633146108e25760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c30565b601154600b54604080516103e08101918290526001600160a01b0390931692660100000000000090920463ffffffff1691600091600690601f908285855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116133a0579050505050505090506000600580548060200260200160405190810160405280929190818152602001828054801561343b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161341d575b5050505050905060005b81518110156137385760006002600084848151811061346657613466615192565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160029054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1690506000600260008585815181106134d2576134d2615192565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160026101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008483601f811061353f5761353f615192565b6020020151600b5490870363ffffffff90811692507201000000000000000000000000000000000000909104168102633b9aca00028201801561372d5760006013600087878151811061359457613594615192565b6020908102919091018101516001600160a01b0390811683529082019290925260409081016000205490517fa9059cbb00000000000000000000000000000000000000000000000000000000815290821660048201819052602482018590529250908a169063a9059cbb906044016020604051808303816000875af1158015613621573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136459190615257565b6136915760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c30565b878786601f81106136a4576136a4615192565b602002019063ffffffff16908163ffffffff1681525050886001600160a01b0316816001600160a01b03168787815181106136e1576136e1615192565b60200260200101516001600160a01b03167fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c8560405161372391815260200190565b60405180910390a4505b505050600101613445565b50611919600683601f614a5a565b6001600160a01b03821660009081526016602052604081205460ff168061114657505060155460ff161592915050565b60606010805461378590615431565b80601f01602080910402602001604051908101604052809291908181526020018280546137b190615431565b80156110765780601f106137d357610100808354040283529160200191611076565b820191906000526020600020905b8154815290600101906020018083116137e157509395945050505050565b6001600160a01b0381166000908152600260209081526040918290208251606081018452905460ff80821615158084526101008304909116938301939093526201000090046bffffffffffffffffffffffff1692810192909252613861575050565b600061386c836108e4565b9050801561305c576001600160a01b03838116600090815260136020526040908190205460115491517fa9059cbb000000000000000000000000000000000000000000000000000000008152908316600482018190526024820185905292919091169063a9059cbb906044016020604051808303816000875af11580156138f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391b9190615257565b6139675760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c30565b600b60000160069054906101000a900463ffffffff166006846020015160ff16601f811061399757613997615192565b6008810491909101805460079092166004026101000a63ffffffff8181021990931693909216919091029190911790556001600160a01b0384811660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff169055601154915186815291841693851692917fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c910160405180910390a450505050565b60008080808063ffffffff69ffffffffffffffffffff87161115613a7d57506000935083925082915081905080611721565b5050505063ffffffff8281166000908152600c602090815260409182902082516060810184529054601781900b8083527801000000000000000000000000000000000000000000000000820486169383018490527c01000000000000000000000000000000000000000000000000000000009091049094169201829052939491939250908490565b6000613b12826020615214565b613b1d856020615214565b613b298861014461522b565b613b33919061522b565b613b3d919061522b565b613b4890600061522b565b9050368114613b995760405162461bcd60e51b815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610c30565b50505050505050565b600080613bae8361468c565b9050601f8160400151511115613c065760405162461bcd60e51b815260206004820152601e60248201527f6e756d206f62736572766174696f6e73206f7574206f6620626f756e647300006044820152606401610c30565b604081015151865160ff1610613c5e5760405162461bcd60e51b815260206004820152601e60248201527f746f6f206665772076616c75657320746f207472757374206d656469616e00006044820152606401610c30565b64ffffffffff841660208701526040810151805160009190613c829060029061547e565b81518110613c9257613c92615192565b602002602001015190508060170b7f000000000000000000000000000000000000000000000000000000000000000160170b13158015613cf857507f00000000000000000000ffffffffffffffffffffffffffffffffffffffffffff60170b8160170b13155b613d445760405162461bcd60e51b815260206004820152601e60248201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e676500006044820152606401610c30565b60408701805190613d54826154b9565b63ffffffff1663ffffffff168152505060405180606001604052808260170b8152602001836000015163ffffffff1681526020014263ffffffff16815250600c6000896040015163ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548177ffffffffffffffffffffffffffffffffffffffffffffffff021916908360170b77ffffffffffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555090505086600b60008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548164ffffffffff021916908364ffffffffff16021790555060408201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001600a6101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600e6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160000160126101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160000160166101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600001601a6101000a81548162ffffff021916908362ffffff160217905550905050866040015163ffffffff167fc797025feeeaf2cd924c99e9205acb8ec04d5cad21c41ce637a38fb6dee6016a823385600001518660400151876020015188606001518d8d604051613fe89897969594939291906154dc565b60405180910390a26040808801518351915163ffffffff9283168152600092909116907f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac602719060200160405180910390a3866040015163ffffffff168160170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f4260405161407891815260200190565b60405180910390a361409187604001518260170b614731565b506060015195945050505050565b60008360170b126124965760006140d1633b9aca003a04866080015163ffffffff16876060015163ffffffff16614881565b90506010360260005a905060006140fa8663ffffffff1685858b60e0015162ffffff16866148a7565b90506000670de0b6b3a764000077ffffffffffffffffffffffffffffffffffffffffffffffff891683026001600160a01b03881660009081526002602052604090205460c08c01519290910492506201000090046bffffffffffffffffffffffff9081169163ffffffff16633b9aca0002828401019081168211156141855750505050505050612496565b6001600160a01b038816600090815260026020526040902080546bffffffffffffffffffffffff90921662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff90921691909117905550505050505050505050565b600063ffffffff82111561420057506000919050565b5063ffffffff166000908152600c602052604090205460170b90565b600063ffffffff82111561423257506000919050565b5063ffffffff9081166000908152600c60205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b60008060058054806020026020016040519081016040528092919081815260200182805480156142c757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116142a9575b50508351600b54604080516103e08101918290529697509195660100000000000090910463ffffffff169450600093509150600690601f908285855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116143035790505050505050905060005b83811015614396578181601f811061436357614363615192565b602002015161437290846151f0565b6143829063ffffffff168761522b565b95508061438e816152d5565b915050614349565b50600b546143c4907201000000000000000000000000000000000000900463ffffffff16633b9aca00615214565b6143ce9086615214565b945060005b8381101561444757600260008683815181106143f1576143f1615192565b6020908102919091018101516001600160a01b0316825281019190915260400160002054614433906201000090046bffffffffffffffffffffffff168761522b565b95508061443f816152d5565b9150506143d3565b505050505090565b600081831015614460575081611149565b50919050565b8060001061148c5760405162461bcd60e51b815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610c30565b6000808a8a8a8a8a8a8a8a8a6040516020016144da99989796959493929190615584565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150505b9998505050505050505050565b336001600160a01b0382160361459c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c30565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6012546001600160a01b039081169082168114610ca157601280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691821790925560408051928416835260208301919091527f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d4891291016119ab565b6146c06040518060800160405280600063ffffffff1681526020016060815260200160608152602001600060170b81525090565b60008060606000858060200190518101906146db919061561e565b929650909450925090506146ef868361490b565b81516040805160208082019690965281519082018252918252805160808101825263ffffffff969096168652938501529183015260170b606082015292915050565b60408051808201909152600e546001600160a01b0381168083527401000000000000000000000000000000000000000090910463ffffffff16602083015261477857505050565b60006147856001856151f0565b63ffffffff8181166000818152600c6020908152604091829020549087015187519251602481019490945260179190910b6044840181905289851660648501526084840189905294955061483593169160a40160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fbeed9b5100000000000000000000000000000000000000000000000000000000179052614983565b6119195760405162461bcd60e51b815260206004820152601060248201527f696e73756666696369656e7420676173000000000000000000000000000000006044820152606401610c30565b6000838381101561489457600285850304015b61489e818461444f565b95945050505050565b6000818610156148f95760405162461bcd60e51b815260206004820181905260248201527f6c6566744761732063616e6e6f742065786365656420696e697469616c4761736044820152606401610c30565b50633b9aca0094039190910101020290565b60008151602061491b9190615214565b6149269060a061522b565b61493190600061522b565b90508083511461305c5760405162461bcd60e51b815260206004820152601660248201527f7265706f7274206c656e677468206d69736d61746368000000000000000000006044820152606401610c30565b60005a61138881106149b757611388810390508460408204820311156149b7576000808451602086016000888af150600191505b509392505050565b508054600082559060005260206000209081019061148c9190614aed565b828054828255906000526020600020908101928215614a4a579160200282015b82811115614a4a57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039091161782556020909201916001909101906149fd565b50614a56929150614aed565b5090565b600483019183908215614a4a5791602002820160005b83821115614ab457835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614a70565b8015614ae45782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614ab4565b5050614a569291505b5b80821115614a565760008155600101614aee565b6001600160a01b038116811461148c57600080fd5b600060208284031215614b2957600080fd5b8135612e7881614b02565b6000815180845260005b81811015614b5a57602081850181015186830182015201614b3e565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006111466020830184614b34565b60008060408385031215614ba057600080fd5b8235614bab81614b02565b91506020830135614bbb81614b02565b809150509250929050565b63ffffffff8116811461148c57600080fd5b600080600080600060a08688031215614bf057600080fd5b8535614bfb81614bc6565b94506020860135614c0b81614bc6565b93506040860135614c1b81614bc6565b92506060860135614c2b81614bc6565b9150608086013562ffffff81168114614c4357600080fd5b809150509295509295909350565b600081518084526020808501945080840160005b83811015614c8a5781516001600160a01b031687529582019590820190600101614c65565b509495945050505050565b6020815260006111466020830184614c51565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614d0057614d00614ca8565b604052919050565b600082601f830112614d1957600080fd5b813567ffffffffffffffff811115614d3357614d33614ca8565b614d466020601f19601f84011601614cd7565b818152846020838601011115614d5b57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215614d8b57600080fd5b8235614d9681614b02565b9150602083013567ffffffffffffffff811115614db257600080fd5b614dbe85828601614d08565b9150509250929050565b600060208284031215614dda57600080fd5b813569ffffffffffffffffffff81168114612e7857600080fd5b60008083601f840112614e0657600080fd5b50813567ffffffffffffffff811115614e1e57600080fd5b6020830191508360208260051b8501011115614e3957600080fd5b9250929050565b60008060008060408587031215614e5657600080fd5b843567ffffffffffffffff80821115614e6e57600080fd5b614e7a88838901614df4565b90965094506020870135915080821115614e9357600080fd5b50614ea087828801614df4565b95989497509550505050565b60008060008060008060008060e0898b031215614ec857600080fd5b606089018a811115614ed957600080fd5b8998503567ffffffffffffffff80821115614ef357600080fd5b818b0191508b601f830112614f0757600080fd5b813581811115614f1657600080fd5b8c6020828501011115614f2857600080fd5b6020830199508098505060808b0135915080821115614f4657600080fd5b614f528c838d01614df4565b909750955060a08b0135915080821115614f6b57600080fd5b50614f788b828c01614df4565b999c989b50969995989497949560c00135949350505050565b600060208284031215614fa357600080fd5b5035919050565b60008060408385031215614fbd57600080fd5b8235614fc881614b02565b946020939093013593505050565b600067ffffffffffffffff821115614ff057614ff0614ca8565b5060051b60200190565b600082601f83011261500b57600080fd5b8135602061502061501b83614fd6565b614cd7565b82815260059290921b8401810191818101908684111561503f57600080fd5b8286015b8481101561506357803561505681614b02565b8352918301918301615043565b509695505050505050565b803560ff8116811461212b57600080fd5b803567ffffffffffffffff8116811461212b57600080fd5b60008060008060008060c087890312156150b057600080fd5b863567ffffffffffffffff808211156150c857600080fd5b6150d48a838b01614ffa565b975060208901359150808211156150ea57600080fd5b6150f68a838b01614ffa565b965061510460408a0161506e565b9550606089013591508082111561511a57600080fd5b6151268a838b01614d08565b945061513460808a0161507f565b935060a089013591508082111561514a57600080fd5b5061515789828a01614d08565b9150509295509295509295565b6000806040838503121561517757600080fd5b823561518281614b02565b91506020830135614bbb81614bc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff82811682821603908082111561520d5761520d6151c1565b5092915050565b8082028115828204841417611149576111496151c1565b80820180821115611149576111496151c1565b60006020828403121561525057600080fd5b5051919050565b60006020828403121561526957600080fd5b81518015158114612e7857600080fd5b6001600160a01b038416815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b63ffffffff81811683821601908082111561520d5761520d6151c1565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615306576153066151c1565b5060010190565b60ff8181168382160190811115611149576111496151c1565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b81810381811115611149576111496151c1565b818103600083128015838313168383128216171561520d5761520d6151c1565b60ff818116838216029081169081811461520d5761520d6151c1565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153cb8184018a614c51565b905082810360808401526153df8189614c51565b905060ff871660a084015282810360c08401526153fc8187614b34565b905067ffffffffffffffff851660e08401528281036101008401526154218185614b34565b9c9b505050505050505050505050565b600181811c9082168061544557607f821691505b602082108103614460577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000826154b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600063ffffffff8083168181036154d2576154d26151c1565b6001019392505050565b600061010080830160178c810b855260206001600160a01b038d168187015263ffffffff8c1660408701528360608701528293508a5180845261012087019450818c01935060005b81811015615542578451840b86529482019493820193600101615524565b505050505082810360808401526155598188614b34565b91505061556b60a083018660170b9052565b8360c083015261453760e083018464ffffffffff169052565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526155be8285018b614c51565b915083820360808501526155d2828a614c51565b915060ff881660a085015283820360c08501526155ef8288614b34565b90861660e085015283810361010085015290506154218185614b34565b8051601781900b811461212b57600080fd5b6000806000806080858703121561563457600080fd5b845161563f81614bc6565b809450506020808601519350604086015167ffffffffffffffff81111561566557600080fd5b8601601f8101881361567657600080fd5b805161568461501b82614fd6565b81815260059190911b8201830190838101908a8311156156a357600080fd5b928401925b828410156156c8576156b98461560c565b825292840192908401906156a8565b80965050505050506156dc6060860161560c565b90509295919450925056fe416363657373436f6e74726f6c6c65644f43523241676772656761746f7220312e302e30a2646970667358221220fed0cd68c5bfb721dbfe295c92e43bb48a83a2d5f53ba8e3528a83638fb3c6ad64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000685ce6742351ae9b618f383883d6d1e0c5a31b4b000000000000000000000000000000000000000000000000000000000000000100000000000000000000ffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d8382f542373cc25c2ef526699f88177713b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000a4c494e4b202f2055534400000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _link (address): 0x685cE6742351ae9b618F383883D6d1e0c5A31B4B
Arg [1] : _minAnswer (int192): 1
Arg [2] : _maxAnswer (int192): 95780971304118053647396689196894323976171195136475135
Arg [3] : _billingAccessController (address): 0x0000000000000000000000000000000000000000
Arg [4] : _requesterAccessController (address): 0x0084d8382F542373cc25C2EF526699F88177713b
Arg [5] : _decimals (uint8): 8
Arg [6] : description (string): LINK / USD
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000685ce6742351ae9b618f383883d6d1e0c5a31b4b
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [2] : 00000000000000000000ffffffffffffffffffffffffffffffffffffffffffff
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000084d8382f542373cc25c2ef526699f88177713b
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [6] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [7] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [8] : 4c494e4b202f2055534400000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.