Source Code
Latest 25 from a total of 129 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Submit | 17584092 | 980 days ago | IN | 0 ETH | 0.00262262 | ||||
| Accept Admin | 16960464 | 1068 days ago | IN | 0 ETH | 0.00055598 | ||||
| Transfer Admin | 16960459 | 1068 days ago | IN | 0 ETH | 0.00098374 | ||||
| Accept Admin | 16960457 | 1068 days ago | IN | 0 ETH | 0.00053957 | ||||
| Transfer Admin | 16960454 | 1068 days ago | IN | 0 ETH | 0.00090918 | ||||
| Change Oracles | 16960451 | 1068 days ago | IN | 0 ETH | 0.00225446 | ||||
| Accept Ownership | 16959243 | 1068 days ago | IN | 0 ETH | 0.00055761 | ||||
| Transfer Ownersh... | 16958954 | 1068 days ago | IN | 0 ETH | 0.00052672 | ||||
| Withdraw Payment | 16718777 | 1102 days ago | IN | 0 ETH | 0.00100159 | ||||
| Change Oracles | 16712671 | 1103 days ago | IN | 0 ETH | 0.00206987 | ||||
| Submit | 16673773 | 1108 days ago | IN | 0 ETH | 0.00438439 | ||||
| Submit | 16666646 | 1109 days ago | IN | 0 ETH | 0.00292279 | ||||
| Submit | 16659526 | 1110 days ago | IN | 0 ETH | 0.00292104 | ||||
| Submit | 16652417 | 1111 days ago | IN | 0 ETH | 0.00398759 | ||||
| Submit | 16645323 | 1112 days ago | IN | 0 ETH | 0.00410887 | ||||
| Submit | 16638168 | 1113 days ago | IN | 0 ETH | 0.0057556 | ||||
| Submit | 16631018 | 1114 days ago | IN | 0 ETH | 0.00480263 | ||||
| Submit | 16623868 | 1115 days ago | IN | 0 ETH | 0.00292479 | ||||
| Submit | 16616705 | 1116 days ago | IN | 0 ETH | 0.00226576 | ||||
| Submit | 16609549 | 1117 days ago | IN | 0 ETH | 0.00247696 | ||||
| Submit | 16602393 | 1118 days ago | IN | 0 ETH | 0.00270911 | ||||
| Submit | 16595226 | 1119 days ago | IN | 0 ETH | 0.00495635 | ||||
| Submit | 16588071 | 1120 days ago | IN | 0 ETH | 0.00366109 | ||||
| Submit | 16584524 | 1121 days ago | IN | 0 ETH | 0.00693606 | ||||
| Submit | 16573782 | 1122 days ago | IN | 0 ETH | 0.00324855 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
FluxAggregator
Compiler Version
v0.6.6+commit.6c089d02
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.6.6;
import "./Median.sol";
import "./Owned.sol";
import "./SafeMath128.sol";
import "./SafeMath32.sol";
import "./SafeMath64.sol";
import "./interfaces/AggregatorV2V3Interface.sol";
import "./interfaces/AggregatorValidatorInterface.sol";
import "./interfaces/LinkTokenInterface.sol";
import "./vendor/SafeMathChainlink.sol";
/**
* @title The Prepaid Aggregator contract
* @notice Handles aggregating data pushed in from off-chain, and unlocks
* payment for oracles as they report. Oracles' submissions are gathered in
* rounds, with each round aggregating the submissions for each oracle into a
* single answer. The latest aggregated answer is exposed as well as historical
* answers and their updated at timestamp.
*/
contract FluxAggregator is AggregatorV2V3Interface, Owned {
using SafeMathChainlink for uint256;
using SafeMath128 for uint128;
using SafeMath64 for uint64;
using SafeMath32 for uint32;
struct Round {
int256 answer;
uint64 startedAt;
uint64 updatedAt;
uint32 answeredInRound;
}
struct RoundDetails {
int256[] submissions;
uint32 maxSubmissions;
uint32 minSubmissions;
uint32 timeout;
uint128 paymentAmount;
}
struct OracleStatus {
uint128 withdrawable;
uint32 startingRound;
uint32 endingRound;
uint32 lastReportedRound;
uint32 lastStartedRound;
int256 latestSubmission;
uint16 index;
address admin;
address pendingAdmin;
}
struct Requester {
bool authorized;
uint32 delay;
uint32 lastStartedRound;
}
struct Funds {
uint128 available;
uint128 allocated;
}
LinkTokenInterface public linkToken;
AggregatorValidatorInterface public validator;
// Round related params
uint128 public paymentAmount;
uint32 public maxSubmissionCount;
uint32 public minSubmissionCount;
uint32 public restartDelay;
uint32 public timeout;
uint8 public override decimals;
string public override description;
int256 immutable public minSubmissionValue;
int256 immutable public maxSubmissionValue;
uint256 constant public override version = 3;
/**
* @notice To ensure owner isn't withdrawing required funds as oracles are
* submitting updates, we enforce that the contract maintains a minimum
* reserve of RESERVE_ROUNDS * oracleCount() LINK earmarked for payment to
* oracles. (Of course, this doesn't prevent the contract from running out of
* funds without the owner's intervention.)
*/
uint256 constant private RESERVE_ROUNDS = 2;
uint256 constant private MAX_ORACLE_COUNT = 77;
uint32 constant private ROUND_MAX = 2**32-1;
uint256 private constant VALIDATOR_GAS_LIMIT = 100000;
// An error specific to the Aggregator V3 Interface, to prevent possible
// confusion around accidentally reading unset values as reported values.
string constant private V3_NO_DATA_ERROR = "No data present";
uint32 private reportingRoundId;
uint32 internal latestRoundId;
mapping(address => OracleStatus) private oracles;
mapping(uint32 => Round) internal rounds;
mapping(uint32 => RoundDetails) internal details;
mapping(address => Requester) internal requesters;
address[] private oracleAddresses;
Funds private recordedFunds;
event AvailableFundsUpdated(
uint256 indexed amount
);
event RoundDetailsUpdated(
uint128 indexed paymentAmount,
uint32 indexed minSubmissionCount,
uint32 indexed maxSubmissionCount,
uint32 restartDelay,
uint32 timeout // measured in seconds
);
event OraclePermissionsUpdated(
address indexed oracle,
bool indexed whitelisted
);
event OracleAdminUpdated(
address indexed oracle,
address indexed newAdmin
);
event OracleAdminUpdateRequested(
address indexed oracle,
address admin,
address newAdmin
);
event SubmissionReceived(
int256 indexed submission,
uint32 indexed round,
address indexed oracle
);
event RequesterPermissionsSet(
address indexed requester,
bool authorized,
uint32 delay
);
event ValidatorUpdated(
address indexed previous,
address indexed current
);
/**
* @notice set up the aggregator with initial configuration
* @param _link The address of the LINK token
* @param _paymentAmount The amount paid of LINK paid to each oracle per submission, in wei (units of 10⁻¹⁸ LINK)
* @param _timeout is the number of seconds after the previous round that are
* allowed to lapse before allowing an oracle to skip an unfinished round
* @param _validator is an optional contract address for validating
* external validation of answers
* @param _minSubmissionValue is an immutable check for a lower bound of what
* submission values are accepted from an oracle
* @param _maxSubmissionValue is an immutable check for an upper bound of what
* submission values are accepted from an oracle
* @param _decimals represents the number of decimals to offset the answer by
* @param _description a short description of what is being reported
*/
constructor(
address _link,
uint128 _paymentAmount,
uint32 _timeout,
address _validator,
int256 _minSubmissionValue,
int256 _maxSubmissionValue,
uint8 _decimals,
string memory _description
) public {
linkToken = LinkTokenInterface(_link);
updateFutureRounds(_paymentAmount, 0, 0, 0, _timeout);
setValidator(_validator);
minSubmissionValue = _minSubmissionValue;
maxSubmissionValue = _maxSubmissionValue;
decimals = _decimals;
description = _description;
rounds[0].updatedAt = uint64(block.timestamp.sub(uint256(_timeout)));
}
/**
* @notice called by oracles when they have witnessed a need to update
* @param _roundId is the ID of the round this submission pertains to
* @param _submission is the updated data that the oracle is submitting
*/
function submit(uint256 _roundId, int256 _submission)
external
{
bytes memory error = validateOracleRound(msg.sender, uint32(_roundId));
require(_submission >= minSubmissionValue, "value below minSubmissionValue");
require(_submission <= maxSubmissionValue, "value above maxSubmissionValue");
require(error.length == 0, string(error));
oracleInitializeNewRound(uint32(_roundId));
recordSubmission(_submission, uint32(_roundId));
(bool updated, int256 newAnswer) = updateRoundAnswer(uint32(_roundId));
payOracle(uint32(_roundId));
deleteRoundDetails(uint32(_roundId));
if (updated) {
validateAnswer(uint32(_roundId), newAnswer);
}
}
/**
* @notice called by the owner to remove and add new oracles as well as
* update the round related parameters that pertain to total oracle count
* @param _removed is the list of addresses for the new Oracles being removed
* @param _added is the list of addresses for the new Oracles being added
* @param _addedAdmins is the admin addresses for the new respective _added
* list. Only this address is allowed to access the respective oracle's funds
* @param _minSubmissions is the new minimum submission count for each round
* @param _maxSubmissions is the new maximum submission count for each round
* @param _restartDelay is the number of rounds an Oracle has to wait before
* they can initiate a round
*/
function changeOracles(
address[] calldata _removed,
address[] calldata _added,
address[] calldata _addedAdmins,
uint32 _minSubmissions,
uint32 _maxSubmissions,
uint32 _restartDelay
)
external
onlyOwner()
{
for (uint256 i = 0; i < _removed.length; i++) {
removeOracle(_removed[i]);
}
require(_added.length == _addedAdmins.length, "need same oracle and admin count");
require(uint256(oracleCount()).add(_added.length) <= MAX_ORACLE_COUNT, "max oracles allowed");
for (uint256 i = 0; i < _added.length; i++) {
addOracle(_added[i], _addedAdmins[i]);
}
updateFutureRounds(paymentAmount, _minSubmissions, _maxSubmissions, _restartDelay, timeout);
}
/**
* @notice update the round and payment related parameters for subsequent
* rounds
* @param _paymentAmount is the payment amount for subsequent rounds
* @param _minSubmissions is the new minimum submission count for each round
* @param _maxSubmissions is the new maximum submission count for each round
* @param _restartDelay is the number of rounds an Oracle has to wait before
* they can initiate a round
*/
function updateFutureRounds(
uint128 _paymentAmount,
uint32 _minSubmissions,
uint32 _maxSubmissions,
uint32 _restartDelay,
uint32 _timeout
)
public
onlyOwner()
{
uint32 oracleNum = oracleCount(); // Save on storage reads
require(_maxSubmissions >= _minSubmissions, "max must equal/exceed min");
require(oracleNum >= _maxSubmissions, "max cannot exceed total");
require(oracleNum == 0 || oracleNum > _restartDelay, "delay cannot exceed total");
require(recordedFunds.available >= requiredReserve(_paymentAmount), "insufficient funds for payment");
if (oracleCount() > 0) {
require(_minSubmissions > 0, "min must be greater than 0");
}
paymentAmount = _paymentAmount;
minSubmissionCount = _minSubmissions;
maxSubmissionCount = _maxSubmissions;
restartDelay = _restartDelay;
timeout = _timeout;
emit RoundDetailsUpdated(
paymentAmount,
_minSubmissions,
_maxSubmissions,
_restartDelay,
_timeout
);
}
/**
* @notice the amount of payment yet to be withdrawn by oracles
*/
function allocatedFunds()
external
view
returns (uint128)
{
return recordedFunds.allocated;
}
/**
* @notice the amount of future funding available to oracles
*/
function availableFunds()
external
view
returns (uint128)
{
return recordedFunds.available;
}
/**
* @notice recalculate the amount of LINK available for payouts
*/
function updateAvailableFunds()
public
{
Funds memory funds = recordedFunds;
uint256 nowAvailable = linkToken.balanceOf(address(this)).sub(funds.allocated);
if (funds.available != nowAvailable) {
recordedFunds.available = uint128(nowAvailable);
emit AvailableFundsUpdated(nowAvailable);
}
}
/**
* @notice returns the number of oracles
*/
function oracleCount() public view returns (uint8) {
return uint8(oracleAddresses.length);
}
/**
* @notice returns an array of addresses containing the oracles on contract
*/
function getOracles() external view returns (address[] memory) {
return oracleAddresses;
}
/**
* @notice get the most recently reported answer
*
* @dev #[deprecated] Use latestRoundData instead. This does not error if no
* answer has been reached, it will simply return 0. Either wait to point to
* an already answered Aggregator or use the recommended latestRoundData
* instead which includes better verification information.
*/
function latestAnswer()
public
view
virtual
override
returns (int256)
{
return rounds[latestRoundId].answer;
}
/**
* @notice get the most recent updated at timestamp
*
* @dev #[deprecated] Use latestRoundData instead. This does not error if no
* answer has been reached, it will simply return 0. Either wait to point to
* an already answered Aggregator or use the recommended latestRoundData
* instead which includes better verification information.
*/
function latestTimestamp()
public
view
virtual
override
returns (uint256)
{
return rounds[latestRoundId].updatedAt;
}
/**
* @notice get the ID of the last updated round
*
* @dev #[deprecated] Use latestRoundData instead. This does not error if no
* answer has been reached, it will simply return 0. Either wait to point to
* an already answered Aggregator or use the recommended latestRoundData
* instead which includes better verification information.
*/
function latestRound()
public
view
virtual
override
returns (uint256)
{
return latestRoundId;
}
/**
* @notice get past rounds answers
* @param _roundId the round number to retrieve the answer for
*
* @dev #[deprecated] Use getRoundData instead. This does not error if no
* answer has been reached, it will simply return 0. Either wait to point to
* an already answered Aggregator or use the recommended getRoundData
* instead which includes better verification information.
*/
function getAnswer(uint256 _roundId)
public
view
virtual
override
returns (int256)
{
if (validRoundId(_roundId)) {
return rounds[uint32(_roundId)].answer;
}
return 0;
}
/**
* @notice get timestamp when an answer was last updated
* @param _roundId the round number to retrieve the updated timestamp for
*
* @dev #[deprecated] Use getRoundData instead. This does not error if no
* answer has been reached, it will simply return 0. Either wait to point to
* an already answered Aggregator or use the recommended getRoundData
* instead which includes better verification information.
*/
function getTimestamp(uint256 _roundId)
public
view
virtual
override
returns (uint256)
{
if (validRoundId(_roundId)) {
return rounds[uint32(_roundId)].updatedAt;
}
return 0;
}
/**
* @notice get data about a round. Consumers are encouraged to check
* that they're receiving fresh data by inspecting the updatedAt and
* answeredInRound return values.
* @param _roundId the round ID to retrieve the round data for
* @return roundId is the round ID for which data was retrieved
* @return answer is the answer for the given round
* @return startedAt is the timestamp when the round was started. This is 0
* if the round hasn't been started yet.
* @return updatedAt is the timestamp when the round last was updated (i.e.
* answer was last computed)
* @return answeredInRound is the round ID of the round in which the answer
* was computed. answeredInRound may be smaller than roundId when the round
* timed out. answeredInRound is equal to roundId when the round didn't time out
* and was completed regularly.
* @dev Note that for in-progress rounds (i.e. rounds that haven't yet received
* maxSubmissions) answer and updatedAt may change between queries.
*/
function getRoundData(uint80 _roundId)
public
view
virtual
override
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{
Round memory r = rounds[uint32(_roundId)];
require(r.answeredInRound > 0 && validRoundId(_roundId), V3_NO_DATA_ERROR);
return (
_roundId,
r.answer,
r.startedAt,
r.updatedAt,
r.answeredInRound
);
}
/**
* @notice get data about the latest round. Consumers are encouraged to check
* that they're receiving fresh data by inspecting the updatedAt and
* answeredInRound return values. Consumers are encouraged to
* use this more fully featured method over the "legacy" latestRound/
* latestAnswer/latestTimestamp functions. Consumers are encouraged to check
* that they're receiving fresh data by inspecting the updatedAt and
* answeredInRound return values.
* @return roundId is the round ID for which data was retrieved
* @return answer is the answer for the given round
* @return startedAt is the timestamp when the round was started. This is 0
* if the round hasn't been started yet.
* @return updatedAt is the timestamp when the round last was updated (i.e.
* answer was last computed)
* @return answeredInRound is the round ID of the round in which the answer
* was computed. answeredInRound may be smaller than roundId when the round
* timed out. answeredInRound is equal to roundId when the round didn't time
* out and was completed regularly.
* @dev Note that for in-progress rounds (i.e. rounds that haven't yet
* received maxSubmissions) answer and updatedAt may change between queries.
*/
function latestRoundData()
public
view
virtual
override
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{
return getRoundData(latestRoundId);
}
/**
* @notice query the available amount of LINK for an oracle to withdraw
*/
function withdrawablePayment(address _oracle)
external
view
returns (uint256)
{
return oracles[_oracle].withdrawable;
}
/**
* @notice transfers the oracle's LINK to another address. Can only be called
* by the oracle's admin.
* @param _oracle is the oracle whose LINK is transferred
* @param _recipient is the address to send the LINK to
* @param _amount is the amount of LINK to send
*/
function withdrawPayment(address _oracle, address _recipient, uint256 _amount)
external
{
require(oracles[_oracle].admin == msg.sender, "only callable by admin");
// Safe to downcast _amount because the total amount of LINK is less than 2^128.
uint128 amount = uint128(_amount);
uint128 available = oracles[_oracle].withdrawable;
require(available >= amount, "insufficient withdrawable funds");
oracles[_oracle].withdrawable = available.sub(amount);
recordedFunds.allocated = recordedFunds.allocated.sub(amount);
assert(linkToken.transfer(_recipient, uint256(amount)));
}
/**
* @notice transfers the owner's LINK to another address
* @param _recipient is the address to send the LINK to
* @param _amount is the amount of LINK to send
*/
function withdrawFunds(address _recipient, uint256 _amount)
external
onlyOwner()
{
uint256 available = uint256(recordedFunds.available);
require(available.sub(requiredReserve(paymentAmount)) >= _amount, "insufficient reserve funds");
require(linkToken.transfer(_recipient, _amount), "token transfer failed");
updateAvailableFunds();
}
/**
* @notice get the admin address of an oracle
* @param _oracle is the address of the oracle whose admin is being queried
*/
function getAdmin(address _oracle)
external
view
returns (address)
{
return oracles[_oracle].admin;
}
/**
* @notice transfer the admin address for an oracle
* @param _oracle is the address of the oracle whose admin is being transferred
* @param _newAdmin is the new admin address
*/
function transferAdmin(address _oracle, address _newAdmin)
external
{
require(oracles[_oracle].admin == msg.sender, "only callable by admin");
oracles[_oracle].pendingAdmin = _newAdmin;
emit OracleAdminUpdateRequested(_oracle, msg.sender, _newAdmin);
}
/**
* @notice accept the admin address transfer for an oracle
* @param _oracle is the address of the oracle whose admin is being transferred
*/
function acceptAdmin(address _oracle)
external
{
require(oracles[_oracle].pendingAdmin == msg.sender, "only callable by pending admin");
oracles[_oracle].pendingAdmin = address(0);
oracles[_oracle].admin = msg.sender;
emit OracleAdminUpdated(_oracle, msg.sender);
}
/**
* @notice allows non-oracles to request a new round
*/
function requestNewRound()
external
returns (uint80)
{
require(requesters[msg.sender].authorized, "not authorized requester");
uint32 current = reportingRoundId;
require(rounds[current].updatedAt > 0 || timedOut(current), "prev round must be supersedable");
uint32 newRoundId = current.add(1);
requesterInitializeNewRound(newRoundId);
return newRoundId;
}
/**
* @notice allows the owner to specify new non-oracles to start new rounds
* @param _requester is the address to set permissions for
* @param _authorized is a boolean specifying whether they can start new rounds or not
* @param _delay is the number of rounds the requester must wait before starting another round
*/
function setRequesterPermissions(address _requester, bool _authorized, uint32 _delay)
external
onlyOwner()
{
if (requesters[_requester].authorized == _authorized) return;
if (_authorized) {
requesters[_requester].authorized = _authorized;
requesters[_requester].delay = _delay;
} else {
delete requesters[_requester];
}
emit RequesterPermissionsSet(_requester, _authorized, _delay);
}
/**
* @notice called through LINK's transferAndCall to update available funds
* in the same transaction as the funds were transferred to the aggregator
* @param _data is mostly ignored. It is checked for length, to be sure
* nothing strange is passed in.
*/
function onTokenTransfer(address, uint256, bytes calldata _data)
external
{
require(_data.length == 0, "transfer doesn't accept calldata");
updateAvailableFunds();
}
/**
* @notice a method to provide all current info oracles need. Intended only
* only to be callable by oracles. Not for use by contracts to read state.
* @param _oracle the address to look up information for.
*/
function oracleRoundState(address _oracle, uint32 _queriedRoundId)
external
view
returns (
bool _eligibleToSubmit,
uint32 _roundId,
int256 _latestSubmission,
uint64 _startedAt,
uint64 _timeout,
uint128 _availableFunds,
uint8 _oracleCount,
uint128 _paymentAmount
)
{
require(msg.sender == tx.origin, "off-chain reading only");
if (_queriedRoundId > 0) {
Round storage round = rounds[_queriedRoundId];
RoundDetails storage details = details[_queriedRoundId];
return (
eligibleForSpecificRound(_oracle, _queriedRoundId),
_queriedRoundId,
oracles[_oracle].latestSubmission,
round.startedAt,
details.timeout,
recordedFunds.available,
oracleCount(),
(round.startedAt > 0 ? details.paymentAmount : paymentAmount)
);
} else {
return oracleRoundStateSuggestRound(_oracle);
}
}
/**
* @notice method to update the address which does external data validation.
* @param _newValidator designates the address of the new validation contract.
*/
function setValidator(address _newValidator)
public
onlyOwner()
{
address previous = address(validator);
if (previous != _newValidator) {
validator = AggregatorValidatorInterface(_newValidator);
emit ValidatorUpdated(previous, _newValidator);
}
}
/**
* Private
*/
function initializeNewRound(uint32 _roundId)
private
{
updateTimedOutRoundInfo(_roundId.sub(1));
reportingRoundId = _roundId;
RoundDetails memory nextDetails = RoundDetails(
new int256[](0),
maxSubmissionCount,
minSubmissionCount,
timeout,
paymentAmount
);
details[_roundId] = nextDetails;
rounds[_roundId].startedAt = uint64(block.timestamp);
emit NewRound(_roundId, msg.sender, rounds[_roundId].startedAt);
}
function oracleInitializeNewRound(uint32 _roundId)
private
{
if (!newRound(_roundId)) return;
uint256 lastStarted = oracles[msg.sender].lastStartedRound; // cache storage reads
if (_roundId <= lastStarted + restartDelay && lastStarted != 0) return;
initializeNewRound(_roundId);
oracles[msg.sender].lastStartedRound = _roundId;
}
function requesterInitializeNewRound(uint32 _roundId)
private
{
if (!newRound(_roundId)) return;
uint256 lastStarted = requesters[msg.sender].lastStartedRound; // cache storage reads
require(_roundId > lastStarted + requesters[msg.sender].delay || lastStarted == 0, "must delay requests");
initializeNewRound(_roundId);
requesters[msg.sender].lastStartedRound = _roundId;
}
function updateTimedOutRoundInfo(uint32 _roundId)
private
{
if (!timedOut(_roundId)) return;
uint32 prevId = _roundId.sub(1);
rounds[_roundId].answer = rounds[prevId].answer;
rounds[_roundId].answeredInRound = rounds[prevId].answeredInRound;
rounds[_roundId].updatedAt = uint64(block.timestamp);
delete details[_roundId];
}
function eligibleForSpecificRound(address _oracle, uint32 _queriedRoundId)
private
view
returns (bool _eligible)
{
if (rounds[_queriedRoundId].startedAt > 0) {
return acceptingSubmissions(_queriedRoundId) && validateOracleRound(_oracle, _queriedRoundId).length == 0;
} else {
return delayed(_oracle, _queriedRoundId) && validateOracleRound(_oracle, _queriedRoundId).length == 0;
}
}
function oracleRoundStateSuggestRound(address _oracle)
private
view
returns (
bool _eligibleToSubmit,
uint32 _roundId,
int256 _latestSubmission,
uint64 _startedAt,
uint64 _timeout,
uint128 _availableFunds,
uint8 _oracleCount,
uint128 _paymentAmount
)
{
Round storage round = rounds[0];
OracleStatus storage oracle = oracles[_oracle];
bool shouldSupersede = oracle.lastReportedRound == reportingRoundId || !acceptingSubmissions(reportingRoundId);
// Instead of nudging oracles to submit to the next round, the inclusion of
// the shouldSupersede bool in the if condition pushes them towards
// submitting in a currently open round.
if (supersedable(reportingRoundId) && shouldSupersede) {
_roundId = reportingRoundId.add(1);
round = rounds[_roundId];
_paymentAmount = paymentAmount;
_eligibleToSubmit = delayed(_oracle, _roundId);
} else {
_roundId = reportingRoundId;
round = rounds[_roundId];
_paymentAmount = details[_roundId].paymentAmount;
_eligibleToSubmit = acceptingSubmissions(_roundId);
}
if (validateOracleRound(_oracle, _roundId).length != 0) {
_eligibleToSubmit = false;
}
return (
_eligibleToSubmit,
_roundId,
oracle.latestSubmission,
round.startedAt,
details[_roundId].timeout,
recordedFunds.available,
oracleCount(),
_paymentAmount
);
}
function updateRoundAnswer(uint32 _roundId)
internal
returns (bool, int256)
{
if (details[_roundId].submissions.length < details[_roundId].minSubmissions) {
return (false, 0);
}
int256 newAnswer = Median.calculateInplace(details[_roundId].submissions);
rounds[_roundId].answer = newAnswer;
rounds[_roundId].updatedAt = uint64(block.timestamp);
rounds[_roundId].answeredInRound = _roundId;
latestRoundId = _roundId;
emit AnswerUpdated(newAnswer, _roundId, now);
return (true, newAnswer);
}
function validateAnswer(
uint32 _roundId,
int256 _newAnswer
)
private
{
AggregatorValidatorInterface av = validator; // cache storage reads
if (address(av) == address(0)) return;
uint32 prevRound = _roundId.sub(1);
uint32 prevAnswerRoundId = rounds[prevRound].answeredInRound;
int256 prevRoundAnswer = rounds[prevRound].answer;
// We do not want the validator to ever prevent reporting, so we limit its
// gas usage and catch any errors that may arise.
try av.validate{gas: VALIDATOR_GAS_LIMIT}(
prevAnswerRoundId,
prevRoundAnswer,
_roundId,
_newAnswer
) {} catch {}
}
function payOracle(uint32 _roundId)
private
{
uint128 payment = details[_roundId].paymentAmount;
Funds memory funds = recordedFunds;
funds.available = funds.available.sub(payment);
funds.allocated = funds.allocated.add(payment);
recordedFunds = funds;
oracles[msg.sender].withdrawable = oracles[msg.sender].withdrawable.add(payment);
emit AvailableFundsUpdated(funds.available);
}
function recordSubmission(int256 _submission, uint32 _roundId)
private
{
require(acceptingSubmissions(_roundId), "round not accepting submissions");
details[_roundId].submissions.push(_submission);
oracles[msg.sender].lastReportedRound = _roundId;
oracles[msg.sender].latestSubmission = _submission;
emit SubmissionReceived(_submission, _roundId, msg.sender);
}
function deleteRoundDetails(uint32 _roundId)
private
{
if (details[_roundId].submissions.length < details[_roundId].maxSubmissions) return;
delete details[_roundId];
}
function timedOut(uint32 _roundId)
private
view
returns (bool)
{
uint64 startedAt = rounds[_roundId].startedAt;
uint32 roundTimeout = details[_roundId].timeout;
return startedAt > 0 && roundTimeout > 0 && startedAt.add(roundTimeout) < block.timestamp;
}
function getStartingRound(address _oracle)
private
view
returns (uint32)
{
uint32 currentRound = reportingRoundId;
if (currentRound != 0 && currentRound == oracles[_oracle].endingRound) {
return currentRound;
}
return currentRound.add(1);
}
function previousAndCurrentUnanswered(uint32 _roundId, uint32 _rrId)
private
view
returns (bool)
{
return _roundId.add(1) == _rrId && rounds[_rrId].updatedAt == 0;
}
function requiredReserve(uint256 payment)
private
view
returns (uint256)
{
return payment.mul(oracleCount()).mul(RESERVE_ROUNDS);
}
function addOracle(
address _oracle,
address _admin
)
private
{
require(!oracleEnabled(_oracle), "oracle already enabled");
require(_admin != address(0), "cannot set admin to 0");
require(oracles[_oracle].admin == address(0) || oracles[_oracle].admin == _admin, "owner cannot overwrite admin");
oracles[_oracle].startingRound = getStartingRound(_oracle);
oracles[_oracle].endingRound = ROUND_MAX;
oracles[_oracle].index = uint16(oracleAddresses.length);
oracleAddresses.push(_oracle);
oracles[_oracle].admin = _admin;
emit OraclePermissionsUpdated(_oracle, true);
emit OracleAdminUpdated(_oracle, _admin);
}
function removeOracle(
address _oracle
)
private
{
require(oracleEnabled(_oracle), "oracle not enabled");
oracles[_oracle].endingRound = reportingRoundId.add(1);
address tail = oracleAddresses[uint256(oracleCount()).sub(1)];
uint16 index = oracles[_oracle].index;
oracles[tail].index = index;
delete oracles[_oracle].index;
oracleAddresses[index] = tail;
oracleAddresses.pop();
emit OraclePermissionsUpdated(_oracle, false);
}
function validateOracleRound(address _oracle, uint32 _roundId)
private
view
returns (bytes memory)
{
// cache storage reads
uint32 startingRound = oracles[_oracle].startingRound;
uint32 rrId = reportingRoundId;
if (startingRound == 0) return "not enabled oracle";
if (startingRound > _roundId) return "not yet enabled oracle";
if (oracles[_oracle].endingRound < _roundId) return "no longer allowed oracle";
if (oracles[_oracle].lastReportedRound >= _roundId) return "cannot report on previous rounds";
if (_roundId != rrId && _roundId != rrId.add(1) && !previousAndCurrentUnanswered(_roundId, rrId)) return "invalid round to report";
if (_roundId != 1 && !supersedable(_roundId.sub(1))) return "previous round not supersedable";
}
function supersedable(uint32 _roundId)
private
view
returns (bool)
{
return rounds[_roundId].updatedAt > 0 || timedOut(_roundId);
}
function oracleEnabled(address _oracle)
private
view
returns (bool)
{
return oracles[_oracle].endingRound == ROUND_MAX;
}
function acceptingSubmissions(uint32 _roundId)
private
view
returns (bool)
{
return details[_roundId].maxSubmissions != 0;
}
function delayed(address _oracle, uint32 _roundId)
private
view
returns (bool)
{
uint256 lastStarted = oracles[_oracle].lastStartedRound;
return _roundId > lastStarted + restartDelay || lastStarted == 0;
}
function newRound(uint32 _roundId)
private
view
returns (bool)
{
return _roundId == reportingRoundId.add(1);
}
function validRoundId(uint256 _roundId)
private
pure
returns (bool)
{
return _roundId <= ROUND_MAX;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./vendor/SafeMathChainlink.sol";
import "./SignedSafeMath.sol";
library Median {
using SignedSafeMath for int256;
int256 constant INT_MAX = 2**255-1;
/**
* @notice Returns the sorted middle, or the average of the two middle indexed items if the
* array has an even number of elements.
* @dev The list passed as an argument isn't modified.
* @dev This algorithm has expected runtime O(n), but for adversarially chosen inputs
* the runtime is O(n^2).
* @param list The list of elements to compare
*/
function calculate(int256[] memory list)
internal
pure
returns (int256)
{
return calculateInplace(copy(list));
}
/**
* @notice See documentation for function calculate.
* @dev The list passed as an argument may be permuted.
*/
function calculateInplace(int256[] memory list)
internal
pure
returns (int256)
{
require(0 < list.length, "list must not be empty");
uint256 len = list.length;
uint256 middleIndex = len / 2;
if (len % 2 == 0) {
int256 median1;
int256 median2;
(median1, median2) = quickselectTwo(list, 0, len - 1, middleIndex - 1, middleIndex);
return SignedSafeMath.avg(median1, median2);
} else {
return quickselect(list, 0, len - 1, middleIndex);
}
}
/**
* @notice Maximum length of list that shortSelectTwo can handle
*/
uint256 constant SHORTSELECTTWO_MAX_LENGTH = 7;
/**
* @notice Select the k1-th and k2-th element from list of length at most 7
* @dev Uses an optimal sorting network
*/
function shortSelectTwo(
int256[] memory list,
uint256 lo,
uint256 hi,
uint256 k1,
uint256 k2
)
private
pure
returns (int256 k1th, int256 k2th)
{
// Uses an optimal sorting network (https://en.wikipedia.org/wiki/Sorting_network)
// for lists of length 7. Network layout is taken from
// http://jgamble.ripco.net/cgi-bin/nw.cgi?inputs=7&algorithm=hibbard&output=svg
uint256 len = hi + 1 - lo;
int256 x0 = list[lo + 0];
int256 x1 = 1 < len ? list[lo + 1] : INT_MAX;
int256 x2 = 2 < len ? list[lo + 2] : INT_MAX;
int256 x3 = 3 < len ? list[lo + 3] : INT_MAX;
int256 x4 = 4 < len ? list[lo + 4] : INT_MAX;
int256 x5 = 5 < len ? list[lo + 5] : INT_MAX;
int256 x6 = 6 < len ? list[lo + 6] : INT_MAX;
if (x0 > x1) {(x0, x1) = (x1, x0);}
if (x2 > x3) {(x2, x3) = (x3, x2);}
if (x4 > x5) {(x4, x5) = (x5, x4);}
if (x0 > x2) {(x0, x2) = (x2, x0);}
if (x1 > x3) {(x1, x3) = (x3, x1);}
if (x4 > x6) {(x4, x6) = (x6, x4);}
if (x1 > x2) {(x1, x2) = (x2, x1);}
if (x5 > x6) {(x5, x6) = (x6, x5);}
if (x0 > x4) {(x0, x4) = (x4, x0);}
if (x1 > x5) {(x1, x5) = (x5, x1);}
if (x2 > x6) {(x2, x6) = (x6, x2);}
if (x1 > x4) {(x1, x4) = (x4, x1);}
if (x3 > x6) {(x3, x6) = (x6, x3);}
if (x2 > x4) {(x2, x4) = (x4, x2);}
if (x3 > x5) {(x3, x5) = (x5, x3);}
if (x3 > x4) {(x3, x4) = (x4, x3);}
uint256 index1 = k1 - lo;
if (index1 == 0) {k1th = x0;}
else if (index1 == 1) {k1th = x1;}
else if (index1 == 2) {k1th = x2;}
else if (index1 == 3) {k1th = x3;}
else if (index1 == 4) {k1th = x4;}
else if (index1 == 5) {k1th = x5;}
else if (index1 == 6) {k1th = x6;}
else {revert("k1 out of bounds");}
uint256 index2 = k2 - lo;
if (k1 == k2) {return (k1th, k1th);}
else if (index2 == 0) {return (k1th, x0);}
else if (index2 == 1) {return (k1th, x1);}
else if (index2 == 2) {return (k1th, x2);}
else if (index2 == 3) {return (k1th, x3);}
else if (index2 == 4) {return (k1th, x4);}
else if (index2 == 5) {return (k1th, x5);}
else if (index2 == 6) {return (k1th, x6);}
else {revert("k2 out of bounds");}
}
/**
* @notice Selects the k-th ranked element from list, looking only at indices between lo and hi
* (inclusive). Modifies list in-place.
*/
function quickselect(int256[] memory list, uint256 lo, uint256 hi, uint256 k)
private
pure
returns (int256 kth)
{
require(lo <= k);
require(k <= hi);
while (lo < hi) {
if (hi - lo < SHORTSELECTTWO_MAX_LENGTH) {
int256 ignore;
(kth, ignore) = shortSelectTwo(list, lo, hi, k, k);
return kth;
}
uint256 pivotIndex = partition(list, lo, hi);
if (k <= pivotIndex) {
// since pivotIndex < (original hi passed to partition),
// termination is guaranteed in this case
hi = pivotIndex;
} else {
// since (original lo passed to partition) <= pivotIndex,
// termination is guaranteed in this case
lo = pivotIndex + 1;
}
}
return list[lo];
}
/**
* @notice Selects the k1-th and k2-th ranked elements from list, looking only at indices between
* lo and hi (inclusive). Modifies list in-place.
*/
function quickselectTwo(
int256[] memory list,
uint256 lo,
uint256 hi,
uint256 k1,
uint256 k2
)
internal // for testing
pure
returns (int256 k1th, int256 k2th)
{
require(k1 < k2);
require(lo <= k1 && k1 <= hi);
require(lo <= k2 && k2 <= hi);
while (true) {
if (hi - lo < SHORTSELECTTWO_MAX_LENGTH) {
return shortSelectTwo(list, lo, hi, k1, k2);
}
uint256 pivotIdx = partition(list, lo, hi);
if (k2 <= pivotIdx) {
hi = pivotIdx;
} else if (pivotIdx < k1) {
lo = pivotIdx + 1;
} else {
assert(k1 <= pivotIdx && pivotIdx < k2);
k1th = quickselect(list, lo, pivotIdx, k1);
k2th = quickselect(list, pivotIdx + 1, hi, k2);
return (k1th, k2th);
}
}
}
/**
* @notice Partitions list in-place using Hoare's partitioning scheme.
* Only elements of list between indices lo and hi (inclusive) will be modified.
* Returns an index i, such that:
* - lo <= i < hi
* - forall j in [lo, i]. list[j] <= list[i]
* - forall j in [i, hi]. list[i] <= list[j]
*/
function partition(int256[] memory list, uint256 lo, uint256 hi)
private
pure
returns (uint256)
{
// We don't care about overflow of the addition, because it would require a list
// larger than any feasible computer's memory.
int256 pivot = list[(lo + hi) / 2];
lo -= 1; // this can underflow. that's intentional.
hi += 1;
while (true) {
do {
lo += 1;
} while (list[lo] < pivot);
do {
hi -= 1;
} while (list[hi] > pivot);
if (lo < hi) {
(list[lo], list[hi]) = (list[hi], list[lo]);
} else {
// Let orig_lo and orig_hi be the original values of lo and hi passed to partition.
// Then, hi < orig_hi, because hi decreases *strictly* monotonically
// in each loop iteration and
// - either list[orig_hi] > pivot, in which case the first loop iteration
// will achieve hi < orig_hi;
// - or list[orig_hi] <= pivot, in which case at least two loop iterations are
// needed:
// - lo will have to stop at least once in the interval
// [orig_lo, (orig_lo + orig_hi)/2]
// - (orig_lo + orig_hi)/2 < orig_hi
return hi;
}
}
}
/**
* @notice Makes an in-memory copy of the array passed in
* @param list Reference to the array to be copied
*/
function copy(int256[] memory list)
private
pure
returns(int256[] memory)
{
int256[] memory list2 = new int256[](list.length);
for (uint256 i = 0; i < list.length; i++) {
list2[i] = list[i];
}
return list2;
}
}// SPDX-License-Identifier: MIT
pragma solidity >0.6.0 <0.8.0;
/**
* @title The Owned contract
* @notice A contract with helpers for basic contract ownership.
*/
contract Owned {
address public owner;
address private pendingOwner;
event OwnershipTransferRequested(
address indexed from,
address indexed to
);
event OwnershipTransferred(
address indexed from,
address indexed to
);
constructor() public {
owner = msg.sender;
}
/**
* @dev Allows an owner to begin transferring ownership to a new address,
* pending.
*/
function transferOwnership(address _to)
external
onlyOwner()
{
pendingOwner = _to;
emit OwnershipTransferRequested(owner, _to);
}
/**
* @dev Allows an ownership transfer to be completed by the recipient.
*/
function acceptOwnership()
external
{
require(msg.sender == pendingOwner, "Must be proposed owner");
address oldOwner = owner;
owner = msg.sender;
pendingOwner = address(0);
emit OwnershipTransferred(oldOwner, msg.sender);
}
/**
* @dev Reverts if called by anyone other than the contract owner.
*/
modifier onlyOwner() {
require(msg.sender == owner, "Only callable by owner");
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* This library is a version of Open Zeppelin's SafeMath, modified to support
* unsigned 128 bit integers.
*/
library SafeMath128 {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint128 a, uint128 b) internal pure returns (uint128) {
uint128 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint128 a, uint128 b) internal pure returns (uint128) {
require(b <= a, "SafeMath: subtraction overflow");
uint128 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint128 a, uint128 b) internal pure returns (uint128) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint128 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint128 a, uint128 b) internal pure returns (uint128) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint128 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint128 a, uint128 b) internal pure returns (uint128) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* This library is a version of Open Zeppelin's SafeMath, modified to support
* unsigned 32 bit integers.
*/
library SafeMath32 {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint32 a, uint32 b) internal pure returns (uint32) {
uint32 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint32 a, uint32 b) internal pure returns (uint32) {
require(b <= a, "SafeMath: subtraction overflow");
uint32 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint32 a, uint32 b) internal pure returns (uint32) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint32 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint32 a, uint32 b) internal pure returns (uint32) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint32 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint32 a, uint32 b) internal pure returns (uint32) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* This library is a version of Open Zeppelin's SafeMath, modified to support
* unsigned 64 bit integers.
*/
library SafeMath64 {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint64 a, uint64 b) internal pure returns (uint64) {
uint64 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint64 a, uint64 b) internal pure returns (uint64) {
require(b <= a, "SafeMath: subtraction overflow");
uint64 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint64 a, uint64 b) internal pure returns (uint64) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint64 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint64 a, uint64 b) internal pure returns (uint64) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint64 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint64 a, uint64 b) internal pure returns (uint64) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./AggregatorInterface.sol";
import "./AggregatorV3Interface.sol";
interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface
{
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
interface AggregatorValidatorInterface {
function validate(
uint256 previousRoundId,
int256 previousAnswer,
uint256 currentRoundId,
int256 currentAnswer
) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.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.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMathChainlink {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
library SignedSafeMath {
int256 constant private _INT256_MIN = -2**255;
/**
* @dev Multiplies two signed integers, reverts on overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
}
/**
* @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "SignedSafeMath: division by zero");
require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;
return c;
}
/**
* @dev Subtracts two signed integers, reverts on overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
}
/**
* @dev Adds two signed integers, reverts on overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
}
/**
* @notice Computes average of two signed integers, ensuring that the computation
* doesn't overflow.
* @dev If the result is not an integer, it is rounded towards zero. For example,
* avg(-3, -4) = -3
*/
function avg(int256 _a, int256 _b)
internal
pure
returns (int256)
{
if ((_a < 0 && _b > 0) || (_a > 0 && _b < 0)) {
return add(_a, _b) / 2;
}
int256 remainder = (_a % 2 + _b % 2) / 2;
return add(add(_a / 2, _b / 2), remainder);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.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.6.0;
interface AggregatorV3Interface {
function decimals()
external
view
returns (
uint8
);
function description()
external
view
returns (
string memory
);
function version()
external
view
returns (
uint256
);
// getRoundData and latestRoundData should both raise "No data present"
// if they do not have data to report, instead of returning unset values
// which could be misinterpreted as actual reported values.
function getRoundData(
uint80 _roundId
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}{
"optimizer": {
"enabled": true,
"runs": 2000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_link","type":"address"},{"internalType":"uint128","name":"_paymentAmount","type":"uint128"},{"internalType":"uint32","name":"_timeout","type":"uint32"},{"internalType":"address","name":"_validator","type":"address"},{"internalType":"int256","name":"_minSubmissionValue","type":"int256"},{"internalType":"int256","name":"_maxSubmissionValue","type":"int256"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"string","name":"_description","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"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":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AvailableFundsUpdated","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":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"OracleAdminUpdateRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"OracleAdminUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":true,"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"OraclePermissionsUpdated","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":"requester","type":"address"},{"indexed":false,"internalType":"bool","name":"authorized","type":"bool"},{"indexed":false,"internalType":"uint32","name":"delay","type":"uint32"}],"name":"RequesterPermissionsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint128","name":"paymentAmount","type":"uint128"},{"indexed":true,"internalType":"uint32","name":"minSubmissionCount","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"maxSubmissionCount","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"restartDelay","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"timeout","type":"uint32"}],"name":"RoundDetailsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"submission","type":"int256"},{"indexed":true,"internalType":"uint32","name":"round","type":"uint32"},{"indexed":true,"internalType":"address","name":"oracle","type":"address"}],"name":"SubmissionReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"ValidatorUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allocatedFunds","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableFunds","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_removed","type":"address[]"},{"internalType":"address[]","name":"_added","type":"address[]"},{"internalType":"address[]","name":"_addedAdmins","type":"address[]"},{"internalType":"uint32","name":"_minSubmissions","type":"uint32"},{"internalType":"uint32","name":"_maxSubmissions","type":"uint32"},{"internalType":"uint32","name":"_restartDelay","type":"uint32"}],"name":"changeOracles","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracles","outputs":[{"internalType":"address[]","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":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"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":"linkToken","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSubmissionCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSubmissionValue","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSubmissionCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSubmissionValue","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracleCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"uint32","name":"_queriedRoundId","type":"uint32"}],"name":"oracleRoundState","outputs":[{"internalType":"bool","name":"_eligibleToSubmit","type":"bool"},{"internalType":"uint32","name":"_roundId","type":"uint32"},{"internalType":"int256","name":"_latestSubmission","type":"int256"},{"internalType":"uint64","name":"_startedAt","type":"uint64"},{"internalType":"uint64","name":"_timeout","type":"uint64"},{"internalType":"uint128","name":"_availableFunds","type":"uint128"},{"internalType":"uint8","name":"_oracleCount","type":"uint8"},{"internalType":"uint128","name":"_paymentAmount","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentAmount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestNewRound","outputs":[{"internalType":"uint80","name":"","type":"uint80"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restartDelay","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_requester","type":"address"},{"internalType":"bool","name":"_authorized","type":"bool"},{"internalType":"uint32","name":"_delay","type":"uint32"}],"name":"setRequesterPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newValidator","type":"address"}],"name":"setValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"},{"internalType":"int256","name":"_submission","type":"int256"}],"name":"submit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timeout","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateAvailableFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_paymentAmount","type":"uint128"},{"internalType":"uint32","name":"_minSubmissions","type":"uint32"},{"internalType":"uint32","name":"_maxSubmissions","type":"uint32"},{"internalType":"uint32","name":"_restartDelay","type":"uint32"},{"internalType":"uint32","name":"_timeout","type":"uint32"}],"name":"updateFutureRounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validator","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"withdrawablePayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162004f7238038062004f7283398181016040526101008110156200003857600080fd5b815160208301516040808501516060860151608087015160a088015160c089015160e08a0180519651989a9799959894979396929591949391820192846401000000008211156200008857600080fd5b9083019060208201858111156200009e57600080fd5b8251640100000000811182820188101715620000b957600080fd5b82525081516020918201929091019080838360005b83811015620000e8578181015183820152602001620000ce565b50505050905090810190601f168015620001165780820380516001836020036101000a031916815260200191505b50604052505060008054336001600160a01b0319918216178255600280549091166001600160a01b038c16179055620001559150889080808a6200021f565b62000169856001600160e01b03620005fd16565b608084905260a08390526005805460ff191660ff8416179055805162000197906006906020840190620007e1565b50620001b88663ffffffff1642620006c760201b620032b61790919060201c565b6000805260096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6c80546001600160401b03929092166801000000000000000002600160401b600160801b031990921691909117905550620008839650505050505050565b6000546001600160a01b031633146200027f576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6000620002946001600160e01b036200072a16565b60ff1690508463ffffffff168463ffffffff161015620002fb576040805162461bcd60e51b815260206004820152601960248201527f6d6178206d75737420657175616c2f657863656564206d696e00000000000000604482015290519081900360640190fd5b8363ffffffff168163ffffffff1610156200035d576040805162461bcd60e51b815260206004820152601760248201527f6d61782063616e6e6f742065786365656420746f74616c000000000000000000604482015290519081900360640190fd5b63ffffffff811615806200037c57508263ffffffff168163ffffffff16115b620003ce576040805162461bcd60e51b815260206004820152601960248201527f64656c61792063616e6e6f742065786365656420746f74616c00000000000000604482015290519081900360640190fd5b620003eb6001600160801b0387166001600160e01b036200073116565b600d546001600160801b031610156200044b576040805162461bcd60e51b815260206004820152601e60248201527f696e73756666696369656e742066756e647320666f72207061796d656e740000604482015290519081900360640190fd5b6000620004606001600160e01b036200072a16565b60ff161115620004c65760008563ffffffff1611620004c6576040805162461bcd60e51b815260206004820152601a60248201527f6d696e206d7573742062652067726561746572207468616e2030000000000000604482015290519081900360640190fd5b85600460006101000a8154816001600160801b0302191690836001600160801b0316021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046001600160801b03166001600160801b03167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b6000546001600160a01b031633146200065d576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6003546001600160a01b039081169082168114620006c357600380546001600160a01b0319166001600160a01b0384811691821790925560405190918316907fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d90600090a35b5050565b6000828211156200071f576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b600c545b90565b600062000724600262000768620007506001600160e01b036200072a16565b60ff16856200077c60201b62003b941790919060201c565b6200077c60201b62003b941790919060201c565b6000826200078d5750600062000724565b828202828482816200079b57fe5b0414620007da5760405162461bcd60e51b815260040180806020018281038252602181526020018062004f516021913960400191505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200082457805160ff191683800117855562000854565b8280016001018555821562000854579182015b828111156200085457825182559160200191906001019062000837565b506200086292915062000866565b5090565b6200072e91905b808211156200086257600081556001016200086d565b60805160a0516146a0620008b160003980610b2c5280610e10525080610ab75280611aba52506146a06000f3fe608060405234801561001057600080fd5b50600436106102d35760003560e01c8063668a0f0211610186578063a4c0ed36116100e3578063c937450011610097578063e9ee6eeb11610071578063e9ee6eeb14610976578063f2fde38b146109a4578063feaf968c146109ca576102d3565b8063c937450014610940578063d4cc54e414610948578063e2e4031714610950576102d3565b8063b633620c116100c8578063b633620c146108ef578063c10753291461090c578063c35905c614610938576102d3565b8063a4c0ed361461084d578063b5ab58dc146108d2576102d3565b80638205bf6a1161013a5780638da5cb5b1161011f5780638da5cb5b146107b657806398e5b12a146107be5780639a6fc8f5146107e5576102d3565b80638205bf6a1461071b57806388aa80e714610723576102d3565b80637284e4161161016b5780637284e4161461068e57806379ba50971461070b5780637c2b0b2114610713576102d3565b8063668a0f021461067e57806370dea79a14610686576102d3565b806340884c521161023457806357970e93116101e8578063613d8fcc116101cd578063613d8fcc1461062a578063628806ef1461063257806364efb22b14610658576102d3565b806357970e931461061a57806358609e4414610622576102d3565b80634f8fc3b5116102195780634f8fc3b51461060257806350d25bcd1461060a57806354fd4d5014610612576102d3565b806340884c521461058657806346fcff4c146105de576102d3565b8063357ebb021161028b5780633969c20f116102705780633969c20f146104005780633a5381b51461052c5780633d3d771414610550576102d3565b8063357ebb021461039557806338aa4c72146103b6576102d3565b806320ed0275116102bc57806320ed02751461032357806323ca29031461035d578063313ce56714610377576102d3565b80631327d3d8146102d8578063202ee0ed14610300575b600080fd5b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b03166109d2565b005b6102fe6004803603604081101561031657600080fd5b5080359060200135610aa7565b6102fe6004803603606081101561033957600080fd5b5080356001600160a01b03169060208101351515906040013563ffffffff16610c79565b610365610e0e565b60408051918252519081900360200190f35b61037f610e32565b6040805160ff9092168252519081900360200190f35b61039d610e3b565b6040805163ffffffff9092168252519081900360200190f35b6102fe600480360360a08110156103cc57600080fd5b506001600160801b038135169063ffffffff6020820135811691604081013582169160608201358116916080013516610e4e565b6102fe600480360360c081101561041657600080fd5b81019060208101813564010000000081111561043157600080fd5b82018360208201111561044357600080fd5b8035906020019184602083028401116401000000008311171561046557600080fd5b91939092909160208101903564010000000081111561048357600080fd5b82018360208201111561049557600080fd5b803590602001918460208302840111640100000000831117156104b757600080fd5b9193909290916020810190356401000000008111156104d557600080fd5b8201836020820111156104e757600080fd5b8035906020019184602083028401116401000000008311171561050957600080fd5b919350915063ffffffff8135811691602081013582169160409091013516611203565b6105346113e7565b604080516001600160a01b039092168252519081900360200190f35b6102fe6004803603606081101561056657600080fd5b506001600160a01b038135811691602081013590911690604001356113f6565b61058e611612565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156105ca5781810151838201526020016105b2565b505050509050019250505060405180910390f35b6105e6611675565b604080516001600160801b039092168252519081900360200190f35b6102fe611684565b6103656117bd565b6103656117e0565b6105346117e5565b61039d6117f4565b61037f611807565b6102fe6004803603602081101561064857600080fd5b50356001600160a01b031661180d565b6105346004803603602081101561066e57600080fd5b50356001600160a01b0316611916565b610365611940565b61039d611954565b610696611967565b6040805160208082528351818301528351919283929083019185019080838360005b838110156106d05781810151838201526020016106b8565b50505050905090810190601f1680156106fd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102fe6119f5565b610365611ab8565b610365611adc565b6107556004803603604081101561073957600080fd5b5080356001600160a01b0316906020013563ffffffff16611b18565b60408051981515895263ffffffff90971660208901528787019590955267ffffffffffffffff93841660608801529190921660808601526001600160801b0391821660a086015260ff1660c08501521660e083015251908190036101000190f35b610534611c8f565b6107c6611c9e565b6040805169ffffffffffffffffffff9092168252519081900360200190f35b61080e600480360360208110156107fb57600080fd5b503569ffffffffffffffffffff16611dc3565b6040805169ffffffffffffffffffff96871681526020810195909552848101939093526060840191909152909216608082015290519081900360a00190f35b6102fe6004803603606081101561086357600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561089357600080fd5b8201836020820111156108a557600080fd5b803590602001918460018302840111640100000000831117156108c757600080fd5b509092509050611f12565b610365600480360360208110156108e857600080fd5b5035611f73565b6103656004803603602081101561090557600080fd5b5035611fa7565b6102fe6004803603604081101561092257600080fd5b506001600160a01b038135169060200135611fec565b6105e66121c1565b61039d6121d0565b6105e66121e3565b6103656004803603602081101561096657600080fd5b50356001600160a01b03166121f9565b6102fe6004803603604081101561098c57600080fd5b506001600160a01b038135811691602001351661221d565b6102fe600480360360208110156109ba57600080fd5b50356001600160a01b0316612314565b61080e6123d1565b6000546001600160a01b03163314610a31576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6003546001600160a01b039081169082168114610aa3576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384811691821790925560405190918316907fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d90600090a35b5050565b6060610ab3338461240b565b90507f0000000000000000000000000000000000000000000000000000000000000000821215610b2a576040805162461bcd60e51b815260206004820152601e60248201527f76616c75652062656c6f77206d696e5375626d697373696f6e56616c75650000604482015290519081900360640190fd5b7f0000000000000000000000000000000000000000000000000000000000000000821315610b9f576040805162461bcd60e51b815260206004820152601e60248201527f76616c75652061626f7665206d61785375626d697373696f6e56616c75650000604482015290519081900360640190fd5b8051819015610c2c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610bf1578181015183820152602001610bd9565b50505050905090810190601f168015610c1e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610c36836126c0565b610c408284612769565b600080610c4c8561285a565b91509150610c59856129db565b610c6285612b39565b8115610c7257610c728582612bb0565b5050505050565b6000546001600160a01b03163314610cd8576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6001600160a01b0383166000908152600b602052604090205460ff1615158215151415610d0457610e09565b8115610d7f576001600160a01b0383166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016831515177fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff841602179055610dbe565b6001600160a01b0383166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000001690555b60408051831515815263ffffffff8316602082015281516001600160a01b038616927fc3df5a754e002718f2e10804b99e6605e7c701d95cec9552c7680ca2b6f2820a928290030190a25b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055460ff1681565b600454600160c01b900463ffffffff1681565b6000546001600160a01b03163314610ead576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6000610eb7611807565b60ff1690508463ffffffff168463ffffffff161015610f1d576040805162461bcd60e51b815260206004820152601960248201527f6d6178206d75737420657175616c2f657863656564206d696e00000000000000604482015290519081900360640190fd5b8363ffffffff168163ffffffff161015610f7e576040805162461bcd60e51b815260206004820152601760248201527f6d61782063616e6e6f742065786365656420746f74616c000000000000000000604482015290519081900360640190fd5b63ffffffff81161580610f9c57508263ffffffff168163ffffffff16115b610fed576040805162461bcd60e51b815260206004820152601960248201527f64656c61792063616e6e6f742065786365656420746f74616c00000000000000604482015290519081900360640190fd5b610fff866001600160801b0316612cc2565b600d546001600160801b0316101561105e576040805162461bcd60e51b815260206004820152601e60248201527f696e73756666696369656e742066756e647320666f72207061796d656e740000604482015290519081900360640190fd5b6000611068611807565b60ff1611156110cc5760008563ffffffff16116110cc576040805162461bcd60e51b815260206004820152601a60248201527f6d696e206d7573742062652067726561746572207468616e2030000000000000604482015290519081900360640190fd5b85600460006101000a8154816001600160801b0302191690836001600160801b0316021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046001600160801b03166001600160801b03167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b6000546001600160a01b03163314611262576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60005b88811015611299576112918a8a8381811061127c57fe5b905060200201356001600160a01b0316612cf0565b600101611265565b508584146112ee576040805162461bcd60e51b815260206004820181905260248201527f6e6565642073616d65206f7261636c6520616e642061646d696e20636f756e74604482015290519081900360640190fd5b604d61130b876112fc611807565b60ff169063ffffffff612eee16565b111561135e576040805162461bcd60e51b815260206004820152601360248201527f6d6178206f7261636c657320616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b60005b868110156113b1576113a988888381811061137857fe5b905060200201356001600160a01b031687878481811061139457fe5b905060200201356001600160a01b0316612f4f565b600101611361565b506004546113dc906001600160801b03811690859085908590600160e01b900463ffffffff16610e4e565b505050505050505050565b6003546001600160a01b031681565b6001600160a01b0383811660009081526008602052604090206002015462010000900416331461146d576040805162461bcd60e51b815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b6001600160a01b03831660009081526008602052604090205481906001600160801b039081169082168110156114ea576040805162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420776974686472617761626c652066756e647300604482015290519081900360640190fd5b6115036001600160801b0382168363ffffffff61324716565b6001600160a01b038616600090815260086020526040902080546fffffffffffffffffffffffffffffffff19166001600160801b03928316179055600d5461155491600160801b9091041683613247565b600d80546001600160801b03928316600160801b02908316179055600254604080517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015293861660248201529051929091169163a9059cbb916044808201926020929091908290030181600087803b1580156115e057600080fd5b505af11580156115f4573d6000803e3d6000fd5b505050506040513d602081101561160a57600080fd5b5051610c7257fe5b6060600c80548060200260200160405190810160405280929190818152602001828054801561166a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161164c575b505050505090505b90565b600d546001600160801b031690565b61168c614539565b50604080518082018252600d546001600160801b038082168352600160801b90910416602080830182905260025484517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529451939460009461175694936001600160a01b03909316926370a082319260248082019391829003018186803b15801561171e57600080fd5b505afa158015611732573d6000803e3d6000fd5b505050506040513d602081101561174857600080fd5b50519063ffffffff6132b616565b82519091506001600160801b03168114610aa357600d80546fffffffffffffffffffffffffffffffff19166001600160801b03831617905560405181907ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f90600090a25050565b600754640100000000900463ffffffff1660009081526009602052604090205490565b600381565b6002546001600160a01b031681565b600454600160801b900463ffffffff1681565b600c5490565b6001600160a01b0381811660009081526008602052604090206003015416331461187e576040805162461bcd60e51b815260206004820152601e60248201527f6f6e6c792063616c6c61626c652062792070656e64696e672061646d696e0000604482015290519081900360640190fd5b6001600160a01b03811660008181526008602052604080822060038101805473ffffffffffffffffffffffffffffffffffffffff1916905560020180547fffffffffffffffffffff0000000000000000000000000000000000000000ffff16336201000081029190911790915590519092917f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90491a350565b6001600160a01b03808216600090815260086020526040902060020154620100009004165b919050565b600754640100000000900463ffffffff1690565b600454600160e01b900463ffffffff1681565b6006805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156119ed5780601f106119c2576101008083540402835291602001916119ed565b820191906000526020600020905b8154815290600101906020018083116119d057829003601f168201915b505050505081565b6001546001600160a01b03163314611a54576040805162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b7f000000000000000000000000000000000000000000000000000000000000000081565b600754640100000000900463ffffffff1660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1690565b600080808080808080333214611b75576040805162461bcd60e51b815260206004820152601660248201527f6f66662d636861696e2072656164696e67206f6e6c7900000000000000000000604482015290519081900360640190fd5b63ffffffff891615611c685763ffffffff89166000908152600960209081526040808320600a909252909120611bab8c8c61330d565b6001600160a01b038d1660009081526008602052604090206001908101548482015491840154600d548f9367ffffffffffffffff169168010000000000000000900463ffffffff16906001600160801b0316611c05611807565b600189015467ffffffffffffffff16611c29576004546001600160801b0316611c48565b60018801546c0100000000000000000000000090046001600160801b03165b8363ffffffff169350995099509950995099509950995099505050611c82565b611c718a613363565b975097509750975097509750975097505b9295985092959890939650565b6000546001600160a01b031681565b336000908152600b602052604081205460ff16611d02576040805162461bcd60e51b815260206004820152601860248201527f6e6f7420617574686f72697a6564207265717565737465720000000000000000604482015290519081900360640190fd5b60075463ffffffff1660008181526009602052604090206001015468010000000000000000900467ffffffffffffffff16151580611d445750611d448161353d565b611d95576040805162461bcd60e51b815260206004820152601f60248201527f7072657620726f756e64206d75737420626520737570657273656461626c6500604482015290519081900360640190fd5b6000611dac63ffffffff808416906001906135d016565b9050611db781613633565b63ffffffff1691505090565b6000806000806000611dd3614550565b5063ffffffff80871660009081526009602090815260409182902082516080810184528154815260019091015467ffffffffffffffff8082169383019390935268010000000000000000810490921692810192909252600160801b90049091166060820181905215801590611e585750611e588769ffffffffffffffffffff16613721565b6040518060400160405280600f81526020017f4e6f20646174612070726573656e74000000000000000000000000000000000081525090611eda5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610bf1578181015183820152602001610bd9565b508051602082015160408301516060909301519899919867ffffffffffffffff91821698509216955063ffffffff9091169350915050565b8015611f65576040805162461bcd60e51b815260206004820181905260248201527f7472616e7366657220646f65736e2774206163636570742063616c6c64617461604482015290519081900360640190fd5b611f6d611684565b50505050565b6000611f7e82613721565b15611f9f575063ffffffff811660009081526009602052604090205461193b565b506000919050565b6000611fb282613721565b15611f9f575063ffffffff811660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1661193b565b6000546001600160a01b0316331461204b576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600d546004546001600160801b0391821691839161207a9161206d9116612cc2565b839063ffffffff6132b616565b10156120cd576040805162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e7420726573657276652066756e6473000000000000604482015290519081900360640190fd5b600254604080517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561213c57600080fd5b505af1158015612150573d6000803e3d6000fd5b505050506040513d602081101561216657600080fd5b50516121b9576040805162461bcd60e51b815260206004820152601560248201527f746f6b656e207472616e73666572206661696c65640000000000000000000000604482015290519081900360640190fd5b610e09611684565b6004546001600160801b031681565b600454600160a01b900463ffffffff1681565b600d54600160801b90046001600160801b031690565b6001600160a01b03166000908152600860205260409020546001600160801b031690565b6001600160a01b03828116600090815260086020526040902060020154620100009004163314612294576040805162461bcd60e51b815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b6001600160a01b03828116600081815260086020908152604091829020600301805473ffffffffffffffffffffffffffffffffffffffff19169486169485179055815133815290810193909352805191927fb79bf2e89c2d70dde91d2991fb1ea69b7e478061ad7c04ed5b02b96bc52b8104929081900390910190a25050565b6000546001600160a01b03163314612373576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060008060006123fa600760049054906101000a900463ffffffff1663ffffffff16611dc3565b945094509450945094509091929394565b6001600160a01b03821660009081526008602052604090205460075460609163ffffffff600160801b909104811691168161247f576040518060400160405280601281526020017f6e6f7420656e61626c6564206f7261636c650000000000000000000000000000815250925050506126ba565b8363ffffffff168263ffffffff1611156124d2576040518060400160405280601681526020017f6e6f742079657420656e61626c6564206f7261636c6500000000000000000000815250925050506126ba565b6001600160a01b03851660009081526008602052604090205463ffffffff808616600160a01b909204161015612541576040518060400160405280601881526020017f6e6f206c6f6e67657220616c6c6f776564206f7261636c650000000000000000815250925050506126ba565b6001600160a01b03851660009081526008602052604090205463ffffffff808616600160c01b90920416106125af576040518060400160405280602081526020017f63616e6e6f74207265706f7274206f6e2070726576696f757320726f756e6473815250925050506126ba565b8063ffffffff168463ffffffff16141580156125eb57506125db63ffffffff808316906001906135d016565b63ffffffff168463ffffffff1614155b80156125fe57506125fc848261372b565b155b15612642576040518060400160405280601781526020017f696e76616c696420726f756e6420746f207265706f7274000000000000000000815250925050506126ba565b8363ffffffff16600114158015612673575061267161266c63ffffffff8087169060019061379116565b6137f4565b155b156126b7576040518060400160405280601f81526020017f70726576696f757320726f756e64206e6f7420737570657273656461626c6500815250925050506126ba565b50505b92915050565b6126c981613834565b6126d257612766565b3360009081526008602052604090205460045463ffffffff600160e01b909204821691600160c01b909104811682019083161180159061271157508015155b1561271c5750612766565b61272582613865565b5033600090815260086020526040902080547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160e01b63ffffffff8416021790555b50565b61277281613a5e565b6127c3576040805162461bcd60e51b815260206004820152601f60248201527f726f756e64206e6f7420616363657074696e67207375626d697373696f6e7300604482015290519081900360640190fd5b63ffffffff81166000818152600a602090815260408083208054600180820183559185528385200187905533808552600890935281842080547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b8702178155018690555190929185917f92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c9190a45050565b63ffffffff8082166000908152600a602052604081206001810154905491928392640100000000909204161115612896575060009050806129d6565b63ffffffff83166000908152600a6020908152604080832080548251818502810185019093528083526128fc938301828280156128f257602002820191906000526020600020905b8154815260200190600101908083116128de575b5050505050613a7e565b63ffffffff851660008181526009602090815260409182902084815560010180547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff8116919091029190911773ffffffff000000000000000000000000000000001916600160801b8602179091556007805467ffffffff000000001916640100000000860217905582519081529151939450919284927f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f928290030190a36001925090505b915091565b63ffffffff81166000908152600a60205260409020600101546c0100000000000000000000000090046001600160801b0316612a15614539565b5060408051808201909152600d546001600160801b03808216808452600160801b909204166020830152612a4f908363ffffffff61324716565b6001600160801b0390811682526020820151612a7291168363ffffffff613b2e16565b6001600160801b0390811660208084018290528351600d8054600160801b9094029185166fffffffffffffffffffffffffffffffff199094169390931784161790915533600090815260089091526040902054612ad691168363ffffffff613b2e16565b3360009081526008602052604080822080546fffffffffffffffffffffffffffffffff19166001600160801b03948516179055835190519216917ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f9190a2505050565b63ffffffff8082166000908152600a602052604090206001810154905491161115612b6357612766565b63ffffffff81166000908152600a6020526040812090612b838282614577565b5060010180547fffffffff0000000000000000000000000000000000000000000000000000000016905550565b6003546001600160a01b031680612bc75750610aa3565b6000612bde63ffffffff8086169060019061379116565b63ffffffff80821660009081526009602090815260408083206001810154905482517fbeed9b51000000000000000000000000000000000000000000000000000000008152600160801b90920486166004830181905260248301829052958b166044830152606482018a90529151959650939490936001600160a01b0388169363beed9b5193620186a093608480850194929391928390030190829088803b158015612c8957600080fd5b5087f193505050508015612caf57506040513d6020811015612caa57600080fd5b505160015b612cb857612cba565b505b505050505050565b60006126ba6002612ce4612cd4611807565b859060ff1663ffffffff613b9416565b9063ffffffff613b9416565b612cf981613bed565b612d4a576040805162461bcd60e51b815260206004820152601260248201527f6f7261636c65206e6f7420656e61626c65640000000000000000000000000000604482015290519081900360640190fd5b600754612d639063ffffffff908116906001906135d016565b6001600160a01b0382166000908152600860205260408120805463ffffffff93909316600160a01b027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff90931692909217909155600c612dd56001612dc6611807565b60ff169063ffffffff6132b616565b81548110612ddf57fe5b6000918252602080832091909101546001600160a01b0385811680855260089093526040808520600290810180549390941680875291862001805461ffff90931661ffff199384168117909155939094528154169055600c8054929350909183919083908110612e4b57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600c805480612e8457fe5b6000828152602081208201600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559091019091556040516001600160a01b038516907f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e908390a3505050565b600082820183811015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b612f5882613bed565b15612faa576040805162461bcd60e51b815260206004820152601660248201527f6f7261636c6520616c726561647920656e61626c656400000000000000000000604482015290519081900360640190fd5b6001600160a01b038116613005576040805162461bcd60e51b815260206004820152601560248201527f63616e6e6f74207365742061646d696e20746f20300000000000000000000000604482015290519081900360640190fd5b6001600160a01b0382811660009081526008602052604090206002015462010000900416158061305a57506001600160a01b038281166000908152600860205260409020600201546201000090048116908216145b6130ab576040805162461bcd60e51b815260206004820152601c60248201527f6f776e65722063616e6e6f74206f76657277726974652061646d696e00000000604482015290519081900360640190fd5b6130b482613c18565b6001600160a01b0380841660008181526008602052604080822080547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff63ffffffff97909716600160801b0273ffffffff0000000000000000000000000000000019909116179590951677ffffffff0000000000000000000000000000000000000000178555600c80546002909601805461ffff90971661ffff19909716969096178655805460018181019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805473ffffffffffffffffffffffffffffffffffffffff191685179055838352855494871662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909516949094179094559251919290917f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e9190a3806001600160a01b0316826001600160a01b03167f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90460405160405180910390a35050565b6000826001600160801b0316826001600160801b031611156132b0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000828211156132b0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b63ffffffff811660009081526009602052604081206001015467ffffffffffffffff16156133595761333e82613a5e565b8015613352575061334f838361240b565b51155b90506126ba565b61333e8383613c7b565b6001600160a01b0381166000908152600860205260408120600754815483928392839283928392839283927fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b929091849163ffffffff908116600160c01b9092041614806133e057506007546133de9063ffffffff16613a5e565b155b6007549091506133f59063ffffffff166137f4565b80156133fe5750805b156134575760075461341c9063ffffffff908116906001906135d016565b63ffffffff81166000908152600960205260409020600454919b506001600160801b03909116945092506134508c8b613c7b565b9a506134aa565b60075463ffffffff166000818152600960209081526040808320600a90925290912060010154919b506c010000000000000000000000009091046001600160801b0316945092506134a78a613a5e565b9a505b6134b48c8b61240b565b51156134bf5760009a505b6001808301548482015463ffffffff808e166000908152600a6020526040902090930154600d548f948f949367ffffffffffffffff169268010000000000000000900416906001600160801b0316613515611807565b8a8363ffffffff1693509a509a509a509a509a509a509a509a50505050919395975091939597565b63ffffffff8082166000908152600960209081526040808320600190810154600a9093529083200154919267ffffffffffffffff90911691680100000000000000009004168115801590613597575060008163ffffffff16115b80156135c85750426135bc67ffffffffffffffff841663ffffffff80851690613cc516565b67ffffffffffffffff16105b949350505050565b600082820163ffffffff8085169082161015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b61363c81613834565b61364557612766565b336000908152600b602052604090205463ffffffff650100000000008204811691610100900481168201908316118061367c575080155b6136cd576040805162461bcd60e51b815260206004820152601360248201527f6d7573742064656c617920726571756573747300000000000000000000000000604482015290519081900360640190fd5b6136d682613865565b50336000908152600b60205260409020805463ffffffff831665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90911617905550565b63ffffffff101590565b60008163ffffffff1661374e60018563ffffffff166135d090919063ffffffff16565b63ffffffff16148015612f4857505063ffffffff1660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1615919050565b60008263ffffffff168263ffffffff1611156132b0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b63ffffffff811660009081526009602052604081206001015468010000000000000000900467ffffffffffffffff161515806126ba57506126ba8261353d565b6007546000906138509063ffffffff908116906001906135d016565b63ffffffff168263ffffffff16149050919050565b61388261387d63ffffffff8084169060019061379116565b613d2c565b6007805463ffffffff191663ffffffff831617905561389f614595565b5060408051600060a0820181815260c083018452825260045463ffffffff600160801b82048116602080860191909152600160a01b8304821685870152600160e01b8304821660608601526001600160801b03909216608085015285168252600a8152929020815180519293849361391a92849201906145c3565b5060208281015160019283018054604080870151606088015160809098015163ffffffff1990931663ffffffff9586161767ffffffff00000000191664010000000091861691909102177fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000097851697909702969096177fffffffff00000000000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006001600160801b0390921691909102179055851660008181526009835284902090920180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff9081169190911791829055845191168152925133937f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac6027192908290030190a35050565b63ffffffff9081166000908152600a602052604090206001015416151590565b60008151600010613ad6576040805162461bcd60e51b815260206004820152601660248201527f6c697374206d757374206e6f7420626520656d70747900000000000000000000604482015290519081900360640190fd5b81516002810460018216613b1557600080613afb866000600187036001870387613e2d565b9092509050613b0a8282613f0b565b94505050505061193b565b613b258460006001850384613f79565b9250505061193b565b60008282016001600160801b038085169082161015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082613ba3575060006126ba565b82820282848281613bb057fe5b0414612f485760405162461bcd60e51b815260040180806020018281038252602181526020018061464a6021913960400191505060405180910390fd5b6001600160a01b031660009081526008602052604090205463ffffffff600160a01b90910481161490565b60075460009063ffffffff168015801590613c5a57506001600160a01b03831660009081526008602052604090205463ffffffff828116600160a01b90920416145b15613c6657905061193b565b612f4863ffffffff808316906001906135d016565b6001600160a01b03821660009081526008602052604081205460045463ffffffff600160e01b909204821691600160c01b9091048116820190841611806135c85750159392505050565b600082820167ffffffffffffffff8085169082161015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b613d358161353d565b613d3e57612766565b6000613d5563ffffffff8084169060019061379116565b63ffffffff8181166000908152600960209081526040808320805488861685528285209081556001918201549101805473ffffffff000000000000000000000000000000001916600160801b92839004909616909102949094177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff160217909355600a9052908120919250613dff8282614577565b5060010180547fffffffff000000000000000000000000000000000000000000000000000000001690555050565b600080828410613e3c57600080fd5b838611158015613e4c5750848411155b613e5557600080fd5b828611158015613e655750848311155b613e6e57600080fd5b60078686031015613e8f57613e86878787878761400a565b91509150613f01565b6000613e9c8888886143f7565b9050808411613ead57809550613efb565b84811015613ec057806001019650613efb565b808511158015613ecf57508381105b613ed557fe5b613ee188888388613f79565b9250613ef288826001018887613f79565b9150613f019050565b50613e6e565b9550959350505050565b60008083128015613f1c5750600082135b80613f325750600083138015613f325750600082125b15613f52576002613f4384846144d4565b81613f4a57fe5b0590506126ba565b60006002808507818507010590506135c8613f7360028605600286056144d4565b826144d4565b600081841115613f8857600080fd5b82821115613f9557600080fd5b82841015613fec5760078484031015613fc1576000613fb7868686868761400a565b5091506135c89050565b6000613fce8686866143f7565b9050808311613fdf57809350613fe6565b8060010194505b50613f95565b848481518110613ff857fe5b60200260200101519050949350505050565b60008060008686600101039050600088886000018151811061402857fe5b60200260200101519050600082600110614049576001600160ff1b03614061565b89896001018151811061405857fe5b60200260200101515b905060008360021061407a576001600160ff1b03614092565b8a8a6002018151811061408957fe5b60200260200101515b90506000846003106140ab576001600160ff1b036140c3565b8b8b600301815181106140ba57fe5b60200260200101515b90506000856004106140dc576001600160ff1b036140f4565b8c8c600401815181106140eb57fe5b60200260200101515b905060008660051061410d576001600160ff1b03614125565b8d8d6005018151811061411c57fe5b60200260200101515b905060008760061061413e576001600160ff1b03614156565b8e8e6006018151811061414d57fe5b60200260200101515b905085871315614164579495945b83851315614170579293925b8183131561417c579091905b84871315614188579395935b83861315614194579294925b8083131561419e57915b848613156141aa579394935b808213156141b457905b828713156141c0579195915b818613156141cc579094905b808513156141d657935b828613156141e2579194915b808413156141ec57925b828513156141f8579193915b81841315614204579092905b82841315614210579192915b8d8c038061422057879a506142d3565b806001141561423157869a506142d3565b806002141561424257859a506142d3565b806003141561425357849a506142d3565b806004141561426457839a506142d3565b806005141561427557829a506142d3565b806006141561428657819a506142d3565b6040805162461bcd60e51b815260206004820152601060248201527f6b31206f7574206f6620626f756e647300000000000000000000000000000000604482015290519081900360640190fd5b8e8c038d8d14156142f157508a9950613f0198505050505050505050565b806143085750969850613f01975050505050505050565b80600114156143235750959850613f01975050505050505050565b806002141561433e5750949850613f01975050505050505050565b80600314156143595750939850613f01975050505050505050565b80600414156143745750929850613f01975050505050505050565b806005141561438f5750919850613f01975050505050505050565b80600614156143aa5750909850613f01975050505050505050565b6040805162461bcd60e51b815260206004820152601060248201527f6b32206f7574206f6620626f756e647300000000000000000000000000000000604482015290519081900360640190fd5b600080846002858501048151811061440b57fe5b602002602001015190506001840393506001830192505b6001840193508085858151811061443557fe5b602002602001015112614422575b6001830392508085848151811061445657fe5b60200260200101511361444357828410156144c65784838151811061447757fe5b602002602001015185858151811061448b57fe5b602002602001015186868151811061449f57fe5b602002602001018786815181106144b257fe5b6020908102919091010191909152526144cf565b82915050612f48565b614422565b60008282018183128015906144e95750838112155b806144fe57506000831280156144fe57508381125b612f485760405162461bcd60e51b81526004018080602001828103825260218152602001806146296021913960400191505060405180910390fd5b604080518082019091526000808252602082015290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5080546000825590600052602060002090810190612766919061460e565b6040805160a08101825260608082526000602083018190529282018390528101829052608081019190915290565b8280548282559060005260206000209081019282156145fe579160200282015b828111156145fe5782518255916020019190600101906145e3565b5061460a92915061460e565b5090565b61167291905b8082111561460a576000815560010161461456fe5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122040e1f6236541e7eeeba27f9d0f0a3ec266fea6447f080ce6be636a3381af280964736f6c63430006060033536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000b44726f70732d4265616e7a000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102d35760003560e01c8063668a0f0211610186578063a4c0ed36116100e3578063c937450011610097578063e9ee6eeb11610071578063e9ee6eeb14610976578063f2fde38b146109a4578063feaf968c146109ca576102d3565b8063c937450014610940578063d4cc54e414610948578063e2e4031714610950576102d3565b8063b633620c116100c8578063b633620c146108ef578063c10753291461090c578063c35905c614610938576102d3565b8063a4c0ed361461084d578063b5ab58dc146108d2576102d3565b80638205bf6a1161013a5780638da5cb5b1161011f5780638da5cb5b146107b657806398e5b12a146107be5780639a6fc8f5146107e5576102d3565b80638205bf6a1461071b57806388aa80e714610723576102d3565b80637284e4161161016b5780637284e4161461068e57806379ba50971461070b5780637c2b0b2114610713576102d3565b8063668a0f021461067e57806370dea79a14610686576102d3565b806340884c521161023457806357970e93116101e8578063613d8fcc116101cd578063613d8fcc1461062a578063628806ef1461063257806364efb22b14610658576102d3565b806357970e931461061a57806358609e4414610622576102d3565b80634f8fc3b5116102195780634f8fc3b51461060257806350d25bcd1461060a57806354fd4d5014610612576102d3565b806340884c521461058657806346fcff4c146105de576102d3565b8063357ebb021161028b5780633969c20f116102705780633969c20f146104005780633a5381b51461052c5780633d3d771414610550576102d3565b8063357ebb021461039557806338aa4c72146103b6576102d3565b806320ed0275116102bc57806320ed02751461032357806323ca29031461035d578063313ce56714610377576102d3565b80631327d3d8146102d8578063202ee0ed14610300575b600080fd5b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b03166109d2565b005b6102fe6004803603604081101561031657600080fd5b5080359060200135610aa7565b6102fe6004803603606081101561033957600080fd5b5080356001600160a01b03169060208101351515906040013563ffffffff16610c79565b610365610e0e565b60408051918252519081900360200190f35b61037f610e32565b6040805160ff9092168252519081900360200190f35b61039d610e3b565b6040805163ffffffff9092168252519081900360200190f35b6102fe600480360360a08110156103cc57600080fd5b506001600160801b038135169063ffffffff6020820135811691604081013582169160608201358116916080013516610e4e565b6102fe600480360360c081101561041657600080fd5b81019060208101813564010000000081111561043157600080fd5b82018360208201111561044357600080fd5b8035906020019184602083028401116401000000008311171561046557600080fd5b91939092909160208101903564010000000081111561048357600080fd5b82018360208201111561049557600080fd5b803590602001918460208302840111640100000000831117156104b757600080fd5b9193909290916020810190356401000000008111156104d557600080fd5b8201836020820111156104e757600080fd5b8035906020019184602083028401116401000000008311171561050957600080fd5b919350915063ffffffff8135811691602081013582169160409091013516611203565b6105346113e7565b604080516001600160a01b039092168252519081900360200190f35b6102fe6004803603606081101561056657600080fd5b506001600160a01b038135811691602081013590911690604001356113f6565b61058e611612565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156105ca5781810151838201526020016105b2565b505050509050019250505060405180910390f35b6105e6611675565b604080516001600160801b039092168252519081900360200190f35b6102fe611684565b6103656117bd565b6103656117e0565b6105346117e5565b61039d6117f4565b61037f611807565b6102fe6004803603602081101561064857600080fd5b50356001600160a01b031661180d565b6105346004803603602081101561066e57600080fd5b50356001600160a01b0316611916565b610365611940565b61039d611954565b610696611967565b6040805160208082528351818301528351919283929083019185019080838360005b838110156106d05781810151838201526020016106b8565b50505050905090810190601f1680156106fd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102fe6119f5565b610365611ab8565b610365611adc565b6107556004803603604081101561073957600080fd5b5080356001600160a01b0316906020013563ffffffff16611b18565b60408051981515895263ffffffff90971660208901528787019590955267ffffffffffffffff93841660608801529190921660808601526001600160801b0391821660a086015260ff1660c08501521660e083015251908190036101000190f35b610534611c8f565b6107c6611c9e565b6040805169ffffffffffffffffffff9092168252519081900360200190f35b61080e600480360360208110156107fb57600080fd5b503569ffffffffffffffffffff16611dc3565b6040805169ffffffffffffffffffff96871681526020810195909552848101939093526060840191909152909216608082015290519081900360a00190f35b6102fe6004803603606081101561086357600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561089357600080fd5b8201836020820111156108a557600080fd5b803590602001918460018302840111640100000000831117156108c757600080fd5b509092509050611f12565b610365600480360360208110156108e857600080fd5b5035611f73565b6103656004803603602081101561090557600080fd5b5035611fa7565b6102fe6004803603604081101561092257600080fd5b506001600160a01b038135169060200135611fec565b6105e66121c1565b61039d6121d0565b6105e66121e3565b6103656004803603602081101561096657600080fd5b50356001600160a01b03166121f9565b6102fe6004803603604081101561098c57600080fd5b506001600160a01b038135811691602001351661221d565b6102fe600480360360208110156109ba57600080fd5b50356001600160a01b0316612314565b61080e6123d1565b6000546001600160a01b03163314610a31576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6003546001600160a01b039081169082168114610aa3576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384811691821790925560405190918316907fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d90600090a35b5050565b6060610ab3338461240b565b90507f00000000000000000000000000000000000000000000000000005af3107a4000821215610b2a576040805162461bcd60e51b815260206004820152601e60248201527f76616c75652062656c6f77206d696e5375626d697373696f6e56616c75650000604482015290519081900360640190fd5b7f000000000000000000000000000000000000000000084595161401484a000000821315610b9f576040805162461bcd60e51b815260206004820152601e60248201527f76616c75652061626f7665206d61785375626d697373696f6e56616c75650000604482015290519081900360640190fd5b8051819015610c2c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610bf1578181015183820152602001610bd9565b50505050905090810190601f168015610c1e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610c36836126c0565b610c408284612769565b600080610c4c8561285a565b91509150610c59856129db565b610c6285612b39565b8115610c7257610c728582612bb0565b5050505050565b6000546001600160a01b03163314610cd8576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6001600160a01b0383166000908152600b602052604090205460ff1615158215151415610d0457610e09565b8115610d7f576001600160a01b0383166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016831515177fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff841602179055610dbe565b6001600160a01b0383166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000001690555b60408051831515815263ffffffff8316602082015281516001600160a01b038616927fc3df5a754e002718f2e10804b99e6605e7c701d95cec9552c7680ca2b6f2820a928290030190a25b505050565b7f000000000000000000000000000000000000000000084595161401484a00000081565b60055460ff1681565b600454600160c01b900463ffffffff1681565b6000546001600160a01b03163314610ead576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6000610eb7611807565b60ff1690508463ffffffff168463ffffffff161015610f1d576040805162461bcd60e51b815260206004820152601960248201527f6d6178206d75737420657175616c2f657863656564206d696e00000000000000604482015290519081900360640190fd5b8363ffffffff168163ffffffff161015610f7e576040805162461bcd60e51b815260206004820152601760248201527f6d61782063616e6e6f742065786365656420746f74616c000000000000000000604482015290519081900360640190fd5b63ffffffff81161580610f9c57508263ffffffff168163ffffffff16115b610fed576040805162461bcd60e51b815260206004820152601960248201527f64656c61792063616e6e6f742065786365656420746f74616c00000000000000604482015290519081900360640190fd5b610fff866001600160801b0316612cc2565b600d546001600160801b0316101561105e576040805162461bcd60e51b815260206004820152601e60248201527f696e73756666696369656e742066756e647320666f72207061796d656e740000604482015290519081900360640190fd5b6000611068611807565b60ff1611156110cc5760008563ffffffff16116110cc576040805162461bcd60e51b815260206004820152601a60248201527f6d696e206d7573742062652067726561746572207468616e2030000000000000604482015290519081900360640190fd5b85600460006101000a8154816001600160801b0302191690836001600160801b0316021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046001600160801b03166001600160801b03167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b6000546001600160a01b03163314611262576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60005b88811015611299576112918a8a8381811061127c57fe5b905060200201356001600160a01b0316612cf0565b600101611265565b508584146112ee576040805162461bcd60e51b815260206004820181905260248201527f6e6565642073616d65206f7261636c6520616e642061646d696e20636f756e74604482015290519081900360640190fd5b604d61130b876112fc611807565b60ff169063ffffffff612eee16565b111561135e576040805162461bcd60e51b815260206004820152601360248201527f6d6178206f7261636c657320616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b60005b868110156113b1576113a988888381811061137857fe5b905060200201356001600160a01b031687878481811061139457fe5b905060200201356001600160a01b0316612f4f565b600101611361565b506004546113dc906001600160801b03811690859085908590600160e01b900463ffffffff16610e4e565b505050505050505050565b6003546001600160a01b031681565b6001600160a01b0383811660009081526008602052604090206002015462010000900416331461146d576040805162461bcd60e51b815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b6001600160a01b03831660009081526008602052604090205481906001600160801b039081169082168110156114ea576040805162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420776974686472617761626c652066756e647300604482015290519081900360640190fd5b6115036001600160801b0382168363ffffffff61324716565b6001600160a01b038616600090815260086020526040902080546fffffffffffffffffffffffffffffffff19166001600160801b03928316179055600d5461155491600160801b9091041683613247565b600d80546001600160801b03928316600160801b02908316179055600254604080517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015293861660248201529051929091169163a9059cbb916044808201926020929091908290030181600087803b1580156115e057600080fd5b505af11580156115f4573d6000803e3d6000fd5b505050506040513d602081101561160a57600080fd5b5051610c7257fe5b6060600c80548060200260200160405190810160405280929190818152602001828054801561166a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161164c575b505050505090505b90565b600d546001600160801b031690565b61168c614539565b50604080518082018252600d546001600160801b038082168352600160801b90910416602080830182905260025484517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529451939460009461175694936001600160a01b03909316926370a082319260248082019391829003018186803b15801561171e57600080fd5b505afa158015611732573d6000803e3d6000fd5b505050506040513d602081101561174857600080fd5b50519063ffffffff6132b616565b82519091506001600160801b03168114610aa357600d80546fffffffffffffffffffffffffffffffff19166001600160801b03831617905560405181907ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f90600090a25050565b600754640100000000900463ffffffff1660009081526009602052604090205490565b600381565b6002546001600160a01b031681565b600454600160801b900463ffffffff1681565b600c5490565b6001600160a01b0381811660009081526008602052604090206003015416331461187e576040805162461bcd60e51b815260206004820152601e60248201527f6f6e6c792063616c6c61626c652062792070656e64696e672061646d696e0000604482015290519081900360640190fd5b6001600160a01b03811660008181526008602052604080822060038101805473ffffffffffffffffffffffffffffffffffffffff1916905560020180547fffffffffffffffffffff0000000000000000000000000000000000000000ffff16336201000081029190911790915590519092917f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90491a350565b6001600160a01b03808216600090815260086020526040902060020154620100009004165b919050565b600754640100000000900463ffffffff1690565b600454600160e01b900463ffffffff1681565b6006805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156119ed5780601f106119c2576101008083540402835291602001916119ed565b820191906000526020600020905b8154815290600101906020018083116119d057829003601f168201915b505050505081565b6001546001600160a01b03163314611a54576040805162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b7f00000000000000000000000000000000000000000000000000005af3107a400081565b600754640100000000900463ffffffff1660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1690565b600080808080808080333214611b75576040805162461bcd60e51b815260206004820152601660248201527f6f66662d636861696e2072656164696e67206f6e6c7900000000000000000000604482015290519081900360640190fd5b63ffffffff891615611c685763ffffffff89166000908152600960209081526040808320600a909252909120611bab8c8c61330d565b6001600160a01b038d1660009081526008602052604090206001908101548482015491840154600d548f9367ffffffffffffffff169168010000000000000000900463ffffffff16906001600160801b0316611c05611807565b600189015467ffffffffffffffff16611c29576004546001600160801b0316611c48565b60018801546c0100000000000000000000000090046001600160801b03165b8363ffffffff169350995099509950995099509950995099505050611c82565b611c718a613363565b975097509750975097509750975097505b9295985092959890939650565b6000546001600160a01b031681565b336000908152600b602052604081205460ff16611d02576040805162461bcd60e51b815260206004820152601860248201527f6e6f7420617574686f72697a6564207265717565737465720000000000000000604482015290519081900360640190fd5b60075463ffffffff1660008181526009602052604090206001015468010000000000000000900467ffffffffffffffff16151580611d445750611d448161353d565b611d95576040805162461bcd60e51b815260206004820152601f60248201527f7072657620726f756e64206d75737420626520737570657273656461626c6500604482015290519081900360640190fd5b6000611dac63ffffffff808416906001906135d016565b9050611db781613633565b63ffffffff1691505090565b6000806000806000611dd3614550565b5063ffffffff80871660009081526009602090815260409182902082516080810184528154815260019091015467ffffffffffffffff8082169383019390935268010000000000000000810490921692810192909252600160801b90049091166060820181905215801590611e585750611e588769ffffffffffffffffffff16613721565b6040518060400160405280600f81526020017f4e6f20646174612070726573656e74000000000000000000000000000000000081525090611eda5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610bf1578181015183820152602001610bd9565b508051602082015160408301516060909301519899919867ffffffffffffffff91821698509216955063ffffffff9091169350915050565b8015611f65576040805162461bcd60e51b815260206004820181905260248201527f7472616e7366657220646f65736e2774206163636570742063616c6c64617461604482015290519081900360640190fd5b611f6d611684565b50505050565b6000611f7e82613721565b15611f9f575063ffffffff811660009081526009602052604090205461193b565b506000919050565b6000611fb282613721565b15611f9f575063ffffffff811660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1661193b565b6000546001600160a01b0316331461204b576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600d546004546001600160801b0391821691839161207a9161206d9116612cc2565b839063ffffffff6132b616565b10156120cd576040805162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e7420726573657276652066756e6473000000000000604482015290519081900360640190fd5b600254604080517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561213c57600080fd5b505af1158015612150573d6000803e3d6000fd5b505050506040513d602081101561216657600080fd5b50516121b9576040805162461bcd60e51b815260206004820152601560248201527f746f6b656e207472616e73666572206661696c65640000000000000000000000604482015290519081900360640190fd5b610e09611684565b6004546001600160801b031681565b600454600160a01b900463ffffffff1681565b600d54600160801b90046001600160801b031690565b6001600160a01b03166000908152600860205260409020546001600160801b031690565b6001600160a01b03828116600090815260086020526040902060020154620100009004163314612294576040805162461bcd60e51b815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b6001600160a01b03828116600081815260086020908152604091829020600301805473ffffffffffffffffffffffffffffffffffffffff19169486169485179055815133815290810193909352805191927fb79bf2e89c2d70dde91d2991fb1ea69b7e478061ad7c04ed5b02b96bc52b8104929081900390910190a25050565b6000546001600160a01b03163314612373576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060008060006123fa600760049054906101000a900463ffffffff1663ffffffff16611dc3565b945094509450945094509091929394565b6001600160a01b03821660009081526008602052604090205460075460609163ffffffff600160801b909104811691168161247f576040518060400160405280601281526020017f6e6f7420656e61626c6564206f7261636c650000000000000000000000000000815250925050506126ba565b8363ffffffff168263ffffffff1611156124d2576040518060400160405280601681526020017f6e6f742079657420656e61626c6564206f7261636c6500000000000000000000815250925050506126ba565b6001600160a01b03851660009081526008602052604090205463ffffffff808616600160a01b909204161015612541576040518060400160405280601881526020017f6e6f206c6f6e67657220616c6c6f776564206f7261636c650000000000000000815250925050506126ba565b6001600160a01b03851660009081526008602052604090205463ffffffff808616600160c01b90920416106125af576040518060400160405280602081526020017f63616e6e6f74207265706f7274206f6e2070726576696f757320726f756e6473815250925050506126ba565b8063ffffffff168463ffffffff16141580156125eb57506125db63ffffffff808316906001906135d016565b63ffffffff168463ffffffff1614155b80156125fe57506125fc848261372b565b155b15612642576040518060400160405280601781526020017f696e76616c696420726f756e6420746f207265706f7274000000000000000000815250925050506126ba565b8363ffffffff16600114158015612673575061267161266c63ffffffff8087169060019061379116565b6137f4565b155b156126b7576040518060400160405280601f81526020017f70726576696f757320726f756e64206e6f7420737570657273656461626c6500815250925050506126ba565b50505b92915050565b6126c981613834565b6126d257612766565b3360009081526008602052604090205460045463ffffffff600160e01b909204821691600160c01b909104811682019083161180159061271157508015155b1561271c5750612766565b61272582613865565b5033600090815260086020526040902080547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160e01b63ffffffff8416021790555b50565b61277281613a5e565b6127c3576040805162461bcd60e51b815260206004820152601f60248201527f726f756e64206e6f7420616363657074696e67207375626d697373696f6e7300604482015290519081900360640190fd5b63ffffffff81166000818152600a602090815260408083208054600180820183559185528385200187905533808552600890935281842080547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b8702178155018690555190929185917f92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c9190a45050565b63ffffffff8082166000908152600a602052604081206001810154905491928392640100000000909204161115612896575060009050806129d6565b63ffffffff83166000908152600a6020908152604080832080548251818502810185019093528083526128fc938301828280156128f257602002820191906000526020600020905b8154815260200190600101908083116128de575b5050505050613a7e565b63ffffffff851660008181526009602090815260409182902084815560010180547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff8116919091029190911773ffffffff000000000000000000000000000000001916600160801b8602179091556007805467ffffffff000000001916640100000000860217905582519081529151939450919284927f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f928290030190a36001925090505b915091565b63ffffffff81166000908152600a60205260409020600101546c0100000000000000000000000090046001600160801b0316612a15614539565b5060408051808201909152600d546001600160801b03808216808452600160801b909204166020830152612a4f908363ffffffff61324716565b6001600160801b0390811682526020820151612a7291168363ffffffff613b2e16565b6001600160801b0390811660208084018290528351600d8054600160801b9094029185166fffffffffffffffffffffffffffffffff199094169390931784161790915533600090815260089091526040902054612ad691168363ffffffff613b2e16565b3360009081526008602052604080822080546fffffffffffffffffffffffffffffffff19166001600160801b03948516179055835190519216917ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f9190a2505050565b63ffffffff8082166000908152600a602052604090206001810154905491161115612b6357612766565b63ffffffff81166000908152600a6020526040812090612b838282614577565b5060010180547fffffffff0000000000000000000000000000000000000000000000000000000016905550565b6003546001600160a01b031680612bc75750610aa3565b6000612bde63ffffffff8086169060019061379116565b63ffffffff80821660009081526009602090815260408083206001810154905482517fbeed9b51000000000000000000000000000000000000000000000000000000008152600160801b90920486166004830181905260248301829052958b166044830152606482018a90529151959650939490936001600160a01b0388169363beed9b5193620186a093608480850194929391928390030190829088803b158015612c8957600080fd5b5087f193505050508015612caf57506040513d6020811015612caa57600080fd5b505160015b612cb857612cba565b505b505050505050565b60006126ba6002612ce4612cd4611807565b859060ff1663ffffffff613b9416565b9063ffffffff613b9416565b612cf981613bed565b612d4a576040805162461bcd60e51b815260206004820152601260248201527f6f7261636c65206e6f7420656e61626c65640000000000000000000000000000604482015290519081900360640190fd5b600754612d639063ffffffff908116906001906135d016565b6001600160a01b0382166000908152600860205260408120805463ffffffff93909316600160a01b027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff90931692909217909155600c612dd56001612dc6611807565b60ff169063ffffffff6132b616565b81548110612ddf57fe5b6000918252602080832091909101546001600160a01b0385811680855260089093526040808520600290810180549390941680875291862001805461ffff90931661ffff199384168117909155939094528154169055600c8054929350909183919083908110612e4b57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600c805480612e8457fe5b6000828152602081208201600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559091019091556040516001600160a01b038516907f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e908390a3505050565b600082820183811015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b612f5882613bed565b15612faa576040805162461bcd60e51b815260206004820152601660248201527f6f7261636c6520616c726561647920656e61626c656400000000000000000000604482015290519081900360640190fd5b6001600160a01b038116613005576040805162461bcd60e51b815260206004820152601560248201527f63616e6e6f74207365742061646d696e20746f20300000000000000000000000604482015290519081900360640190fd5b6001600160a01b0382811660009081526008602052604090206002015462010000900416158061305a57506001600160a01b038281166000908152600860205260409020600201546201000090048116908216145b6130ab576040805162461bcd60e51b815260206004820152601c60248201527f6f776e65722063616e6e6f74206f76657277726974652061646d696e00000000604482015290519081900360640190fd5b6130b482613c18565b6001600160a01b0380841660008181526008602052604080822080547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff63ffffffff97909716600160801b0273ffffffff0000000000000000000000000000000019909116179590951677ffffffff0000000000000000000000000000000000000000178555600c80546002909601805461ffff90971661ffff19909716969096178655805460018181019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805473ffffffffffffffffffffffffffffffffffffffff191685179055838352855494871662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909516949094179094559251919290917f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e9190a3806001600160a01b0316826001600160a01b03167f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90460405160405180910390a35050565b6000826001600160801b0316826001600160801b031611156132b0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000828211156132b0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b63ffffffff811660009081526009602052604081206001015467ffffffffffffffff16156133595761333e82613a5e565b8015613352575061334f838361240b565b51155b90506126ba565b61333e8383613c7b565b6001600160a01b0381166000908152600860205260408120600754815483928392839283928392839283927fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b929091849163ffffffff908116600160c01b9092041614806133e057506007546133de9063ffffffff16613a5e565b155b6007549091506133f59063ffffffff166137f4565b80156133fe5750805b156134575760075461341c9063ffffffff908116906001906135d016565b63ffffffff81166000908152600960205260409020600454919b506001600160801b03909116945092506134508c8b613c7b565b9a506134aa565b60075463ffffffff166000818152600960209081526040808320600a90925290912060010154919b506c010000000000000000000000009091046001600160801b0316945092506134a78a613a5e565b9a505b6134b48c8b61240b565b51156134bf5760009a505b6001808301548482015463ffffffff808e166000908152600a6020526040902090930154600d548f948f949367ffffffffffffffff169268010000000000000000900416906001600160801b0316613515611807565b8a8363ffffffff1693509a509a509a509a509a509a509a509a50505050919395975091939597565b63ffffffff8082166000908152600960209081526040808320600190810154600a9093529083200154919267ffffffffffffffff90911691680100000000000000009004168115801590613597575060008163ffffffff16115b80156135c85750426135bc67ffffffffffffffff841663ffffffff80851690613cc516565b67ffffffffffffffff16105b949350505050565b600082820163ffffffff8085169082161015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b61363c81613834565b61364557612766565b336000908152600b602052604090205463ffffffff650100000000008204811691610100900481168201908316118061367c575080155b6136cd576040805162461bcd60e51b815260206004820152601360248201527f6d7573742064656c617920726571756573747300000000000000000000000000604482015290519081900360640190fd5b6136d682613865565b50336000908152600b60205260409020805463ffffffff831665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90911617905550565b63ffffffff101590565b60008163ffffffff1661374e60018563ffffffff166135d090919063ffffffff16565b63ffffffff16148015612f4857505063ffffffff1660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1615919050565b60008263ffffffff168263ffffffff1611156132b0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b63ffffffff811660009081526009602052604081206001015468010000000000000000900467ffffffffffffffff161515806126ba57506126ba8261353d565b6007546000906138509063ffffffff908116906001906135d016565b63ffffffff168263ffffffff16149050919050565b61388261387d63ffffffff8084169060019061379116565b613d2c565b6007805463ffffffff191663ffffffff831617905561389f614595565b5060408051600060a0820181815260c083018452825260045463ffffffff600160801b82048116602080860191909152600160a01b8304821685870152600160e01b8304821660608601526001600160801b03909216608085015285168252600a8152929020815180519293849361391a92849201906145c3565b5060208281015160019283018054604080870151606088015160809098015163ffffffff1990931663ffffffff9586161767ffffffff00000000191664010000000091861691909102177fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000097851697909702969096177fffffffff00000000000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006001600160801b0390921691909102179055851660008181526009835284902090920180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff9081169190911791829055845191168152925133937f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac6027192908290030190a35050565b63ffffffff9081166000908152600a602052604090206001015416151590565b60008151600010613ad6576040805162461bcd60e51b815260206004820152601660248201527f6c697374206d757374206e6f7420626520656d70747900000000000000000000604482015290519081900360640190fd5b81516002810460018216613b1557600080613afb866000600187036001870387613e2d565b9092509050613b0a8282613f0b565b94505050505061193b565b613b258460006001850384613f79565b9250505061193b565b60008282016001600160801b038085169082161015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082613ba3575060006126ba565b82820282848281613bb057fe5b0414612f485760405162461bcd60e51b815260040180806020018281038252602181526020018061464a6021913960400191505060405180910390fd5b6001600160a01b031660009081526008602052604090205463ffffffff600160a01b90910481161490565b60075460009063ffffffff168015801590613c5a57506001600160a01b03831660009081526008602052604090205463ffffffff828116600160a01b90920416145b15613c6657905061193b565b612f4863ffffffff808316906001906135d016565b6001600160a01b03821660009081526008602052604081205460045463ffffffff600160e01b909204821691600160c01b9091048116820190841611806135c85750159392505050565b600082820167ffffffffffffffff8085169082161015612f48576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b613d358161353d565b613d3e57612766565b6000613d5563ffffffff8084169060019061379116565b63ffffffff8181166000908152600960209081526040808320805488861685528285209081556001918201549101805473ffffffff000000000000000000000000000000001916600160801b92839004909616909102949094177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff160217909355600a9052908120919250613dff8282614577565b5060010180547fffffffff000000000000000000000000000000000000000000000000000000001690555050565b600080828410613e3c57600080fd5b838611158015613e4c5750848411155b613e5557600080fd5b828611158015613e655750848311155b613e6e57600080fd5b60078686031015613e8f57613e86878787878761400a565b91509150613f01565b6000613e9c8888886143f7565b9050808411613ead57809550613efb565b84811015613ec057806001019650613efb565b808511158015613ecf57508381105b613ed557fe5b613ee188888388613f79565b9250613ef288826001018887613f79565b9150613f019050565b50613e6e565b9550959350505050565b60008083128015613f1c5750600082135b80613f325750600083138015613f325750600082125b15613f52576002613f4384846144d4565b81613f4a57fe5b0590506126ba565b60006002808507818507010590506135c8613f7360028605600286056144d4565b826144d4565b600081841115613f8857600080fd5b82821115613f9557600080fd5b82841015613fec5760078484031015613fc1576000613fb7868686868761400a565b5091506135c89050565b6000613fce8686866143f7565b9050808311613fdf57809350613fe6565b8060010194505b50613f95565b848481518110613ff857fe5b60200260200101519050949350505050565b60008060008686600101039050600088886000018151811061402857fe5b60200260200101519050600082600110614049576001600160ff1b03614061565b89896001018151811061405857fe5b60200260200101515b905060008360021061407a576001600160ff1b03614092565b8a8a6002018151811061408957fe5b60200260200101515b90506000846003106140ab576001600160ff1b036140c3565b8b8b600301815181106140ba57fe5b60200260200101515b90506000856004106140dc576001600160ff1b036140f4565b8c8c600401815181106140eb57fe5b60200260200101515b905060008660051061410d576001600160ff1b03614125565b8d8d6005018151811061411c57fe5b60200260200101515b905060008760061061413e576001600160ff1b03614156565b8e8e6006018151811061414d57fe5b60200260200101515b905085871315614164579495945b83851315614170579293925b8183131561417c579091905b84871315614188579395935b83861315614194579294925b8083131561419e57915b848613156141aa579394935b808213156141b457905b828713156141c0579195915b818613156141cc579094905b808513156141d657935b828613156141e2579194915b808413156141ec57925b828513156141f8579193915b81841315614204579092905b82841315614210579192915b8d8c038061422057879a506142d3565b806001141561423157869a506142d3565b806002141561424257859a506142d3565b806003141561425357849a506142d3565b806004141561426457839a506142d3565b806005141561427557829a506142d3565b806006141561428657819a506142d3565b6040805162461bcd60e51b815260206004820152601060248201527f6b31206f7574206f6620626f756e647300000000000000000000000000000000604482015290519081900360640190fd5b8e8c038d8d14156142f157508a9950613f0198505050505050505050565b806143085750969850613f01975050505050505050565b80600114156143235750959850613f01975050505050505050565b806002141561433e5750949850613f01975050505050505050565b80600314156143595750939850613f01975050505050505050565b80600414156143745750929850613f01975050505050505050565b806005141561438f5750919850613f01975050505050505050565b80600614156143aa5750909850613f01975050505050505050565b6040805162461bcd60e51b815260206004820152601060248201527f6b32206f7574206f6620626f756e647300000000000000000000000000000000604482015290519081900360640190fd5b600080846002858501048151811061440b57fe5b602002602001015190506001840393506001830192505b6001840193508085858151811061443557fe5b602002602001015112614422575b6001830392508085848151811061445657fe5b60200260200101511361444357828410156144c65784838151811061447757fe5b602002602001015185858151811061448b57fe5b602002602001015186868151811061449f57fe5b602002602001018786815181106144b257fe5b6020908102919091010191909152526144cf565b82915050612f48565b614422565b60008282018183128015906144e95750838112155b806144fe57506000831280156144fe57508381125b612f485760405162461bcd60e51b81526004018080602001828103825260218152602001806146296021913960400191505060405180910390fd5b604080518082019091526000808252602082015290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5080546000825590600052602060002090810190612766919061460e565b6040805160a08101825260608082526000602083018190529282018390528101829052608081019190915290565b8280548282559060005260206000209081019282156145fe579160200282015b828111156145fe5782518255916020019190600101906145e3565b5061460a92915061460e565b5090565b61167291905b8082111561460a576000815560010161461456fe5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122040e1f6236541e7eeeba27f9d0f0a3ec266fea6447f080ce6be636a3381af280964736f6c63430006060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000b44726f70732d4265616e7a000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _link (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [1] : _paymentAmount (uint128): 10000000000000000
Arg [2] : _timeout (uint32): 100
Arg [3] : _validator (address): 0x0000000000000000000000000000000000000000
Arg [4] : _minSubmissionValue (int256): 100000000000000
Arg [5] : _maxSubmissionValue (int256): 10000000000000000000000000
Arg [6] : _decimals (uint8): 18
Arg [7] : _description (string): Drops-Beanz
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [1] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 00000000000000000000000000000000000000000000000000005af3107a4000
Arg [5] : 000000000000000000000000000000000000000000084595161401484a000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000b
Arg [9] : 44726f70732d4265616e7a000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$7.37
Net Worth in ETH
0.003542
Token Allocations
LINK
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $9.21 | 0.8 | $7.37 |
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.