Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 6 from a total of 6 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Migrate | 12138990 | 1790 days ago | IN | 0 ETH | 0.00226599 | ||||
| Migrate | 12138989 | 1790 days ago | IN | 0 ETH | 0.00231956 | ||||
| Migrate | 11916141 | 1824 days ago | IN | 0 ETH | 0.00282173 | ||||
| Submit Mining So... | 11916082 | 1824 days ago | IN | 0 ETH | 0.04447187 | ||||
| Submit Mining So... | 11916045 | 1824 days ago | IN | 0 ETH | 0.04784 | ||||
| Submit Mining So... | 11916001 | 1824 days ago | IN | 0 ETH | 0.04134 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Tellor
Compiler Version
v0.7.4+commit.3f05b770
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
import "./TellorStake.sol";
import "./TellorGetters.sol";
import "./Utilities.sol";
import "./ITellor.sol";
import "./SafeMath.sol";
/**
* @title Tellor Oracle System
* @dev Oracle contract where miners can submit the proof of work along with the value.
*/
contract Tellor is TellorStake {
using SafeMath for uint256;
event TipAdded(
address indexed _sender,
uint256 indexed _requestId,
uint256 _tip,
uint256 _totalTips
);
//emits when a new challenge is created (either on mined block or when a new request is pushed forward on waiting system)
event NewChallenge(
bytes32 indexed _currentChallenge,
uint256[5] _currentRequestId,
uint256 _difficulty,
uint256 _totalTips
);
//Emits upon a successful Mine, indicates the blockTime at point of the mine and the value mined
event NewValue(
uint256[5] _requestId,
uint256 _time,
uint256[5] _value,
uint256 _totalTips,
bytes32 indexed _currentChallenge
);
//Emits upon each mine (5 total) and shows the miner, nonce, and value submitted
event NonceSubmitted(
address indexed _miner,
string _nonce,
uint256[5] _requestId,
uint256[5] _value,
bytes32 indexed _currentChallenge,
uint256 _slot
);
/**
* @dev This is an internal function used by the function migrate that helps to
* swap old trb tokens for new ones based on the user's old Tellor balance
* @param _user is the msg.sender address of the user to migrate the balance from
*/
function _migrate(address _user) internal {
require(!migrated[_user], "alredy migrated");
_doMint(_user, ITellor(addresses[_OLD_TELLOR]).balanceOf(_user));
migrated[_user] = true;
}
/**
* @dev This function allows users to swap old trb tokens for new ones based
* on the user's old Tellor balance
*/
function migrate() external {
_migrate(msg.sender);
}
/**
* @dev allows for the deity to update the TellorStake contract address
* @param _tGetters the address of the new Tellor Contract
*/
function changeTellorGetters(address _tGetters) external {
require(msg.sender == addresses[_DEITY]);
addresses[_TELLOR_GETTERS] = _tGetters;
}
/**
* @dev This function allows miners to submit their mining solution and data requested
* @param _nonce is the mining solution
* @param _requestIds iare the 5 request ids being mined
* @param _values are the 5 values correspoding to the 5 request ids
*/
function submitMiningSolution(
string calldata _nonce,
uint256[5] calldata _requestIds,
uint256[5] calldata _values
) external {
bytes32 _hashMsgSender = keccak256(abi.encode(msg.sender));
require(
uints[_hashMsgSender] == 0 ||
block.timestamp - uints[_hashMsgSender] > 15 minutes,
"Miner can only win rewards once per 15 min"
);
if (uints[_SLOT_PROGRESS] != 4) {
_verifyNonce(_nonce);
}
uints[_hashMsgSender] = block.timestamp;
_submitMiningSolution(_nonce, _requestIds, _values);
}
/**
* @dev This is an internal function used by submitMiningSolution to allows miners to submit
* their mining solution and data requested. It checks the miner is staked, has not
* won in the las 15 min, and checks they are submitting all the correct requestids
* @param _nonce is the mining solution
* @param _requestIds iare the 5 request ids being mined
* @param _values are the 5 values correspoding to the 5 request ids
*/
function _submitMiningSolution(
string memory _nonce,
uint256[5] memory _requestIds,
uint256[5] memory _values
) internal {
//Verifying Miner Eligibility
bytes32 _hashMsgSender = keccak256(abi.encode(msg.sender));
require(
stakerDetails[msg.sender].currentStatus == 1,
"Miner status is not staker"
);
require(
_requestIds[0] == currentMiners[0].value,
"Request ID is wrong"
);
require(
_requestIds[1] == currentMiners[1].value,
"Request ID is wrong"
);
require(
_requestIds[2] == currentMiners[2].value,
"Request ID is wrong"
);
require(
_requestIds[3] == currentMiners[3].value,
"Request ID is wrong"
);
require(
_requestIds[4] == currentMiners[4].value,
"Request ID is wrong"
);
uints[_hashMsgSender] = block.timestamp;
bytes32 _currChallenge = bytesVars[_CURRENT_CHALLENGE];
uint256 _slotP = uints[_SLOT_PROGRESS];
//Checking and updating Miner Status
require(
minersByChallenge[_currChallenge][msg.sender] == false,
"Miner already submitted the value"
);
//Update the miner status to true once they submit a value so they don't submit more than once
minersByChallenge[_currChallenge][msg.sender] = true;
//Updating Request
Request storage _tblock = requestDetails[uints[_T_BLOCK]];
//Assigning directly is cheaper than using a for loop
_tblock.valuesByTimestamp[0][_slotP] = _values[0];
_tblock.valuesByTimestamp[1][_slotP] = _values[1];
_tblock.valuesByTimestamp[2][_slotP] = _values[2];
_tblock.valuesByTimestamp[3][_slotP] = _values[3];
_tblock.valuesByTimestamp[4][_slotP] = _values[4];
_tblock.minersByValue[0][_slotP] = msg.sender;
_tblock.minersByValue[1][_slotP] = msg.sender;
_tblock.minersByValue[2][_slotP] = msg.sender;
_tblock.minersByValue[3][_slotP] = msg.sender;
_tblock.minersByValue[4][_slotP] = msg.sender;
if (_slotP + 1 == 4) {
_adjustDifficulty();
}
if (_slotP + 1 == 5) {
//slotProgress has been incremented, but we're using the variable on stack to save gas
_newBlock(_nonce, _requestIds);
uints[_SLOT_PROGRESS] = 0;
} else {
uints[_SLOT_PROGRESS]++;
}
emit NonceSubmitted(
msg.sender,
_nonce,
_requestIds,
_values,
_currChallenge,
_slotP
);
}
/**
* @dev This is an internal function used by submitMiningSolution to allows miners to submit
* their mining solution and data requested. It checks the miner has submitted a
* valid nonce or allows any solution if 15 minutes or more have passed since last
* mine values
* @param _nonce is the mining solution
*/
function _verifyNonce(string memory _nonce) internal view {
require(
uint256(
sha256(
abi.encodePacked(
ripemd160(
abi.encodePacked(
keccak256(
abi.encodePacked(
bytesVars[_CURRENT_CHALLENGE],
msg.sender,
_nonce
)
)
)
)
)
)
) %
uints[_DIFFICULTY] ==
0 ||
block.timestamp - uints[_TIME_OF_LAST_NEW_VALUE] >= 15 minutes,
"Incorrect nonce for current challenge"
);
}
/**
* @dev This is an internal function used by submitMiningSolution and adjusts the difficulty
* based on the the difference between the target time and how long it took to solve
* the previous challenge otherwise it sets it to 1
*/
function _adjustDifficulty() internal {
// If the difference between the timeTarget and how long it takes to solve the challenge this updates the challenge
//difficulty up or down by the difference between the target time and how long it took to solve the previous challenge
//otherwise it sets it to 1
uint256 timeDiff = block.timestamp - uints[_TIME_OF_LAST_NEW_VALUE];
int256 _change = int256(SafeMath.min(1200, timeDiff));
int256 _diff = int256(uints[_DIFFICULTY]);
_change = (_diff * (int256(uints[_TIME_TARGET]) - _change)) / 4000;
if (_change == 0) {
_change = 1;
}
uints[_DIFFICULTY] = uint256(SafeMath.max(_diff + _change, 1));
}
/**
* @dev This is an internal function used by submitMiningSolution to
* calculate and pay rewards to miners
* @param miners are the 5 miners to reward
* @param _previousTime is the previous mine time based on the 4th entry
*/
function _payReward(address[5] memory miners, uint256 _previousTime)
internal
{
//_timeDiff is how many seconds passed since last block
uint256 _timeDiff = block.timestamp - _previousTime;
uint256 reward = (_timeDiff * uints[_CURRENT_REWARD]) / 300;
uint256 _tip = uints[_CURRENT_TOTAL_TIPS] / 10;
uint256 _devShare = reward / 2;
_doMint(miners[0], reward + _tip);
_doMint(miners[1], reward + _tip);
_doMint(miners[2], reward + _tip);
_doMint(miners[3], reward + _tip);
_doMint(miners[4], reward + _tip);
_doMint(addresses[_OWNER], _devShare);
uints[_CURRENT_TOTAL_TIPS] = 0;
}
/**
* @dev This is an internal function called by submitMiningSolution and adjusts the difficulty,
* sorts and stores the first 5 values received, pays the miners, the dev share and
* assigns a new challenge
* @param _nonce or solution for the PoW for the requestId
* @param _requestIds for the current request being mined
*/
function _newBlock(string memory _nonce, uint256[5] memory _requestIds)
internal
{
Request storage _tblock = requestDetails[uints[_T_BLOCK]];
bytes32 _currChallenge = bytesVars[_CURRENT_CHALLENGE];
uint256 _previousTime = uints[_TIME_OF_LAST_NEW_VALUE];
uint256 _timeOfLastNewValueVar = block.timestamp;
uints[_TIME_OF_LAST_NEW_VALUE] = _timeOfLastNewValueVar;
//this loop sorts the values and stores the median as the official value
uint256[5] memory a;
uint256[5] memory b;
for (uint256 k = 0; k < 5; k++) {
for (uint256 i = 1; i < 5; i++) {
uint256 temp = _tblock.valuesByTimestamp[k][i];
address temp2 = _tblock.minersByValue[k][i];
uint256 j = i;
while (j > 0 && temp < _tblock.valuesByTimestamp[k][j - 1]) {
_tblock.valuesByTimestamp[k][j] = _tblock.valuesByTimestamp[
k
][j - 1];
_tblock.minersByValue[k][j] = _tblock.minersByValue[k][
j - 1
];
j--;
}
if (j < i) {
_tblock.valuesByTimestamp[k][j] = temp;
_tblock.minersByValue[k][j] = temp2;
}
}
Request storage _request = requestDetails[_requestIds[k]];
//Save the official(finalValue), timestamp of it, 5 miners and their submitted values for it, and its block number
a = _tblock.valuesByTimestamp[k];
_request.finalValues[_timeOfLastNewValueVar] = a[2];
b[k] = a[2];
_request.minersByValue[_timeOfLastNewValueVar] = _tblock
.minersByValue[k];
_request.valuesByTimestamp[_timeOfLastNewValueVar] = _tblock
.valuesByTimestamp[k];
delete _tblock.minersByValue[k];
delete _tblock.valuesByTimestamp[k];
_request.requestTimestamps.push(_timeOfLastNewValueVar);
_request.minedBlockNum[_timeOfLastNewValueVar] = block.number;
_request.apiUintVars[_TOTAL_TIP] = 0;
}
emit NewValue(
_requestIds,
_timeOfLastNewValueVar,
b,
uints[_CURRENT_TOTAL_TIPS],
_currChallenge
);
//add timeOfLastValue to the newValueTimestamps array
newValueTimestamps.push(_timeOfLastNewValueVar);
address[5] memory miners =
requestDetails[_requestIds[0]].minersByValue[
_timeOfLastNewValueVar
];
//pay Miners Rewards
_payReward(miners, _previousTime);
uints[_T_BLOCK]++;
uint256[5] memory _topId = _getTopRequestIDs();
for (uint256 i = 0; i < 5; i++) {
currentMiners[i].value = _topId[i];
requestQ[
requestDetails[_topId[i]].apiUintVars[_REQUEST_Q_POSITION]
] = 0;
uints[_CURRENT_TOTAL_TIPS] += requestDetails[_topId[i]].apiUintVars[
_TOTAL_TIP
];
}
//Issue the the next challenge
_currChallenge = keccak256(
abi.encode(_nonce, _currChallenge, blockhash(block.number - 1))
);
bytesVars[_CURRENT_CHALLENGE] = _currChallenge; // Save hash for next proof
emit NewChallenge(
_currChallenge,
_topId,
uints[_DIFFICULTY],
uints[_CURRENT_TOTAL_TIPS]
);
}
/**
* @dev Add tip to Request value from oracle
* @param _requestId being requested to be mined
* @param _tip amount the requester is willing to pay to be get on queue. Miners
* mine the onDeckQueryHash, or the api with the highest payout pool
*/
function addTip(uint256 _requestId, uint256 _tip) external {
require(_requestId != 0, "RequestId is 0");
require(_tip != 0, "Tip should be greater than 0");
uint256 _count = uints[_REQUEST_COUNT] + 1;
if (_requestId == _count) {
uints[_REQUEST_COUNT] = _count;
} else {
require(_requestId < _count, "RequestId is not less than count");
}
_doBurn(msg.sender, _tip);
//Update the information for the request that should be mined next based on the tip submitted
updateOnDeck(_requestId, _tip);
emit TipAdded(
msg.sender,
_requestId,
_tip,
requestDetails[_requestId].apiUintVars[_TOTAL_TIP]
);
}
/**
* @dev This function updates the requestQ when addTip are ran
* @param _requestId being requested
* @param _tip is the tip to add
*/
function updateOnDeck(uint256 _requestId, uint256 _tip) internal {
Request storage _request = requestDetails[_requestId];
_request.apiUintVars[_TOTAL_TIP] = _request.apiUintVars[_TOTAL_TIP].add(
_tip
);
if (
currentMiners[0].value == _requestId ||
currentMiners[1].value == _requestId ||
currentMiners[2].value == _requestId ||
currentMiners[3].value == _requestId ||
currentMiners[4].value == _requestId
) {
uints[_CURRENT_TOTAL_TIPS] += _tip;
} else {
//if the request is not part of the requestQ[51] array
//then add to the requestQ[51] only if the _payout/tip is greater than the minimum(tip) in the requestQ[51] array
if (_request.apiUintVars[_REQUEST_Q_POSITION] == 0) {
uint256 _min;
uint256 _index;
(_min, _index) = _getMin(requestQ);
//we have to zero out the oldOne
//if the _payout is greater than the current minimum payout in the requestQ[51] or if the minimum is zero
//then add it to the requestQ array and map its index information to the requestId and the apiUintVars
if (_request.apiUintVars[_TOTAL_TIP] > _min || _min == 0) {
requestQ[_index] = _request.apiUintVars[_TOTAL_TIP];
requestDetails[requestIdByRequestQIndex[_index]]
.apiUintVars[_REQUEST_Q_POSITION] = 0;
requestIdByRequestQIndex[_index] = _requestId;
_request.apiUintVars[_REQUEST_Q_POSITION] = _index;
}
// else if the requestId is part of the requestQ[51] then update the tip for it
} else {
requestQ[_request.apiUintVars[_REQUEST_Q_POSITION]] += _tip;
}
}
}
/**
* @dev This is an internal function called by updateOnDeck that gets the min value
* @param data is an array [51] to determine the min from
* @return min the min value and it's index in the data array
*/
function _getMin(uint256[51] memory data)
internal
pure
returns (uint256 min, uint256 minIndex)
{
minIndex = data.length - 1;
min = data[minIndex];
for (uint256 i = data.length - 2; i > 0; i--) {
if (data[i] < min) {
min = data[i];
minIndex = i;
}
}
}
/**
* @dev This is an internal function called by updateOnDeck that gets the top 5 values
* @param data is an array [51] to determine the top 5 values from
* @return max the top 5 values and their index values in the data array
*/
function _getMax5(uint256[51] memory data)
internal
pure
returns (uint256[5] memory max, uint256[5] memory maxIndex)
{
uint256 min5 = data[1];
uint256 minI = 0;
for (uint256 j = 0; j < 5; j++) {
max[j] = data[j + 1]; //max[0]=data[1]
maxIndex[j] = j + 1; //maxIndex[0]= 1
if (max[j] < min5) {
min5 = max[j];
minI = j;
}
}
for (uint256 i = 6; i < data.length; i++) {
if (data[i] > min5) {
max[minI] = data[i];
maxIndex[minI] = i;
min5 = data[i];
for (uint256 j = 0; j < 5; j++) {
if (max[j] < min5) {
min5 = max[j];
minI = j;
}
}
}
}
}
/**
* @dev Getter function for the top 5 requests with highest payouts.
* This function is used within the newBlock function
* @return _requestIds the top 5 requests ids based on tips or the last 5 requests ids mined
*/
function _getTopRequestIDs()
internal
view
returns (uint256[5] memory _requestIds)
{
uint256[5] memory _max;
uint256[5] memory _index;
(_max, _index) = _getMax5(requestQ);
for (uint256 i = 0; i < 5; i++) {
if (_max[i] != 0) {
_requestIds[i] = requestIdByRequestQIndex[_index[i]];
} else {
_requestIds[i] = currentMiners[4 - i].value;
}
}
}
/**
* @dev This is an internal function called within the fallback function to help delegate calls.
* This functions helps delegate calls to the TellorGetters
* contract.
*/
function _delegate(address implementation)
internal
virtual
returns (bool succ, bytes memory ret)
{
(succ, ret) = implementation.delegatecall(msg.data);
}
/**
* @dev The tellor logic does not fit in one contract so it has been split into two:
* Tellor and TellorGetters This functions helps delegate calls to the TellorGetters
* contract.
*/
fallback() external payable {
address addr = addresses[_TELLOR_GETTERS];
(bool result, ) = _delegate(addr);
assembly {
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
import "./TellorTransfer.sol";
import "./TellorGetters.sol";
import "./Utilities.sol";
/**
* title Tellor Stake
* @dev Contains the methods related to miners staking, unstaking, initiating disputes,
* voting on them. Tellor.sol
* references this library for function's logic.
*/
contract TellorStake is TellorTransfer {
using SafeMath for uint256;
using SafeMath for int256;
//emitted when a new dispute is initialized
event NewDispute(
uint256 indexed _disputeId,
uint256 indexed _requestId,
uint256 _timestamp,
address _miner
);
//emitted when a new vote happens
event Voted(
uint256 indexed _disputeID,
bool _position,
address indexed _voter,
uint256 indexed _voteWeight
);
//emitted upon dispute tally
event DisputeVoteTallied(
uint256 indexed _disputeID,
int256 _result,
address indexed _reportedMiner,
address _reportingParty,
bool _active
);
event NewStake(address indexed _sender); //Emits upon new staker
event StakeWithdrawn(address indexed _sender); //Emits when a staker is block.timestamp no longer staked
event StakeWithdrawRequested(address indexed _sender); //Emits when a staker begins the 7 day withdraw period
/*Functions*/
/**
* @dev This function allows stakers to request to withdraw their stake (no longer stake)
* once they lock for withdraw(stakes.currentStatus = 2) they are locked for 7 days before they
* can withdraw the deposit
*/
function requestStakingWithdraw() public {
StakeInfo storage stakes = stakerDetails[msg.sender];
//Require that the miner is staked
require(stakes.currentStatus == 1, "Miner is not staked");
//Change the miner staked to locked to be withdrawStake
stakes.currentStatus = 2;
//Change the startDate to block.timestamp since the lock up period begins block.timestamp
//and the miner can only withdraw 7 days later from block.timestamp(check the withdraw function)
stakes.startDate = block.timestamp - (block.timestamp % 86400);
//Reduce the staker count
uints[_STAKE_COUNT] -= 1;
//Update the minimum dispute fee that is based on the number of stakers
updateMinDisputeFee();
emit StakeWithdrawRequested(msg.sender);
}
/**
* @dev This function allows users to withdraw their stake after a 7 day waiting
* period from request
*/
function withdrawStake() public {
StakeInfo storage stakes = stakerDetails[msg.sender];
//Require the staker has locked for withdraw(currentStatus ==2) and that 7 days have
//passed by since they locked for withdraw
require(
block.timestamp - (block.timestamp % 86400) - stakes.startDate >=
7 days,
"7 days didn't pass"
);
require(
stakes.currentStatus == 2,
"Miner was not locked for withdrawal"
);
stakes.currentStatus = 0;
emit StakeWithdrawn(msg.sender);
}
/**
* @dev This function allows miners to deposit their stake.
*/
function depositStake() public {
newStake(msg.sender);
updateMinDisputeFee();
}
/**
* @dev This internal function is used the depositStake function to successfully stake miners.
* The function updates their status/state and status start date so they are locked it so they can't withdraw
* and updates the number of stakers in the system.
*/
function newStake(address _staker) internal {
require(
balanceOf(_staker) >= uints[_STAKE_AMOUNT],
"Balance is lower than stake amount"
);
//Ensure they can only stake if they are not currently staked or if their stake time frame has ended
//and they are currently locked for withdraw
require(
stakerDetails[_staker].currentStatus == 0 ||
stakerDetails[_staker].currentStatus == 2,
"Miner is in the wrong state"
);
uints[_STAKE_COUNT] += 1;
stakerDetails[_staker] = StakeInfo({
currentStatus: 1, //this resets their stake start date to today
startDate: block.timestamp - (block.timestamp % 86400)
});
emit NewStake(_staker);
}
/**
* @dev Helps initialize a dispute by assigning it a disputeId
* when a miner returns a false/bad value on the validate array(in Tellor.ProofOfWork) it sends the
* invalidated value information to POS voting
* @param _requestId being disputed
* @param _timestamp being disputed
* @param _minerIndex the index of the miner that submitted the value being disputed. Since each official value
* requires 5 miners to submit a value.
*/
function beginDispute(
uint256 _requestId,
uint256 _timestamp,
uint256 _minerIndex
) public {
Request storage _request = requestDetails[_requestId];
require(_request.minedBlockNum[_timestamp] != 0, "Mined block is 0");
require(_minerIndex < 5, "Miner index is wrong");
//_miner is the miner being disputed. For every mined value 5 miners are saved in an array and the _minerIndex
//provided by the party initiating the dispute
address _miner = _request.minersByValue[_timestamp][_minerIndex];
bytes32 _hash =
keccak256(abi.encodePacked(_miner, _requestId, _timestamp));
//Increase the dispute count by 1
uint256 disputeId = uints[_DISPUTE_COUNT] + 1;
uints[_DISPUTE_COUNT] = disputeId;
//Ensures that a dispute is not already open for the that miner, requestId and timestamp
uint256 hashId = disputeIdByDisputeHash[_hash];
if (hashId != 0) {
disputesById[disputeId].disputeUintVars[_ORIGINAL_ID] = hashId;
} else {
disputeIdByDisputeHash[_hash] = disputeId;
hashId = disputeId;
}
uint256 origID = hashId;
uint256 dispRounds =
disputesById[origID].disputeUintVars[_DISPUTE_ROUNDS] + 1;
disputesById[origID].disputeUintVars[_DISPUTE_ROUNDS] = dispRounds;
disputesById[origID].disputeUintVars[
keccak256(abi.encode(dispRounds))
] = disputeId;
if (disputeId != origID) {
uint256 lastID =
disputesById[origID].disputeUintVars[
keccak256(abi.encode(dispRounds - 1))
];
require(
disputesById[lastID].disputeUintVars[_MIN_EXECUTION_DATE] <=
block.timestamp,
"Dispute is already open"
);
if (disputesById[lastID].executed) {
require(
block.timestamp -
disputesById[lastID].disputeUintVars[_TALLY_DATE] <=
1 days,
"Time for voting haven't elapsed"
);
}
}
uint256 _fee;
if (_minerIndex == 2) {
requestDetails[_requestId].apiUintVars[_DISPUTE_COUNT] =
requestDetails[_requestId].apiUintVars[_DISPUTE_COUNT] +
1;
//update dispute fee for this case
_fee =
uints[_STAKE_AMOUNT] *
requestDetails[_requestId].apiUintVars[_DISPUTE_COUNT];
} else {
_fee = uints[_DISPUTE_FEE] * dispRounds;
}
//maps the dispute to the Dispute struct
disputesById[disputeId].hash = _hash;
disputesById[disputeId].isPropFork = false;
disputesById[disputeId].reportedMiner = _miner;
disputesById[disputeId].reportingParty = msg.sender;
disputesById[disputeId].proposedForkAddress = address(0);
disputesById[disputeId].executed = false;
disputesById[disputeId].disputeVotePassed = false;
disputesById[disputeId].tally = 0;
//Saves all the dispute variables for the disputeId
disputesById[disputeId].disputeUintVars[_REQUEST_ID] = _requestId;
disputesById[disputeId].disputeUintVars[_TIMESTAMP] = _timestamp;
disputesById[disputeId].disputeUintVars[_VALUE] = _request
.valuesByTimestamp[_timestamp][_minerIndex];
disputesById[disputeId].disputeUintVars[_MIN_EXECUTION_DATE] =
block.timestamp +
2 days *
dispRounds;
disputesById[disputeId].disputeUintVars[_BLOCK_NUMBER] = block.number;
disputesById[disputeId].disputeUintVars[_MINER_SLOT] = _minerIndex;
disputesById[disputeId].disputeUintVars[_FEE] = _fee;
_doTransfer(msg.sender, address(this), _fee);
//Values are sorted as they come in and the official value is the median of the first five
//So the "official value" miner is always minerIndex==2. If the official value is being
//disputed, it sets its status to inDispute(currentStatus = 3) so that users are made aware it is under dispute
if (_minerIndex == 2) {
_request.inDispute[_timestamp] = true;
_request.finalValues[_timestamp] = 0;
}
stakerDetails[_miner].currentStatus = 3;
emit NewDispute(disputeId, _requestId, _timestamp, _miner);
}
/**
* @dev Allows token holders to vote
* @param _disputeId is the dispute id
* @param _supportsDispute is the vote (true=the dispute has basis false = vote against dispute)
*/
function vote(uint256 _disputeId, bool _supportsDispute) public {
Dispute storage disp = disputesById[_disputeId];
//Get the voteWeight or the balance of the user at the time/blockNumber the dispute began
uint256 voteWeight =
balanceOfAt(msg.sender, disp.disputeUintVars[_BLOCK_NUMBER]);
//Require that the msg.sender has not voted
require(disp.voted[msg.sender] != true, "Sender has already voted");
//Require that the user had a balance >0 at time/blockNumber the dispute began
require(voteWeight != 0, "User balance is 0");
//ensures miners that are under dispute cannot vote
require(
stakerDetails[msg.sender].currentStatus != 3,
"Miner is under dispute"
);
//Update user voting status to true
disp.voted[msg.sender] = true;
//Update the number of votes for the dispute
disp.disputeUintVars[_NUM_OF_VOTES] += 1;
//If the user supports the dispute increase the tally for the dispute by the voteWeight
//otherwise decrease it
if (_supportsDispute) {
disp.tally = disp.tally.add(int256(voteWeight));
} else {
disp.tally = disp.tally.sub(int256(voteWeight));
}
//Let the network kblock.timestamp the user has voted on the dispute and their casted vote
emit Voted(_disputeId, _supportsDispute, msg.sender, voteWeight);
}
/**
* @dev tallies the votes and locks the stake disbursement(currentStatus = 4) if the vote passes
* @param _disputeId is the dispute id
*/
function tallyVotes(uint256 _disputeId) public {
Dispute storage disp = disputesById[_disputeId];
//Ensure this has not already been executed/tallied
require(disp.executed == false, "Dispute has been already executed");
require(
block.timestamp >= disp.disputeUintVars[_MIN_EXECUTION_DATE],
"Time for voting haven't elapsed"
);
require(
disp.reportingParty != address(0),
"reporting Party is address 0"
);
int256 _tally = disp.tally;
if (_tally > 0) {
//Set the dispute state to passed/true
disp.disputeVotePassed = true;
}
//If the vote is not a proposed fork
if (disp.isPropFork == false) {
//Ensure the time for voting has elapsed
StakeInfo storage stakes = stakerDetails[disp.reportedMiner];
//If the vote for disputing a value is successful(disp.tally >0) then unstake the reported
// miner and transfer the stakeAmount and dispute fee to the reporting party
if (stakes.currentStatus == 3) {
stakes.currentStatus = 4;
}
}
disp.disputeUintVars[_TALLY_DATE] = block.timestamp;
disp.executed = true;
emit DisputeVoteTallied(
_disputeId,
_tally,
disp.reportedMiner,
disp.reportingParty,
disp.disputeVotePassed
);
}
/**
* @dev Allows disputer to unlock the dispute fee
* @param _disputeId to unlock fee from
*/
function unlockDisputeFee(uint256 _disputeId) public {
uint256 origID = disputeIdByDisputeHash[disputesById[_disputeId].hash];
uint256 lastID =
disputesById[origID].disputeUintVars[
keccak256(
abi.encode(
disputesById[origID].disputeUintVars[_DISPUTE_ROUNDS]
)
)
];
if (lastID == 0) {
lastID = origID;
}
Dispute storage disp = disputesById[origID];
Dispute storage last = disputesById[lastID];
//disputeRounds is increased by 1 so that the _id is not a negative number when it is the first time a dispute is initiated
uint256 dispRounds = disp.disputeUintVars[_DISPUTE_ROUNDS];
if (dispRounds == 0) {
dispRounds = 1;
}
uint256 _id;
require(disp.disputeUintVars[_PAID] == 0, "already paid out");
require(
block.timestamp - last.disputeUintVars[_TALLY_DATE] > 1 days,
"Time for voting haven't elapsed"
);
StakeInfo storage stakes = stakerDetails[disp.reportedMiner];
disp.disputeUintVars[_PAID] = 1;
if (last.disputeVotePassed == true) {
//Changing the currentStatus and startDate unstakes the reported miner and transfers the stakeAmount
stakes.startDate = block.timestamp - (block.timestamp % 86400);
//Reduce the staker count
uints[_STAKE_COUNT] -= 1;
//Update the minimum dispute fee that is based on the number of stakers
updateMinDisputeFee();
//Decreases the stakerCount since the miner's stake is being slashed
if (stakes.currentStatus == 4) {
stakes.currentStatus = 5;
_doTransfer(
disp.reportedMiner,
disp.reportingParty,
uints[_STAKE_AMOUNT]
);
stakes.currentStatus = 0;
}
for (uint256 i = 0; i < dispRounds; i++) {
_id = disp.disputeUintVars[
keccak256(abi.encode(dispRounds - i))
];
if (_id == 0) {
_id = origID;
}
Dispute storage disp2 = disputesById[_id];
//transfer fee adjusted based on number of miners if the minerIndex is not 2(official value)
_doTransfer(
address(this),
disp2.reportingParty,
disp2.disputeUintVars[_FEE]
);
}
} else {
stakes.currentStatus = 1;
TellorStorage.Request storage _request =
requestDetails[disp.disputeUintVars[_REQUEST_ID]];
if (disp.disputeUintVars[_MINER_SLOT] == 2) {
//note we still don't put timestamp back into array (is this an issue? (shouldn't be))
_request.finalValues[disp.disputeUintVars[_TIMESTAMP]] = disp
.disputeUintVars[_VALUE];
}
if (_request.inDispute[disp.disputeUintVars[_TIMESTAMP]] == true) {
_request.inDispute[disp.disputeUintVars[_TIMESTAMP]] = false;
}
for (uint256 i = 0; i < dispRounds; i++) {
_id = disp.disputeUintVars[
keccak256(abi.encode(dispRounds - i))
];
if (_id != 0) {
last = disputesById[_id]; //handling if happens during an upgrade
}
_doTransfer(
address(this),
last.reportedMiner,
disputesById[_id].disputeUintVars[_FEE]
);
}
}
if (disp.disputeUintVars[_MINER_SLOT] == 2) {
requestDetails[disp.disputeUintVars[_REQUEST_ID]].apiUintVars[
_DISPUTE_COUNT
]--;
}
}
/**
* @dev This function updates the minimum dispute fee as a function of the amount
* of staked miners
*/
function updateMinDisputeFee() public {
uint256 _stakeAmt = uints[_STAKE_AMOUNT];
uint256 _trgtMiners = uints[_TARGET_MINERS];
uints[_DISPUTE_FEE] = SafeMath.max(
15e18,
(_stakeAmt -
((_stakeAmt *
(SafeMath.min(_trgtMiners, uints[_STAKE_COUNT]) * 1000)) /
_trgtMiners) /
1000)
);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
import "./SafeMath.sol";
import "./TellorStorage.sol";
import "./TellorVariables.sol";
import "./Utilities.sol";
/**
* @title Tellor Getters
* @dev Oracle contract with all tellor getter functions
*/
contract TellorGetters is TellorStorage, TellorVariables, Utilities {
using SafeMath for uint256;
/**
* @dev This function tells you if a given challenge has been completed by a given miner
* @param _challenge the challenge to search for
* @param _miner address that you want to know if they solved the challenge
* @return true if the _miner address provided solved the
*/
function didMine(bytes32 _challenge, address _miner)
public
view
returns (bool)
{
return minersByChallenge[_challenge][_miner];
}
/**
* @dev Checks if an address voted in a given dispute
* @param _disputeId to look up
* @param _address to look up
* @return bool of whether or not party voted
*/
function didVote(uint256 _disputeId, address _address)
external
view
returns (bool)
{
return disputesById[_disputeId].voted[_address];
}
/**
* @dev allows Tellor to read data from the addressVars mapping
* @param _data is the keccak256("variable_name") of the variable that is being accessed.
* These are examples of how the variables are saved within other functions:
* addressVars[keccak256("_owner")]
* addressVars[keccak256("tellorContract")]
* @return address of the requested variable
*/
function getAddressVars(bytes32 _data) external view returns (address) {
return addresses[_data];
}
/**
* @dev Gets all dispute variables
* @param _disputeId to look up
* @return bytes32 hash of dispute
* bool executed where true if it has been voted on
* bool disputeVotePassed
* bool isPropFork true if the dispute is a proposed fork
* address of reportedMiner
* address of reportingParty
* address of proposedForkAddress
* uint of requestId
* uint of timestamp
* uint of value
* uint of minExecutionDate
* uint of numberOfVotes
* uint of blocknumber
* uint of minerSlot
* uint of quorum
* uint of fee
* int count of the current tally
*/
function getAllDisputeVars(uint256 _disputeId)
public
view
returns (
bytes32,
bool,
bool,
bool,
address,
address,
address,
uint256[9] memory,
int256
)
{
Dispute storage disp = disputesById[_disputeId];
return (
disp.hash,
disp.executed,
disp.disputeVotePassed,
disp.isPropFork,
disp.reportedMiner,
disp.reportingParty,
disp.proposedForkAddress,
[
disp.disputeUintVars[_REQUEST_ID],
disp.disputeUintVars[_TIMESTAMP],
disp.disputeUintVars[_VALUE],
disp.disputeUintVars[_MIN_EXECUTION_DATE],
disp.disputeUintVars[_NUM_OF_VOTES],
disp.disputeUintVars[_BLOCK_NUMBER],
disp.disputeUintVars[_MINER_SLOT],
disp.disputeUintVars[keccak256("quorum")],
disp.disputeUintVars[_FEE]
],
disp.tally
);
}
/**
* @dev Checks if a given hash of miner,requestId has been disputed
* @param _hash is the sha256(abi.encodePacked(_miners[2],_requestId,_timestamp));
* @return uint disputeId
*/
function getDisputeIdByDisputeHash(bytes32 _hash)
external
view
returns (uint256)
{
return disputeIdByDisputeHash[_hash];
}
/**
* @dev Checks for uint variables in the disputeUintVars mapping based on the disputeId
* @param _disputeId is the dispute id;
* @param _data the variable to pull from the mapping. _data = keccak256("variable_name") where variable_name is
* the variables/strings used to save the data in the mapping. The variables names are
* commented out under the disputeUintVars under the Dispute struct
* @return uint value for the bytes32 data submitted
*/
function getDisputeUintVars(uint256 _disputeId, bytes32 _data)
external
view
returns (uint256)
{
return disputesById[_disputeId].disputeUintVars[_data];
}
/**
* @dev Gets the a value for the latest timestamp available
* @return value for timestamp of last proof of work submitted
* @return true if the is a timestamp for the lastNewValue
*/
function getLastNewValue() external view returns (uint256, bool) {
return (
retrieveData(
requestIdByTimestamp[uints[_TIME_OF_LAST_NEW_VALUE]],
uints[_TIME_OF_LAST_NEW_VALUE]
),
true
);
}
/**
* @dev Gets the a value for the latest timestamp available
* @param _requestId being requested
* @return value for timestamp of last proof of work submitted and if true if it exist or 0 and false if it doesn't
*/
function getLastNewValueById(uint256 _requestId)
external
view
returns (uint256, bool)
{
Request storage _request = requestDetails[_requestId];
if (_request.requestTimestamps.length != 0) {
return (
retrieveData(
_requestId,
_request.requestTimestamps[
_request.requestTimestamps.length - 1
]
),
true
);
} else {
return (0, false);
}
}
/**
* @dev Gets blocknumber for mined timestamp
* @param _requestId to look up
* @param _timestamp is the timestamp to look up blocknumber
* @return uint of the blocknumber which the dispute was mined
*/
function getMinedBlockNum(uint256 _requestId, uint256 _timestamp)
external
view
returns (uint256)
{
return requestDetails[_requestId].minedBlockNum[_timestamp];
}
/**
* @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp
* @param _requestId to look up
* @param _timestamp is the timestamp to look up miners for
* @return the 5 miners' addresses
*/
function getMinersByRequestIdAndTimestamp(
uint256 _requestId,
uint256 _timestamp
) external view returns (address[5] memory) {
return requestDetails[_requestId].minersByValue[_timestamp];
}
/**
* @dev Counts the number of values that have been submitted for the request
* if called for the currentRequest being mined it can tell you how many miners have submitted a value for that
* request so far
* @param _requestId the requestId to look up
* @return uint count of the number of values received for the requestId
*/
function getNewValueCountbyRequestId(uint256 _requestId)
external
view
returns (uint256)
{
return requestDetails[_requestId].requestTimestamps.length;
}
/**
* @dev Getter function for the specified requestQ index
* @param _index to look up in the requestQ array
* @return uint of requestId
*/
function getRequestIdByRequestQIndex(uint256 _index)
external
view
returns (uint256)
{
require(_index <= 50, "RequestQ index is above 50");
return requestIdByRequestQIndex[_index];
}
/**
* @dev Getter function for requestId based on timestamp
* @param _timestamp to check requestId
* @return uint of requestId
*/
function getRequestIdByTimestamp(uint256 _timestamp)
external
view
returns (uint256)
{
return requestIdByTimestamp[_timestamp];
}
/**
* @dev Getter function for the requestQ array
* @return the requestQ array
*/
function getRequestQ() public view returns (uint256[51] memory) {
return requestQ;
}
/**
* @dev Allows access to the uint variables saved in the apiUintVars under the requestDetails struct
* for the requestId specified
* @param _requestId to look up
* @param _data the variable to pull from the mapping. _data = keccak256("variable_name") where variable_name is
* the variables/strings used to save the data in the mapping. The variables names are
* commented out under the apiUintVars under the requestDetails struct
* @return uint value of the apiUintVars specified in _data for the requestId specified
*/
function getRequestUintVars(uint256 _requestId, bytes32 _data)
external
view
returns (uint256)
{
return requestDetails[_requestId].apiUintVars[_data];
}
/**
* @dev Gets the API struct variables that are not mappings
* @param _requestId to look up
* @return uint of index in requestQ array
* @return uint of current payout/tip for this requestId
*/
function getRequestVars(uint256 _requestId)
external
view
returns (uint256, uint256)
{
Request storage _request = requestDetails[_requestId];
return (
_request.apiUintVars[_REQUEST_Q_POSITION],
_request.apiUintVars[_TOTAL_TIP]
);
}
/**
* @dev This function allows users to retrieve all information about a staker
* @param _staker address of staker inquiring about
* @return uint current state of staker
* @return uint startDate of staking
*/
function getStakerInfo(address _staker)
external
view
returns (uint256, uint256)
{
return (
stakerDetails[_staker].currentStatus,
stakerDetails[_staker].startDate
);
}
/**
* @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp
* @param _requestId to look up
* @param _timestamp is the timestamp to look up miners for
* @return address[5] array of 5 addresses of miners that mined the requestId
*/
function getSubmissionsByTimestamp(uint256 _requestId, uint256 _timestamp)
external
view
returns (uint256[5] memory)
{
return requestDetails[_requestId].valuesByTimestamp[_timestamp];
}
/**
* @dev Gets the timestamp for the value based on their index
* @param _requestID is the requestId to look up
* @param _index is the value index to look up
* @return uint timestamp
*/
function getTimestampbyRequestIDandIndex(uint256 _requestID, uint256 _index)
external
view
returns (uint256)
{
return requestDetails[_requestID].requestTimestamps[_index];
}
/**
* @dev Getter for the variables saved under the TellorStorageStruct uints variable
* @param _data the variable to pull from the mapping. _data = keccak256("variable_name")
* where variable_name is the variables/strings used to save the data in the mapping.
* The variables names in the TellorVariables contract
* @return uint of specified variable
*/
function getUintVar(bytes32 _data) public view returns (uint256) {
return uints[_data];
}
/**
* @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp
* @param _requestId to look up
* @param _timestamp is the timestamp to look up miners for
* @return bool true if requestId/timestamp is under dispute
*/
function isInDispute(uint256 _requestId, uint256 _timestamp)
external
view
returns (bool)
{
return requestDetails[_requestId].inDispute[_timestamp];
}
/**
* @dev Retrieve value from oracle based on timestamp
* @param _requestId being requested
* @param _timestamp to retrieve data/value from
* @return value for timestamp submitted
*/
function retrieveData(uint256 _requestId, uint256 _timestamp)
public
view
returns (uint256)
{
return requestDetails[_requestId].finalValues[_timestamp];
}
/**
* @dev Getter for the total_supply of oracle tokens
* @return uint total supply
*/
function totalSupply() external view returns (uint256) {
return uints[_TOTAL_SUPPLY];
}
/**
* @dev Allows users to access the token's name
*/
function name() external pure returns (string memory) {
return "Tellor Tributes";
}
/**
* @dev Allows users to access the token's symbol
*/
function symbol() external pure returns (string memory) {
return "TRB";
}
/**
* @dev Allows users to access the number of decimals
*/
function decimals() external pure returns (uint8) {
return 18;
}
/**
* @dev Getter function for the requestId being mined
* returns the currentChallenge, array of requestIDs, difficulty, and the current Tip of the 5 IDs
*/
function getNewCurrentVariables()
external
view
returns (
bytes32 _challenge,
uint256[5] memory _requestIds,
uint256 _diff,
uint256 _tip
)
{
for (uint256 i = 0; i < 5; i++) {
_requestIds[i] = currentMiners[i].value;
}
return (
bytesVars[_CURRENT_CHALLENGE],
_requestIds,
uints[_DIFFICULTY],
uints[_CURRENT_TOTAL_TIPS]
);
}
/**
* @dev Getter function for next requestIds on queue/request with highest payouts at time the function is called
*/
function getNewVariablesOnDeck()
external
view
returns (uint256[5] memory idsOnDeck, uint256[5] memory tipsOnDeck)
{
idsOnDeck = getTopRequestIDs();
for (uint256 i = 0; i < 5; i++) {
tipsOnDeck[i] = requestDetails[idsOnDeck[i]].apiUintVars[
_TOTAL_TIP
];
}
}
/**
* @dev Getter function for the top 5 requests with highest payouts. This function is used within the getNewVariablesOnDeck function
*/
function getTopRequestIDs()
public
view
returns (uint256[5] memory _requestIds)
{
uint256[5] memory _max;
uint256[5] memory _index;
(_max, _index) = getMax5(requestQ);
for (uint256 i = 0; i < 5; i++) {
if (_max[i] != 0) {
_requestIds[i] = requestIdByRequestQIndex[_index[i]];
} else {
_requestIds[i] = currentMiners[4 - i].value;
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
//Functions for retrieving min and Max in 51 length array (requestQ)
//Taken partly from: https://github.com/modular-network/ethereum-libraries-array-utils/blob/master/contracts/Array256Lib.sol
contract Utilities {
/**
* @dev This is an internal function called by updateOnDeck that gets the top 5 values
* @param data is an array [51] to determine the top 5 values from
* @return max the top 5 values and their index values in the data array
*/
function getMax5(uint256[51] memory data)
public
view
returns (uint256[5] memory max, uint256[5] memory maxIndex)
{
uint256 min5 = data[1];
uint256 minI = 0;
for (uint256 j = 0; j < 5; j++) {
max[j] = data[j + 1]; //max[0]=data[1]
maxIndex[j] = j + 1; //maxIndex[0]= 1
if (max[j] < min5) {
min5 = max[j];
minI = j;
}
}
for (uint256 i = 6; i < data.length; i++) {
if (data[i] > min5) {
max[minI] = data[i];
maxIndex[minI] = i;
min5 = data[i];
for (uint256 j = 0; j < 5; j++) {
if (max[j] < min5) {
min5 = max[j];
minI = j;
}
}
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
abstract contract ITellor {
event NewTellorAddress(address _newTellor);
event NewDispute(
uint256 indexed _disputeId,
uint256 indexed _requestId,
uint256 _timestamp,
address _miner
);
event Voted(
uint256 indexed _disputeID,
bool _position,
address indexed _voter,
uint256 indexed _voteWeight
);
event DisputeVoteTallied(
uint256 indexed _disputeID,
int256 _result,
address indexed _reportedMiner,
address _reportingParty,
bool _active
);
event TipAdded(
address indexed _sender,
uint256 indexed _requestId,
uint256 _tip,
uint256 _totalTips
);
event NewChallenge(
bytes32 indexed _currentChallenge,
uint256[5] _currentRequestId,
uint256 _difficulty,
uint256 _totalTips
);
event NewValue(
uint256[5] _requestId,
uint256 _time,
uint256[5] _value,
uint256 _totalTips,
bytes32 indexed _currentChallenge
);
event NonceSubmitted(
address indexed _miner,
string _nonce,
uint256[5] _requestId,
uint256[5] _value,
bytes32 indexed _currentChallenge
);
event OwnershipTransferred(
address indexed _previousOwner,
address indexed _newOwner
);
event OwnershipProposed(
address indexed _previousOwner,
address indexed _newOwner
);
event NewStake(address indexed _sender); //Emits upon new staker
event StakeWithdrawn(address indexed _sender); //Emits when a staker is now no longer staked
event StakeWithdrawRequested(address indexed _sender); //Emits when a staker begins the 7 day withdraw period
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
); //ERC20 Approval event
event Transfer(address indexed _from, address indexed _to, uint256 _value); //ERC20 Transfer Event
function changeDeity(address _newDeity) external virtual;
function changeTellorContract(address _tellorContract) external virtual;
function allowance(address _user, address _spender)
external
view
virtual
returns (uint256);
function allowedToTrade(address _user, uint256 _amount)
external
view
virtual
returns (bool);
function balanceOf(address _user) external view virtual returns (uint256);
function balanceOfAt(address _user, uint256 _blockNumber)
external
view
virtual
returns (uint256);
function didMine(bytes32 _challenge, address _miner)
external
view
virtual
returns (bool);
function didVote(uint256 _disputeId, address _address)
external
view
virtual
returns (bool);
function getAddressVars(bytes32 _data)
external
view
virtual
returns (address);
function getAllDisputeVars(uint256 _disputeId)
public
view
virtual
returns (
bytes32,
bool,
bool,
bool,
address,
address,
address,
uint256[9] memory,
int256
);
function getCurrentVariables()
external
view
virtual
returns (
bytes32,
uint256,
uint256,
string memory,
uint256,
uint256
);
function getDisputeIdByDisputeHash(bytes32 _hash)
external
view
virtual
returns (uint256);
function getDisputeUintVars(uint256 _disputeId, bytes32 _data)
external
view
virtual
returns (uint256);
function getLastNewValue() external view virtual returns (uint256, bool);
function getLastNewValueById(uint256 _requestId)
external
view
virtual
returns (uint256, bool);
function getMinedBlockNum(uint256 _requestId, uint256 _timestamp)
external
view
virtual
returns (uint256);
function getMinersByRequestIdAndTimestamp(
uint256 _requestId,
uint256 _timestamp
) external view virtual returns (address[5] memory);
function getNewValueCountbyRequestId(uint256 _requestId)
external
view
virtual
returns (uint256);
function getRequestIdByRequestQIndex(uint256 _index)
external
view
virtual
returns (uint256);
function getRequestIdByTimestamp(uint256 _timestamp)
external
view
virtual
returns (uint256);
function getRequestIdByQueryHash(bytes32 _request)
external
view
virtual
returns (uint256);
function getRequestQ() public view virtual returns (uint256[51] memory);
function getRequestUintVars(uint256 _requestId, bytes32 _data)
external
view
virtual
returns (uint256);
function getRequestVars(uint256 _requestId)
external
view
virtual
returns (uint256, uint256);
function getStakerInfo(address _staker)
external
view
virtual
returns (uint256, uint256);
function getSubmissionsByTimestamp(uint256 _requestId, uint256 _timestamp)
external
view
virtual
returns (uint256[5] memory);
function getTimestampbyRequestIDandIndex(uint256 _requestID, uint256 _index)
external
view
virtual
returns (uint256);
function getUintVar(bytes32 _data) public view virtual returns (uint256);
function getVariablesOnDeck()
external
view
virtual
returns (
uint256,
uint256,
string memory
);
function isInDispute(uint256 _requestId, uint256 _timestamp)
external
view
virtual
returns (bool);
function retrieveData(uint256 _requestId, uint256 _timestamp)
external
view
virtual
returns (uint256);
function totalSupply() external view virtual returns (uint256);
function beginDispute(
uint256 _requestId,
uint256 _timestamp,
uint256 _minerIndex
) external virtual;
function vote(uint256 _disputeId, bool _supportsDispute) external virtual;
function tallyVotes(uint256 _disputeId) external virtual;
function proposeFork(address _propNewTellorAddress) external virtual;
function addTip(uint256 _requestId, uint256 _tip) external virtual;
function submitMiningSolution(
string calldata _nonce,
uint256[5] calldata _requestId,
uint256[5] calldata _value
) external virtual;
function proposeOwnership(address payable _pendingOwner) external virtual;
function claimOwnership() external virtual;
function depositStake() external virtual;
function requestStakingWithdraw() external virtual;
function withdrawStake() external virtual;
function approve(address _spender, uint256 _amount)
external
virtual
returns (bool);
function transfer(address _to, uint256 _amount)
external
virtual
returns (bool);
function transferFrom(
address _from,
address _to,
uint256 _amount
) external virtual returns (bool);
function name() external pure virtual returns (string memory);
function symbol() external pure virtual returns (string memory);
function decimals() external pure virtual returns (uint8);
function getNewCurrentVariables()
external
view
virtual
returns (
bytes32 _challenge,
uint256[5] memory _requestIds,
uint256 _difficutly,
uint256 _tip
);
function getTopRequestIDs()
external
view
virtual
returns (uint256[5] memory _requestIds);
function getNewVariablesOnDeck()
external
view
virtual
returns (uint256[5] memory idsOnDeck, uint256[5] memory tipsOnDeck);
function updateTellor(uint256 _disputeId) external virtual;
function unlockDisputeFee(uint256 _disputeId) external virtual;
//Test Functions
function theLazyCoon(address _address, uint256 _amount) external virtual;
function testSubmitMiningSolution(
string calldata _nonce,
uint256[5] calldata _requestId,
uint256[5] calldata _value
) external virtual;
function manuallySetDifficulty(uint256 _diff) external virtual {}
function migrate() external {}
function getMax(uint256[51] memory data)
public
view
virtual
returns (uint256 max, uint256 maxIndex);
function getMin(uint256[51] memory data)
public
view
virtual
returns (uint256 min, uint256 minIndex);
function getMax5(uint256[51] memory data)
public
view
virtual
returns (uint256[5] memory max, uint256[5] memory maxIndex);
function changeTellorGetters(address _tGetters) external virtual;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
//Slightly modified SafeMath library - includes a min and max function, removes useless div function
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
function add(int256 a, int256 b) internal pure returns (int256 c) {
if (b > 0) {
c = a + b;
assert(c >= a);
} else {
c = a + b;
assert(c <= a);
}
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function max(int256 a, int256 b) internal pure returns (uint256) {
return a > b ? uint256(a) : uint256(b);
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function sub(int256 a, int256 b) internal pure returns (int256 c) {
if (b > 0) {
c = a - b;
assert(c <= a);
} else {
c = a - b;
assert(c >= a);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
import "./SafeMath.sol";
import "./TellorStorage.sol";
import "./TellorVariables.sol";
/**
* @title Tellor Transfer
* @dev Contains the methods related to transfers and ERC20, its storage and hashes of tellor variable
* that are used to save gas on transactions.
*/
contract TellorTransfer is TellorStorage, TellorVariables {
using SafeMath for uint256;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
/*Functions*/
/**
* @dev Allows for a transfer of tokens to _to
* @param _to The address to send tokens to
* @param _amount The amount of tokens to send
*/
function transfer(address _to, uint256 _amount)
public
returns (bool success)
{
_doTransfer(msg.sender, _to, _amount);
return true;
}
/**
* @notice Send _amount tokens to _to from _from on the condition it
* is approved by _from
* @param _from The address holding the tokens being transferred
* @param _to The address of the recipient
* @param _amount The amount of tokens to be transferred
*/
function transferFrom(
address _from,
address _to,
uint256 _amount
) public returns (bool success) {
require(
_allowances[_from][msg.sender] >= _amount,
"Allowance is wrong"
);
_allowances[_from][msg.sender] -= _amount;
_doTransfer(_from, _to, _amount);
return true;
}
/**
* @dev This function approves a _spender an _amount of tokens to use
* @param _spender address
* @param _amount amount the spender is being approved for
* @return true if spender approved successfully
*/
function approve(address _spender, uint256 _amount) public returns (bool) {
require(
msg.sender != address(0),
"ERC20: approve from the zero address"
);
require(_spender != address(0), "ERC20: approve to the zero address");
_allowances[msg.sender][_spender] = _amount;
emit Approval(msg.sender, _spender, _amount);
return true;
}
/**
* @dev Getter function for remaining spender balance
* @param _user address of party with the balance
* @param _spender address of spender of parties said balance
* @return Returns the remaining allowance of tokens granted to the _spender from the _user
*/
function allowance(address _user, address _spender)
public
view
returns (uint256)
{
return _allowances[_user][_spender];
}
/**
* @dev Completes transfers by updating the balances on the current block number
* and ensuring the amount does not contain tokens staked for mining
* @param _from address to transfer from
* @param _to address to transfer to
* @param _amount to transfer
*/
function _doTransfer(
address _from,
address _to,
uint256 _amount
) internal {
require(_amount != 0, "Tried to send non-positive amount");
require(_to != address(0), "Receiver is 0 address");
require(
allowedToTrade(_from, _amount),
"Should have sufficient balance to trade"
);
uint256 previousBalance = balanceOf(_from);
updateBalanceAtNow(_from, previousBalance - _amount);
previousBalance = balanceOf(_to);
require(
previousBalance + _amount >= previousBalance,
"Overflow happened"
); // Check for overflow
updateBalanceAtNow(_to, previousBalance + _amount);
emit Transfer(_from, _to, _amount);
}
/**
* @dev Helps swap the old Tellor contract Tokens to the new one
* @param _to is the adress to send minted amount to
* @param _amount is the amount of TRB to send
*/
function _doMint(address _to, uint256 _amount) internal {
require(_amount != 0, "Tried to mint non-positive amount");
require(_to != address(0), "Receiver is 0 address");
uint256 previousBalance = balanceOf(_to);
require(
previousBalance + _amount >= previousBalance,
"Overflow happened"
); // Check for overflow
uint256 previousSupply = uints[_TOTAL_SUPPLY];
require(
previousSupply + _amount >= previousSupply,
"Overflow happened"
);
uints[_TOTAL_SUPPLY] += _amount;
updateBalanceAtNow(_to, previousBalance + _amount);
emit Transfer(address(0), _to, _amount);
}
/**
* @dev Helps burn TRB Tokens
* @param _from is the adress to burn or remove TRB amount
* @param _amount is the amount of TRB to burn
*/
function _doBurn(address _from, uint256 _amount) internal {
if (_amount == 0) return;
uint256 previousBalance = balanceOf(_from);
require(
previousBalance - _amount <= previousBalance,
"Overflow happened"
); // Check for overflow
uint256 previousSupply = uints[_TOTAL_SUPPLY];
require(
previousSupply - _amount <= previousSupply,
"Overflow happened"
);
updateBalanceAtNow(_from, previousBalance - _amount);
uints[_TOTAL_SUPPLY] -= _amount;
}
/**
* @dev Gets balance of owner specified
* @param _user is the owner address used to look up the balance
* @return Returns the balance associated with the passed in _user
*/
function balanceOf(address _user) public view returns (uint256) {
return balanceOfAt(_user, block.number);
}
/**
* @dev Queries the balance of _user at a specific _blockNumber
* @param _user The address from which the balance will be retrieved
* @param _blockNumber The block number when the balance is queried
* @return The balance at _blockNumber specified
*/
function balanceOfAt(address _user, uint256 _blockNumber)
public
view
returns (uint256)
{
TellorStorage.Checkpoint[] storage checkpoints = balances[_user];
if (
checkpoints.length == 0 || checkpoints[0].fromBlock > _blockNumber
) {
return 0;
} else {
if (_blockNumber >= checkpoints[checkpoints.length - 1].fromBlock)
return checkpoints[checkpoints.length - 1].value;
// Binary search of the value in the array
uint256 min = 0;
uint256 max = checkpoints.length - 2;
while (max > min) {
uint256 mid = (max + min + 1) / 2;
if (checkpoints[mid].fromBlock == _blockNumber) {
return checkpoints[mid].value;
} else if (checkpoints[mid].fromBlock < _blockNumber) {
min = mid;
} else {
max = mid - 1;
}
}
return checkpoints[min].value;
}
}
/**
* @dev This function returns whether or not a given user is allowed to trade a given amount
* and removing the staked amount from their balance if they are staked
* @param _user address of user
* @param _amount to check if the user can spend
* @return true if they are allowed to spend the amount being checked
*/
function allowedToTrade(address _user, uint256 _amount)
public
view
returns (bool)
{
if (
stakerDetails[_user].currentStatus != 0 &&
stakerDetails[_user].currentStatus < 5
) {
//Subtracts the stakeAmount from balance if the _user is staked
if (balanceOf(_user) - uints[_STAKE_AMOUNT] >= _amount) {
return true;
}
return false;
}
return (balanceOf(_user) >= _amount);
}
/**
* @dev Updates balance for from and to on the current block number via doTransfer
* @param _value is the new balance
*/
function updateBalanceAtNow(address _user, uint256 _value) public {
Checkpoint[] storage checkpoints = balances[_user];
if (
checkpoints.length == 0 ||
checkpoints[checkpoints.length - 1].fromBlock != block.number
) {
checkpoints.push(
TellorStorage.Checkpoint({
fromBlock: uint128(block.number),
value: uint128(_value)
})
);
} else {
TellorStorage.Checkpoint storage oldCheckPoint =
checkpoints[checkpoints.length - 1];
oldCheckPoint.value = uint128(_value);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
/**
* @title Tellor Oracle Storage Library
* @dev Contains all the variables/structs used by Tellor
*/
contract TellorStorage {
//Internal struct for use in proof-of-work submission
struct Details {
uint256 value;
address miner;
}
struct Dispute {
bytes32 hash; //unique hash of dispute: keccak256(_miner,_requestId,_timestamp)
int256 tally; //current tally of votes for - against measure
bool executed; //is the dispute settled
bool disputeVotePassed; //did the vote pass?
bool isPropFork; //true for fork proposal NEW
address reportedMiner; //miner who submitted the 'bad value' will get disputeFee if dispute vote fails
address reportingParty; //miner reporting the 'bad value'-pay disputeFee will get reportedMiner's stake if dispute vote passes
address proposedForkAddress; //new fork address (if fork proposal)
mapping(bytes32 => uint256) disputeUintVars;
//Each of the variables below is saved in the mapping disputeUintVars for each disputeID
//e.g. TellorStorageStruct.DisputeById[disputeID].disputeUintVars[keccak256("requestId")]
//These are the variables saved in this mapping:
// uint keccak256("requestId");//apiID of disputed value
// uint keccak256("timestamp");//timestamp of disputed value
// uint keccak256("value"); //the value being disputed
// uint keccak256("minExecutionDate");//7 days from when dispute initialized
// uint keccak256("numberOfVotes");//the number of parties who have voted on the measure
// uint keccak256("blockNumber");// the blocknumber for which votes will be calculated from
// uint keccak256("minerSlot"); //index in dispute array
// uint keccak256("fee"); //fee paid corresponding to dispute
mapping(address => bool) voted; //mapping of address to whether or not they voted
}
struct StakeInfo {
uint256 currentStatus; //0-not Staked, 1=Staked, 2=LockedForWithdraw 3= OnDispute 4=ReadyForUnlocking 5=Unlocked
uint256 startDate; //stake start date
}
//Internal struct to allow balances to be queried by blocknumber for voting purposes
struct Checkpoint {
uint128 fromBlock; // fromBlock is the block number that the value was generated from
uint128 value; // value is the amount of tokens at a specific block number
}
struct Request {
uint256[] requestTimestamps; //array of all newValueTimestamps requested
mapping(bytes32 => uint256) apiUintVars;
//Each of the variables below is saved in the mapping apiUintVars for each api request
//e.g. requestDetails[_requestId].apiUintVars[keccak256("totalTip")]
//These are the variables saved in this mapping:
// uint keccak256("requestQPosition"); //index in requestQ
// uint keccak256("totalTip");//bonus portion of payout
mapping(uint256 => uint256) minedBlockNum; //[apiId][minedTimestamp]=>block.number
//This the time series of finalValues stored by the contract where uint UNIX timestamp is mapped to value
mapping(uint256 => uint256) finalValues;
mapping(uint256 => bool) inDispute; //checks if API id is in dispute or finalized.
mapping(uint256 => address[5]) minersByValue;
mapping(uint256 => uint256[5]) valuesByTimestamp;
}
uint256[51] requestQ; //uint50 array of the top50 requests by payment amount
uint256[] public newValueTimestamps; //array of all timestamps requested
//Address fields in the Tellor contract are saved the addressVars mapping
//e.g. addressVars[keccak256("tellorContract")] = address
//These are the variables saved in this mapping:
// address keccak256("tellorContract");//Tellor address
// address keccak256("_owner");//Tellor Owner address
// address keccak256("_deity");//Tellor Owner that can do things at will
// address keccak256("pending_owner"); // The proposed new owner
//uint fields in the Tellor contract are saved the uintVars mapping
//e.g. uintVars[keccak256("decimals")] = uint
//These are the variables saved in this mapping:
// keccak256("decimals"); //18 decimal standard ERC20
// keccak256("disputeFee");//cost to dispute a mined value
// keccak256("disputeCount");//totalHistoricalDisputes
// keccak256("total_supply"); //total_supply of the token in circulation
// keccak256("stakeAmount");//stakeAmount for miners (we can cut gas if we just hardcoded it in...or should it be variable?)
// keccak256("stakerCount"); //number of parties currently staked
// keccak256("timeOfLastNewValue"); // time of last challenge solved
// keccak256("difficulty"); // Difficulty of current block
// keccak256("currentTotalTips"); //value of highest api/timestamp PayoutPool
// keccak256("currentRequestId"); //API being mined--updates with the ApiOnQ Id
// keccak256("requestCount"); // total number of requests through the system
// keccak256("slotProgress");//Number of miners who have mined this value so far
// keccak256("miningReward");//Mining Reward in PoWo tokens given to all miners per value
// keccak256("timeTarget"); //The time between blocks (mined Oracle values)
// keccak256("_tblock"); //
// keccak256("runningTips"); // VAriable to track running tips
// keccak256("currentReward"); // The current reward
// keccak256("devShare"); // The amount directed towards th devShare
// keccak256("currentTotalTips"); //
//This is a boolean that tells you if a given challenge has been completed by a given miner
mapping(uint256 => uint256) requestIdByTimestamp; //minedTimestamp to apiId
mapping(uint256 => uint256) requestIdByRequestQIndex; //link from payoutPoolIndex (position in payout pool array) to apiId
mapping(uint256 => Dispute) public disputesById; //disputeId=> Dispute details
mapping(bytes32 => uint256) public requestIdByQueryHash; // api bytes32 gets an id = to count of requests array
mapping(bytes32 => uint256) public disputeIdByDisputeHash; //maps a hash to an ID for each dispute
mapping(bytes32 => mapping(address => bool)) public minersByChallenge;
Details[5] public currentMiners; //This struct is for organizing the five mined values to find the median
mapping(address => StakeInfo) stakerDetails; //mapping from a persons address to their staking info
mapping(uint256 => Request) requestDetails;
mapping(bytes32 => uint256) public uints;
mapping(bytes32 => address) public addresses;
mapping(bytes32 => bytes32) public bytesVars;
//ERC20 storage
mapping(address => Checkpoint[]) public balances;
mapping(address => mapping(address => uint256)) public _allowances;
//Migration storage
mapping(address => bool) public migrated;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
// Helper contract to store hashes of variables
contract TellorVariables {
bytes32 constant _BLOCK_NUMBER =
0x4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c; //keccak256("_BLOCK_NUMBER");
bytes32 constant _CURRENT_CHALLENGE =
0xd54702836c9d21d0727ffacc3e39f57c92b5ae0f50177e593bfb5ec66e3de280; //keccak256("_CURRENT_CHALLENGE");
bytes32 constant _CURRENT_REQUESTID =
0xf5126bb0ac211fbeeac2c0e89d4c02ac8cadb2da1cfb27b53c6c1f4587b48020; //keccak256("_CURRENT_REQUESTID");
bytes32 constant _CURRENT_REWARD =
0xd415862fd27fb74541e0f6f725b0c0d5b5fa1f22367d9b78ec6f61d97d05d5f8; //keccak256("_CURRENT_REWARD");
bytes32 constant _CURRENT_TOTAL_TIPS =
0x09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a; //keccak256("_CURRENT_TOTAL_TIPS");
bytes32 constant _DEITY =
0x5fc094d10c65bc33cc842217b2eccca0191ff24148319da094e540a559898961; //keccak256("_DEITY");
bytes32 constant _DIFFICULTY =
0xf758978fc1647996a3d9992f611883adc442931dc49488312360acc90601759b; //keccak256("_DIFFICULTY");
bytes32 constant _DISPUTE_COUNT =
0x310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d7; //keccak256("_DISPUTE_COUNT");
bytes32 constant _DISPUTE_FEE =
0x675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc; //keccak256("_DISPUTE_FEE");
bytes32 constant _DISPUTE_ROUNDS =
0x6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a923; //keccak256("_DISPUTE_ROUNDS");
bytes32 constant _FEE =
0x1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc409; //keccak256("FEE");
bytes32 constant _MIN_EXECUTION_DATE =
0x46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d28; //keccak256("_MIN_EXECUTION_DATE");
bytes32 constant _MINER_SLOT =
0x6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d; //keccak256("_MINER_SLOT");
bytes32 constant _NUM_OF_VOTES =
0x1da378694063870452ce03b189f48e04c1aa026348e74e6c86e10738514ad2c4; //keccak256("_NUM_OF_VOTES");
bytes32 constant _OLD_TELLOR =
0x56e0987db9eaec01ed9e0af003a0fd5c062371f9d23722eb4a3ebc74f16ea371; //keccak256("_OLD_TELLOR");
bytes32 constant _ORIGINAL_ID =
0xed92b4c1e0a9e559a31171d487ecbec963526662038ecfa3a71160bd62fb8733; //keccak256("_ORIGINAL_ID");
bytes32 constant _OWNER =
0x7a39905194de50bde334d18b76bbb36dddd11641d4d50b470cb837cf3bae5def; //keccak256("_OWNER");
bytes32 constant _PAID =
0x29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc; //keccak256("_PAID");
bytes32 constant _PENDING_OWNER =
0x7ec081f029b8ac7e2321f6ae8c6a6a517fda8fcbf63cabd63dfffaeaafa56cc0; //keccak256("_PENDING_OWNER");
bytes32 constant _REQUEST_COUNT =
0x3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c865; //keccak256("_REQUEST_COUNT");
bytes32 constant _REQUEST_ID =
0x9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f; //keccak256("_REQUEST_ID");
bytes32 constant _REQUEST_Q_POSITION =
0xf68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa1; //keccak256("_REQUEST_Q_POSITION");
bytes32 constant _SLOT_PROGRESS =
0xdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b082; //keccak256("_SLOT_PROGRESS");
bytes32 constant _STAKE_AMOUNT =
0x5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc97; //keccak256("_STAKE_AMOUNT");
bytes32 constant _STAKE_COUNT =
0x10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b; //keccak256("_STAKE_COUNT");
bytes32 constant _T_BLOCK =
0xf3b93531fa65b3a18680d9ea49df06d96fbd883c4889dc7db866f8b131602dfb; //keccak256("_T_BLOCK");
bytes32 constant _TALLY_DATE =
0xf9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a6; //keccak256("_TALLY_DATE");
bytes32 constant _TARGET_MINERS =
0x0b8561044b4253c8df1d9ad9f9ce2e0f78e4bd42b2ed8dd2e909e85f750f3bc1; //keccak256("_TARGET_MINERS");
bytes32 constant _TELLOR_CONTRACT =
0x0f1293c916694ac6af4daa2f866f0448d0c2ce8847074a7896d397c961914a08; //keccak256("_TELLOR_CONTRACT");
bytes32 constant _TELLOR_GETTERS =
0xabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a; //keccak256("_TELLOR_GETTERS");
bytes32 constant _TIME_OF_LAST_NEW_VALUE =
0x2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f1; //keccak256("_TIME_OF_LAST_NEW_VALUE");
bytes32 constant _TIME_TARGET =
0xd4f87b8d0f3d3b7e665df74631f6100b2695daa0e30e40eeac02172e15a999e1; //keccak256("_TIME_TARGET");
bytes32 constant _TIMESTAMP =
0x2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5; //keccak256("_TIMESTAMP");
bytes32 constant _TOTAL_SUPPLY =
0xe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb7380160; //keccak256("_TOTAL_SUPPLY");
bytes32 constant _TOTAL_TIP =
0x1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d; //keccak256("_TOTAL_TIP");
bytes32 constant _VALUE =
0x9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f47; //keccak256("_VALUE");
bytes32 constant _EIP_SLOT =
0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;
}{
"optimizer": {
"enabled": true,
"runs": 999999
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_disputeID","type":"uint256"},{"indexed":false,"internalType":"int256","name":"_result","type":"int256"},{"indexed":true,"internalType":"address","name":"_reportedMiner","type":"address"},{"indexed":false,"internalType":"address","name":"_reportingParty","type":"address"},{"indexed":false,"internalType":"bool","name":"_active","type":"bool"}],"name":"DisputeVoteTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_currentChallenge","type":"bytes32"},{"indexed":false,"internalType":"uint256[5]","name":"_currentRequestId","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"_difficulty","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalTips","type":"uint256"}],"name":"NewChallenge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_disputeId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"_miner","type":"address"}],"name":"NewDispute","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"}],"name":"NewStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[5]","name":"_requestId","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"},{"indexed":false,"internalType":"uint256[5]","name":"_value","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"_totalTips","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"_currentChallenge","type":"bytes32"}],"name":"NewValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_miner","type":"address"},{"indexed":false,"internalType":"string","name":"_nonce","type":"string"},{"indexed":false,"internalType":"uint256[5]","name":"_requestId","type":"uint256[5]"},{"indexed":false,"internalType":"uint256[5]","name":"_value","type":"uint256[5]"},{"indexed":true,"internalType":"bytes32","name":"_currentChallenge","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_slot","type":"uint256"}],"name":"NonceSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"}],"name":"StakeWithdrawRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"}],"name":"StakeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tip","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalTips","type":"uint256"}],"name":"TipAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_disputeID","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_position","type":"bool"},{"indexed":true,"internalType":"address","name":"_voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"_voteWeight","type":"uint256"}],"name":"Voted","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"_allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_tip","type":"uint256"}],"name":"addTip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"addresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"allowedToTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balances","outputs":[{"internalType":"uint128","name":"fromBlock","type":"uint128"},{"internalType":"uint128","name":"value","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"uint256","name":"_minerIndex","type":"uint256"}],"name":"beginDispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"bytesVars","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tGetters","type":"address"}],"name":"changeTellorGetters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentMiners","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"miner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"disputeIdByDisputeHash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"disputesById","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"int256","name":"tally","type":"int256"},{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"bool","name":"disputeVotePassed","type":"bool"},{"internalType":"bool","name":"isPropFork","type":"bool"},{"internalType":"address","name":"reportedMiner","type":"address"},{"internalType":"address","name":"reportingParty","type":"address"},{"internalType":"address","name":"proposedForkAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"migrated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"minersByChallenge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"newValueTimestamps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdByQueryHash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestStakingWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_nonce","type":"string"},{"internalType":"uint256[5]","name":"_requestIds","type":"uint256[5]"},{"internalType":"uint256[5]","name":"_values","type":"uint256[5]"}],"name":"submitMiningSolution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"tallyVotes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"uints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"unlockDisputeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"updateBalanceAtNow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateMinDisputeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"},{"internalType":"bool","name":"_supportsDispute","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50615f5e80620000216000396000f3fe6080604052600436106101e35760003560e01c806370a0823111610102578063b59e14d411610095578063d01f4d9e11610064578063d01f4d9e146108f7578063d67dcbc514610921578063db085beb14610967578063dd62ed3e146109ee576101e3565b8063b59e14d4146107ff578063bed9d86114610829578063c9d27afe1461083e578063cbf1304d14610870576101e3565b806390e5b235116100d157806390e5b23514610734578063999cf26c146107495780639a01ca131461078f578063a9059cbb146107b9576101e3565b806370a0823114610679578063752d49a1146106b95780638581af19146106e95780638fd3ab801461071f576101e3565b8063453990161161017a5780634ee2cd7e116101495780634ee2cd7e1461058c5780635700242c146105d257806362dd1d2a146105fc578063699f200f14610626576101e3565b8063453990161461049c57806348b18e54146104dc5780634ba0a5ee146105225780634d318b0e14610562576101e3565b806323b872dd116101b657806323b872dd1461038c57806328449c3a146103dc5780634350283e146103f1578063438c0aa314610472576101e3565b8063024c2ddd14610269578063095ea7b3146102c35780630d2d76a21461031d5780631fd2236414610334575b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a600090815260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc5473ffffffffffffffffffffffffffffffffffffffff169061025082610a36565b5090503d6000803e808015610264573d6000f35b3d6000fd5b34801561027557600080fd5b506102b16004803603604081101561028c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610ab3565b60408051918252519081900360200190f35b3480156102cf57600080fd5b50610309600480360360408110156102e657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610ad0565b604080519115158252519081900360200190f35b34801561032957600080fd5b50610332610c09565b005b34801561034057600080fd5b5061035e6004803603602081101561035757600080fd5b5035610c1c565b6040805192835273ffffffffffffffffffffffffffffffffffffffff90911660208301528051918290030190f35b34801561039857600080fd5b50610309600480360360608110156103af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610c54565b3480156103e857600080fd5b50610332610d3f565b3480156103fd57600080fd5b50610332600480360361016081101561041557600080fd5b81019060208101813564010000000081111561043057600080fd5b82018360208201111561044257600080fd5b8035906020019184600183028401116401000000008311171561046457600080fd5b919350915060a08101610e75565b34801561047e57600080fd5b506102b16004803603602081101561049557600080fd5b503561104e565b3480156104a857600080fd5b50610332600480360360208110156104bf57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661106f565b3480156104e857600080fd5b50610309600480360360408110156104ff57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661116a565b34801561052e57600080fd5b506103096004803603602081101561054557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661118a565b34801561056e57600080fd5b506103326004803603602081101561058557600080fd5b503561119f565b34801561059857600080fd5b506102b1600480360360408110156105af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356114a0565b3480156105de57600080fd5b506102b1600480360360208110156105f557600080fd5b5035611711565b34801561060857600080fd5b506102b16004803603602081101561061f57600080fd5b5035611723565b34801561063257600080fd5b506106506004803603602081101561064957600080fd5b5035611735565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561068557600080fd5b506102b16004803603602081101561069c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661175d565b3480156106c557600080fd5b50610332600480360360408110156106dc57600080fd5b5080359060200135611769565b3480156106f557600080fd5b506103326004803603606081101561070c57600080fd5b50803590602081013590604001356119e8565b34801561072b57600080fd5b50610332612386565b34801561074057600080fd5b5061033261238f565b34801561075557600080fd5b506103096004803603604081101561076c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356124a9565b34801561079b57600080fd5b50610332600480360360208110156107b257600080fd5b5035612586565b3480156107c557600080fd5b50610309600480360360408110156107dc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612d27565b34801561080b57600080fd5b506102b16004803603602081101561082257600080fd5b5035612d3d565b34801561083557600080fd5b50610332612d4f565b34801561084a57600080fd5b506103326004803603604081101561086157600080fd5b50803590602001351515612e68565b34801561087c57600080fd5b506108b66004803603604081101561089357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135613112565b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b34801561090357600080fd5b506102b16004803603602081101561091a57600080fd5b503561316b565b34801561092d57600080fd5b506103326004803603604081101561094457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561317d565b34801561097357600080fd5b506109916004803603602081101561098a57600080fd5b5035613307565b604080519889526020890197909752941515878701529215156060870152901515608086015273ffffffffffffffffffffffffffffffffffffffff90811660a086015290811660c08501521660e083015251908190036101000190f35b3480156109fa57600080fd5b506102b160048036036040811015610a1157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613370565b600060608273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610aa3576040519150601f19603f3d011682016040523d82523d6000602084013e610aa8565b606091505b509094909350915050565b604a60209081526000928352604080842090915290825290205481565b600033610b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615ee06024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316610b94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615df16022913960400191505060405180910390fd5b336000818152604a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b610c12336133a8565b610c1a61238f565b565b603a8160058110610c2c57600080fd5b60020201805460019091015490915073ffffffffffffffffffffffffffffffffffffffff1682565b73ffffffffffffffffffffffffffffffffffffffff83166000908152604a60209081526040808320338452909152812054821115610cf357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f416c6c6f77616e63652069732077726f6e670000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152604a60209081526040808320338452909152902080548390039055610d358484846135ba565b5060019392505050565b3360009081526044602052604090208054600114610dbe57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d696e6572206973206e6f74207374616b656400000000000000000000000000604482015290519081900360640190fd5b60028155620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055610e4761238f565b60405133907f453865710d0cb4b14ad25de371c860da196368895daa9662e5087711d14daecf90600090a250565b6040805133602080830191909152825180830382018152918301835281519181019190912060008181526046909252919020541580610ec857506000818152604660205260409020546103844291909103115b610f1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615da4602a913960400191505060405180910390fd5b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249254600414610fae57610fae85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137fd92505050565b6000818152604660209081526040918290204290558151601f870182900482028101820190925285825261104791908790879081908401838280828437600092019190915250506040805160a081810190925292508791506005908390839080828437600092019190915250506040805160a0818101909252915086906005908390839080828437600092019190915250613b96915050565b5050505050565b6033818154811061105e57600080fd5b600091825260209091200154905081565b7f5fc094d10c65bc33cc842217b2eccca0191ff24148319da094e540a55989896160005260476020527f437dd27c2043efdfef03344e9331c924985f7bd1752abef5ea93bdbfed6851005473ffffffffffffffffffffffffffffffffffffffff1633146110db57600080fd5b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a60005260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b603960209081526000928352604080842090915290825290205460ff1681565b604b6020526000908152604090205460ff1681565b6000818152603660205260409020600281015460ff161561120b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e9e6021913960400191505060405180910390fd5b7f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2860009081526005820160205260409020544210156112ab57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b600381015473ffffffffffffffffffffffffffffffffffffffff1661133157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706f7274696e672050617274792069732061646472657373203000000000604482015290519081900360640190fd5b6001810154600081131561136e576002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600282015462010000900460ff166113c15760028201546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602052604090208054600314156113bf57600481555b505b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005830160209081526040918290204290556002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117908190556003850154835185815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352610100820460ff1615158385015292516301000000909104929092169185917f21459c2f5447ebcf83a7f0a238c32c71076faef0d12295e771c0cb1e10434739919081900360600190a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260408120805415806114fc575082816000815481106114dc57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff16115b1561150b576000915050610c03565b805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061153b57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1683106115ca57805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061158f57fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169150610c039050565b80546000907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe015b818111156116c857600060026001838501010490508584828154811061161457fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614156116825783818154811061164457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169450610c039350505050565b8584828154811061168f57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1610156116bb578092506116c2565b6001810391505b506115f2565b8282815481106116d457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169350610c0392505050565b60376020526000908152604090205481565b60486020526000908152604090205481565b60476020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6000610c0382436114a0565b816117d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f5265717565737449642069732030000000000000000000000000000000000000604482015290519081900360640190fd5b8061184157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5469702073686f756c642062652067726561746572207468616e203000000000604482015290519081900360640190fd5b7f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d654600101828114156118e9577f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d6819055611957565b80831061195757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f526571756573744964206973206e6f74206c657373207468616e20636f756e74604482015290519081900360640190fd5b6119613383614433565b61196b83836145db565b60008381526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d8452600101825291829020548251858152918201528151859233927fd32134405b68f6f7220f9c38ae310df1b648d16188006768d45be2f7c24e8820929081900390910190a3505050565b60008381526045602090815260408083208584526002810190925290912054611a7257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d696e656420626c6f636b206973203000000000000000000000000000000000604482015290519081900360640190fd5b60058210611ae157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4d696e657220696e6465782069732077726f6e67000000000000000000000000604482015290519081900360640190fd5b60008381526005808301602052604082209084908110611afd57fe5b0154604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b1660208083019190915260348201899052605480830189905283518084039091018152607490920183528151918101919091207f1ce2382bc92689b00ba121fa5a411aa976168affdd8ac143a69035dd984b3b6a80546001019081905560008281526038909352929091205473ffffffffffffffffffffffffffffffffffffffff9093169350918015611bfa5760008281526036602090815260408083207fed92b4c1e0a9e559a31171d487ecbec963526662038ecfa3a71160bd62fb873384526005019091529020819055611c0e565b506000828152603860205260409020819055805b60008181526036602081815260408084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005018083528185208054600101908190558686529383528151808401859052825180820385018152908301835280519084012085529091529091208390558190838214611e5657600082815260366020818152604080842081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8701818501528251808203850181529083018352805190840120855260059081018352818520548086529383528185207f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2886520190915290912054421015611d8757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4469737075746520697320616c7265616479206f70656e000000000000000000604482015290519081900360640190fd5b60008181526036602052604090206002015460ff1615611e545760008181526036602090815260408083207ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a684526005019091529020546201518042919091031115611e5457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b505b60008860021415611ef9575060008a81526045602090815260408083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600190810183529083208054909101908190557f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc97909252604690527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be5402611f48565b507f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda449865481025b85603660008781526020019081526020016000206000018190555060006036600087815260200190815260200160002060020160026101000a81548160ff021916908315150217905550866036600087815260200190815260200160002060020160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336036600087815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060020160006101000a81548160ff02191690831515021790555060006036600087815260200190815260200160002060020160016101000a81548160ff021916908315150217905550600060366000878152602001908152602001600020600101819055508a6036600087815260200190815260200160002060050160007f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60001b815260200190815260200160002081905550896036600087815260200190815260200160002060050160007f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e560001b8152602001908152602001600020819055508760060160008b815260200190815260200160002089600581106121ca57fe5b015460008681526036602090815260408083207f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f478452600501909152808220929092557f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2881528181206202a3008502420190557f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c81528181204390557f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d81528181208b90557f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098152208190556122c13330836135ba565b88600214156123115760008a8152600489016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560038b019091528120555b73ffffffffffffffffffffffffffffffffffffffff87166000818152604460209081526040918290206003905581518d81529081019290925280518d9288927feceec1aebf67772b2440120c4b4dc913a1fe1b865509219f9456785c23b9da6492918290030190a35050505050505050505050565b610c1a3361488b565b60466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be547f2e2f0a18eb55ef91e37921b3810d7feeef7a855ddc7f4f4249ef03d7b887ae31547f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b6000527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd35461245a9067d02ab486cedc0000906103e890849061243d908290614a5f565b6103e80286028161244a57fe5b048161245257fe5b048403614a77565b7f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda44986555050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526044602052604081205415801590612502575073ffffffffffffffffffffffffffffffffffffffff83166000908152604460205260409020546005115b15612573577f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be54829061255d8561175d565b031061256b57506001610c03565b506000610c03565b8161257d8461175d565b10159392505050565b600081815260366020818152604080842054845260388252808420548085529282528084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a9238552600501808352818520548251808501919091528251808203850181529083018352805190840120855290915290912054806126065750805b60008281526036602090815260408083208484528184207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005820190935292205480612653575060015b7f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc6000908152600584016020526040812054156126f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f616c72656164792070616964206f757400000000000000000000000000000000604482015290519081900360640190fd5b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005840160205260409020546201518042919091031161279857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b6002848101546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602090815260408083207f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc84526005890190925290912060019081905591850154909161010090910460ff16151514156129ef57620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01905561289b61238f565b80546004141561292e5760058155600285015460038601547f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546129299273ffffffffffffffffffffffffffffffffffffffff630100000090910481169216906135ba565b600081555b60005b838110156129e9576040805182860360208083019190915282518083038201815291830183528151918101919091206000908152600589019091522054925082612979578792505b600083815260366020908152604080832060038101547f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098552600582019093529220546129e091309173ffffffffffffffffffffffffffffffffffffffff909116906135ba565b50600101612931565b50612c53565b600181557f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160208181526040808420548452604582528084207f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d8552929091529091205460021415612ace577f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f4760009081526005870160209081526040808320547f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5845281842054845260038501909252909120555b7f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5600090815260058701602090815260408083205483526004840190915290205460ff16151560011415612b83577f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e56000908152600587016020908152604080832054835260048401909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b60005b84811015612c5057604080518287036020808301919091528251808303820181529183018352815191810191909120600090815260058a01909152205493508315612bdc57600084815260366020526040902095505b600286015460008581526036602090815260408083207f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098452600501909152902054612c48913091630100000090910473ffffffffffffffffffffffffffffffffffffffff16906135ba565b600101612b86565b50505b7f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d600090815260058601602052604090205460021415612d1d577f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160209081526040808320548352604582528083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600101909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b5050505050505050565b6000612d343384846135ba565b50600192915050565b60466020526000908152604090205481565b336000908152604460205260409020600181015462093a80906201518042064203031015612dde57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f372064617973206469646e277420706173730000000000000000000000000000604482015290519081900360640190fd5b8054600214612e38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615dce6023913960400191505060405180910390fd5b600080825560405133917f4a7934670bd8304e7da22378be1368f7c4fef17c5aee81804beda8638fe428ec91a250565b60008281526036602090815260408083207f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c845260058101909252822054909190612eb49033906114a0565b33600090815260068401602052604090205490915060ff16151560011415612f3d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f53656e6465722068617320616c726561647920766f7465640000000000000000604482015290519081900360640190fd5b80612fa957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f557365722062616c616e63652069732030000000000000000000000000000000604482015290519081900360640190fd5b336000908152604460205260409020546003141561302857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e657220697320756e646572206469737075746500000000000000000000604482015290519081900360640190fd5b336000908152600683016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091557f1da378694063870452ce03b189f48e04c1aa026348e74e6c86e10738514ad2c48452600586019092529091208054909101905582156130bb5760018201546130b19082614a86565b60018301556130d0565b60018201546130ca9082614ab1565b60018301555b60408051841515815290518291339187917f911ef2e98570b1d96c0e8ef81107a33d5b8e844aeb8f9710f9bc76c3b3fef40e919081900360200190a450505050565b6049602052816000526040600020818154811061312e57600080fd5b6000918252602090912001546fffffffffffffffffffffffffffffffff808216935070010000000000000000000000000000000090910416905082565b60386020526000908152604090205481565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260409020805415806131fe57508054439082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106131dd57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614155b156132945760408051808201909152436fffffffffffffffffffffffffffffffff90811682528381166020808401918252845460018101865560008681529190912093519301805491517fffffffffffffffffffffffffffffffff000000000000000000000000000000009092169383169390931782167001000000000000000000000000000000009190921602179055613302565b805460009082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106132c757fe5b600091825260209091200180546fffffffffffffffffffffffffffffffff808616700100000000000000000000000000000000029116179055505b505050565b603660205260009081526040902080546001820154600283015460038401546004909401549293919260ff8083169361010084048216936201000081049092169273ffffffffffffffffffffffffffffffffffffffff6301000000909304831692918216911688565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152604a6020908152604080832093909416825291909152205490565b7f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546133fc8261175d565b1015613453576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615e7c6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526044602052604090205415806134aa575073ffffffffffffffffffffffffffffffffffffffff81166000908152604460205260409020546002145b61351557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e657220697320696e207468652077726f6e672073746174650000000000604482015290519081900360640190fd5b7fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd38054600190810190915560408051808201825282815262015180429081069003602082810191825273ffffffffffffffffffffffffffffffffffffffff8616600081815260449092528482209351845591519290940191909155905190917f46d8ab1385f70e5a3673e97c23c764f7600f7ed7a09b6687deae7131d51752e291a250565b80613610576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e5b6021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661369257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b61369c83826124a9565b6136f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180615e346027913960400191505060405180910390fd5b60006136fc8461175d565b905061370a8483830361317d565b6137138361175d565b905080828201101561378657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6137928383830161317d565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b7f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd54702836c9d21d0727ffacc3e39f57c92b5ae0f50177e593bfb5ec66e3de280600052604860209081527f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d546040805180840183815233606081901b93830193909352865160029560039594938993926054909101918401908083835b602083106138da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161389d565b6001836020036101000a038019825116818451168082178552505050505050905001935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061398357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613946565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156139e0573d6000803e3d6000fd5b5050506040515160601b60405160200180826bffffffffffffffffffffffff191681526014019150506040516020818303038152906040526040518082805190602001908083835b60208310613a6557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613a28565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015613ac2573d6000803e3d6000fd5b5050506040513d6020811015613ad757600080fd5b505181613ae057fe5b061580613b3e57507f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f160005260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854610384429190910310155b613b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615f046025913960400191505060405180910390fd5b50565b604080513360208083018290528351808403820181529284018452825192810192909220600091825260449092529190912054600114613c3757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e657220737461747573206973206e6f74207374616b6572000000000000604482015290519081900360640190fd5b603a54835114613ca857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603c54602084015114613d1c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603e54604084015114613d9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604054606084015114613e0457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604254608084015114613e7857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b60008181526046602090815260408083204290557f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492548185526039845282852033865290935292205460ff1615613f3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615ebf6021913960400191505060405180910390fd5b6000828152603960209081526040808320338452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c5483526045825280832087518480526006820190935292208360058110613fc257fe5b0155602080860151600160009081526006840190925260409091208360058110613fe857fe5b0155604080860151600260009081526006840160205291909120836005811061400d57fe5b01556060850151600360009081526006830160205260409020836005811061403157fe5b01556080850151600460009081526006830160205260409020836005811061405557fe5b015560008080526005808301602052604090912033918490811061407557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560016000908152600582810160205260409091203391849081106140d957fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600260009081526005828101602052604090912033918490811061413d57fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560036000908152600582810160205260409091203391849081106141a157fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600460009081526005828101602052604090912033918490811061420557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600182016004141561425d5761425d614ad7565b81600101600514156142c5576142738787614c15565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b082600090815260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249255614317565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492805460010190555b823373ffffffffffffffffffffffffffffffffffffffff167f9d2e5f03fc65aff196e0f3a8dd924b24099de487e8cffc888921d420ab196e3989898987604051808060200185600560200280838360005b83811015614380578181015183820152602001614368565b5050505090500184600560200280838360005b838110156143ab578181015183820152602001614393565b50505050905001838152602001828103825286818151815260200191508051906020019080838360005b838110156143ed5781810151838201526020016143d5565b50505050905090810190601f16801561441a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a350505050505050565b8061443d576145d7565b60006144488361175d565b90508082820311156144bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810381101561457757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6145838484840361317d565b50507fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e805482900390555b5050565b60008281526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d845260018101909252909120546146249083615605565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d6000908152600183016020526040902055603a548314806146675750603c5483145b806146735750603e5483145b8061467f575060405483145b8061468b575060425483145b156146e5577f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60005260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b72805483019055613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa1600090815260018201602052604090205461483f5760408051610660810191829052600091829161475691839060339082845b815481526020019060010190808311614739575050505050615614565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001860160205260409020549193509150821080614798575081155b15614838577f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001840160205260408120549082603381106147db57fe5b0155600081815260356020908152604080832080548452604583528184207ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa185526001908101845282852085905590899055860190915290208190555b5050613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160009081526001820160205260408120548391906033811061487e57fe5b0180549091019055505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152604b602052604090205460ff161561492057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f616c72656479206d696772617465640000000000000000000000000000000000604482015290519081900360640190fd5b7f56e0987db9eaec01ed9e0af003a0fd5c062371f9d23722eb4a3ebc74f16ea371600052604760209081527fc930326aab6c1874fc004d856083a6ed34e057e064970b7effb48e8e6e8ca12754604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301529151614a1094869493909316926370a082319260248082019391829003018186803b1580156149df57600080fd5b505afa1580156149f3573d6000803e3d6000fd5b505050506040513d6020811015614a0957600080fd5b5051615681565b73ffffffffffffffffffffffffffffffffffffffff166000908152604b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000818310614a6e5781614a70565b825b9392505050565b6000818311614a6e5781614a70565b600080821315614aa3575081810182811215614a9e57fe5b610c03565b5081810182811315610c0357fe5b600080821315614ac9575080820382811315614a9e57fe5b5080820382811215610c0357fe5b7f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f1600090815260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854420390614b336104b083614a5f565b60466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd4f87b8d0f3d3b7e665df74631f6100b2695daa0e30e40eeac02172e15a999e16000527f8156e704072c396780f8253d0562de28216b73a1503daa96e259b9cdd951d71c54610fa0929003810291909105915081614bb857600191505b614bc58282016001615943565b7ff758978fc1647996a3d9992f611883adc442931dc49488312360acc90601759b60005260466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d15002555505050565b7fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c54600090815260456020908152604082207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f190935260469091527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e031188054429182905591929190614cc6615d12565b614cce615d12565b60005b600581101561510d5760015b6005811015614f6857600082815260068901602052604081208260058110614d0157fe5b0154905060008960050160008581526020019081526020016000208360058110614d2757fe5b015473ffffffffffffffffffffffffffffffffffffffff169050825b600081118015614d905750600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614d8b57fe5b015483105b15614ed357600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614dd257fe5b0154600086815260068d01602052604090208260058110614def57fe5b015560008581526005808d016020526040909120907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301908110614e3057fe5b015460008681526005808e01602052604090912073ffffffffffffffffffffffffffffffffffffffff909216919083908110614e6857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01614d43565b83811015614f5d57600085815260068c016020526040902083908260058110614ef857fe5b015560008581526005808d016020526040909120839183908110614f1857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b505050600101614cdd565b506000604560008a8460058110614f7b57fe5b602002015181526020019081526020016000209050876006016000838152602001908152602001600020600580602002604051908101604052809291908260058015614fdc576020028201915b815481526020019060010190808311614fc8575b5050505050935083600260058110614ff057fe5b602090810291909101516000878152600384019092526040918290205584015183836005811061501c57fe5b6020908102919091019190915260008381526005808b0183526040808320898452858301909452909120615051929091615d30565b5060008281526006808a016020908152604080842089855292850190915290912061507d916005615d30565b506000828152600589016020526040812061509791615d6b565b600082815260068901602052604081206150b091615d6b565b8054600181810183556000838152602080822090930188905587815260028401835260408082204390557f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d82529382019092529181205501614cd1565b50847fbeb3b9f46c8d7bb00c873fca10d307538df350866d25f891ffb395147ddbdc45888584604660007f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60001b8152602001908152602001600020546040518085600560200280838360005b8381101561519257818101518382015260200161517a565b5050505090500184815260200183600560200280838360005b838110156151c35781810151838201526020016151ab565b5050505090500182815260200194505050505060405180910390a2603380546001810182556000919091527f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a820183905561521b615d12565b87516000908152604560209081526040808320878452600590810190925291829020825160a08101938490529290919082845b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161524e57505050505090506152898186615952565b7ff3b93531fa65b3a18680d9ea49df06d96fbd883c4889dc7db866f8b131602dfb60005260466020527fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c805460010190556152e2615d12565b6152ea615ad9565b905060005b60058110156154375781816005811061530457fe5b6020020151603a826005811061531657fe5b600202015560008060458185856005811061532d57fe5b6020020151815260200190815260200160002060010160007ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160001b8152602001908152602001600020546033811061538257fe5b01556045600083836005811061539457fe5b60209081029190910151825281810192909252604090810160009081207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d825260019081018452918120547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a90915260469092527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b728054909201909155016152ef565b50898760014303406040516020018080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561548b578181015183820152602001615473565b50505050905090810190601f1680156154b85780820380516001836020036101000a031916815260200191505b50604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d81905560469091527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254929f508f98507f1d85ce10456e29b67de37887496d3f1fcf1b64c79c4d07484038703a9f5c140897508996509094509092508190859060a0908190849084905b838110156155db5781810151838201526020016155c3565b5050505091909101938452505060208201526040805191829003019150a250505050505050505050565b600082820183811015614a7057fe5b610640810151603260315b801561567b578284826033811061563257fe5b602002015110156156545783816033811061564957fe5b602002015192508091505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161561f565b50915091565b806156d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e136021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661575957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b60006157648361175d565b90508082820110156157d757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810181111561589357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e8054840190556158ef8483850161317d565b60408051848152905173ffffffffffffffffffffffffffffffffffffffff8616916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350505050565b6000818313614a6e5781614a70565b60466020527fc2c579d641b643400780d5c7ce967b420034b9f66962a5ee405cf70e4cbed6bb547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254428490039261012c9084020491600a9091049060028304906159ed9087905b6020020151838501615681565b6159f88660016159e0565b615a038660026159e0565b615a0e8660036159e0565b615a198660046159e0565b7f7a39905194de50bde334d18b76bbb36dddd11641d4d50b470cb837cf3bae5def60005260476020527fb5f7e7387e8e977cc9c4c9513388b0d7224264b9a0159cd8e8bdd84a9ed504c354615a849073ffffffffffffffffffffffffffffffffffffffff1682615681565b50507f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a600090815260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b725550505050565b615ae1615d12565b615ae9615d12565b615af1615d12565b60408051610660810191829052615b289160009060339082845b815481526020019060010190808311615b0b575050505050615bbe565b909250905060005b6005811015615bb857828160058110615b4557fe5b602002015115615b895760356000838360058110615b5f57fe5b6020020151815260200190815260200160002054848260058110615b7f57fe5b6020020152615bb0565b603a8160040360058110615b9957fe5b6002020154848260058110615baa57fe5b60200201525b600101615b30565b50505090565b615bc6615d12565b615bce615d12565b60208301516000805b6005811015615c5157858160010160338110615bef57fe5b6020020151858260058110615c0057fe5b602002015260018101848260058110615c1557fe5b602002015282858260058110615c2757fe5b60200201511015615c4957848160058110615c3e57fe5b602002015192508091505b600101615bd7565b5060065b6033811015615d0a5782868260338110615c6b57fe5b60200201511115615d0257858160338110615c8257fe5b6020020151858360058110615c9357fe5b602002015280848360058110615ca557fe5b6020020152858160338110615cb657fe5b6020020151925060005b6005811015615d005783868260058110615cd657fe5b60200201511015615cf857858160058110615ced57fe5b602002015193508092505b600101615cc0565b505b600101615c55565b505050915091565b6040518060a001604052806005906020820280368337509192915050565b8260058101928215615d5b579182015b82811115615d5b578254825591600101919060010190615d40565b50615d67929150615d8e565b5090565b506000815560010160008155600101600081556001016000815560010160009055565b5b80821115615d675760008155600101615d8f56fe4d696e65722063616e206f6e6c792077696e2072657761726473206f6e636520706572203135206d696e4d696e657220776173206e6f74206c6f636b656420666f72207769746864726177616c45524332303a20617070726f766520746f20746865207a65726f2061646472657373547269656420746f206d696e74206e6f6e2d706f73697469766520616d6f756e7453686f756c6420686176652073756666696369656e742062616c616e636520746f207472616465547269656420746f2073656e64206e6f6e2d706f73697469766520616d6f756e7442616c616e6365206973206c6f776572207468616e207374616b6520616d6f756e744469737075746520686173206265656e20616c72656164792065786563757465644d696e657220616c7265616479207375626d6974746564207468652076616c756545524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373496e636f7272656374206e6f6e636520666f722063757272656e74206368616c6c656e6765a2646970667358221220283d77407206ff6c4cc0f6e78ee639e4e194574cc796cf2b7dbf2fa45ca9e7dc64736f6c63430007040033
Deployed Bytecode
0x6080604052600436106101e35760003560e01c806370a0823111610102578063b59e14d411610095578063d01f4d9e11610064578063d01f4d9e146108f7578063d67dcbc514610921578063db085beb14610967578063dd62ed3e146109ee576101e3565b8063b59e14d4146107ff578063bed9d86114610829578063c9d27afe1461083e578063cbf1304d14610870576101e3565b806390e5b235116100d157806390e5b23514610734578063999cf26c146107495780639a01ca131461078f578063a9059cbb146107b9576101e3565b806370a0823114610679578063752d49a1146106b95780638581af19146106e95780638fd3ab801461071f576101e3565b8063453990161161017a5780634ee2cd7e116101495780634ee2cd7e1461058c5780635700242c146105d257806362dd1d2a146105fc578063699f200f14610626576101e3565b8063453990161461049c57806348b18e54146104dc5780634ba0a5ee146105225780634d318b0e14610562576101e3565b806323b872dd116101b657806323b872dd1461038c57806328449c3a146103dc5780634350283e146103f1578063438c0aa314610472576101e3565b8063024c2ddd14610269578063095ea7b3146102c35780630d2d76a21461031d5780631fd2236414610334575b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a600090815260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc5473ffffffffffffffffffffffffffffffffffffffff169061025082610a36565b5090503d6000803e808015610264573d6000f35b3d6000fd5b34801561027557600080fd5b506102b16004803603604081101561028c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610ab3565b60408051918252519081900360200190f35b3480156102cf57600080fd5b50610309600480360360408110156102e657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610ad0565b604080519115158252519081900360200190f35b34801561032957600080fd5b50610332610c09565b005b34801561034057600080fd5b5061035e6004803603602081101561035757600080fd5b5035610c1c565b6040805192835273ffffffffffffffffffffffffffffffffffffffff90911660208301528051918290030190f35b34801561039857600080fd5b50610309600480360360608110156103af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610c54565b3480156103e857600080fd5b50610332610d3f565b3480156103fd57600080fd5b50610332600480360361016081101561041557600080fd5b81019060208101813564010000000081111561043057600080fd5b82018360208201111561044257600080fd5b8035906020019184600183028401116401000000008311171561046457600080fd5b919350915060a08101610e75565b34801561047e57600080fd5b506102b16004803603602081101561049557600080fd5b503561104e565b3480156104a857600080fd5b50610332600480360360208110156104bf57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661106f565b3480156104e857600080fd5b50610309600480360360408110156104ff57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661116a565b34801561052e57600080fd5b506103096004803603602081101561054557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661118a565b34801561056e57600080fd5b506103326004803603602081101561058557600080fd5b503561119f565b34801561059857600080fd5b506102b1600480360360408110156105af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356114a0565b3480156105de57600080fd5b506102b1600480360360208110156105f557600080fd5b5035611711565b34801561060857600080fd5b506102b16004803603602081101561061f57600080fd5b5035611723565b34801561063257600080fd5b506106506004803603602081101561064957600080fd5b5035611735565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561068557600080fd5b506102b16004803603602081101561069c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661175d565b3480156106c557600080fd5b50610332600480360360408110156106dc57600080fd5b5080359060200135611769565b3480156106f557600080fd5b506103326004803603606081101561070c57600080fd5b50803590602081013590604001356119e8565b34801561072b57600080fd5b50610332612386565b34801561074057600080fd5b5061033261238f565b34801561075557600080fd5b506103096004803603604081101561076c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356124a9565b34801561079b57600080fd5b50610332600480360360208110156107b257600080fd5b5035612586565b3480156107c557600080fd5b50610309600480360360408110156107dc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612d27565b34801561080b57600080fd5b506102b16004803603602081101561082257600080fd5b5035612d3d565b34801561083557600080fd5b50610332612d4f565b34801561084a57600080fd5b506103326004803603604081101561086157600080fd5b50803590602001351515612e68565b34801561087c57600080fd5b506108b66004803603604081101561089357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135613112565b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b34801561090357600080fd5b506102b16004803603602081101561091a57600080fd5b503561316b565b34801561092d57600080fd5b506103326004803603604081101561094457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561317d565b34801561097357600080fd5b506109916004803603602081101561098a57600080fd5b5035613307565b604080519889526020890197909752941515878701529215156060870152901515608086015273ffffffffffffffffffffffffffffffffffffffff90811660a086015290811660c08501521660e083015251908190036101000190f35b3480156109fa57600080fd5b506102b160048036036040811015610a1157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613370565b600060608273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610aa3576040519150601f19603f3d011682016040523d82523d6000602084013e610aa8565b606091505b509094909350915050565b604a60209081526000928352604080842090915290825290205481565b600033610b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615ee06024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316610b94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615df16022913960400191505060405180910390fd5b336000818152604a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b610c12336133a8565b610c1a61238f565b565b603a8160058110610c2c57600080fd5b60020201805460019091015490915073ffffffffffffffffffffffffffffffffffffffff1682565b73ffffffffffffffffffffffffffffffffffffffff83166000908152604a60209081526040808320338452909152812054821115610cf357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f416c6c6f77616e63652069732077726f6e670000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152604a60209081526040808320338452909152902080548390039055610d358484846135ba565b5060019392505050565b3360009081526044602052604090208054600114610dbe57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d696e6572206973206e6f74207374616b656400000000000000000000000000604482015290519081900360640190fd5b60028155620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055610e4761238f565b60405133907f453865710d0cb4b14ad25de371c860da196368895daa9662e5087711d14daecf90600090a250565b6040805133602080830191909152825180830382018152918301835281519181019190912060008181526046909252919020541580610ec857506000818152604660205260409020546103844291909103115b610f1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615da4602a913960400191505060405180910390fd5b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249254600414610fae57610fae85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137fd92505050565b6000818152604660209081526040918290204290558151601f870182900482028101820190925285825261104791908790879081908401838280828437600092019190915250506040805160a081810190925292508791506005908390839080828437600092019190915250506040805160a0818101909252915086906005908390839080828437600092019190915250613b96915050565b5050505050565b6033818154811061105e57600080fd5b600091825260209091200154905081565b7f5fc094d10c65bc33cc842217b2eccca0191ff24148319da094e540a55989896160005260476020527f437dd27c2043efdfef03344e9331c924985f7bd1752abef5ea93bdbfed6851005473ffffffffffffffffffffffffffffffffffffffff1633146110db57600080fd5b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a60005260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b603960209081526000928352604080842090915290825290205460ff1681565b604b6020526000908152604090205460ff1681565b6000818152603660205260409020600281015460ff161561120b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e9e6021913960400191505060405180910390fd5b7f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2860009081526005820160205260409020544210156112ab57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b600381015473ffffffffffffffffffffffffffffffffffffffff1661133157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706f7274696e672050617274792069732061646472657373203000000000604482015290519081900360640190fd5b6001810154600081131561136e576002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600282015462010000900460ff166113c15760028201546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602052604090208054600314156113bf57600481555b505b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005830160209081526040918290204290556002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117908190556003850154835185815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352610100820460ff1615158385015292516301000000909104929092169185917f21459c2f5447ebcf83a7f0a238c32c71076faef0d12295e771c0cb1e10434739919081900360600190a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260408120805415806114fc575082816000815481106114dc57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff16115b1561150b576000915050610c03565b805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061153b57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1683106115ca57805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061158f57fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169150610c039050565b80546000907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe015b818111156116c857600060026001838501010490508584828154811061161457fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614156116825783818154811061164457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169450610c039350505050565b8584828154811061168f57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1610156116bb578092506116c2565b6001810391505b506115f2565b8282815481106116d457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169350610c0392505050565b60376020526000908152604090205481565b60486020526000908152604090205481565b60476020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6000610c0382436114a0565b816117d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f5265717565737449642069732030000000000000000000000000000000000000604482015290519081900360640190fd5b8061184157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5469702073686f756c642062652067726561746572207468616e203000000000604482015290519081900360640190fd5b7f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d654600101828114156118e9577f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d6819055611957565b80831061195757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f526571756573744964206973206e6f74206c657373207468616e20636f756e74604482015290519081900360640190fd5b6119613383614433565b61196b83836145db565b60008381526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d8452600101825291829020548251858152918201528151859233927fd32134405b68f6f7220f9c38ae310df1b648d16188006768d45be2f7c24e8820929081900390910190a3505050565b60008381526045602090815260408083208584526002810190925290912054611a7257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d696e656420626c6f636b206973203000000000000000000000000000000000604482015290519081900360640190fd5b60058210611ae157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4d696e657220696e6465782069732077726f6e67000000000000000000000000604482015290519081900360640190fd5b60008381526005808301602052604082209084908110611afd57fe5b0154604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b1660208083019190915260348201899052605480830189905283518084039091018152607490920183528151918101919091207f1ce2382bc92689b00ba121fa5a411aa976168affdd8ac143a69035dd984b3b6a80546001019081905560008281526038909352929091205473ffffffffffffffffffffffffffffffffffffffff9093169350918015611bfa5760008281526036602090815260408083207fed92b4c1e0a9e559a31171d487ecbec963526662038ecfa3a71160bd62fb873384526005019091529020819055611c0e565b506000828152603860205260409020819055805b60008181526036602081815260408084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005018083528185208054600101908190558686529383528151808401859052825180820385018152908301835280519084012085529091529091208390558190838214611e5657600082815260366020818152604080842081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8701818501528251808203850181529083018352805190840120855260059081018352818520548086529383528185207f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2886520190915290912054421015611d8757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4469737075746520697320616c7265616479206f70656e000000000000000000604482015290519081900360640190fd5b60008181526036602052604090206002015460ff1615611e545760008181526036602090815260408083207ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a684526005019091529020546201518042919091031115611e5457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b505b60008860021415611ef9575060008a81526045602090815260408083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600190810183529083208054909101908190557f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc97909252604690527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be5402611f48565b507f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda449865481025b85603660008781526020019081526020016000206000018190555060006036600087815260200190815260200160002060020160026101000a81548160ff021916908315150217905550866036600087815260200190815260200160002060020160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336036600087815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060020160006101000a81548160ff02191690831515021790555060006036600087815260200190815260200160002060020160016101000a81548160ff021916908315150217905550600060366000878152602001908152602001600020600101819055508a6036600087815260200190815260200160002060050160007f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60001b815260200190815260200160002081905550896036600087815260200190815260200160002060050160007f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e560001b8152602001908152602001600020819055508760060160008b815260200190815260200160002089600581106121ca57fe5b015460008681526036602090815260408083207f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f478452600501909152808220929092557f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2881528181206202a3008502420190557f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c81528181204390557f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d81528181208b90557f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098152208190556122c13330836135ba565b88600214156123115760008a8152600489016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560038b019091528120555b73ffffffffffffffffffffffffffffffffffffffff87166000818152604460209081526040918290206003905581518d81529081019290925280518d9288927feceec1aebf67772b2440120c4b4dc913a1fe1b865509219f9456785c23b9da6492918290030190a35050505050505050505050565b610c1a3361488b565b60466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be547f2e2f0a18eb55ef91e37921b3810d7feeef7a855ddc7f4f4249ef03d7b887ae31547f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b6000527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd35461245a9067d02ab486cedc0000906103e890849061243d908290614a5f565b6103e80286028161244a57fe5b048161245257fe5b048403614a77565b7f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda44986555050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526044602052604081205415801590612502575073ffffffffffffffffffffffffffffffffffffffff83166000908152604460205260409020546005115b15612573577f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be54829061255d8561175d565b031061256b57506001610c03565b506000610c03565b8161257d8461175d565b10159392505050565b600081815260366020818152604080842054845260388252808420548085529282528084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a9238552600501808352818520548251808501919091528251808203850181529083018352805190840120855290915290912054806126065750805b60008281526036602090815260408083208484528184207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005820190935292205480612653575060015b7f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc6000908152600584016020526040812054156126f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f616c72656164792070616964206f757400000000000000000000000000000000604482015290519081900360640190fd5b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005840160205260409020546201518042919091031161279857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b6002848101546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602090815260408083207f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc84526005890190925290912060019081905591850154909161010090910460ff16151514156129ef57620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01905561289b61238f565b80546004141561292e5760058155600285015460038601547f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546129299273ffffffffffffffffffffffffffffffffffffffff630100000090910481169216906135ba565b600081555b60005b838110156129e9576040805182860360208083019190915282518083038201815291830183528151918101919091206000908152600589019091522054925082612979578792505b600083815260366020908152604080832060038101547f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098552600582019093529220546129e091309173ffffffffffffffffffffffffffffffffffffffff909116906135ba565b50600101612931565b50612c53565b600181557f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160208181526040808420548452604582528084207f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d8552929091529091205460021415612ace577f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f4760009081526005870160209081526040808320547f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5845281842054845260038501909252909120555b7f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5600090815260058701602090815260408083205483526004840190915290205460ff16151560011415612b83577f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e56000908152600587016020908152604080832054835260048401909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b60005b84811015612c5057604080518287036020808301919091528251808303820181529183018352815191810191909120600090815260058a01909152205493508315612bdc57600084815260366020526040902095505b600286015460008581526036602090815260408083207f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098452600501909152902054612c48913091630100000090910473ffffffffffffffffffffffffffffffffffffffff16906135ba565b600101612b86565b50505b7f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d600090815260058601602052604090205460021415612d1d577f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160209081526040808320548352604582528083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600101909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b5050505050505050565b6000612d343384846135ba565b50600192915050565b60466020526000908152604090205481565b336000908152604460205260409020600181015462093a80906201518042064203031015612dde57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f372064617973206469646e277420706173730000000000000000000000000000604482015290519081900360640190fd5b8054600214612e38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615dce6023913960400191505060405180910390fd5b600080825560405133917f4a7934670bd8304e7da22378be1368f7c4fef17c5aee81804beda8638fe428ec91a250565b60008281526036602090815260408083207f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c845260058101909252822054909190612eb49033906114a0565b33600090815260068401602052604090205490915060ff16151560011415612f3d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f53656e6465722068617320616c726561647920766f7465640000000000000000604482015290519081900360640190fd5b80612fa957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f557365722062616c616e63652069732030000000000000000000000000000000604482015290519081900360640190fd5b336000908152604460205260409020546003141561302857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e657220697320756e646572206469737075746500000000000000000000604482015290519081900360640190fd5b336000908152600683016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091557f1da378694063870452ce03b189f48e04c1aa026348e74e6c86e10738514ad2c48452600586019092529091208054909101905582156130bb5760018201546130b19082614a86565b60018301556130d0565b60018201546130ca9082614ab1565b60018301555b60408051841515815290518291339187917f911ef2e98570b1d96c0e8ef81107a33d5b8e844aeb8f9710f9bc76c3b3fef40e919081900360200190a450505050565b6049602052816000526040600020818154811061312e57600080fd5b6000918252602090912001546fffffffffffffffffffffffffffffffff808216935070010000000000000000000000000000000090910416905082565b60386020526000908152604090205481565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260409020805415806131fe57508054439082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106131dd57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614155b156132945760408051808201909152436fffffffffffffffffffffffffffffffff90811682528381166020808401918252845460018101865560008681529190912093519301805491517fffffffffffffffffffffffffffffffff000000000000000000000000000000009092169383169390931782167001000000000000000000000000000000009190921602179055613302565b805460009082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106132c757fe5b600091825260209091200180546fffffffffffffffffffffffffffffffff808616700100000000000000000000000000000000029116179055505b505050565b603660205260009081526040902080546001820154600283015460038401546004909401549293919260ff8083169361010084048216936201000081049092169273ffffffffffffffffffffffffffffffffffffffff6301000000909304831692918216911688565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152604a6020908152604080832093909416825291909152205490565b7f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546133fc8261175d565b1015613453576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615e7c6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526044602052604090205415806134aa575073ffffffffffffffffffffffffffffffffffffffff81166000908152604460205260409020546002145b61351557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e657220697320696e207468652077726f6e672073746174650000000000604482015290519081900360640190fd5b7fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd38054600190810190915560408051808201825282815262015180429081069003602082810191825273ffffffffffffffffffffffffffffffffffffffff8616600081815260449092528482209351845591519290940191909155905190917f46d8ab1385f70e5a3673e97c23c764f7600f7ed7a09b6687deae7131d51752e291a250565b80613610576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e5b6021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661369257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b61369c83826124a9565b6136f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180615e346027913960400191505060405180910390fd5b60006136fc8461175d565b905061370a8483830361317d565b6137138361175d565b905080828201101561378657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6137928383830161317d565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b7f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd54702836c9d21d0727ffacc3e39f57c92b5ae0f50177e593bfb5ec66e3de280600052604860209081527f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d546040805180840183815233606081901b93830193909352865160029560039594938993926054909101918401908083835b602083106138da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161389d565b6001836020036101000a038019825116818451168082178552505050505050905001935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061398357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613946565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156139e0573d6000803e3d6000fd5b5050506040515160601b60405160200180826bffffffffffffffffffffffff191681526014019150506040516020818303038152906040526040518082805190602001908083835b60208310613a6557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613a28565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015613ac2573d6000803e3d6000fd5b5050506040513d6020811015613ad757600080fd5b505181613ae057fe5b061580613b3e57507f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f160005260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854610384429190910310155b613b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615f046025913960400191505060405180910390fd5b50565b604080513360208083018290528351808403820181529284018452825192810192909220600091825260449092529190912054600114613c3757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e657220737461747573206973206e6f74207374616b6572000000000000604482015290519081900360640190fd5b603a54835114613ca857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603c54602084015114613d1c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603e54604084015114613d9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604054606084015114613e0457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604254608084015114613e7857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b60008181526046602090815260408083204290557f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492548185526039845282852033865290935292205460ff1615613f3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615ebf6021913960400191505060405180910390fd5b6000828152603960209081526040808320338452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c5483526045825280832087518480526006820190935292208360058110613fc257fe5b0155602080860151600160009081526006840190925260409091208360058110613fe857fe5b0155604080860151600260009081526006840160205291909120836005811061400d57fe5b01556060850151600360009081526006830160205260409020836005811061403157fe5b01556080850151600460009081526006830160205260409020836005811061405557fe5b015560008080526005808301602052604090912033918490811061407557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560016000908152600582810160205260409091203391849081106140d957fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600260009081526005828101602052604090912033918490811061413d57fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560036000908152600582810160205260409091203391849081106141a157fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600460009081526005828101602052604090912033918490811061420557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600182016004141561425d5761425d614ad7565b81600101600514156142c5576142738787614c15565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b082600090815260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249255614317565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492805460010190555b823373ffffffffffffffffffffffffffffffffffffffff167f9d2e5f03fc65aff196e0f3a8dd924b24099de487e8cffc888921d420ab196e3989898987604051808060200185600560200280838360005b83811015614380578181015183820152602001614368565b5050505090500184600560200280838360005b838110156143ab578181015183820152602001614393565b50505050905001838152602001828103825286818151815260200191508051906020019080838360005b838110156143ed5781810151838201526020016143d5565b50505050905090810190601f16801561441a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a350505050505050565b8061443d576145d7565b60006144488361175d565b90508082820311156144bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810381101561457757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6145838484840361317d565b50507fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e805482900390555b5050565b60008281526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d845260018101909252909120546146249083615605565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d6000908152600183016020526040902055603a548314806146675750603c5483145b806146735750603e5483145b8061467f575060405483145b8061468b575060425483145b156146e5577f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60005260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b72805483019055613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa1600090815260018201602052604090205461483f5760408051610660810191829052600091829161475691839060339082845b815481526020019060010190808311614739575050505050615614565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001860160205260409020549193509150821080614798575081155b15614838577f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001840160205260408120549082603381106147db57fe5b0155600081815260356020908152604080832080548452604583528184207ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa185526001908101845282852085905590899055860190915290208190555b5050613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160009081526001820160205260408120548391906033811061487e57fe5b0180549091019055505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152604b602052604090205460ff161561492057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f616c72656479206d696772617465640000000000000000000000000000000000604482015290519081900360640190fd5b7f56e0987db9eaec01ed9e0af003a0fd5c062371f9d23722eb4a3ebc74f16ea371600052604760209081527fc930326aab6c1874fc004d856083a6ed34e057e064970b7effb48e8e6e8ca12754604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301529151614a1094869493909316926370a082319260248082019391829003018186803b1580156149df57600080fd5b505afa1580156149f3573d6000803e3d6000fd5b505050506040513d6020811015614a0957600080fd5b5051615681565b73ffffffffffffffffffffffffffffffffffffffff166000908152604b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000818310614a6e5781614a70565b825b9392505050565b6000818311614a6e5781614a70565b600080821315614aa3575081810182811215614a9e57fe5b610c03565b5081810182811315610c0357fe5b600080821315614ac9575080820382811315614a9e57fe5b5080820382811215610c0357fe5b7f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f1600090815260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854420390614b336104b083614a5f565b60466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd4f87b8d0f3d3b7e665df74631f6100b2695daa0e30e40eeac02172e15a999e16000527f8156e704072c396780f8253d0562de28216b73a1503daa96e259b9cdd951d71c54610fa0929003810291909105915081614bb857600191505b614bc58282016001615943565b7ff758978fc1647996a3d9992f611883adc442931dc49488312360acc90601759b60005260466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d15002555505050565b7fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c54600090815260456020908152604082207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f190935260469091527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e031188054429182905591929190614cc6615d12565b614cce615d12565b60005b600581101561510d5760015b6005811015614f6857600082815260068901602052604081208260058110614d0157fe5b0154905060008960050160008581526020019081526020016000208360058110614d2757fe5b015473ffffffffffffffffffffffffffffffffffffffff169050825b600081118015614d905750600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614d8b57fe5b015483105b15614ed357600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614dd257fe5b0154600086815260068d01602052604090208260058110614def57fe5b015560008581526005808d016020526040909120907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301908110614e3057fe5b015460008681526005808e01602052604090912073ffffffffffffffffffffffffffffffffffffffff909216919083908110614e6857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01614d43565b83811015614f5d57600085815260068c016020526040902083908260058110614ef857fe5b015560008581526005808d016020526040909120839183908110614f1857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b505050600101614cdd565b506000604560008a8460058110614f7b57fe5b602002015181526020019081526020016000209050876006016000838152602001908152602001600020600580602002604051908101604052809291908260058015614fdc576020028201915b815481526020019060010190808311614fc8575b5050505050935083600260058110614ff057fe5b602090810291909101516000878152600384019092526040918290205584015183836005811061501c57fe5b6020908102919091019190915260008381526005808b0183526040808320898452858301909452909120615051929091615d30565b5060008281526006808a016020908152604080842089855292850190915290912061507d916005615d30565b506000828152600589016020526040812061509791615d6b565b600082815260068901602052604081206150b091615d6b565b8054600181810183556000838152602080822090930188905587815260028401835260408082204390557f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d82529382019092529181205501614cd1565b50847fbeb3b9f46c8d7bb00c873fca10d307538df350866d25f891ffb395147ddbdc45888584604660007f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60001b8152602001908152602001600020546040518085600560200280838360005b8381101561519257818101518382015260200161517a565b5050505090500184815260200183600560200280838360005b838110156151c35781810151838201526020016151ab565b5050505090500182815260200194505050505060405180910390a2603380546001810182556000919091527f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a820183905561521b615d12565b87516000908152604560209081526040808320878452600590810190925291829020825160a08101938490529290919082845b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161524e57505050505090506152898186615952565b7ff3b93531fa65b3a18680d9ea49df06d96fbd883c4889dc7db866f8b131602dfb60005260466020527fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c805460010190556152e2615d12565b6152ea615ad9565b905060005b60058110156154375781816005811061530457fe5b6020020151603a826005811061531657fe5b600202015560008060458185856005811061532d57fe5b6020020151815260200190815260200160002060010160007ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160001b8152602001908152602001600020546033811061538257fe5b01556045600083836005811061539457fe5b60209081029190910151825281810192909252604090810160009081207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d825260019081018452918120547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a90915260469092527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b728054909201909155016152ef565b50898760014303406040516020018080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561548b578181015183820152602001615473565b50505050905090810190601f1680156154b85780820380516001836020036101000a031916815260200191505b50604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d81905560469091527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254929f508f98507f1d85ce10456e29b67de37887496d3f1fcf1b64c79c4d07484038703a9f5c140897508996509094509092508190859060a0908190849084905b838110156155db5781810151838201526020016155c3565b5050505091909101938452505060208201526040805191829003019150a250505050505050505050565b600082820183811015614a7057fe5b610640810151603260315b801561567b578284826033811061563257fe5b602002015110156156545783816033811061564957fe5b602002015192508091505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161561f565b50915091565b806156d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e136021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661575957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b60006157648361175d565b90508082820110156157d757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810181111561589357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e8054840190556158ef8483850161317d565b60408051848152905173ffffffffffffffffffffffffffffffffffffffff8616916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350505050565b6000818313614a6e5781614a70565b60466020527fc2c579d641b643400780d5c7ce967b420034b9f66962a5ee405cf70e4cbed6bb547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254428490039261012c9084020491600a9091049060028304906159ed9087905b6020020151838501615681565b6159f88660016159e0565b615a038660026159e0565b615a0e8660036159e0565b615a198660046159e0565b7f7a39905194de50bde334d18b76bbb36dddd11641d4d50b470cb837cf3bae5def60005260476020527fb5f7e7387e8e977cc9c4c9513388b0d7224264b9a0159cd8e8bdd84a9ed504c354615a849073ffffffffffffffffffffffffffffffffffffffff1682615681565b50507f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a600090815260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b725550505050565b615ae1615d12565b615ae9615d12565b615af1615d12565b60408051610660810191829052615b289160009060339082845b815481526020019060010190808311615b0b575050505050615bbe565b909250905060005b6005811015615bb857828160058110615b4557fe5b602002015115615b895760356000838360058110615b5f57fe5b6020020151815260200190815260200160002054848260058110615b7f57fe5b6020020152615bb0565b603a8160040360058110615b9957fe5b6002020154848260058110615baa57fe5b60200201525b600101615b30565b50505090565b615bc6615d12565b615bce615d12565b60208301516000805b6005811015615c5157858160010160338110615bef57fe5b6020020151858260058110615c0057fe5b602002015260018101848260058110615c1557fe5b602002015282858260058110615c2757fe5b60200201511015615c4957848160058110615c3e57fe5b602002015192508091505b600101615bd7565b5060065b6033811015615d0a5782868260338110615c6b57fe5b60200201511115615d0257858160338110615c8257fe5b6020020151858360058110615c9357fe5b602002015280848360058110615ca557fe5b6020020152858160338110615cb657fe5b6020020151925060005b6005811015615d005783868260058110615cd657fe5b60200201511015615cf857858160058110615ced57fe5b602002015193508092505b600101615cc0565b505b600101615c55565b505050915091565b6040518060a001604052806005906020820280368337509192915050565b8260058101928215615d5b579182015b82811115615d5b578254825591600101919060010190615d40565b50615d67929150615d8e565b5090565b506000815560010160008155600101600081556001016000815560010160009055565b5b80821115615d675760008155600101615d8f56fe4d696e65722063616e206f6e6c792077696e2072657761726473206f6e636520706572203135206d696e4d696e657220776173206e6f74206c6f636b656420666f72207769746864726177616c45524332303a20617070726f766520746f20746865207a65726f2061646472657373547269656420746f206d696e74206e6f6e2d706f73697469766520616d6f756e7453686f756c6420686176652073756666696369656e742062616c616e636520746f207472616465547269656420746f2073656e64206e6f6e2d706f73697469766520616d6f756e7442616c616e6365206973206c6f776572207468616e207374616b6520616d6f756e744469737075746520686173206265656e20616c72656164792065786563757465644d696e657220616c7265616479207375626d6974746564207468652076616c756545524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373496e636f7272656374206e6f6e636520666f722063757272656e74206368616c6c656e6765a2646970667358221220283d77407206ff6c4cc0f6e78ee639e4e194574cc796cf2b7dbf2fa45ca9e7dc64736f6c63430007040033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.