Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 6 from a total of 6 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Migrate | 12138990 | 1403 days ago | IN | 0 ETH | 0.00226599 | ||||
Migrate | 12138989 | 1403 days ago | IN | 0 ETH | 0.00231956 | ||||
Migrate | 11916141 | 1438 days ago | IN | 0 ETH | 0.00282173 | ||||
Submit Mining So... | 11916082 | 1438 days ago | IN | 0 ETH | 0.04447187 | ||||
Submit Mining So... | 11916045 | 1438 days ago | IN | 0 ETH | 0.04784 | ||||
Submit Mining So... | 11916001 | 1438 days ago | IN | 0 ETH | 0.04134 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
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 Source Code Verified (Exact Match)
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
[{"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
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.