Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- AccessControlledOffchainAggregator
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 20000
- EVM Version
- default
- Verified at
- 2022-03-19T13:31:33.163574Z
Constructor Arguments
000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000094d4a54202f205553440000000000000000000000000000000000000000000000
Arg [0] (uint8) : 95
Arg [1] (uint8) : 105
Arg [2] (uint8) : 8
Arg [3] (string) : MJT / USD
Contract source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
interface AccessControllerInterface {
function hasAccess(address user, bytes calldata data) external view returns (bool);
}
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);
}
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
// getRoundData and latestRoundData should both raise "No data present"
// if they do not have data to report, instead of returning unset values
// which could be misinterpreted as actual reported values.
function getRoundData(uint80 _roundId)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
// File contracts/interfaces/AggregatorV2V3Interface.sol
interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}
// File contracts/interfaces/TypeAndVersionInterface.sol
abstract contract TypeAndVersionInterface {
function typeAndVersion() external pure virtual returns (string memory);
}
// File contracts/interfaces/OwnableInterface.sol
interface OwnableInterface {
function owner() external returns (address);
function transferOwnership(address recipient) external;
function acceptOwnership() external;
}
// File contracts/ConfirmedOwnerWithProposal.sol
/**
* @title The ConfirmedOwner contract
* @notice A contract with helpers for basic contract ownership.
*/
contract ConfirmedOwnerWithProposal is OwnableInterface {
address private s_owner;
address private s_pendingOwner;
event OwnershipTransferRequested(address indexed from, address indexed to);
event OwnershipTransferred(address indexed from, address indexed to);
constructor(address newOwner, address pendingOwner) {
require(newOwner != address(0), "Cannot set owner to zero");
s_owner = newOwner;
if (pendingOwner != address(0)) {
_transferOwnership(pendingOwner);
}
}
/**
* @notice Allows an owner to begin transferring ownership to a new address,
* pending.
*/
function transferOwnership(address to) public override onlyOwner {
_transferOwnership(to);
}
/**
* @notice Allows an ownership transfer to be completed by the recipient.
*/
function acceptOwnership() external override {
require(msg.sender == s_pendingOwner, "Must be proposed owner");
address oldOwner = s_owner;
s_owner = msg.sender;
s_pendingOwner = address(0);
emit OwnershipTransferred(oldOwner, msg.sender);
}
/**
* @notice Get the current owner
*/
function owner() public view override returns (address) {
return s_owner;
}
/**
* @notice validate, transfer ownership, and emit relevant events
*/
function _transferOwnership(address to) private {
require(to != msg.sender, "Cannot transfer to self");
s_pendingOwner = to;
emit OwnershipTransferRequested(s_owner, to);
}
/**
* @notice validate access
*/
function _validateOwnership() internal view {
require(msg.sender == s_owner, "Only callable by owner");
}
/**
* @notice Reverts if called by anyone other than the contract owner.
*/
modifier onlyOwner() {
_validateOwnership();
_;
}
}
// File contracts/ConfirmedOwner.sol
/**
* @title The ConfirmedOwner contract
* @notice A contract with helpers for basic contract ownership.
*/
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}
// File contracts/OwnerIsCreator.sol
/**
* @title The OwnerIsCreator contract
* @notice A contract with helpers for basic contract ownership.
*/
contract OwnerIsCreator is ConfirmedOwner {
constructor() ConfirmedOwner(msg.sender) {}
}
// File contracts/SafeMath.sol
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the 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;
}
}
// File contracts/OffchainAggregator.sol
/**
* @notice Onchain verification of reports from the offchain reporting protocol
* @dev For details on its operation, see the offchain reporting protocol design
* @dev doc, which refers to this contract as simply the "contract".
*/
contract OffchainAggregator is OwnerIsCreator, AggregatorV2V3Interface, TypeAndVersionInterface {
using SafeMath for uint256;
// Storing these fields used on the hot path in a HotVars variable reduces the
// retrieval of all of them to a single SLOAD. If any further fields are
// added, make sure that storage of the struct still takes at most 32 bytes.
struct HotVars {
// Oracle Aggregators expose a roundId to consumers. The offchain reporting
// protocol does not use this id anywhere. We increment it whenever a new
// transmission is made to provide callers with contiguous ids for successive
// reports.
uint32 latestAggregatorRoundId;
}
HotVars internal s_hotVars;
// Transmission records the median answer from the transmit transaction at 发送中位数结果
// time timestamp
struct Transmission {
int192 answer; // 192 bits ought to be enough for anyone
uint32 observationsTimestamp; // when were observations made offchain
uint32 transmissionTimestamp; // when was report received onchain
}
mapping(uint32 => Transmission) /* aggregator round ID */
internal s_transmissions;
// incremented each time a new config is posted. This count is incorporated
// into the config digest to prevent replay attacks.
uint32 internal s_configCount;
// makes it easier for offchain systems to extract config from logs
uint32 internal s_latestConfigBlockNumber;
// makes it easier for offchain systems to extract config from logs
address internal s_latestTransmitter;
uint8 public lowerBoundAnchorRatio; //0.8e2
uint8 public upperBoundAnchorRatio; //1.2e2
uint8 internal constant minLowerBoundAnchorRatio = 0.8e2;
uint8 internal constant maxUpperBoundAnchorRatio = 1.2e2;
struct Transmitter {
bool active;
// Index of oracle in s_signersList/s_transmittersList
uint8 index;
}
mapping(address => Transmitter) /* transmitter address */
internal s_transmitters;
struct Signer {
bool active;
// Index of oracle in s_signersList/s_transmittersList
uint8 index;
}
mapping(address => Signer) /* signer address */
internal s_signers;
// s_signersList contains the signing address of each oracle
address[] internal s_signersList;
// s_transmittersList contains the transmission address of each oracle,
// i.e. the address the oracle actually sends transactions to the contract from
address[] internal s_transmittersList;
/*
* @param _minAnswer lowest answer the median of a report is allowed to be
* @param _maxAnswer highest answer the median of a report is allowed to be
* @param _decimals answers are stored in fixed-point format, with this many digits of precision
* @param _description short human-readable description of observable this contract's answers pertain to
*/
constructor(
uint8 _lowerBoundAnchorRatio,
uint8 _upperBoundAnchorRatio,
uint8 _decimals,
string memory _description
) {
lowerBoundAnchorRatio = _lowerBoundAnchorRatio;
upperBoundAnchorRatio = _upperBoundAnchorRatio;
decimals = _decimals;
s_description = _description;
}
/*
* Versioning
*/
function typeAndVersion() external pure virtual override returns (string memory) {
return "OffchainAggregator 1.0.0";
}
/*
* AnchorRatio logic
*/
event AnchorRatioUpdated(uint8 lowerBoundAnchorRatio, uint8 upperBoundAnchorRatio);
function setAnchorRatio(uint8 _lowerBoundAnchorRatio, uint8 _upperBoundAnchorRatio) external onlyOwner {
require(
minLowerBoundAnchorRatio <= _lowerBoundAnchorRatio,
"lowerBoundAnchorRatio must greater or equal to minLowerBoundAnchorRatio"
);
require(
maxUpperBoundAnchorRatio >= _upperBoundAnchorRatio,
"upperBoundAnchorRatio must Less than or equal to maxUpperBoundAnchorRatio"
);
require(
_upperBoundAnchorRatio > _lowerBoundAnchorRatio,
"upperBoundAnchorRatio must Less than lowerBoundAnchorRatio"
);
lowerBoundAnchorRatio = _lowerBoundAnchorRatio;
upperBoundAnchorRatio = _upperBoundAnchorRatio;
emit AnchorRatioUpdated(lowerBoundAnchorRatio, upperBoundAnchorRatio);
}
/*
* Config logic
*/
/**
* @notice triggers a new run of the offchain reporting protocol
* @param previousConfigBlockNumber block in which the previous config was set, to simplify historic analysis
* @param configCount ordinal number of this config setting among all config settings over the life of this contract
* @param signers ith element is address ith oracle uses to sign a report
* @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method
*/
event ConfigSet(uint32 previousConfigBlockNumber, uint64 configCount, address[] signers, address[] transmitters);
/**
* @notice sets offchain reporting protocol configuration incl. participating oracles
* @param _transmitters addresses oracles use to transmit the reports
*/
function setConfig(address[] calldata _signers, address[] calldata _transmitters) external onlyOwner {
require(_signers.length == _transmitters.length, "oracle length mismatch");
// remove any old signer/transmitter addresses
uint256 oldLength = s_signersList.length;
for (uint256 i = 0; i < oldLength; i++) {
address signer = s_signersList[i];
address transmitter = s_transmittersList[i];
delete s_signers[signer];
delete s_transmitters[transmitter];
}
delete s_signersList;
delete s_transmittersList;
// add new signer/transmitter addresses
for (uint256 i = 0; i < _signers.length; i++) {
require(!s_signers[_signers[i]].active, "repeated signer address");
s_signers[_signers[i]] = Signer({active: true, index: uint8(i)});
require(!s_transmitters[_transmitters[i]].active, "repeated transmitter address");
s_transmitters[_transmitters[i]] = Transmitter({active: true, index: uint8(i)});
}
s_signersList = _signers;
s_transmittersList = _transmitters;
uint32 previousConfigBlockNumber = s_latestConfigBlockNumber;
s_latestConfigBlockNumber = uint32(block.number);
s_configCount += 1;
emit ConfigSet(previousConfigBlockNumber, s_configCount, _signers, _transmitters);
}
/**
* @notice information about current offchain reporting protocol configuration
* @return configCount ordinal number of current config, out of all configs applied to this contract so far
* @return blockNumber block at which this config was set
*/
function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber) {
return (s_configCount, s_latestConfigBlockNumber);
}
/**
* @return list of addresses permitted to transmit reports to this contract
* @dev The list will match the order used to specify the transmitter during setConfig
*/
function getTransmitters() external view returns (address[] memory) {
return s_transmittersList;
}
/*
* Transmission logic
*/
/**
* @notice indicates that a new report was transmitted
* @param aggregatorRoundId the round to which this report was assigned
* @param answer median of the observations attached this report
* @param transmitter address from which the report was transmitted
* @param observationsTimestamp when were observations made offchain
*/
event NewTransmission(
uint32 indexed aggregatorRoundId,
int192 answer,
address transmitter,
uint32 observationsTimestamp
);
/*
* @notice details about the most transmission details
* @return nextTransmitter who will be next to transmit the report
* @return afterNextTransmitter who will transmit the report next afterwards
* @return nextIndex the index of the next transmitter
* @return length the length of the s_transmittersList
* @return roundId aggregator round of latest report
* @return answer median value from latest report
* @return startedAt when the latest report was transmitted
* @return updatedAt when the latest report was transmitted
*/
function latestTransmissionDetails()
external
view
returns (
address nextTransmitter,
address afterNextTransmitter,
uint8 nextIndex,
uint256 transmittersLength,
uint80 roundId,
int192 answer,
uint256 startedAt,
uint256 updatedAt
)
{
require(msg.sender == tx.origin, "Only callable by EOA");
nextIndex = 0;
uint8 afterNextIndex = 0;
// Calculating the index of the next transmitter
uint256 s_length = s_transmittersList.length;
if (s_length > 0) {
// the index of the current transmitter
Transmitter memory s_transmitter;
s_transmitter = s_transmitters[s_latestTransmitter];
if (s_transmitter.active) {
nextIndex = s_transmitter.index;
nextIndex++;
if (s_length == nextIndex) {
nextIndex = 0;
}
}
afterNextIndex = nextIndex;
afterNextIndex++;
if (s_length == afterNextIndex) {
afterNextIndex = 0;
}
nextTransmitter = s_transmittersList[nextIndex];
afterNextTransmitter = s_transmittersList[afterNextIndex];
}
roundId = s_hotVars.latestAggregatorRoundId;
Transmission memory transmission = s_transmissions[uint32(roundId)];
return (
nextTransmitter,
afterNextTransmitter,
nextIndex,
s_length,
roundId,
transmission.answer,
transmission.observationsTimestamp,
transmission.transmissionTimestamp
);
}
// The constant-length components of the msg.data sent to transmit.
// See the "If we wanted to call sam" example on for example reasoning
// https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html
uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT =
4 + // function selector
32 + // word containing start location of abiencoded _report value
32 + // _rs value
32 + // _ss value
32 + // _vs value
32 + // word containing length of _report
0; // placeholder
function expectedMsgDataLength() private pure returns (uint256 length) {
// calldata will never be big enough to make this overflow
return
uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) +
64 + // one byte pure entry in _report
0; // placeholder
}
/**
* @notice transmit is called to post a new report to the contract
* @param _report serialized report, which the signatures are signing. See parsing code below for format.
* @param _rs the R components of the signature on report.
* @param _ss the S components of the signature on report.
* @param _vs the V component of the signature on report.
*/
function transmit(
// NOTE: If these parameters are changed, expectedMsgDataLength and/or
// TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly
bytes calldata _report,
// ECDSA signature
bytes32 _rs,
bytes32 _ss,
uint8 _vs
) external {
require(s_transmitters[msg.sender].active, "unauthorized transmitter");
require(msg.data.length == expectedMsgDataLength(), "transmit message length mismatch");
uint192 median;
uint32 observationsTimestamp;
(median, observationsTimestamp) = abi.decode(_report, (uint192, uint32));
uint32 s_latestTimestamp = s_transmissions[s_hotVars.latestAggregatorRoundId].transmissionTimestamp;
require(observationsTimestamp > s_latestTimestamp, "invalid observations timestamp");
// Verify signatures attached to report
{
bytes32 h = keccak256(_report);
Signer memory signer;
address signerAddress = ecrecover(h, _vs + 27, _rs, _ss);
signer = s_signers[signerAddress];
require(signer.active, "signature error");
}
uint256 previousAnswer = uint192(s_transmissions[s_hotVars.latestAggregatorRoundId].answer);
if (previousAnswer > 0) {
uint256 minAnswer = previousAnswer.mul(lowerBoundAnchorRatio).div(1e2);
uint256 maxAnswer = previousAnswer.mul(upperBoundAnchorRatio).div(1e2);
require(minAnswer <= median && median <= maxAnswer, "median is out of min-max range");
}
_transmit(int192(median), observationsTimestamp);
}
function transmitWithForce(uint192 median) external onlyOwner {
_transmit(int192(median), uint32(block.timestamp));
}
function _transmit(int192 median, uint32 observationsTimestamp) internal {
HotVars memory hotVars = s_hotVars; // cache read from storage
hotVars.latestAggregatorRoundId++;
s_transmissions[hotVars.latestAggregatorRoundId] = Transmission({
answer: median,
observationsTimestamp: observationsTimestamp,
transmissionTimestamp: uint32(block.timestamp)
});
s_latestTransmitter = msg.sender;
emit NewTransmission(hotVars.latestAggregatorRoundId, median, msg.sender, observationsTimestamp);
// Emit these for backwards compatability with offchain consumers
// that only support legacy events
emit NewRound(
hotVars.latestAggregatorRoundId,
address(0x0), // use zero address since we don't have anybody "starting" the round here
observationsTimestamp
);
emit AnswerUpdated(median, hotVars.latestAggregatorRoundId, block.timestamp);
// persist updates to hotVars
s_hotVars = hotVars;
}
/*
* v2 Aggregator interface
*/
/**
* @notice median from the most recent report
*/
function latestAnswer() public view virtual override returns (int256) {
return s_transmissions[s_hotVars.latestAggregatorRoundId].answer;
}
/**
* @notice timestamp of block in which last report was transmitted
*/
function latestTimestamp() public view virtual override returns (uint256) {
return s_transmissions[s_hotVars.latestAggregatorRoundId].transmissionTimestamp;
}
/**
* @notice Aggregator round (NOT OCR round) in which last report was transmitted
*/
function latestRound() public view virtual override returns (uint256) {
return s_hotVars.latestAggregatorRoundId;
}
/**
* @notice median of report from given aggregator round (NOT OCR round)
* @param _roundId the aggregator round of the target report
*/
function getAnswer(uint256 _roundId) public view virtual override returns (int256) {
if (_roundId > 0xFFFFFFFF) {
return 0;
}
return s_transmissions[uint32(_roundId)].answer;
}
/**
* @notice timestamp of block in which report from given aggregator round was transmitted
* @param _roundId aggregator round (NOT OCR round) of target report
*/
function getTimestamp(uint256 _roundId) public view virtual override returns (uint256) {
if (_roundId > 0xFFFFFFFF) {
return 0;
}
return s_transmissions[uint32(_roundId)].transmissionTimestamp;
}
/*
* v3 Aggregator interface
*/
string private constant V3_NO_DATA_ERROR = "No data present";
/**
* @return answers are stored in fixed-point format, with this many digits of precision
*/
uint8 public immutable override decimals;
/**
* @notice aggregator contract version
*/
uint256 public constant override version = 1;
string internal s_description;
/**
* @notice human-readable description of observable this contract is reporting on
*/
function description() public view virtual override returns (string memory) {
return s_description;
}
/**
* @notice details for the given aggregator round
* @param _roundId target aggregator round (NOT OCR round). Must fit in uint32
* @return roundId _roundId
* @return answer median of report from given _roundId
* @return startedAt timestamp of block in which report from given _roundId was transmitted
* @return updatedAt timestamp of block in which report from given _roundId was transmitted
* @return answeredInRound _roundId
*/
function getRoundData(uint80 _roundId)
public
view
virtual
override
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{
require(_roundId <= 0xFFFFFFFF, V3_NO_DATA_ERROR);
Transmission memory transmission = s_transmissions[uint32(_roundId)];
return (
_roundId,
transmission.answer,
transmission.observationsTimestamp,
transmission.transmissionTimestamp,
_roundId
);
}
/**
* @notice aggregator details for the most recently transmitted report
* @return roundId aggregator round of latest report (NOT OCR round)
* @return answer median of latest report
* @return startedAt timestamp of block containing latest report
* @return updatedAt timestamp of block containing latest report
* @return answeredInRound aggregator round of latest report
*/
function latestRoundData()
public
view
virtual
override
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{
roundId = s_hotVars.latestAggregatorRoundId;
// Skipped for compatability with existing FluxAggregator in which latestRoundData never reverts.
// require(roundId != 0, V3_NO_DATA_ERROR);
Transmission memory transmission = s_transmissions[uint32(roundId)];
return (
roundId,
transmission.answer,
transmission.observationsTimestamp,
transmission.transmissionTimestamp,
roundId
);
}
}
// File contracts/SimpleWriteAccessController.sol
/**
* @title SimpleWriteAccessController
* @notice Gives access to accounts explicitly added to an access list by the
* controller's owner.
* @dev does not make any special permissions for externally, see
* SimpleReadAccessController for that.
*/
contract SimpleWriteAccessController is AccessControllerInterface, OwnerIsCreator {
bool public checkEnabled;
mapping(address => bool) internal accessList;
event AddedAccess(address user);
event RemovedAccess(address user);
event CheckAccessEnabled();
event CheckAccessDisabled();
constructor() {
checkEnabled = true;
}
/**
* @notice Returns the access of an address
* @param _user The address to query
*/
function hasAccess(address _user, bytes memory) public view virtual override returns (bool) {
return accessList[_user] || !checkEnabled;
}
/**
* @notice Adds an address to the access list
* @param _user The address to add
*/
function addAccess(address _user) external onlyOwner {
if (!accessList[_user]) {
accessList[_user] = true;
emit AddedAccess(_user);
}
}
/**
* @notice Removes an address from the access list
* @param _user The address to remove
*/
function removeAccess(address _user) external onlyOwner {
if (accessList[_user]) {
accessList[_user] = false;
emit RemovedAccess(_user);
}
}
/**
* @notice makes the access check enforced
*/
function enableAccessCheck() external onlyOwner {
if (!checkEnabled) {
checkEnabled = true;
emit CheckAccessEnabled();
}
}
/**
* @notice makes the access check unenforced
*/
function disableAccessCheck() external onlyOwner {
if (checkEnabled) {
checkEnabled = false;
emit CheckAccessDisabled();
}
}
/**
* @dev reverts if the caller does not have access
*/
modifier checkAccess() {
require(hasAccess(msg.sender, msg.data), "No access");
_;
}
}
// File contracts/SimpleReadAccessController.sol
/**
* @title SimpleReadAccessController
* @notice Gives access to:
* - any externally owned account (note that offchain actors can always read
* any contract storage regardless of onchain access control measures, so this
* does not weaken the access control while improving usability)
* - accounts explicitly added to an access list
* @dev SimpleReadAccessController is not suitable for access controlling writes
* since it grants any externally owned account access! See
* SimpleWriteAccessController for that.
*/
contract SimpleReadAccessController is SimpleWriteAccessController {
/**
* @notice Returns the access of an address
* @param _user The address to query
*/
function hasAccess(address _user, bytes memory _calldata) public view virtual override returns (bool) {
return super.hasAccess(_user, _calldata) || _user == tx.origin;
}
}
// File contracts/AccessControlledOffchainAggregator.sol
/**
* @notice Wrapper of OffchainAggregator which checks read access on Aggregator-interface methods
*/
contract AccessControlledOffchainAggregator is OffchainAggregator, SimpleReadAccessController {
constructor(
uint8 _lowerBoundAnchorRatio,
uint8 _upperBoundAnchorRatio,
uint8 _decimals,
string memory _description
) OffchainAggregator(_lowerBoundAnchorRatio, _upperBoundAnchorRatio, _decimals, _description) {}
/*
* Versioning
*/
function typeAndVersion() external pure virtual override returns (string memory) {
return "AccessControlledOffchainAggregator 1.0.0";
}
/*
* v2 Aggregator interface
*/
/// @inheritdoc OffchainAggregator
function latestAnswer() public view override checkAccess returns (int256) {
return super.latestAnswer();
}
/// @inheritdoc OffchainAggregator
function latestTimestamp() public view override checkAccess returns (uint256) {
return super.latestTimestamp();
}
/// @inheritdoc OffchainAggregator
function latestRound() public view override checkAccess returns (uint256) {
return super.latestRound();
}
/// @inheritdoc OffchainAggregator
function getAnswer(uint256 _roundId) public view override checkAccess returns (int256) {
return super.getAnswer(_roundId);
}
/// @inheritdoc OffchainAggregator
function getTimestamp(uint256 _roundId) public view override checkAccess returns (uint256) {
return super.getTimestamp(_roundId);
}
/*
* v3 Aggregator interface
*/
/// @inheritdoc OffchainAggregator
function description() public view override checkAccess returns (string memory) {
return super.description();
}
/// @inheritdoc OffchainAggregator
function getRoundData(uint80 _roundId)
public
view
override
checkAccess
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{
return super.getRoundData(_roundId);
}
/// @inheritdoc OffchainAggregator
function latestRoundData()
public
view
override
checkAccess
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{
return super.latestRoundData();
}
}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"uint8","name":"_lowerBoundAnchorRatio","internalType":"uint8"},{"type":"uint8","name":"_upperBoundAnchorRatio","internalType":"uint8"},{"type":"uint8","name":"_decimals","internalType":"uint8"},{"type":"string","name":"_description","internalType":"string"}]},{"type":"event","name":"AddedAccess","inputs":[{"type":"address","name":"user","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"AnchorRatioUpdated","inputs":[{"type":"uint8","name":"lowerBoundAnchorRatio","internalType":"uint8","indexed":false},{"type":"uint8","name":"upperBoundAnchorRatio","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"AnswerUpdated","inputs":[{"type":"int256","name":"current","internalType":"int256","indexed":true},{"type":"uint256","name":"roundId","internalType":"uint256","indexed":true},{"type":"uint256","name":"updatedAt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"CheckAccessDisabled","inputs":[],"anonymous":false},{"type":"event","name":"CheckAccessEnabled","inputs":[],"anonymous":false},{"type":"event","name":"ConfigSet","inputs":[{"type":"uint32","name":"previousConfigBlockNumber","internalType":"uint32","indexed":false},{"type":"uint64","name":"configCount","internalType":"uint64","indexed":false},{"type":"address[]","name":"signers","internalType":"address[]","indexed":false},{"type":"address[]","name":"transmitters","internalType":"address[]","indexed":false}],"anonymous":false},{"type":"event","name":"NewRound","inputs":[{"type":"uint256","name":"roundId","internalType":"uint256","indexed":true},{"type":"address","name":"startedBy","internalType":"address","indexed":true},{"type":"uint256","name":"startedAt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"NewTransmission","inputs":[{"type":"uint32","name":"aggregatorRoundId","internalType":"uint32","indexed":true},{"type":"int192","name":"answer","internalType":"int192","indexed":false},{"type":"address","name":"transmitter","internalType":"address","indexed":false},{"type":"uint32","name":"observationsTimestamp","internalType":"uint32","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferRequested","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RemovedAccess","inputs":[{"type":"address","name":"user","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addAccess","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"checkEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"description","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disableAccessCheck","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableAccessCheck","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"getAnswer","inputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int256","name":"answer","internalType":"int256"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"},{"type":"uint80","name":"answeredInRound","internalType":"uint80"}],"name":"getRoundData","inputs":[{"type":"uint80","name":"_roundId","internalType":"uint80"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTimestamp","inputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getTransmitters","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasAccess","inputs":[{"type":"address","name":"_user","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"latestAnswer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"configCount","internalType":"uint32"},{"type":"uint32","name":"blockNumber","internalType":"uint32"}],"name":"latestConfigDetails","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestRound","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int256","name":"answer","internalType":"int256"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"},{"type":"uint80","name":"answeredInRound","internalType":"uint80"}],"name":"latestRoundData","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"nextTransmitter","internalType":"address"},{"type":"address","name":"afterNextTransmitter","internalType":"address"},{"type":"uint8","name":"nextIndex","internalType":"uint8"},{"type":"uint256","name":"transmittersLength","internalType":"uint256"},{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int192","name":"answer","internalType":"int192"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"}],"name":"latestTransmissionDetails","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"lowerBoundAnchorRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeAccess","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAnchorRatio","inputs":[{"type":"uint8","name":"_lowerBoundAnchorRatio","internalType":"uint8"},{"type":"uint8","name":"_upperBoundAnchorRatio","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setConfig","inputs":[{"type":"address[]","name":"_signers","internalType":"address[]"},{"type":"address[]","name":"_transmitters","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"to","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transmit","inputs":[{"type":"bytes","name":"_report","internalType":"bytes"},{"type":"bytes32","name":"_rs","internalType":"bytes32"},{"type":"bytes32","name":"_ss","internalType":"bytes32"},{"type":"uint8","name":"_vs","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transmitWithForce","inputs":[{"type":"uint192","name":"median","internalType":"uint192"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"typeAndVersion","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"upperBoundAnchorRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"version","inputs":[]}]
Contract Creation Code
0x60a06040523480156200001157600080fd5b5060405162002d4538038062002d45833981810160405260808110156200003757600080fd5b8151602083015160408085015160608601805192519496939591949391820192846401000000008211156200006b57600080fd5b9083019060208201858111156200008157600080fd5b82516401000000008111828201881017156200009c57600080fd5b82525081516020918201929091019080838360005b83811015620000cb578181015183820152602001620000b1565b50505050905090810190601f168015620000f95780820380516001836020036101000a031916815260200191505b5060405250859150849050838333806000816200015d576040805162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001905762000190816200021e565b50506004805460ff868116600160e81b0260ff60e81b19918916600160e01b0260ff60e01b199093169290921716179055507fff0000000000000000000000000000000000000000000000000000000000000060f883901b16608052805162000201906009906020840190620002ce565b5050600a805460ff19166001179055506200037a95505050505050565b6001600160a01b0381163314156200027d576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262000306576000855562000351565b82601f106200032157805160ff191683800117855562000351565b8280016001018555821562000351579182015b828111156200035157825182559160200191906001019062000334565b506200035f92915062000363565b5090565b5b808211156200035f576000815560010162000364565b60805160f81c6129ad620003986000398061087f52506129ad6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806381ff704811610104578063a118f249116100a2578063e5fe457711610071578063e5fe4577146106e8578063f27f55c01461075a578063f2fde38b14610791578063feaf968c146107c4576101cf565b8063a118f24914610673578063b5ab58dc146106a6578063b633620c146106c3578063dc7f0124146106e0576101cf565b80638da5cb5b116100de5780638da5cb5b1461059f57806392b84357146105d057806397953585146105d85780639a6fc8f514610600576101cf565b806381ff7048146105335780638205bf6a146105645780638823da6c1461056c576101cf565b8063632042b4116101715780636b14daf81161014b5780636b14daf8146104445780637284e4161461051b57806379ba5097146105235780638038e4a11461052b576101cf565b8063632042b414610322578063666cab8d146103e4578063668a0f021461043c576101cf565b8063313ce567116101ad578063313ce5671461027957806343c417a21461028157806350d25bcd1461030057806354fd4d501461031a576101cf565b80630a756983146101d4578063181f5a77146101de578063241052091461025b575b600080fd5b6101dc6107cc565b005b6101e6610833565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610220578181015183820152602001610208565b50505050905090810190601f16801561024d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610263610853565b6040805160ff9092168252519081900360200190f35b61026361087d565b6101dc6004803603608081101561029757600080fd5b8101906020810181356401000000008111156102b257600080fd5b8201836020820111156102c457600080fd5b803590602001918460018302840111640100000000831117156102e657600080fd5b91935091508035906020810135906040013560ff166108a1565b610308610ceb565b60408051918252519081900360200190f35b610308610d8c565b6101dc6004803603604081101561033857600080fd5b81019060208101813564010000000081111561035357600080fd5b82018360208201111561036557600080fd5b8035906020019184602083028401116401000000008311171561038757600080fd5b9193909290916020810190356401000000008111156103a557600080fd5b8201836020820111156103b757600080fd5b803590602001918460208302840111640100000000831117156103d957600080fd5b509092509050610d91565b6103ec61130a565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610428578181015183820152602001610410565b505050509050019250505060405180910390f35b610308611379565b6105076004803603604081101561045a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561049257600080fd5b8201836020820111156104a457600080fd5b803590602001918460018302840111640100000000831117156104c657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611415945050505050565b604080519115158252519081900360200190f35b6101e661144a565b6101dc6114e6565b6101dc6115ce565b61053b611636565b604051808363ffffffff1681526020018263ffffffff1681526020019250505060405180910390f35b61030861164f565b6101dc6004803603602081101561058257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166116eb565b6105a76117a5565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102636117c1565b6101dc600480360360408110156105ee57600080fd5b5060ff813581169160200135166117ea565b6106296004803603602081101561061657600080fd5b503569ffffffffffffffffffff1661199e565b604051808669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1681526020019550505050505060405180910390f35b6101dc6004803603602081101561068957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a53565b610308600480360360208110156106bc57600080fd5b5035611b0e565b610308600480360360208110156106d957600080fd5b5035611bb3565b610507611c50565b6106f0611c59565b6040805173ffffffffffffffffffffffffffffffffffffffff998a16815297909816602088015260ff90951686880152606086019390935269ffffffffffffffffffff909116608085015260170b60a084015260c083015260e08201529051908190036101000190f35b6101dc6004803603602081101561077057600080fd5b503577ffffffffffffffffffffffffffffffffffffffffffffffff16611e5f565b6101dc600480360360208110156107a757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611e71565b610629611e82565b6107d4611f35565b600a5460ff161561083157600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b606060405180606001604052806028815260200161286560289139905090565b6004547d010000000000000000000000000000000000000000000000000000000000900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b3360009081526005602052604090205460ff16610905576040805162461bcd60e51b815260206004820152601860248201527f756e617574686f72697a6564207472616e736d69747465720000000000000000604482015290519081900360640190fd5b61090d611fa1565b3614610960576040805162461bcd60e51b815260206004820181905260248201527f7472616e736d6974206d657373616765206c656e677468206d69736d61746368604482015290519081900360640190fd5b6000808686604081101561097357600080fd5b5060025463ffffffff90811660009081526003602090815260409091205477ffffffffffffffffffffffffffffffffffffffffffffffff8435169550920135811692507c010000000000000000000000000000000000000000000000000000000090910416808211610a2c576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c6964206f62736572766174696f6e732074696d657374616d700000604482015290519081900360640190fd5b600088886040518083838082843760405192018290039091209450610a55935061279292505050565b600060018388601b018b8b60405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610ab4573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526006602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290945092509050610b7d576040805162461bcd60e51b815260206004820152600f60248201527f7369676e6174757265206572726f720000000000000000000000000000000000604482015290519081900360640190fd5b505060025463ffffffff1660009081526003602052604090205460170b77ffffffffffffffffffffffffffffffffffffffffffffffff1690508015610cd657600454600090610bfd90606490610bf79085907c0100000000000000000000000000000000000000000000000000000000900460ff16611fa6565b90611fff565b600454909150600090610c3c90606490610bf79086907d010000000000000000000000000000000000000000000000000000000000900460ff16611fa6565b90508577ffffffffffffffffffffffffffffffffffffffffffffffff168211158015610c825750808677ffffffffffffffffffffffffffffffffffffffffffffffff1611155b610cd3576040805162461bcd60e51b815260206004820152601e60248201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e67650000604482015290519081900360640190fd5b50505b610ce08484612069565b505050505050505050565b6000610d2e336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b610d7f576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d876122d7565b905090565b600181565b610d99611f35565b828114610ded576040805162461bcd60e51b815260206004820152601660248201527f6f7261636c65206c656e677468206d69736d6174636800000000000000000000604482015290519081900360640190fd5b60075460005b81811015610eb657600060078281548110610e0a57fe5b60009182526020822001546008805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110610e3e57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff948516835260068252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915595909116835260059091529020805490921690915550600101610df3565b50610ec3600760006127a9565b610ecf600860006127a9565b60005b8481101561118b5760066000878784818110610eea57fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff168352508101919091526040016000205460ff1615610f6f576040805162461bcd60e51b815260206004820152601760248201527f7265706561746564207369676e65722061646472657373000000000000000000604482015290519081900360640190fd5b604080518082019091526001815260ff8216602082015260066000888885818110610f9657fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff168352508181019290925260400160009081208351815494909301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909416921515929092177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9094169390930292909217905560059085858481811061103f57fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff168352508101919091526040016000205460ff16156110c4576040805162461bcd60e51b815260206004820152601c60248201527f7265706561746564207472616e736d6974746572206164647265737300000000604482015290519081900360640190fd5b604080518082019091526001815260ff82166020820152600560008686858181106110eb57fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff16835250818101929092526040016000208251815493909201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316911515919091177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff90931692909202919091179055600101610ed2565b50611198600786866127c7565b506111a5600884846127c7565b50600480544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff84161780831660010183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000090911617938490556040805191909304821680825293909116602080830182905260809383018481529383018990527fe8d070a65cc69d4aaeb20e8cdc65fdd7a656a77ee34614d6758ffd9eac3d1cd09385938b928b928b928b92909190606083019060a08401908890880280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169091018481038352858152602090810191508690860280828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039a509098505050505050505050a1505050505050565b6060600880548060200260200160405190810160405280929190818152602001828054801561136f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611344575b5050505050905090565b60006113bc336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b61140d576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d876122f9565b60006114218383612305565b80611441575073ffffffffffffffffffffffffffffffffffffffff831632145b90505b92915050565b606061148d336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b6114de576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d87612342565b60015473ffffffffffffffffffffffffffffffffffffffff163314611552576040805162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6115d6611f35565b600a5460ff1661083157600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b60045463ffffffff808216916401000000009004169091565b6000611692336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b6116e3576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d876123ed565b6116f3611f35565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff16156117a25773ffffffffffffffffffffffffffffffffffffffff81166000818152600b602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055815192835290517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d19281900390910190a15b50565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6004547c0100000000000000000000000000000000000000000000000000000000900460ff1681565b6117f2611f35565b60ff8216605011156118355760405162461bcd60e51b815260040180806020018281038252604781526020018061288d6047913960600191505060405180910390fd5b60ff8116607810156118785760405162461bcd60e51b815260040180806020018281038252604981526020018061292f6049913960600191505060405180910390fd5b8160ff168160ff16116118bc5760405162461bcd60e51b815260040180806020018281038252603a8152602001806128f5603a913960400191505060405180910390fd5b6004805460ff8381167d0100000000000000000000000000000000000000000000000000000000009081027fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8388167c01000000000000000000000000000000000000000000000000000000009081027fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff909616959095171617938490556040805193850483168452930416602082015281517ff899e0ea4845aabbeda4bd108029c91ecfd7e0afa5a1eefbdbf436d15a6ffb3c929181900390910190a15050565b60008060008060006119e7336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611a38576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611a418661242b565b939a9299509097509550909350915050565b611a5b611f35565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff166117a25773ffffffffffffffffffffffffffffffffffffffff81166000818152600b602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055815192835290517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49281900390910190a150565b6000611b51336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611ba2576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611bab8261259a565b90505b919050565b6000611bf6336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611c47576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611bab826125d0565b600a5460ff1681565b600080808080808080333214611cb6576040805162461bcd60e51b815260206004820152601460248201527f4f6e6c792063616c6c61626c6520627920454f41000000000000000000000000604482015290519081900360640190fd5b6008546000965086908015611dc857611ccd612792565b5060045468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526005602090815260409182902082518084019093525460ff80821615801585526101009092041691830191909152611d44576020810151600101985060ff8916821415611d4457600098505b60018901925060ff8316821415611d5a57600092505b60088960ff1681548110611d6a57fe5b6000918252602090912001546008805473ffffffffffffffffffffffffffffffffffffffff9092169c509060ff8516908110611da257fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169950505b60025463ffffffff90811660008181526003602090815260409182902082516060810184529054601781810b810b900b8083527801000000000000000000000000000000000000000000000000820487169383018490527c010000000000000000000000000000000000000000000000000000000090910490951692018290529c9d9b9c9a9b939a91995091975095509350915050565b611e67611f35565b6117a28142612069565b611e79611f35565b6117a281612622565b6000806000806000611ecb336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611f1c576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611f24612703565b945094509450945094509091929394565b60005473ffffffffffffffffffffffffffffffffffffffff163314610831576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60e490565b600082611fb557506000611444565b82820282848281611fc257fe5b04146114415760405162461bcd60e51b81526004018080602001828103825260218152602001806128d46021913960400191505060405180910390fd5b6000808211612055576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161206057fe5b04949350505050565b604080516020808201835260025463ffffffff90811660010181168352835160608082018652601788810b808452888516848701818152428716868b0190815289518816600090815260038a528b9020965187549251915189167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff928a167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9290970b77ffffffffffffffffffffffffffffffffffffffffffffffff167fffffffffffffffff00000000000000000000000000000000000000000000000090941693909317169490941793909316929092179093556004805468010000000000000000339081027fffffffff0000000000000000000000000000000000000000ffffffffffffffff909216919091179091558651885194855295840152828701529451939492909116927f38567aa999bdbf56a2a0e536f6d3420a6befcc0d5a443f686e3bded71d09157e929181900390910190a280516040805163ffffffff8581168252915160009392909216917f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac602719181900360200190a3806000015163ffffffff168360170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a351600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790555050565b60025463ffffffff16600090815260036020526040902054601790810b900b90565b60025463ffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604081205460ff1680611441575050600a5460ff161592915050565b60098054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561136f5780601f106123c15761010080835404028352916020019161136f565b820191906000526020600020905b8154815290600101906020018083116123cf57509395945050505050565b60025463ffffffff9081166000908152600360205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b600080600080600063ffffffff8669ffffffffffffffffffff1611156040518060400160405280600f81526020017f4e6f20646174612070726573656e740000000000000000000000000000000000815250906125065760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156124cb5781810151838201526020016124b3565b50505050905090810190601f1680156124f85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5050505063ffffffff83811660009081526003602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830487169484018590527c01000000000000000000000000000000000000000000000000000000009092049095169190930181905295969190920b949193509091508490565b600063ffffffff8211156125b057506000611bae565b5063ffffffff16600090815260036020526040902054601790810b900b90565b600063ffffffff8211156125e657506000611bae565b5063ffffffff9081166000908152600360205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b73ffffffffffffffffffffffffffffffffffffffff811633141561268d576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60025463ffffffff90811660008181526003602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830488169484018590527c01000000000000000000000000000000000000000000000000000000009092049096169190930181905292949190930b9291908490565b604080518082019091526000808252602082015290565b50805460008255906000526020600020908101906117a2919061284f565b82805482825590600052602060002090810192821561283f579160200282015b8281111561283f5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906127e7565b5061284b92915061284f565b5090565b5b8082111561284b576000815560010161285056fe416363657373436f6e74726f6c6c65644f6666636861696e41676772656761746f7220312e302e306c6f776572426f756e64416e63686f72526174696f206d7573742067726561746572206f7220657175616c20746f206d696e4c6f776572426f756e64416e63686f72526174696f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777570706572426f756e64416e63686f72526174696f206d757374204c657373207468616e206c6f776572426f756e64416e63686f72526174696f7570706572426f756e64416e63686f72526174696f206d757374204c657373207468616e206f7220657175616c20746f206d61785570706572426f756e64416e63686f72526174696fa26469706673582212201eaf4ce9e35de264068eb4745235e435acf0a6342afc5ea0e9837ce073f74ec264736f6c63430007060033000000000000000000000000000000000000000000000000000000000000005f00000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000094d4a54202f205553440000000000000000000000000000000000000000000000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c806381ff704811610104578063a118f249116100a2578063e5fe457711610071578063e5fe4577146106e8578063f27f55c01461075a578063f2fde38b14610791578063feaf968c146107c4576101cf565b8063a118f24914610673578063b5ab58dc146106a6578063b633620c146106c3578063dc7f0124146106e0576101cf565b80638da5cb5b116100de5780638da5cb5b1461059f57806392b84357146105d057806397953585146105d85780639a6fc8f514610600576101cf565b806381ff7048146105335780638205bf6a146105645780638823da6c1461056c576101cf565b8063632042b4116101715780636b14daf81161014b5780636b14daf8146104445780637284e4161461051b57806379ba5097146105235780638038e4a11461052b576101cf565b8063632042b414610322578063666cab8d146103e4578063668a0f021461043c576101cf565b8063313ce567116101ad578063313ce5671461027957806343c417a21461028157806350d25bcd1461030057806354fd4d501461031a576101cf565b80630a756983146101d4578063181f5a77146101de578063241052091461025b575b600080fd5b6101dc6107cc565b005b6101e6610833565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610220578181015183820152602001610208565b50505050905090810190601f16801561024d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610263610853565b6040805160ff9092168252519081900360200190f35b61026361087d565b6101dc6004803603608081101561029757600080fd5b8101906020810181356401000000008111156102b257600080fd5b8201836020820111156102c457600080fd5b803590602001918460018302840111640100000000831117156102e657600080fd5b91935091508035906020810135906040013560ff166108a1565b610308610ceb565b60408051918252519081900360200190f35b610308610d8c565b6101dc6004803603604081101561033857600080fd5b81019060208101813564010000000081111561035357600080fd5b82018360208201111561036557600080fd5b8035906020019184602083028401116401000000008311171561038757600080fd5b9193909290916020810190356401000000008111156103a557600080fd5b8201836020820111156103b757600080fd5b803590602001918460208302840111640100000000831117156103d957600080fd5b509092509050610d91565b6103ec61130a565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610428578181015183820152602001610410565b505050509050019250505060405180910390f35b610308611379565b6105076004803603604081101561045a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561049257600080fd5b8201836020820111156104a457600080fd5b803590602001918460018302840111640100000000831117156104c657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611415945050505050565b604080519115158252519081900360200190f35b6101e661144a565b6101dc6114e6565b6101dc6115ce565b61053b611636565b604051808363ffffffff1681526020018263ffffffff1681526020019250505060405180910390f35b61030861164f565b6101dc6004803603602081101561058257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166116eb565b6105a76117a5565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102636117c1565b6101dc600480360360408110156105ee57600080fd5b5060ff813581169160200135166117ea565b6106296004803603602081101561061657600080fd5b503569ffffffffffffffffffff1661199e565b604051808669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1681526020019550505050505060405180910390f35b6101dc6004803603602081101561068957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a53565b610308600480360360208110156106bc57600080fd5b5035611b0e565b610308600480360360208110156106d957600080fd5b5035611bb3565b610507611c50565b6106f0611c59565b6040805173ffffffffffffffffffffffffffffffffffffffff998a16815297909816602088015260ff90951686880152606086019390935269ffffffffffffffffffff909116608085015260170b60a084015260c083015260e08201529051908190036101000190f35b6101dc6004803603602081101561077057600080fd5b503577ffffffffffffffffffffffffffffffffffffffffffffffff16611e5f565b6101dc600480360360208110156107a757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611e71565b610629611e82565b6107d4611f35565b600a5460ff161561083157600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b606060405180606001604052806028815260200161286560289139905090565b6004547d010000000000000000000000000000000000000000000000000000000000900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000881565b3360009081526005602052604090205460ff16610905576040805162461bcd60e51b815260206004820152601860248201527f756e617574686f72697a6564207472616e736d69747465720000000000000000604482015290519081900360640190fd5b61090d611fa1565b3614610960576040805162461bcd60e51b815260206004820181905260248201527f7472616e736d6974206d657373616765206c656e677468206d69736d61746368604482015290519081900360640190fd5b6000808686604081101561097357600080fd5b5060025463ffffffff90811660009081526003602090815260409091205477ffffffffffffffffffffffffffffffffffffffffffffffff8435169550920135811692507c010000000000000000000000000000000000000000000000000000000090910416808211610a2c576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c6964206f62736572766174696f6e732074696d657374616d700000604482015290519081900360640190fd5b600088886040518083838082843760405192018290039091209450610a55935061279292505050565b600060018388601b018b8b60405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610ab4573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526006602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290945092509050610b7d576040805162461bcd60e51b815260206004820152600f60248201527f7369676e6174757265206572726f720000000000000000000000000000000000604482015290519081900360640190fd5b505060025463ffffffff1660009081526003602052604090205460170b77ffffffffffffffffffffffffffffffffffffffffffffffff1690508015610cd657600454600090610bfd90606490610bf79085907c0100000000000000000000000000000000000000000000000000000000900460ff16611fa6565b90611fff565b600454909150600090610c3c90606490610bf79086907d010000000000000000000000000000000000000000000000000000000000900460ff16611fa6565b90508577ffffffffffffffffffffffffffffffffffffffffffffffff168211158015610c825750808677ffffffffffffffffffffffffffffffffffffffffffffffff1611155b610cd3576040805162461bcd60e51b815260206004820152601e60248201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e67650000604482015290519081900360640190fd5b50505b610ce08484612069565b505050505050505050565b6000610d2e336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b610d7f576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d876122d7565b905090565b600181565b610d99611f35565b828114610ded576040805162461bcd60e51b815260206004820152601660248201527f6f7261636c65206c656e677468206d69736d6174636800000000000000000000604482015290519081900360640190fd5b60075460005b81811015610eb657600060078281548110610e0a57fe5b60009182526020822001546008805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110610e3e57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff948516835260068252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915595909116835260059091529020805490921690915550600101610df3565b50610ec3600760006127a9565b610ecf600860006127a9565b60005b8481101561118b5760066000878784818110610eea57fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff168352508101919091526040016000205460ff1615610f6f576040805162461bcd60e51b815260206004820152601760248201527f7265706561746564207369676e65722061646472657373000000000000000000604482015290519081900360640190fd5b604080518082019091526001815260ff8216602082015260066000888885818110610f9657fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff168352508181019290925260400160009081208351815494909301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909416921515929092177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9094169390930292909217905560059085858481811061103f57fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff168352508101919091526040016000205460ff16156110c4576040805162461bcd60e51b815260206004820152601c60248201527f7265706561746564207472616e736d6974746572206164647265737300000000604482015290519081900360640190fd5b604080518082019091526001815260ff82166020820152600560008686858181106110eb57fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff16835250818101929092526040016000208251815493909201517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316911515919091177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff90931692909202919091179055600101610ed2565b50611198600786866127c7565b506111a5600884846127c7565b50600480544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff84161780831660010183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000090911617938490556040805191909304821680825293909116602080830182905260809383018481529383018990527fe8d070a65cc69d4aaeb20e8cdc65fdd7a656a77ee34614d6758ffd9eac3d1cd09385938b928b928b928b92909190606083019060a08401908890880280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169091018481038352858152602090810191508690860280828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039a509098505050505050505050a1505050505050565b6060600880548060200260200160405190810160405280929190818152602001828054801561136f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611344575b5050505050905090565b60006113bc336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b61140d576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d876122f9565b60006114218383612305565b80611441575073ffffffffffffffffffffffffffffffffffffffff831632145b90505b92915050565b606061148d336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b6114de576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d87612342565b60015473ffffffffffffffffffffffffffffffffffffffff163314611552576040805162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6115d6611f35565b600a5460ff1661083157600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b60045463ffffffff808216916401000000009004169091565b6000611692336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b6116e3576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610d876123ed565b6116f3611f35565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff16156117a25773ffffffffffffffffffffffffffffffffffffffff81166000818152600b602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055815192835290517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d19281900390910190a15b50565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6004547c0100000000000000000000000000000000000000000000000000000000900460ff1681565b6117f2611f35565b60ff8216605011156118355760405162461bcd60e51b815260040180806020018281038252604781526020018061288d6047913960600191505060405180910390fd5b60ff8116607810156118785760405162461bcd60e51b815260040180806020018281038252604981526020018061292f6049913960600191505060405180910390fd5b8160ff168160ff16116118bc5760405162461bcd60e51b815260040180806020018281038252603a8152602001806128f5603a913960400191505060405180910390fd5b6004805460ff8381167d0100000000000000000000000000000000000000000000000000000000009081027fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8388167c01000000000000000000000000000000000000000000000000000000009081027fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff909616959095171617938490556040805193850483168452930416602082015281517ff899e0ea4845aabbeda4bd108029c91ecfd7e0afa5a1eefbdbf436d15a6ffb3c929181900390910190a15050565b60008060008060006119e7336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611a38576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611a418661242b565b939a9299509097509550909350915050565b611a5b611f35565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff166117a25773ffffffffffffffffffffffffffffffffffffffff81166000818152600b602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055815192835290517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49281900390910190a150565b6000611b51336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611ba2576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611bab8261259a565b90505b919050565b6000611bf6336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611c47576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611bab826125d0565b600a5460ff1681565b600080808080808080333214611cb6576040805162461bcd60e51b815260206004820152601460248201527f4f6e6c792063616c6c61626c6520627920454f41000000000000000000000000604482015290519081900360640190fd5b6008546000965086908015611dc857611ccd612792565b5060045468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526005602090815260409182902082518084019093525460ff80821615801585526101009092041691830191909152611d44576020810151600101985060ff8916821415611d4457600098505b60018901925060ff8316821415611d5a57600092505b60088960ff1681548110611d6a57fe5b6000918252602090912001546008805473ffffffffffffffffffffffffffffffffffffffff9092169c509060ff8516908110611da257fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169950505b60025463ffffffff90811660008181526003602090815260409182902082516060810184529054601781810b810b900b8083527801000000000000000000000000000000000000000000000000820487169383018490527c010000000000000000000000000000000000000000000000000000000090910490951692018290529c9d9b9c9a9b939a91995091975095509350915050565b611e67611f35565b6117a28142612069565b611e79611f35565b6117a281612622565b6000806000806000611ecb336000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141592505050565b611f1c576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611f24612703565b945094509450945094509091929394565b60005473ffffffffffffffffffffffffffffffffffffffff163314610831576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60e490565b600082611fb557506000611444565b82820282848281611fc257fe5b04146114415760405162461bcd60e51b81526004018080602001828103825260218152602001806128d46021913960400191505060405180910390fd5b6000808211612055576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161206057fe5b04949350505050565b604080516020808201835260025463ffffffff90811660010181168352835160608082018652601788810b808452888516848701818152428716868b0190815289518816600090815260038a528b9020965187549251915189167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff928a167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9290970b77ffffffffffffffffffffffffffffffffffffffffffffffff167fffffffffffffffff00000000000000000000000000000000000000000000000090941693909317169490941793909316929092179093556004805468010000000000000000339081027fffffffff0000000000000000000000000000000000000000ffffffffffffffff909216919091179091558651885194855295840152828701529451939492909116927f38567aa999bdbf56a2a0e536f6d3420a6befcc0d5a443f686e3bded71d09157e929181900390910190a280516040805163ffffffff8581168252915160009392909216917f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac602719181900360200190a3806000015163ffffffff168360170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a351600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790555050565b60025463ffffffff16600090815260036020526040902054601790810b900b90565b60025463ffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604081205460ff1680611441575050600a5460ff161592915050565b60098054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561136f5780601f106123c15761010080835404028352916020019161136f565b820191906000526020600020905b8154815290600101906020018083116123cf57509395945050505050565b60025463ffffffff9081166000908152600360205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b600080600080600063ffffffff8669ffffffffffffffffffff1611156040518060400160405280600f81526020017f4e6f20646174612070726573656e740000000000000000000000000000000000815250906125065760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156124cb5781810151838201526020016124b3565b50505050905090810190601f1680156124f85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5050505063ffffffff83811660009081526003602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830487169484018590527c01000000000000000000000000000000000000000000000000000000009092049095169190930181905295969190920b949193509091508490565b600063ffffffff8211156125b057506000611bae565b5063ffffffff16600090815260036020526040902054601790810b900b90565b600063ffffffff8211156125e657506000611bae565b5063ffffffff9081166000908152600360205260409020547c010000000000000000000000000000000000000000000000000000000090041690565b73ffffffffffffffffffffffffffffffffffffffff811633141561268d576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60025463ffffffff90811660008181526003602090815260409182902082516060810184529054601781810b810b810b8084527801000000000000000000000000000000000000000000000000830488169484018590527c01000000000000000000000000000000000000000000000000000000009092049096169190930181905292949190930b9291908490565b604080518082019091526000808252602082015290565b50805460008255906000526020600020908101906117a2919061284f565b82805482825590600052602060002090810192821561283f579160200282015b8281111561283f5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906127e7565b5061284b92915061284f565b5090565b5b8082111561284b576000815560010161285056fe416363657373436f6e74726f6c6c65644f6666636861696e41676772656761746f7220312e302e306c6f776572426f756e64416e63686f72526174696f206d7573742067726561746572206f7220657175616c20746f206d696e4c6f776572426f756e64416e63686f72526174696f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777570706572426f756e64416e63686f72526174696f206d757374204c657373207468616e206c6f776572426f756e64416e63686f72526174696f7570706572426f756e64416e63686f72526174696f206d757374204c657373207468616e206f7220657175616c20746f206d61785570706572426f756e64416e63686f72526174696fa26469706673582212201eaf4ce9e35de264068eb4745235e435acf0a6342afc5ea0e9837ce073f74ec264736f6c63430007060033