Contract Overview
Balance:
0 frxETH
Token:
My Name Tag:
Not Available
[ Download CSV Export ]
Contract Name:
TellorFlex
Compiler Version
v0.8.3+commit.8d00100c
Contract Source Code (Solidity)
/** *Submitted for verification at holesky.fraxscan.com on 2024-03-26 */ // SPDX-License-Identifier: MIT pragma solidity 0.8.3; interface IERC20 { function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); } /** @author Tellor Inc. @title TellorFlex @dev This is a streamlined Tellor oracle system which handles staking, reporting, * slashing, and user data getters in one contract. This contract is controlled * by a single address known as 'governance', which could be an externally owned * account or a contract, allowing for a flexible, modular design. */ contract TellorFlex { // Storage IERC20 public immutable token; // token used for staking and rewards address public governance; // address with ability to remove values and slash reporters address public immutable owner; // contract deployer, can call init function once uint256 public accumulatedRewardPerShare; // accumulated staking reward per staked token uint256 public immutable minimumStakeAmount; // minimum amount of tokens required to stake uint256 public immutable reportingLock; // base amount of time before a reporter is able to submit a value again uint256 public rewardRate; // total staking rewards released per second uint256 public stakeAmount; // minimum amount required to be a staker uint256 public immutable stakeAmountDollarTarget; // amount of US dollars required to be a staker uint256 public stakingRewardsBalance; // total amount of staking rewards bytes32 public immutable stakingTokenPriceQueryId; // staking token SpotPrice queryId, used for updating stakeAmount uint256 public constant timeBasedReward = 5e17; // amount of TB rewards released per 5 minutes uint256 public timeOfLastAllocation; // time of last update to accumulatedRewardPerShare uint256 public timeOfLastNewValue = block.timestamp; // time of the last new submitted value, originally set to the block timestamp uint256 public totalRewardDebt; // staking reward debt, used to calculate real staking rewards balance uint256 public totalStakeAmount; // total amount of tokens locked in contract (via stake) uint256 public totalStakers; // total number of stakers with at least stakeAmount staked, not exact uint256 public toWithdraw; //amountLockedForWithdrawal mapping(bytes32 => Report) private reports; // mapping of query IDs to a report mapping(address => StakeInfo) private stakerDetails; // mapping from a persons address to their staking info // Structs struct Report { uint256[] timestamps; // array of all newValueTimestamps reported mapping(uint256 => uint256) timestampIndex; // mapping of timestamps to respective indices mapping(uint256 => bytes) valueByTimestamp; // mapping of timestamps to values mapping(uint256 => address) reporterByTimestamp; // mapping of timestamps to reporters mapping(uint256 => bool) isDisputed; } struct StakeInfo { uint256 startDate; // stake or withdrawal request start date uint256 stakedBalance; // staked token balance uint256 lockedBalance; // amount locked for withdrawal uint256 rewardDebt; // used for staking reward calculation uint256 reporterLastTimestamp; // timestamp of reporter's last reported value uint256 reportsSubmitted; // total number of reports submitted by reporter uint256 startVoteCount; // total number of governance votes when stake deposited uint256 startVoteTally; // staker vote tally when stake deposited bool staked; // used to keep track of total stakers } // Events event NewReport( bytes32 indexed _queryId, uint256 indexed _time, bytes _value, uint256 _nonce, bytes _queryData, address indexed _reporter ); event NewStakeAmount(uint256 _newStakeAmount); event NewStaker(address indexed _staker, uint256 indexed _amount); event ReporterSlashed( address indexed _reporter, address _recipient, uint256 _slashAmount ); event StakeWithdrawn(address _staker); event StakeWithdrawRequested(address _staker, uint256 _amount); event ValueRemoved(bytes32 _queryId, uint256 _timestamp); // Functions /** * @dev Initializes system parameters * @param _token address of token used for staking and rewards * @param _reportingLock base amount of time (seconds) before reporter is able to report again * @param _stakeAmountDollarTarget fixed USD amount that stakeAmount targets on updateStakeAmount * @param _stakingTokenPrice current price of staking token in USD (18 decimals) * @param _stakingTokenPriceQueryId queryId where staking token price is reported */ constructor( address _token, uint256 _reportingLock, uint256 _stakeAmountDollarTarget, uint256 _stakingTokenPrice, uint256 _minimumStakeAmount, bytes32 _stakingTokenPriceQueryId ) { require(_token != address(0), "must set token address"); require(_stakingTokenPrice > 0, "must set staking token price"); require(_reportingLock > 0, "must set reporting lock"); require(_stakingTokenPriceQueryId != bytes32(0), "must set staking token price queryId"); token = IERC20(_token); owner = msg.sender; reportingLock = _reportingLock; stakeAmountDollarTarget = _stakeAmountDollarTarget; minimumStakeAmount = _minimumStakeAmount; uint256 _potentialStakeAmount = (_stakeAmountDollarTarget * 1e18) / _stakingTokenPrice; if(_potentialStakeAmount < _minimumStakeAmount) { stakeAmount = _minimumStakeAmount; } else { stakeAmount = _potentialStakeAmount; } stakingTokenPriceQueryId = _stakingTokenPriceQueryId; } /** * @dev Allows the owner to initialize the governance (flex addy needed for governance deployment) * @param _governanceAddress address of governance contract (github.com/tellor-io/governance) */ function init(address _governanceAddress) external { require(msg.sender == owner, "only owner can set governance address"); require(governance == address(0), "governance address already set"); require( _governanceAddress != address(0), "governance address can't be zero address" ); governance = _governanceAddress; } /** * @dev Funds the Flex contract with staking rewards (paid by autopay and minting) * @param _amount amount of tokens to fund contract with */ function addStakingRewards(uint256 _amount) external { require(token.transferFrom(msg.sender, address(this), _amount)); _updateRewards(); stakingRewardsBalance += _amount; // update reward rate = real staking rewards balance / 30 days rewardRate = (stakingRewardsBalance - ((accumulatedRewardPerShare * totalStakeAmount) / 1e18 - totalRewardDebt)) / 30 days; } /** * @dev Allows a reporter to submit stake * @param _amount amount of tokens to stake */ function depositStake(uint256 _amount) external { require(governance != address(0), "governance address not set"); StakeInfo storage _staker = stakerDetails[msg.sender]; uint256 _stakedBalance = _staker.stakedBalance; uint256 _lockedBalance = _staker.lockedBalance; if (_lockedBalance > 0) { if (_lockedBalance >= _amount) { // if staker's locked balance covers full _amount, use that _staker.lockedBalance -= _amount; toWithdraw -= _amount; } else { // otherwise, stake the whole locked balance and transfer the // remaining amount from the staker's address require( token.transferFrom( msg.sender, address(this), _amount - _lockedBalance ) ); toWithdraw -= _staker.lockedBalance; _staker.lockedBalance = 0; } } else { if (_stakedBalance == 0) { // if staked balance and locked balance equal 0, save current vote tally. // voting participation used for calculating rewards (bool _success, bytes memory _returnData) = governance.call( abi.encodeWithSignature("getVoteCount()") ); if (_success) { _staker.startVoteCount = uint256(abi.decode(_returnData, (uint256))); } (_success,_returnData) = governance.call( abi.encodeWithSignature("getVoteTallyByAddress(address)",msg.sender) ); if(_success){ _staker.startVoteTally = abi.decode(_returnData,(uint256)); } } require(token.transferFrom(msg.sender, address(this), _amount)); } _updateStakeAndPayRewards(msg.sender, _stakedBalance + _amount); _staker.startDate = block.timestamp; // This resets the staker start date to now emit NewStaker(msg.sender, _amount); } /** * @dev Removes a value from the oracle. * Note: this function is only callable by the Governance contract. * @param _queryId is ID of the specific data feed * @param _timestamp is the timestamp of the data value to remove */ function removeValue(bytes32 _queryId, uint256 _timestamp) external { require(msg.sender == governance, "caller must be governance address"); Report storage _report = reports[_queryId]; require(!_report.isDisputed[_timestamp], "value already disputed"); uint256 _index = _report.timestampIndex[_timestamp]; require(_timestamp == _report.timestamps[_index], "invalid timestamp"); _report.valueByTimestamp[_timestamp] = ""; _report.isDisputed[_timestamp] = true; emit ValueRemoved(_queryId, _timestamp); } /** * @dev Allows a reporter to request to withdraw their stake * @param _amount amount of staked tokens requesting to withdraw */ function requestStakingWithdraw(uint256 _amount) external { StakeInfo storage _staker = stakerDetails[msg.sender]; require( _staker.stakedBalance >= _amount, "insufficient staked balance" ); _updateStakeAndPayRewards(msg.sender, _staker.stakedBalance - _amount); _staker.startDate = block.timestamp; _staker.lockedBalance += _amount; toWithdraw += _amount; emit StakeWithdrawRequested(msg.sender, _amount); } /** * @dev Slashes a reporter and transfers their stake amount to the given recipient * Note: this function is only callable by the governance address. * @param _reporter is the address of the reporter being slashed * @param _recipient is the address receiving the reporter's stake * @return _slashAmount uint256 amount of token slashed and sent to recipient address */ function slashReporter(address _reporter, address _recipient) external returns (uint256 _slashAmount) { require(msg.sender == governance, "only governance can slash reporter"); StakeInfo storage _staker = stakerDetails[_reporter]; uint256 _stakedBalance = _staker.stakedBalance; uint256 _lockedBalance = _staker.lockedBalance; require(_stakedBalance + _lockedBalance > 0, "zero staker balance"); if (_lockedBalance >= stakeAmount) { // if locked balance is at least stakeAmount, slash from locked balance _slashAmount = stakeAmount; _staker.lockedBalance -= stakeAmount; toWithdraw -= stakeAmount; } else if (_lockedBalance + _stakedBalance >= stakeAmount) { // if locked balance + staked balance is at least stakeAmount, // slash from locked balance and slash remainder from staked balance _slashAmount = stakeAmount; _updateStakeAndPayRewards( _reporter, _stakedBalance - (stakeAmount - _lockedBalance) ); toWithdraw -= _lockedBalance; _staker.lockedBalance = 0; } else { // if sum(locked balance + staked balance) is less than stakeAmount, // slash sum _slashAmount = _stakedBalance + _lockedBalance; toWithdraw -= _lockedBalance; _updateStakeAndPayRewards(_reporter, 0); _staker.lockedBalance = 0; } require(token.transfer(_recipient, _slashAmount)); emit ReporterSlashed(_reporter, _recipient, _slashAmount); } /** * @dev Allows a reporter to submit a value to the oracle * @param _queryId is ID of the specific data feed. Equals keccak256(_queryData) for non-legacy IDs * @param _value is the value the user submits to the oracle * @param _nonce is the current value count for the query id * @param _queryData is the data used to fulfill the data query */ function submitValue( bytes32 _queryId, bytes calldata _value, uint256 _nonce, bytes calldata _queryData ) external { require(keccak256(_value) != keccak256(""), "value must be submitted"); Report storage _report = reports[_queryId]; require( _nonce == _report.timestamps.length || _nonce == 0, "nonce must match timestamp index" ); StakeInfo storage _staker = stakerDetails[msg.sender]; require( _staker.stakedBalance >= stakeAmount, "balance must be greater than stake amount" ); // Require reporter to abide by given reporting lock require( (block.timestamp - _staker.reporterLastTimestamp) * 1000 > (reportingLock * 1000) / (_staker.stakedBalance / stakeAmount), "still in reporter time lock, please wait!" ); require( _queryId == keccak256(_queryData), "query id must be hash of query data" ); _staker.reporterLastTimestamp = block.timestamp; // Checks for no double reporting of timestamps require( _report.reporterByTimestamp[block.timestamp] == address(0), "timestamp already reported for" ); // Update number of timestamps, value for given timestamp, and reporter for timestamp _report.timestampIndex[block.timestamp] = _report.timestamps.length; _report.timestamps.push(block.timestamp); _report.valueByTimestamp[block.timestamp] = _value; _report.reporterByTimestamp[block.timestamp] = msg.sender; // Disperse Time Based Reward uint256 _reward = ((block.timestamp - timeOfLastNewValue) * timeBasedReward) / 300; //.5 TRB per 5 minutes uint256 _totalTimeBasedRewardsBalance = token.balanceOf(address(this)) - (totalStakeAmount + stakingRewardsBalance + toWithdraw); if (_totalTimeBasedRewardsBalance > 0 && _reward > 0) { if (_totalTimeBasedRewardsBalance < _reward) { token.transfer(msg.sender, _totalTimeBasedRewardsBalance); } else { token.transfer(msg.sender, _reward); } } // Update last oracle value and number of values submitted by a reporter timeOfLastNewValue = block.timestamp; unchecked{ _staker.reportsSubmitted++; } emit NewReport( _queryId, block.timestamp, _value, _nonce, _queryData, msg.sender ); } /** * @dev Updates the stake amount after retrieving the latest * 12+-hour-old staking token price from the oracle */ function updateStakeAmount() external { // get staking token price (bool _valFound, bytes memory _val, ) = getDataBefore( stakingTokenPriceQueryId, block.timestamp - 12 hours ); if (_valFound) { uint256 _stakingTokenPrice = abi.decode(_val, (uint256)); require( _stakingTokenPrice >= 0.01 ether && _stakingTokenPrice < 1000000 ether, "invalid staking token price" ); uint256 _adjustedStakeAmount = (stakeAmountDollarTarget * 1e18) / _stakingTokenPrice; if(_adjustedStakeAmount < minimumStakeAmount) { stakeAmount = minimumStakeAmount; } else { stakeAmount = _adjustedStakeAmount; } emit NewStakeAmount(stakeAmount); } } /** * @dev Withdraws a reporter's stake after the lock period expires */ function withdrawStake() external { StakeInfo storage _staker = stakerDetails[msg.sender]; // Ensure reporter is locked and that enough time has passed require( block.timestamp - _staker.startDate >= 7 days, "7 days didn't pass" ); require( _staker.lockedBalance > 0, "reporter not locked for withdrawal" ); require(token.transfer(msg.sender, _staker.lockedBalance)); toWithdraw -= _staker.lockedBalance; _staker.lockedBalance = 0; emit StakeWithdrawn(msg.sender); } // ***************************************************************************** // * * // * Getters * // * * // ***************************************************************************** /** * @dev Returns the current value of a data feed given a specific ID * @param _queryId is the ID of the specific data feed * @return _value the latest submitted value for the given queryId */ function getCurrentValue(bytes32 _queryId) external view returns (bytes memory _value) { bool _didGet; (_didGet, _value, ) = getDataBefore(_queryId, block.timestamp + 1); if(!_didGet){revert();} } /** * @dev Retrieves the latest value for the queryId before the specified timestamp * @param _queryId is the queryId to look up the value for * @param _timestamp before which to search for latest value * @return _ifRetrieve bool true if able to retrieve a non-zero value * @return _value the value retrieved * @return _timestampRetrieved the value's timestamp */ function getDataBefore(bytes32 _queryId, uint256 _timestamp) public view returns ( bool _ifRetrieve, bytes memory _value, uint256 _timestampRetrieved ) { (bool _found, uint256 _index) = getIndexForDataBefore( _queryId, _timestamp ); if (!_found) return (false, bytes(""), 0); _timestampRetrieved = getTimestampbyQueryIdandIndex(_queryId, _index); _value = retrieveData(_queryId, _timestampRetrieved); return (true, _value, _timestampRetrieved); } /** * @dev Returns governance address * @return address governance */ function getGovernanceAddress() external view returns (address) { return governance; } /** * @dev Counts the number of values that have been submitted for the request. * @param _queryId the id to look up * @return uint256 count of the number of values received for the id */ function getNewValueCountbyQueryId(bytes32 _queryId) public view returns (uint256) { return reports[_queryId].timestamps.length; } /** * @dev Returns the pending staking reward for a given address * @param _stakerAddress staker address to look up * @return _pendingReward - pending reward for given staker */ function getPendingRewardByStaker(address _stakerAddress) external returns (uint256 _pendingReward) { StakeInfo storage _staker = stakerDetails[_stakerAddress]; _pendingReward = (_staker.stakedBalance * _getUpdatedAccumulatedRewardPerShare()) / 1e18 - _staker.rewardDebt; (bool _success, bytes memory _returnData) = governance.call( abi.encodeWithSignature("getVoteCount()") ); uint256 _numberOfVotes; if (_success) { _numberOfVotes = uint256(abi.decode(_returnData, (uint256))) - _staker.startVoteCount; } if (_numberOfVotes > 0) { (_success,_returnData) = governance.call( abi.encodeWithSignature("getVoteTallyByAddress(address)",_stakerAddress) ); if(_success){ _pendingReward = (_pendingReward * (abi.decode(_returnData,(uint256)) - _staker.startVoteTally)) / _numberOfVotes; } } } /** * @dev Returns the real staking rewards balance after accounting for unclaimed rewards * @return uint256 real staking rewards balance */ function getRealStakingRewardsBalance() external view returns (uint256) { uint256 _pendingRewards = (_getUpdatedAccumulatedRewardPerShare() * totalStakeAmount) / 1e18 - totalRewardDebt; return (stakingRewardsBalance - _pendingRewards); } /** * @dev Returns reporter address and whether a value was removed for a given queryId and timestamp * @param _queryId the id to look up * @param _timestamp is the timestamp of the value to look up * @return address reporter who submitted the value * @return bool true if the value was removed */ function getReportDetails(bytes32 _queryId, uint256 _timestamp) external view returns (address, bool) { return (reports[_queryId].reporterByTimestamp[_timestamp], reports[_queryId].isDisputed[_timestamp]); } /** * @dev Returns the address of the reporter who submitted a value for a data ID at a specific time * @param _queryId is ID of the specific data feed * @param _timestamp is the timestamp to find a corresponding reporter for * @return address of the reporter who reported the value for the data ID at the given timestamp */ function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) external view returns (address) { return reports[_queryId].reporterByTimestamp[_timestamp]; } /** * @dev Returns the timestamp of the reporter's last submission * @param _reporter is address of the reporter * @return uint256 timestamp of the reporter's last submission */ function getReporterLastTimestamp(address _reporter) external view returns (uint256) { return stakerDetails[_reporter].reporterLastTimestamp; } /** * @dev Returns the reporting lock time, the amount of time a reporter must wait to submit again * @return uint256 reporting lock time */ function getReportingLock() external view returns (uint256) { return reportingLock; } /** * @dev Returns the number of values submitted by a specific reporter address * @param _reporter is the address of a reporter * @return uint256 the number of values submitted by the given reporter */ function getReportsSubmittedByAddress(address _reporter) external view returns (uint256) { return stakerDetails[_reporter].reportsSubmitted; } /** * @dev Returns amount required to report oracle values * @return uint256 stake amount */ function getStakeAmount() external view returns (uint256) { return stakeAmount; } /** * @dev Returns all information about a staker * @param _stakerAddress address of staker inquiring about * @return uint startDate of staking * @return uint current amount staked * @return uint current amount locked for withdrawal * @return uint reward debt used to calculate staking rewards * @return uint reporter's last reported timestamp * @return uint total number of reports submitted by reporter * @return uint governance vote count when first staked * @return uint number of votes cast by staker when first staked * @return bool whether staker is counted in totalStakers */ function getStakerInfo(address _stakerAddress) external view returns ( uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, bool ) { StakeInfo storage _staker = stakerDetails[_stakerAddress]; return ( _staker.startDate, _staker.stakedBalance, _staker.lockedBalance, _staker.rewardDebt, _staker.reporterLastTimestamp, _staker.reportsSubmitted, _staker.startVoteCount, _staker.startVoteTally, _staker.staked ); } /** * @dev Returns the timestamp for the last value of any ID from the oracle * @return uint256 timestamp of the last oracle value */ function getTimeOfLastNewValue() external view returns (uint256) { return timeOfLastNewValue; } /** * @dev Gets the timestamp for the value based on their index * @param _queryId is the id to look up * @param _index is the value index to look up * @return uint256 timestamp */ function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) public view returns (uint256) { return reports[_queryId].timestamps[_index]; } /** * @dev Retrieves latest array index of data before the specified timestamp for the queryId * @param _queryId is the queryId to look up the index for * @param _timestamp is the timestamp before which to search for the latest index * @return _found whether the index was found * @return _index the latest index found before the specified timestamp */ // slither-disable-next-line calls-loop function getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) public view returns (bool _found, uint256 _index) { uint256 _count = getNewValueCountbyQueryId(_queryId); if (_count > 0) { uint256 _middle; uint256 _start = 0; uint256 _end = _count - 1; uint256 _time; //Checking Boundaries to short-circuit the algorithm _time = getTimestampbyQueryIdandIndex(_queryId, _start); if (_time >= _timestamp) return (false, 0); _time = getTimestampbyQueryIdandIndex(_queryId, _end); if (_time < _timestamp) { while(isInDispute(_queryId, _time) && _end > 0) { _end--; _time = getTimestampbyQueryIdandIndex(_queryId, _end); } if(_end == 0 && isInDispute(_queryId, _time)) { return (false, 0); } return (true, _end); } //Since the value is within our boundaries, do a binary search while (true) { _middle = (_end - _start) / 2 + 1 + _start; _time = getTimestampbyQueryIdandIndex(_queryId, _middle); if (_time < _timestamp) { //get immediate next value uint256 _nextTime = getTimestampbyQueryIdandIndex( _queryId, _middle + 1 ); if (_nextTime >= _timestamp) { if(!isInDispute(_queryId, _time)) { // _time is correct return (true, _middle); } else { // iterate backwards until we find a non-disputed value while(isInDispute(_queryId, _time) && _middle > 0) { _middle--; _time = getTimestampbyQueryIdandIndex(_queryId, _middle); } if(_middle == 0 && isInDispute(_queryId, _time)) { return (false, 0); } // _time is correct return (true, _middle); } } else { //look from middle + 1(next value) to end _start = _middle + 1; } } else { uint256 _prevTime = getTimestampbyQueryIdandIndex( _queryId, _middle - 1 ); if (_prevTime < _timestamp) { if(!isInDispute(_queryId, _prevTime)) { // _prevTime is correct return (true, _middle - 1); } else { // iterate backwards until we find a non-disputed value _middle--; while(isInDispute(_queryId, _prevTime) && _middle > 0) { _middle--; _prevTime = getTimestampbyQueryIdandIndex( _queryId, _middle ); } if(_middle == 0 && isInDispute(_queryId, _prevTime)) { return (false, 0); } // _prevtime is correct return (true, _middle); } } else { //look from start to middle -1(prev value) _end = _middle - 1; } } } } return (false, 0); } /** * @dev Returns the index of a reporter timestamp in the timestamp array for a specific data ID * @param _queryId is ID of the specific data feed * @param _timestamp is the timestamp to find in the timestamps array * @return uint256 of the index of the reporter timestamp in the array for specific ID */ function getTimestampIndexByTimestamp(bytes32 _queryId, uint256 _timestamp) external view returns (uint256) { return reports[_queryId].timestampIndex[_timestamp]; } /** * @dev Returns the address of the token used for staking * @return address of the token used for staking */ function getTokenAddress() external view returns (address) { return address(token); } /** * @dev Returns total amount of token staked for reporting * @return uint256 total amount of token staked */ function getTotalStakeAmount() external view returns (uint256) { return totalStakeAmount; } /** * @dev Returns total number of current stakers. Reporters with stakedBalance less than stakeAmount are excluded from this total * @return uint256 total stakers */ function getTotalStakers() external view returns (uint256) { return totalStakers; } /** * @dev Returns total balance of time based rewards in contract * @return uint256 amount of trb */ function getTotalTimeBasedRewardsBalance() external view returns (uint256) { return token.balanceOf(address(this)) - (totalStakeAmount + stakingRewardsBalance + toWithdraw); } /** * @dev Returns whether a given value is disputed * @param _queryId unique ID of the data feed * @param _timestamp timestamp of the value * @return bool whether the value is disputed */ function isInDispute(bytes32 _queryId, uint256 _timestamp) public view returns (bool) { return reports[_queryId].isDisputed[_timestamp]; } /** * @dev Retrieve value from oracle based on timestamp * @param _queryId being requested * @param _timestamp to retrieve data/value from * @return bytes value for timestamp submitted */ function retrieveData(bytes32 _queryId, uint256 _timestamp) public view returns (bytes memory) { return reports[_queryId].valueByTimestamp[_timestamp]; } /** * @dev Used during the upgrade process to verify valid Tellor contracts * @return bool value used to verify valid Tellor contracts */ function verify() external pure returns (uint256) { return 9999; } // ***************************************************************************** // * * // * Internal functions * // * * // ***************************************************************************** /** * @dev Updates accumulated staking rewards per staked token */ function _updateRewards() internal { if (timeOfLastAllocation == block.timestamp) { return; } if (totalStakeAmount == 0 || rewardRate == 0) { timeOfLastAllocation = block.timestamp; return; } // calculate accumulated reward per token staked uint256 _newAccumulatedRewardPerShare = accumulatedRewardPerShare + ((block.timestamp - timeOfLastAllocation) * rewardRate * 1e18) / totalStakeAmount; // calculate accumulated reward with _newAccumulatedRewardPerShare uint256 _accumulatedReward = (_newAccumulatedRewardPerShare * totalStakeAmount) / 1e18 - totalRewardDebt; if (_accumulatedReward >= stakingRewardsBalance) { // if staking rewards run out, calculate remaining reward per staked // token and set rewardRate to 0 uint256 _newPendingRewards = stakingRewardsBalance - ((accumulatedRewardPerShare * totalStakeAmount) / 1e18 - totalRewardDebt); accumulatedRewardPerShare += (_newPendingRewards * 1e18) / totalStakeAmount; rewardRate = 0; } else { accumulatedRewardPerShare = _newAccumulatedRewardPerShare; } timeOfLastAllocation = block.timestamp; } /** * @dev Called whenever a user's stake amount changes. First updates staking rewards, * transfers pending rewards to user's address, and finally updates user's stake amount * and other relevant variables. * @param _stakerAddress address of user whose stake is being updated * @param _newStakedBalance new staked balance of user */ function _updateStakeAndPayRewards( address _stakerAddress, uint256 _newStakedBalance ) internal { _updateRewards(); StakeInfo storage _staker = stakerDetails[_stakerAddress]; if (_staker.stakedBalance > 0) { // if address already has a staked balance, calculate and transfer pending rewards uint256 _pendingReward = (_staker.stakedBalance * accumulatedRewardPerShare) / 1e18 - _staker.rewardDebt; // get staker voting participation rate uint256 _numberOfVotes; (bool _success, bytes memory _returnData) = governance.call( abi.encodeWithSignature("getVoteCount()") ); if (_success) { _numberOfVotes = uint256(abi.decode(_returnData, (uint256))) - _staker.startVoteCount; } if (_numberOfVotes > 0) { // staking reward = pending reward * voting participation rate (_success, _returnData) = governance.call( abi.encodeWithSignature("getVoteTallyByAddress(address)",_stakerAddress) ); if(_success){ uint256 _voteTally = abi.decode(_returnData,(uint256)); uint256 _tempPendingReward = (_pendingReward * (_voteTally - _staker.startVoteTally)) / _numberOfVotes; if (_tempPendingReward < _pendingReward) { _pendingReward = _tempPendingReward; } } } stakingRewardsBalance -= _pendingReward; require(token.transfer(msg.sender, _pendingReward)); totalRewardDebt -= _staker.rewardDebt; totalStakeAmount -= _staker.stakedBalance; } _staker.stakedBalance = _newStakedBalance; // Update total stakers if (_staker.stakedBalance >= stakeAmount) { if (_staker.staked == false) { totalStakers++; } _staker.staked = true; } else { if (_staker.staked == true && totalStakers > 0) { totalStakers--; } _staker.staked = false; } // tracks rewards accumulated before stake amount updated _staker.rewardDebt = (_staker.stakedBalance * accumulatedRewardPerShare) / 1e18; totalRewardDebt += _staker.rewardDebt; totalStakeAmount += _staker.stakedBalance; // update reward rate if staking rewards are available // given staker's updated parameters if(rewardRate == 0) { rewardRate = (stakingRewardsBalance - ((accumulatedRewardPerShare * totalStakeAmount) / 1e18 - totalRewardDebt)) / 30 days; } } /** * @dev Internal function retrieves updated accumulatedRewardPerShare * @return uint256 up-to-date accumulated reward per share */ function _getUpdatedAccumulatedRewardPerShare() internal view returns (uint256) { if (totalStakeAmount == 0) { return accumulatedRewardPerShare; } uint256 _newAccumulatedRewardPerShare = accumulatedRewardPerShare + ((block.timestamp - timeOfLastAllocation) * rewardRate * 1e18) / totalStakeAmount; uint256 _accumulatedReward = (_newAccumulatedRewardPerShare * totalStakeAmount) / 1e18 - totalRewardDebt; if (_accumulatedReward >= stakingRewardsBalance) { uint256 _newPendingRewards = stakingRewardsBalance - ((accumulatedRewardPerShare * totalStakeAmount) / 1e18 - totalRewardDebt); _newAccumulatedRewardPerShare = accumulatedRewardPerShare + (_newPendingRewards * 1e18) / totalStakeAmount; } return _newAccumulatedRewardPerShare; } }
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_reportingLock","type":"uint256"},{"internalType":"uint256","name":"_stakeAmountDollarTarget","type":"uint256"},{"internalType":"uint256","name":"_stakingTokenPrice","type":"uint256"},{"internalType":"uint256","name":"_minimumStakeAmount","type":"uint256"},{"internalType":"bytes32","name":"_stakingTokenPriceQueryId","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"_time","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_value","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_queryData","type":"bytes"},{"indexed":true,"internalType":"address","name":"_reporter","type":"address"}],"name":"NewReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newStakeAmount","type":"uint256"}],"name":"NewStakeAmount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_staker","type":"address"},{"indexed":true,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"NewStaker","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_reporter","type":"address"},{"indexed":false,"internalType":"address","name":"_recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"_slashAmount","type":"uint256"}],"name":"ReporterSlashed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"StakeWithdrawRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_staker","type":"address"}],"name":"StakeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"ValueRemoved","type":"event"},{"inputs":[],"name":"accumulatedRewardPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addStakingRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"}],"name":"getCurrentValue","outputs":[{"internalType":"bytes","name":"_value","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getDataBefore","outputs":[{"internalType":"bool","name":"_ifRetrieve","type":"bool"},{"internalType":"bytes","name":"_value","type":"bytes"},{"internalType":"uint256","name":"_timestampRetrieved","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGovernanceAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getIndexForDataBefore","outputs":[{"internalType":"bool","name":"_found","type":"bool"},{"internalType":"uint256","name":"_index","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"}],"name":"getNewValueCountbyQueryId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakerAddress","type":"address"}],"name":"getPendingRewardByStaker","outputs":[{"internalType":"uint256","name":"_pendingReward","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRealStakingRewardsBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getReportDetails","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getReporterByTimestamp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_reporter","type":"address"}],"name":"getReporterLastTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReportingLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_reporter","type":"address"}],"name":"getReportsSubmittedByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakerAddress","type":"address"}],"name":"getStakerInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTimeOfLastNewValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getTimestampIndexByTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getTimestampbyQueryIdandIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalStakers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalTimeBasedRewardsBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_governanceAddress","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"isInDispute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"removeValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reportingLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"requestStakingWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"retrieveData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_reporter","type":"address"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"slashReporter","outputs":[{"internalType":"uint256","name":"_slashAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakeAmountDollarTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingRewardsBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingTokenPriceQueryId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"bytes","name":"_value","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes","name":"_queryData","type":"bytes"}],"name":"submitValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timeBasedReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeOfLastAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeOfLastNewValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewardDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateStakeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"verify","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
610140604052426006553480156200001657600080fd5b50604051620035803803806200358083398101604081905262000039916200020c565b6001600160a01b038616620000955760405162461bcd60e51b815260206004820152601660248201527f6d7573742073657420746f6b656e20616464726573730000000000000000000060448201526064015b60405180910390fd5b60008311620000e75760405162461bcd60e51b815260206004820152601c60248201527f6d75737420736574207374616b696e6720746f6b656e2070726963650000000060448201526064016200008c565b60008511620001395760405162461bcd60e51b815260206004820152601760248201527f6d75737420736574207265706f7274696e67206c6f636b00000000000000000060448201526064016200008c565b80620001945760405162461bcd60e51b8152602060048201526024808201527f6d75737420736574207374616b696e6720746f6b656e207072696365207175656044820152631c9e525960e21b60648201526084016200008c565b606086811b6001600160601b03191660805233901b60a05260e085905261010084905260c0829052600083620001d386670de0b6b3a76400006200028c565b620001df91906200026b565b905082811015620001f5576003839055620001fb565b60038190555b506101205250620002b89350505050565b60008060008060008060c0878903121562000225578182fd5b86516001600160a01b03811681146200023c578283fd5b6020880151604089015160608a015160808b015160a0909b0151939c929b509099909850965090945092505050565b6000826200028757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615620002b357634e487b7160e01b81526011600452602481fd5b500290565b60805160601c60a05160601c60c05160e05161010051610120516131f46200038c600039600081816108050152610db701526000818161079d0152610e7901526000818161044a015281816104dd015261154601526000818161058701528181610eb40152610edc0152600081816106d201526108d901526000818161087f015281816108ab015281816111220152818161179d015281816118640152818161190a01528181611c9b015281816120eb01528181612360015281816124a601528181612559015261289f01526131f46000f3fe608060405234801561001057600080fd5b50600436106103415760003560e01c806373252494116101bd578063bed9d861116100f9578063ce5e11bf116100a2578063d9c51cd41161007c578063d9c51cd41461082f578063e07c548614610842578063fc0c546a1461087a578063fc735e99146108a157610341565b8063ce5e11bf146107ed578063cecb064714610800578063d75174e11461082757610341565b8063c0f95d52116100d3578063c0f95d52146107bf578063c5958af9146107c7578063cb82cc8f146107da57610341565b8063bed9d8611461077d578063bf5745d614610785578063c0d416b81461079857610341565b80638929f4c61161016657806396426d971161014057806396426d97146106fd5780639d9b16ed1461070c578063a792765f1461073b578063adf1639d1461075d57610341565b80638929f4c6146106ba5780638da5cb5b146106cd57806394409a56146106f457610341565b80637b0a47ee116101975780637b0a47ee1461069f57806383bb3877146106a857806386989038146106b157610341565b806373252494146105c2578063733bdef0146105d357806377b03e0d1461067f57610341565b80633a0ce3421161028c5780635b5edcfc116102355780636b036f451161020f5780636b036f45146105825780636dd0a70f146105a95780636fd4f229146105b1578063722580b6146105ba57610341565b80635b5edcfc146105535780635eaa9ced1461056657806360c7dc471461057957610341565b80634dfc2a34116102665780634dfc2a341461050157806350005b83146105145780635aa6e6751461054057610341565b80633a0ce3421461049157806344e87f9114610499578063460c33a2146104db57610341565b80632e206cd7116102ee578063347f2336116102c8578063347f23361461046c57806336d42195146104755780633878293e1461047e57610341565b80632e206cd71461043457806331ed0db41461043d5780633321fc411461044557610341565b806319ab453c1161031f57806319ab453c1461038a578063294490851461039f5780632b6696a7146103c957610341565b806304d932e21461034657806310fe9ae81461036257806314c2a1bc14610382575b600080fd5b61034f60045481565b6040519081526020015b60405180910390f35b61036a6108a9565b6040516001600160a01b039091168152602001610359565b60085461034f565b61039d610398366004612e66565b6108ce565b005b6103b26103ad366004612f71565b610a3b565b604080519215158352602083019190915201610359565b6104156103d7366004612f71565b6000918252600b60209081526040808420928452600383018252808420546004909301909152909120546001600160a01b039091169160ff90911690565b604080516001600160a01b039093168352901515602083015201610359565b61034f60055481565b60095461034f565b61034f7f000000000000000000000000000000000000000000000000000000000000000081565b61034f600a5481565b61034f60015481565b61034f61048c366004612e66565b610d8d565b61039d610daf565b6104cb6104a7366004612f71565b6000918252600b602090815260408084209284526004909201905290205460ff1690565b6040519015158152602001610359565b7f000000000000000000000000000000000000000000000000000000000000000061034f565b61034f61050f366004612e87565b610f4b565b61034f610522366004612e66565b6001600160a01b03166000908152600c602052604090206004015490565b60005461036a906001600160a01b031681565b61039d610561366004612f71565b6111f6565b61039d610574366004612ef1565b6113ca565b61034f60035481565b61034f7f000000000000000000000000000000000000000000000000000000000000000081565b61034f6119f2565b61034f60065481565b60035461034f565b6000546001600160a01b031661036a565b6106396105e1366004612e66565b6001600160a01b03166000908152600c6020526040902080546001820154600283015460038401546004850154600586015460068701546007880154600890980154969895979496939592949193909260ff90911690565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152151561010082015261012001610359565b61034f61068d366004612ed9565b6000908152600b602052604090205490565b61034f60025481565b61034f60075481565b61034f60095481565b61039d6106c8366004612ed9565b611a40565b61036a7f000000000000000000000000000000000000000000000000000000000000000081565b61034f60085481565b61034f6706f05b59d3b2000081565b61034f61071a366004612f71565b6000918252600b602090815260408084209284526001909201905290205490565b61074e610749366004612f71565b611b2c565b6040516103599392919061302c565b61077061076b366004612ed9565b611b8f565b6040516103599190613090565b61039d611bb7565b61034f610793366004612e66565b611d80565b61034f7f000000000000000000000000000000000000000000000000000000000000000081565b60065461034f565b6107706107d5366004612f71565b611f7a565b61039d6107e8366004612ed9565b61202b565b61034f6107fb366004612f71565b612431565b61034f7f000000000000000000000000000000000000000000000000000000000000000081565b61034f612472565b61039d61083d366004612ed9565b612537565b61036a610850366004612f71565b6000918252600b60209081526040808420928452600390920190529020546001600160a01b031690565b61036a7f000000000000000000000000000000000000000000000000000000000000000081565b61270f61034f565b7f00000000000000000000000000000000000000000000000000000000000000005b90565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109595760405162461bcd60e51b815260206004820152602560248201527f6f6e6c79206f776e65722063616e2073657420676f7665726e616e6365206164604482015264647265737360d81b60648201526084015b60405180910390fd5b6000546001600160a01b0316156109b25760405162461bcd60e51b815260206004820152601e60248201527f676f7665726e616e6365206164647265737320616c72656164792073657400006044820152606401610950565b6001600160a01b038116610a195760405162461bcd60e51b815260206004820152602860248201527f676f7665726e616e636520616464726573732063616e2774206265207a65726f604482015267206164647265737360c01b6064820152608401610950565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152600b602052604081205481908015610d7d5760008080610a616001856130fa565b90506000610a6f8984612431565b9050878110610a8957600080965096505050505050610d86565b610a938983612431565b905087811015610b3d575b6000898152600b6020908152604080832084845260040190915290205460ff168015610aca5750600082115b15610aed5781610ad981613141565b925050610ae68983612431565b9050610a9e565b81158015610b1757506000898152600b6020908152604080832084845260040190915290205460ff165b15610b2d57600080965096505050505050610d86565b50600195509350610d8692505050565b826002610b4a82856130fa565b610b5491906130bb565b610b5f9060016130a3565b610b6991906130a3565b9350610b758985612431565b905087811015610c84576000610b908a6107fb8760016130a3565b9050888110610c715760008a8152600b6020908152604080832085845260040190915290205460ff16610bcf5760018597509750505050505050610d86565b60008a8152600b6020908152604080832085845260040190915290205460ff168015610bfb5750600085115b15610c1e5784610c0a81613141565b955050610c178a86612431565b9150610bcf565b84158015610c48575060008a8152600b6020908152604080832085845260040190915290205460ff165b15610c5f5760008097509750505050505050610d86565b60018597509750505050505050610d86565b610c7c8560016130a3565b935050610d78565b6000610c958a6107fb6001886130fa565b905088811015610d695760008a8152600b6020908152604080832084845260040190915290205460ff16610cde576001610ccf81876130fa565b97509750505050505050610d86565b84610ce881613141565b9550505b60008a8152600b6020908152604080832084845260040190915290205460ff168015610d185750600085115b15610d3b5784610d2781613141565b955050610d348a86612431565b9050610cec565b84158015610c48575060008a8152600b6020908152604080832084845260040190915290205460ff16610c48565b610d746001866130fa565b9250505b610b3d565b60008092509250505b9250929050565b6001600160a01b0381166000908152600c60205260409020600501545b919050565b600080610de27f000000000000000000000000000000000000000000000000000000000000000061074961a8c0426130fa565b50915091508115610f4757600081806020019051810190610e039190612f92565b9050662386f26fc100008110158015610e25575069d3c21bcecceda100000081105b610e715760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207374616b696e6720746f6b656e20707269636500000000006044820152606401610950565b600081610ea67f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a76400006130db565b610eb091906130bb565b90507f0000000000000000000000000000000000000000000000000000000000000000811015610f03577f0000000000000000000000000000000000000000000000000000000000000000600355610f09565b60038190555b7f1af37d6aaef3c5ef293c3c63d0ac302f60db7fde22eb9f5e96ebd56992832110600354604051610f3c91815260200190565b60405180910390a150505b5050565b600080546001600160a01b03163314610fb15760405162461bcd60e51b815260206004820152602260248201527f6f6e6c7920676f7665726e616e63652063616e20736c617368207265706f727460448201526132b960f11b6064820152608401610950565b6001600160a01b0383166000908152600c60205260408120600181015460028201549192909190610fe282846130a3565b116110255760405162461bcd60e51b81526020600482015260136024820152727a65726f207374616b65722062616c616e636560681b6044820152606401610950565b600354811061106e57600354935060035483600201600082825461104991906130fa565b9091555050600354600a80546000906110639084906130fa565b909155506110fc9050565b60035461107b83836130a3565b106110c55760035493506110a28661109383876130fa565b61109d90856130fa565b612658565b80600a60008282546110b491906130fa565b9091555050600060028401556110fc565b6110cf81836130a3565b935080600a60008282546110e391906130fa565b909155506110f49050866000612658565b600060028401555b60405163a9059cbb60e01b81526001600160a01b038681166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561116657600080fd5b505af115801561117a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119e9190612eb9565b6111a757600080fd5b604080516001600160a01b038781168252602082018790528816917f4317784407a22e643706ef000f5c0eea399dea3632613786167ab71c9446e3ac910160405180910390a250505092915050565b6000546001600160a01b0316331461125a5760405162461bcd60e51b815260206004820152602160248201527f63616c6c6572206d75737420626520676f7665726e616e6365206164647265736044820152607360f81b6064820152608401610950565b6000828152600b60209081526040808320848452600481019092529091205460ff16156112c95760405162461bcd60e51b815260206004820152601660248201527f76616c756520616c7265616479206469737075746564000000000000000000006044820152606401610950565b600082815260018201602052604090205481548290829081106112fc57634e487b7160e01b600052603260045260246000fd5b906000526020600020015483146113495760405162461bcd60e51b81526020600482015260116024820152700696e76616c69642074696d657374616d7607c1b6044820152606401610950565b60408051602080820180845260008084528781526002870190925292902090516113739290612d02565b50600083815260048301602052604090819020805460ff19166001179055517fb326db0e54476c677e2b35b75856ac6f4d8bbfb0a6de6690582ebe4dabce0de790610f3c9086908690918252602082015260400190565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47085856040516113fb929190613000565b604051809103902014156114515760405162461bcd60e51b815260206004820152601760248201527f76616c7565206d757374206265207375626d69747465640000000000000000006044820152606401610950565b6000868152600b60205260409020805484148061146c575083155b6114b85760405162461bcd60e51b815260206004820181905260248201527f6e6f6e6365206d757374206d617463682074696d657374616d7020696e6465786044820152606401610950565b336000908152600c602052604090206003546001820154101561152f5760405162461bcd60e51b815260206004820152602960248201527f62616c616e6365206d7573742062652067726561746572207468616e207374616044820152681ad948185b5bdd5b9d60ba1b6064820152608401610950565b600354816001015461154191906130bb565b61156d7f00000000000000000000000000000000000000000000000000000000000000006103e86130db565b61157791906130bb565b600482015461158690426130fa565b611592906103e86130db565b116115f15760405162461bcd60e51b815260206004820152602960248201527f7374696c6c20696e207265706f727465722074696d65206c6f636b2c20706c6560448201526861736520776169742160b81b6064820152608401610950565b8383604051611601929190613000565b604051809103902088146116635760405162461bcd60e51b815260206004820152602360248201527f7175657279206964206d7573742062652068617368206f66207175657279206460448201526261746160e81b6064820152608401610950565b426004820181905560009081526003830160205260409020546001600160a01b0316156116d25760405162461bcd60e51b815260206004820152601e60248201527f74696d657374616d7020616c7265616479207265706f7274656420666f7200006044820152606401610950565b81544260008181526001808601602090815260408084208690559185018755868352808320909401839055918152600285019092529020611714908888612d86565b50426000818152600384016020526040812080546001600160a01b03191633179055600654909161012c916706f05b59d3b200009161175391906130fa565b61175d91906130db565b61176791906130bb565b90506000600a5460045460085461177e91906130a3565b61178891906130a3565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b1580156117e757600080fd5b505afa1580156117fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181f9190612f92565b61182991906130fa565b905060008111801561183b5750600082115b1561199057818110156118ee5760405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156118b057600080fd5b505af11580156118c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e89190612eb9565b50611990565b60405163a9059cbb60e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561195657600080fd5b505af115801561196a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198e9190612eb9565b505b42600681905560058401805460010190556040513391908c907f48e9e2c732ba278de6ac88a3a57a5c5ba13d3d8370e709b3b98333a57876ca95906119de908e908e908e908e908e90613057565b60405180910390a450505050505050505050565b600080600754670de0b6b3a7640000600854611a0c612aab565b611a1691906130db565b611a2091906130bb565b611a2a91906130fa565b905080600454611a3a91906130fa565b91505090565b336000908152600c602052604090206001810154821115611aa35760405162461bcd60e51b815260206004820152601b60248201527f696e73756666696369656e74207374616b65642062616c616e636500000000006044820152606401610950565b611ab73383836001015461109d91906130fa565b428155600281018054839190600090611ad19084906130a3565b9250508190555081600a6000828254611aea91906130a3565b909155505060408051338152602081018490527f3d8d9df4bd0172df32e557fa48e96435cd7f2cac06aaffacfaee608e6f7898ef910160405180910390a15050565b600060606000806000611b3f8787610a3b565b9150915081611b695760006040518060200160405280600081525060009450945094505050611b88565b611b738782612431565b9250611b7f8784611f7a565b93506001945050505b9250925092565b60606000611ba2836107494260016130a3565b509250905080611bb157600080fd5b50919050565b336000908152600c60205260409020805462093a8090611bd790426130fa565b1015611c1a5760405162461bcd60e51b8152602060048201526012602482015271372064617973206469646e2774207061737360701b6044820152606401610950565b6000816002015411611c795760405162461bcd60e51b815260206004820152602260248201527f7265706f72746572206e6f74206c6f636b656420666f72207769746864726177604482015261185b60f21b6064820152608401610950565b600281015460405163a9059cbb60e01b815233600482015260248101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b158015611ce757600080fd5b505af1158015611cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1f9190612eb9565b611d2857600080fd5b8060020154600a6000828254611d3e91906130fa565b9091555050600060028201556040513381527f4a7934670bd8304e7da22378be1368f7c4fef17c5aee81804beda8638fe428ec9060200160405180910390a150565b6001600160a01b0381166000908152600c602052604081206003810154670de0b6b3a7640000611dae612aab565b8360010154611dbd91906130db565b611dc791906130bb565b611dd191906130fa565b6000805460408051600481526024810182526020810180516001600160e01b03166339ecce1f60e21b1790529051939550919283926001600160a01b0390921691611e1b91613010565b6000604051808303816000865af19150503d8060008114611e58576040519150601f19603f3d011682016040523d82523d6000602084013e611e5d565b606091505b509150915060008215611e9057836006015482806020019051810190611e839190612f92565b611e8d91906130fa565b90505b8015611f71576000546040516001600160a01b0388811660248301529091169060440160408051601f198184030181529181526020820180516001600160e01b03166317b8fb3b60e31b17905251611ee89190613010565b6000604051808303816000865af19150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b5090935091508215611f715780846007015483806020019051810190611f509190612f92565b611f5a91906130fa565b611f6490876130db565b611f6e91906130bb565b94505b50505050919050565b6000828152600b602090815260408083208484526002019091529020805460609190611fa590613158565b80601f0160208091040260200160405190810160405280929190818152602001828054611fd190613158565b801561201e5780601f10611ff35761010080835404028352916020019161201e565b820191906000526020600020905b81548152906001019060200180831161200157829003601f168201915b5050505050905092915050565b6000546001600160a01b03166120835760405162461bcd60e51b815260206004820152601a60248201527f676f7665726e616e63652061646472657373206e6f74207365740000000000006044820152606401610950565b336000908152600c602052604090206001810154600282015480156121d4578381106120e157838360020160008282546120bd91906130fa565b9250508190555083600a60008282546120d691906130fa565b909155506121cf9050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166323b872dd333061211c85896130fa565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561216b57600080fd5b505af115801561217f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a39190612eb9565b6121ac57600080fd5b8260020154600a60008282546121c291906130fa565b9091555050600060028401555b6123ed565b8161233e576000805460408051600481526024810182526020810180516001600160e01b03166339ecce1f60e21b179052905183926001600160a01b03169161221c91613010565b6000604051808303816000865af19150503d8060008114612259576040519150601f19603f3d011682016040523d82523d6000602084013e61225e565b606091505b50915091508115612283578080602001905181019061227d9190612f92565b60068601555b6000546040513360248201526001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b03166317b8fb3b60e31b179052516122d39190613010565b6000604051808303816000865af19150503d8060008114612310576040519150601f19603f3d011682016040523d82523d6000602084013e612315565b606091505b509092509050811561233b57808060200190518101906123359190612f92565b60078601555b50505b6040516323b872dd60e01b8152336004820152306024820152604481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156123ac57600080fd5b505af11580156123c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e49190612eb9565b6123ed57600080fd5b6123fb3361109d86856130a3565b428355604051849033907fa96c2cce65119a2170d1711a6e82f18f2006448828483ba7545e59547654364790600090a350505050565b6000828152600b6020526040812080548390811061245f57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b6000600a5460045460085461248791906130a3565b61249191906130a3565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b1580156124f057600080fd5b505afa158015612504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125289190612f92565b61253291906130fa565b905090565b6040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156125a557600080fd5b505af11580156125b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125dd9190612eb9565b6125e657600080fd5b6125ee612bbf565b806004600082825461260091906130a3565b9250508190555062278d00600754670de0b6b3a764000060085460015461262791906130db565b61263191906130bb565b61263b91906130fa565b60045461264891906130fa565b61265291906130bb565b60025550565b612660612bbf565b6001600160a01b0382166000908152600c602052604090206001810154156129685760008160030154670de0b6b3a764000060015484600101546126a491906130db565b6126ae91906130bb565b6126b891906130fa565b6000805460408051600481526024810182526020810180516001600160e01b03166339ecce1f60e21b17905290519394509192839283926001600160a01b0316916127039190613010565b6000604051808303816000865af19150503d8060008114612740576040519150601f19603f3d011682016040523d82523d6000602084013e612745565b606091505b50915091508115612776578460060154818060200190518101906127699190612f92565b61277391906130fa565b92505b821561286c576000546040516001600160a01b0389811660248301529091169060440160408051601f198184030181529181526020820180516001600160e01b03166317b8fb3b60e31b179052516127ce9190613010565b6000604051808303816000865af19150503d806000811461280b576040519150601f19603f3d011682016040523d82523d6000602084013e612810565b606091505b509092509050811561286c576000818060200190518101906128329190612f92565b905060008487600701548361284791906130fa565b61285190886130db565b61285b91906130bb565b905085811015612869578095505b50505b836004600082825461287e91906130fa565b909155505060405163a9059cbb60e01b8152336004820152602481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156128eb57600080fd5b505af11580156128ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129239190612eb9565b61292c57600080fd5b84600301546007600082825461294291906130fa565b909155505060018501546008805460009061295e9084906130fa565b9091555050505050505b6001810182905560035482106129ae57600881015460ff1661299a57600980549060006129948361318d565b91905055505b60088101805460ff191660011790556129f1565b600881015460ff16151560011480156129c957506000600954115b156129e457600980549060006129de83613141565b91905055505b60088101805460ff191690555b670de0b6b3a76400006001548260010154612a0c91906130db565b612a1691906130bb565b6003820181905560078054600090612a2f9084906130a3565b9091555050600181015460088054600090612a4b9084906130a3565b9091555050600254612aa65762278d00600754670de0b6b3a7640000600854600154612a7791906130db565b612a8191906130bb565b612a8b91906130fa565b600454612a9891906130fa565b612aa291906130bb565b6002555b505050565b600060085460001415612ac157506001546108cb565b600060085460025460055442612ad791906130fa565b612ae191906130db565b612af390670de0b6b3a76400006130db565b612afd91906130bb565b600154612b0a91906130a3565b90506000600754670de0b6b3a764000060085484612b2891906130db565b612b3291906130bb565b612b3c91906130fa565b90506004548110612bb9576000600754670de0b6b3a7640000600854600154612b6591906130db565b612b6f91906130bb565b612b7991906130fa565b600454612b8691906130fa565b600854909150612b9e82670de0b6b3a76400006130db565b612ba891906130bb565b600154612bb591906130a3565b9250505b50905090565b426005541415612bce57612d00565b6008541580612bdd5750600254155b15612beb5742600555612d00565b600060085460025460055442612c0191906130fa565b612c0b91906130db565b612c1d90670de0b6b3a76400006130db565b612c2791906130bb565b600154612c3491906130a3565b90506000600754670de0b6b3a764000060085484612c5291906130db565b612c5c91906130bb565b612c6691906130fa565b90506004548110612cf3576000600754670de0b6b3a7640000600854600154612c8f91906130db565b612c9991906130bb565b612ca391906130fa565b600454612cb091906130fa565b600854909150612cc882670de0b6b3a76400006130db565b612cd291906130bb565b60016000828254612ce391906130a3565b9091555050600060025550612cf9565b60018290555b5050426005555b565b828054612d0e90613158565b90600052602060002090601f016020900481019282612d305760008555612d76565b82601f10612d4957805160ff1916838001178555612d76565b82800160010185558215612d76579182015b82811115612d76578251825591602001919060010190612d5b565b50612d82929150612dfa565b5090565b828054612d9290613158565b90600052602060002090601f016020900481019282612db45760008555612d76565b82601f10612dcd5782800160ff19823516178555612d76565b82800160010185558215612d76579182015b82811115612d76578235825591602001919060010190612ddf565b5b80821115612d825760008155600101612dfb565b80356001600160a01b0381168114610daa57600080fd5b60008083601f840112612e37578182fd5b50813567ffffffffffffffff811115612e4e578182fd5b602083019150836020828501011115610d8657600080fd5b600060208284031215612e77578081fd5b612e8082612e0f565b9392505050565b60008060408385031215612e99578081fd5b612ea283612e0f565b9150612eb060208401612e0f565b90509250929050565b600060208284031215612eca578081fd5b81518015158114612e80578182fd5b600060208284031215612eea578081fd5b5035919050565b60008060008060008060808789031215612f09578182fd5b86359550602087013567ffffffffffffffff80821115612f27578384fd5b612f338a838b01612e26565b9097509550604089013594506060890135915080821115612f52578384fd5b50612f5f89828a01612e26565b979a9699509497509295939492505050565b60008060408385031215612f83578182fd5b50508035926020909101359150565b600060208284031215612fa3578081fd5b5051919050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612fec816020860160208601613111565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b60008251613022818460208701613111565b9190910192915050565b60008415158252606060208301526130476060830185612fd4565b9050826040830152949350505050565b60006060825261306b606083018789612faa565b8560208401528281036040840152613084818587612faa565b98975050505050505050565b600060208252612e806020830184612fd4565b600082198211156130b6576130b66131a8565b500190565b6000826130d657634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156130f5576130f56131a8565b500290565b60008282101561310c5761310c6131a8565b500390565b60005b8381101561312c578181015183820152602001613114565b8381111561313b576000848401525b50505050565b600081613150576131506131a8565b506000190190565b600181811c9082168061316c57607f821691505b60208210811415611bb157634e487b7160e01b600052602260045260246000fd5b60006000198214156131a1576131a16131a8565b5060010190565b634e487b7160e01b600052601160045260246000fdfea26469706673582212204d04a6a545bc4bdeecb3a12a978d0a416164adc4c7de1063c71ee786fd702f4a64736f6c63430008030033000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d81000000000000000000000000000000000000000000000000000000000000a8c000000000000000000000000000000000000000000000000821ab0d44149800000000000000000000000000000000000000000000000000052663ccab1e1c00000000000000000000000000000000000000000000000000008ac7230489e800005c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103415760003560e01c806373252494116101bd578063bed9d861116100f9578063ce5e11bf116100a2578063d9c51cd41161007c578063d9c51cd41461082f578063e07c548614610842578063fc0c546a1461087a578063fc735e99146108a157610341565b8063ce5e11bf146107ed578063cecb064714610800578063d75174e11461082757610341565b8063c0f95d52116100d3578063c0f95d52146107bf578063c5958af9146107c7578063cb82cc8f146107da57610341565b8063bed9d8611461077d578063bf5745d614610785578063c0d416b81461079857610341565b80638929f4c61161016657806396426d971161014057806396426d97146106fd5780639d9b16ed1461070c578063a792765f1461073b578063adf1639d1461075d57610341565b80638929f4c6146106ba5780638da5cb5b146106cd57806394409a56146106f457610341565b80637b0a47ee116101975780637b0a47ee1461069f57806383bb3877146106a857806386989038146106b157610341565b806373252494146105c2578063733bdef0146105d357806377b03e0d1461067f57610341565b80633a0ce3421161028c5780635b5edcfc116102355780636b036f451161020f5780636b036f45146105825780636dd0a70f146105a95780636fd4f229146105b1578063722580b6146105ba57610341565b80635b5edcfc146105535780635eaa9ced1461056657806360c7dc471461057957610341565b80634dfc2a34116102665780634dfc2a341461050157806350005b83146105145780635aa6e6751461054057610341565b80633a0ce3421461049157806344e87f9114610499578063460c33a2146104db57610341565b80632e206cd7116102ee578063347f2336116102c8578063347f23361461046c57806336d42195146104755780633878293e1461047e57610341565b80632e206cd71461043457806331ed0db41461043d5780633321fc411461044557610341565b806319ab453c1161031f57806319ab453c1461038a578063294490851461039f5780632b6696a7146103c957610341565b806304d932e21461034657806310fe9ae81461036257806314c2a1bc14610382575b600080fd5b61034f60045481565b6040519081526020015b60405180910390f35b61036a6108a9565b6040516001600160a01b039091168152602001610359565b60085461034f565b61039d610398366004612e66565b6108ce565b005b6103b26103ad366004612f71565b610a3b565b604080519215158352602083019190915201610359565b6104156103d7366004612f71565b6000918252600b60209081526040808420928452600383018252808420546004909301909152909120546001600160a01b039091169160ff90911690565b604080516001600160a01b039093168352901515602083015201610359565b61034f60055481565b60095461034f565b61034f7f000000000000000000000000000000000000000000000000000000000000a8c081565b61034f600a5481565b61034f60015481565b61034f61048c366004612e66565b610d8d565b61039d610daf565b6104cb6104a7366004612f71565b6000918252600b602090815260408084209284526004909201905290205460ff1690565b6040519015158152602001610359565b7f000000000000000000000000000000000000000000000000000000000000a8c061034f565b61034f61050f366004612e87565b610f4b565b61034f610522366004612e66565b6001600160a01b03166000908152600c602052604090206004015490565b60005461036a906001600160a01b031681565b61039d610561366004612f71565b6111f6565b61039d610574366004612ef1565b6113ca565b61034f60035481565b61034f7f0000000000000000000000000000000000000000000000008ac7230489e8000081565b61034f6119f2565b61034f60065481565b60035461034f565b6000546001600160a01b031661036a565b6106396105e1366004612e66565b6001600160a01b03166000908152600c6020526040902080546001820154600283015460038401546004850154600586015460068701546007880154600890980154969895979496939592949193909260ff90911690565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152151561010082015261012001610359565b61034f61068d366004612ed9565b6000908152600b602052604090205490565b61034f60025481565b61034f60075481565b61034f60095481565b61039d6106c8366004612ed9565b611a40565b61036a7f0000000000000000000000005c84d7220d87e3de7fdbf9037be8f48442f8e40a81565b61034f60085481565b61034f6706f05b59d3b2000081565b61034f61071a366004612f71565b6000918252600b602090815260408084209284526001909201905290205490565b61074e610749366004612f71565b611b2c565b6040516103599392919061302c565b61077061076b366004612ed9565b611b8f565b6040516103599190613090565b61039d611bb7565b61034f610793366004612e66565b611d80565b61034f7f00000000000000000000000000000000000000000000000821ab0d441498000081565b60065461034f565b6107706107d5366004612f71565b611f7a565b61039d6107e8366004612ed9565b61202b565b61034f6107fb366004612f71565b612431565b61034f7f5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded081565b61034f612472565b61039d61083d366004612ed9565b612537565b61036a610850366004612f71565b6000918252600b60209081526040808420928452600390920190529020546001600160a01b031690565b61036a7f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d8181565b61270f61034f565b7f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d815b90565b336001600160a01b037f0000000000000000000000005c84d7220d87e3de7fdbf9037be8f48442f8e40a16146109595760405162461bcd60e51b815260206004820152602560248201527f6f6e6c79206f776e65722063616e2073657420676f7665726e616e6365206164604482015264647265737360d81b60648201526084015b60405180910390fd5b6000546001600160a01b0316156109b25760405162461bcd60e51b815260206004820152601e60248201527f676f7665726e616e6365206164647265737320616c72656164792073657400006044820152606401610950565b6001600160a01b038116610a195760405162461bcd60e51b815260206004820152602860248201527f676f7665726e616e636520616464726573732063616e2774206265207a65726f604482015267206164647265737360c01b6064820152608401610950565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152600b602052604081205481908015610d7d5760008080610a616001856130fa565b90506000610a6f8984612431565b9050878110610a8957600080965096505050505050610d86565b610a938983612431565b905087811015610b3d575b6000898152600b6020908152604080832084845260040190915290205460ff168015610aca5750600082115b15610aed5781610ad981613141565b925050610ae68983612431565b9050610a9e565b81158015610b1757506000898152600b6020908152604080832084845260040190915290205460ff165b15610b2d57600080965096505050505050610d86565b50600195509350610d8692505050565b826002610b4a82856130fa565b610b5491906130bb565b610b5f9060016130a3565b610b6991906130a3565b9350610b758985612431565b905087811015610c84576000610b908a6107fb8760016130a3565b9050888110610c715760008a8152600b6020908152604080832085845260040190915290205460ff16610bcf5760018597509750505050505050610d86565b60008a8152600b6020908152604080832085845260040190915290205460ff168015610bfb5750600085115b15610c1e5784610c0a81613141565b955050610c178a86612431565b9150610bcf565b84158015610c48575060008a8152600b6020908152604080832085845260040190915290205460ff165b15610c5f5760008097509750505050505050610d86565b60018597509750505050505050610d86565b610c7c8560016130a3565b935050610d78565b6000610c958a6107fb6001886130fa565b905088811015610d695760008a8152600b6020908152604080832084845260040190915290205460ff16610cde576001610ccf81876130fa565b97509750505050505050610d86565b84610ce881613141565b9550505b60008a8152600b6020908152604080832084845260040190915290205460ff168015610d185750600085115b15610d3b5784610d2781613141565b955050610d348a86612431565b9050610cec565b84158015610c48575060008a8152600b6020908152604080832084845260040190915290205460ff16610c48565b610d746001866130fa565b9250505b610b3d565b60008092509250505b9250929050565b6001600160a01b0381166000908152600c60205260409020600501545b919050565b600080610de27f5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded061074961a8c0426130fa565b50915091508115610f4757600081806020019051810190610e039190612f92565b9050662386f26fc100008110158015610e25575069d3c21bcecceda100000081105b610e715760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207374616b696e6720746f6b656e20707269636500000000006044820152606401610950565b600081610ea67f00000000000000000000000000000000000000000000000821ab0d4414980000670de0b6b3a76400006130db565b610eb091906130bb565b90507f0000000000000000000000000000000000000000000000008ac7230489e80000811015610f03577f0000000000000000000000000000000000000000000000008ac7230489e80000600355610f09565b60038190555b7f1af37d6aaef3c5ef293c3c63d0ac302f60db7fde22eb9f5e96ebd56992832110600354604051610f3c91815260200190565b60405180910390a150505b5050565b600080546001600160a01b03163314610fb15760405162461bcd60e51b815260206004820152602260248201527f6f6e6c7920676f7665726e616e63652063616e20736c617368207265706f727460448201526132b960f11b6064820152608401610950565b6001600160a01b0383166000908152600c60205260408120600181015460028201549192909190610fe282846130a3565b116110255760405162461bcd60e51b81526020600482015260136024820152727a65726f207374616b65722062616c616e636560681b6044820152606401610950565b600354811061106e57600354935060035483600201600082825461104991906130fa565b9091555050600354600a80546000906110639084906130fa565b909155506110fc9050565b60035461107b83836130a3565b106110c55760035493506110a28661109383876130fa565b61109d90856130fa565b612658565b80600a60008282546110b491906130fa565b9091555050600060028401556110fc565b6110cf81836130a3565b935080600a60008282546110e391906130fa565b909155506110f49050866000612658565b600060028401555b60405163a9059cbb60e01b81526001600160a01b038681166004830152602482018690527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d81169063a9059cbb90604401602060405180830381600087803b15801561116657600080fd5b505af115801561117a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119e9190612eb9565b6111a757600080fd5b604080516001600160a01b038781168252602082018790528816917f4317784407a22e643706ef000f5c0eea399dea3632613786167ab71c9446e3ac910160405180910390a250505092915050565b6000546001600160a01b0316331461125a5760405162461bcd60e51b815260206004820152602160248201527f63616c6c6572206d75737420626520676f7665726e616e6365206164647265736044820152607360f81b6064820152608401610950565b6000828152600b60209081526040808320848452600481019092529091205460ff16156112c95760405162461bcd60e51b815260206004820152601660248201527f76616c756520616c7265616479206469737075746564000000000000000000006044820152606401610950565b600082815260018201602052604090205481548290829081106112fc57634e487b7160e01b600052603260045260246000fd5b906000526020600020015483146113495760405162461bcd60e51b81526020600482015260116024820152700696e76616c69642074696d657374616d7607c1b6044820152606401610950565b60408051602080820180845260008084528781526002870190925292902090516113739290612d02565b50600083815260048301602052604090819020805460ff19166001179055517fb326db0e54476c677e2b35b75856ac6f4d8bbfb0a6de6690582ebe4dabce0de790610f3c9086908690918252602082015260400190565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47085856040516113fb929190613000565b604051809103902014156114515760405162461bcd60e51b815260206004820152601760248201527f76616c7565206d757374206265207375626d69747465640000000000000000006044820152606401610950565b6000868152600b60205260409020805484148061146c575083155b6114b85760405162461bcd60e51b815260206004820181905260248201527f6e6f6e6365206d757374206d617463682074696d657374616d7020696e6465786044820152606401610950565b336000908152600c602052604090206003546001820154101561152f5760405162461bcd60e51b815260206004820152602960248201527f62616c616e6365206d7573742062652067726561746572207468616e207374616044820152681ad948185b5bdd5b9d60ba1b6064820152608401610950565b600354816001015461154191906130bb565b61156d7f000000000000000000000000000000000000000000000000000000000000a8c06103e86130db565b61157791906130bb565b600482015461158690426130fa565b611592906103e86130db565b116115f15760405162461bcd60e51b815260206004820152602960248201527f7374696c6c20696e207265706f727465722074696d65206c6f636b2c20706c6560448201526861736520776169742160b81b6064820152608401610950565b8383604051611601929190613000565b604051809103902088146116635760405162461bcd60e51b815260206004820152602360248201527f7175657279206964206d7573742062652068617368206f66207175657279206460448201526261746160e81b6064820152608401610950565b426004820181905560009081526003830160205260409020546001600160a01b0316156116d25760405162461bcd60e51b815260206004820152601e60248201527f74696d657374616d7020616c7265616479207265706f7274656420666f7200006044820152606401610950565b81544260008181526001808601602090815260408084208690559185018755868352808320909401839055918152600285019092529020611714908888612d86565b50426000818152600384016020526040812080546001600160a01b03191633179055600654909161012c916706f05b59d3b200009161175391906130fa565b61175d91906130db565b61176791906130bb565b90506000600a5460045460085461177e91906130a3565b61178891906130a3565b6040516370a0823160e01b81523060048201527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b0316906370a082319060240160206040518083038186803b1580156117e757600080fd5b505afa1580156117fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181f9190612f92565b61182991906130fa565b905060008111801561183b5750600082115b1561199057818110156118ee5760405163a9059cbb60e01b8152336004820152602481018290527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156118b057600080fd5b505af11580156118c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e89190612eb9565b50611990565b60405163a9059cbb60e01b8152336004820152602481018390527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561195657600080fd5b505af115801561196a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198e9190612eb9565b505b42600681905560058401805460010190556040513391908c907f48e9e2c732ba278de6ac88a3a57a5c5ba13d3d8370e709b3b98333a57876ca95906119de908e908e908e908e908e90613057565b60405180910390a450505050505050505050565b600080600754670de0b6b3a7640000600854611a0c612aab565b611a1691906130db565b611a2091906130bb565b611a2a91906130fa565b905080600454611a3a91906130fa565b91505090565b336000908152600c602052604090206001810154821115611aa35760405162461bcd60e51b815260206004820152601b60248201527f696e73756666696369656e74207374616b65642062616c616e636500000000006044820152606401610950565b611ab73383836001015461109d91906130fa565b428155600281018054839190600090611ad19084906130a3565b9250508190555081600a6000828254611aea91906130a3565b909155505060408051338152602081018490527f3d8d9df4bd0172df32e557fa48e96435cd7f2cac06aaffacfaee608e6f7898ef910160405180910390a15050565b600060606000806000611b3f8787610a3b565b9150915081611b695760006040518060200160405280600081525060009450945094505050611b88565b611b738782612431565b9250611b7f8784611f7a565b93506001945050505b9250925092565b60606000611ba2836107494260016130a3565b509250905080611bb157600080fd5b50919050565b336000908152600c60205260409020805462093a8090611bd790426130fa565b1015611c1a5760405162461bcd60e51b8152602060048201526012602482015271372064617973206469646e2774207061737360701b6044820152606401610950565b6000816002015411611c795760405162461bcd60e51b815260206004820152602260248201527f7265706f72746572206e6f74206c6f636b656420666f72207769746864726177604482015261185b60f21b6064820152608401610950565b600281015460405163a9059cbb60e01b815233600482015260248101919091527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b03169063a9059cbb90604401602060405180830381600087803b158015611ce757600080fd5b505af1158015611cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1f9190612eb9565b611d2857600080fd5b8060020154600a6000828254611d3e91906130fa565b9091555050600060028201556040513381527f4a7934670bd8304e7da22378be1368f7c4fef17c5aee81804beda8638fe428ec9060200160405180910390a150565b6001600160a01b0381166000908152600c602052604081206003810154670de0b6b3a7640000611dae612aab565b8360010154611dbd91906130db565b611dc791906130bb565b611dd191906130fa565b6000805460408051600481526024810182526020810180516001600160e01b03166339ecce1f60e21b1790529051939550919283926001600160a01b0390921691611e1b91613010565b6000604051808303816000865af19150503d8060008114611e58576040519150601f19603f3d011682016040523d82523d6000602084013e611e5d565b606091505b509150915060008215611e9057836006015482806020019051810190611e839190612f92565b611e8d91906130fa565b90505b8015611f71576000546040516001600160a01b0388811660248301529091169060440160408051601f198184030181529181526020820180516001600160e01b03166317b8fb3b60e31b17905251611ee89190613010565b6000604051808303816000865af19150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b5090935091508215611f715780846007015483806020019051810190611f509190612f92565b611f5a91906130fa565b611f6490876130db565b611f6e91906130bb565b94505b50505050919050565b6000828152600b602090815260408083208484526002019091529020805460609190611fa590613158565b80601f0160208091040260200160405190810160405280929190818152602001828054611fd190613158565b801561201e5780601f10611ff35761010080835404028352916020019161201e565b820191906000526020600020905b81548152906001019060200180831161200157829003601f168201915b5050505050905092915050565b6000546001600160a01b03166120835760405162461bcd60e51b815260206004820152601a60248201527f676f7665726e616e63652061646472657373206e6f74207365740000000000006044820152606401610950565b336000908152600c602052604090206001810154600282015480156121d4578381106120e157838360020160008282546120bd91906130fa565b9250508190555083600a60008282546120d691906130fa565b909155506121cf9050565b6001600160a01b037f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d81166323b872dd333061211c85896130fa565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561216b57600080fd5b505af115801561217f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a39190612eb9565b6121ac57600080fd5b8260020154600a60008282546121c291906130fa565b9091555050600060028401555b6123ed565b8161233e576000805460408051600481526024810182526020810180516001600160e01b03166339ecce1f60e21b179052905183926001600160a01b03169161221c91613010565b6000604051808303816000865af19150503d8060008114612259576040519150601f19603f3d011682016040523d82523d6000602084013e61225e565b606091505b50915091508115612283578080602001905181019061227d9190612f92565b60068601555b6000546040513360248201526001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b03166317b8fb3b60e31b179052516122d39190613010565b6000604051808303816000865af19150503d8060008114612310576040519150601f19603f3d011682016040523d82523d6000602084013e612315565b606091505b509092509050811561233b57808060200190518101906123359190612f92565b60078601555b50505b6040516323b872dd60e01b8152336004820152306024820152604481018590527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156123ac57600080fd5b505af11580156123c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e49190612eb9565b6123ed57600080fd5b6123fb3361109d86856130a3565b428355604051849033907fa96c2cce65119a2170d1711a6e82f18f2006448828483ba7545e59547654364790600090a350505050565b6000828152600b6020526040812080548390811061245f57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b6000600a5460045460085461248791906130a3565b61249191906130a3565b6040516370a0823160e01b81523060048201527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b0316906370a082319060240160206040518083038186803b1580156124f057600080fd5b505afa158015612504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125289190612f92565b61253291906130fa565b905090565b6040516323b872dd60e01b8152336004820152306024820152604481018290527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156125a557600080fd5b505af11580156125b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125dd9190612eb9565b6125e657600080fd5b6125ee612bbf565b806004600082825461260091906130a3565b9250508190555062278d00600754670de0b6b3a764000060085460015461262791906130db565b61263191906130bb565b61263b91906130fa565b60045461264891906130fa565b61265291906130bb565b60025550565b612660612bbf565b6001600160a01b0382166000908152600c602052604090206001810154156129685760008160030154670de0b6b3a764000060015484600101546126a491906130db565b6126ae91906130bb565b6126b891906130fa565b6000805460408051600481526024810182526020810180516001600160e01b03166339ecce1f60e21b17905290519394509192839283926001600160a01b0316916127039190613010565b6000604051808303816000865af19150503d8060008114612740576040519150601f19603f3d011682016040523d82523d6000602084013e612745565b606091505b50915091508115612776578460060154818060200190518101906127699190612f92565b61277391906130fa565b92505b821561286c576000546040516001600160a01b0389811660248301529091169060440160408051601f198184030181529181526020820180516001600160e01b03166317b8fb3b60e31b179052516127ce9190613010565b6000604051808303816000865af19150503d806000811461280b576040519150601f19603f3d011682016040523d82523d6000602084013e612810565b606091505b509092509050811561286c576000818060200190518101906128329190612f92565b905060008487600701548361284791906130fa565b61285190886130db565b61285b91906130bb565b905085811015612869578095505b50505b836004600082825461287e91906130fa565b909155505060405163a9059cbb60e01b8152336004820152602481018590527f000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d816001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156128eb57600080fd5b505af11580156128ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129239190612eb9565b61292c57600080fd5b84600301546007600082825461294291906130fa565b909155505060018501546008805460009061295e9084906130fa565b9091555050505050505b6001810182905560035482106129ae57600881015460ff1661299a57600980549060006129948361318d565b91905055505b60088101805460ff191660011790556129f1565b600881015460ff16151560011480156129c957506000600954115b156129e457600980549060006129de83613141565b91905055505b60088101805460ff191690555b670de0b6b3a76400006001548260010154612a0c91906130db565b612a1691906130bb565b6003820181905560078054600090612a2f9084906130a3565b9091555050600181015460088054600090612a4b9084906130a3565b9091555050600254612aa65762278d00600754670de0b6b3a7640000600854600154612a7791906130db565b612a8191906130bb565b612a8b91906130fa565b600454612a9891906130fa565b612aa291906130bb565b6002555b505050565b600060085460001415612ac157506001546108cb565b600060085460025460055442612ad791906130fa565b612ae191906130db565b612af390670de0b6b3a76400006130db565b612afd91906130bb565b600154612b0a91906130a3565b90506000600754670de0b6b3a764000060085484612b2891906130db565b612b3291906130bb565b612b3c91906130fa565b90506004548110612bb9576000600754670de0b6b3a7640000600854600154612b6591906130db565b612b6f91906130bb565b612b7991906130fa565b600454612b8691906130fa565b600854909150612b9e82670de0b6b3a76400006130db565b612ba891906130bb565b600154612bb591906130a3565b9250505b50905090565b426005541415612bce57612d00565b6008541580612bdd5750600254155b15612beb5742600555612d00565b600060085460025460055442612c0191906130fa565b612c0b91906130db565b612c1d90670de0b6b3a76400006130db565b612c2791906130bb565b600154612c3491906130a3565b90506000600754670de0b6b3a764000060085484612c5291906130db565b612c5c91906130bb565b612c6691906130fa565b90506004548110612cf3576000600754670de0b6b3a7640000600854600154612c8f91906130db565b612c9991906130bb565b612ca391906130fa565b600454612cb091906130fa565b600854909150612cc882670de0b6b3a76400006130db565b612cd291906130bb565b60016000828254612ce391906130a3565b9091555050600060025550612cf9565b60018290555b5050426005555b565b828054612d0e90613158565b90600052602060002090601f016020900481019282612d305760008555612d76565b82601f10612d4957805160ff1916838001178555612d76565b82800160010185558215612d76579182015b82811115612d76578251825591602001919060010190612d5b565b50612d82929150612dfa565b5090565b828054612d9290613158565b90600052602060002090601f016020900481019282612db45760008555612d76565b82601f10612dcd5782800160ff19823516178555612d76565b82800160010185558215612d76579182015b82811115612d76578235825591602001919060010190612ddf565b5b80821115612d825760008155600101612dfb565b80356001600160a01b0381168114610daa57600080fd5b60008083601f840112612e37578182fd5b50813567ffffffffffffffff811115612e4e578182fd5b602083019150836020828501011115610d8657600080fd5b600060208284031215612e77578081fd5b612e8082612e0f565b9392505050565b60008060408385031215612e99578081fd5b612ea283612e0f565b9150612eb060208401612e0f565b90509250929050565b600060208284031215612eca578081fd5b81518015158114612e80578182fd5b600060208284031215612eea578081fd5b5035919050565b60008060008060008060808789031215612f09578182fd5b86359550602087013567ffffffffffffffff80821115612f27578384fd5b612f338a838b01612e26565b9097509550604089013594506060890135915080821115612f52578384fd5b50612f5f89828a01612e26565b979a9699509497509295939492505050565b60008060408385031215612f83578182fd5b50508035926020909101359150565b600060208284031215612fa3578081fd5b5051919050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612fec816020860160208601613111565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b60008251613022818460208701613111565b9190910192915050565b60008415158252606060208301526130476060830185612fd4565b9050826040830152949350505050565b60006060825261306b606083018789612faa565b8560208401528281036040840152613084818587612faa565b98975050505050505050565b600060208252612e806020830184612fd4565b600082198211156130b6576130b66131a8565b500190565b6000826130d657634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156130f5576130f56131a8565b500290565b60008282101561310c5761310c6131a8565b500390565b60005b8381101561312c578181015183820152602001613114565b8381111561313b576000848401525b50505050565b600081613150576131506131a8565b506000190190565b600181811c9082168061316c57607f821691505b60208210811415611bb157634e487b7160e01b600052602260045260246000fd5b60006000198214156131a1576131a16131a8565b5060010190565b634e487b7160e01b600052601160045260246000fdfea26469706673582212204d04a6a545bc4bdeecb3a12a978d0a416164adc4c7de1063c71ee786fd702f4a64736f6c63430008030033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d81000000000000000000000000000000000000000000000000000000000000a8c000000000000000000000000000000000000000000000000821ab0d44149800000000000000000000000000000000000000000000000000052663ccab1e1c00000000000000000000000000000000000000000000000000008ac7230489e800005c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0
-----Decoded View---------------
Arg [0] : _token (address): 0xC866DB9021fe81856fF6c5B3E3514BF9D1593D81
Arg [1] : _reportingLock (uint256): 43200
Arg [2] : _stakeAmountDollarTarget (uint256): 150000000000000000000
Arg [3] : _stakingTokenPrice (uint256): 95000000000000000000
Arg [4] : _minimumStakeAmount (uint256): 10000000000000000000
Arg [5] : _stakingTokenPriceQueryId (bytes32): 0x5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000c866db9021fe81856ff6c5b3e3514bf9d1593d81
Arg [1] : 000000000000000000000000000000000000000000000000000000000000a8c0
Arg [2] : 00000000000000000000000000000000000000000000000821ab0d4414980000
Arg [3] : 0000000000000000000000000000000000000000000000052663ccab1e1c0000
Arg [4] : 0000000000000000000000000000000000000000000000008ac7230489e80000
Arg [5] : 5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0
Deployed ByteCode Sourcemap
766:40368:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1626:36;;;;;;;;;6429:25:1;;;6417:2;6402:18;1626:36:0;;;;;;;;32428:99;;;:::i;:::-;;;-1:-1:-1;;;;;4370:55:1;;;4352:74;;4340:2;4325:18;32428:99:0;4307:125:1;32670:105:0;32751:16;;32670:105;;6386:392;;;;;;:::i;:::-;;:::i;:::-;;27654:4071;;;;;;:::i;:::-;;:::i;:::-;;;;6213:14:1;;6206:22;6188:41;;6260:2;6245:18;;6238:34;;;;6161:18;27654:4071:0;6143:135:1;22955:253:0;;;;;;:::i;:::-;23069:7;23108:17;;;:7;:17;;;;;;;;:49;;;:37;;;:49;;;;;;23159:28;;;;:40;;;;;;;-1:-1:-1;;;;;23108:49:0;;;;23159:40;;;;;22955:253;;;;;-1:-1:-1;;;;;5026:55:1;;;5008:74;;5125:14;;5118:22;5113:2;5098:18;;5091:50;4981:18;22955:253:0;4963:184:1;1926:35:0;;;;;;32973:97;33050:12;;32973:97;;1253:38;;;;;2465:25;;;;;;1063:40;;;;;;24700:188;;;;;;:::i;:::-;;:::i;16662:869::-;;;:::i;33624:184::-;;;;;;:::i;:::-;33731:4;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;;;:40;;;;;;;;33624:184;;;;5619:14:1;;5612:22;5594:41;;5582:2;5567:18;33624:184:0;5549:92:1;24361:99:0;24439:13;24361:99;;11724:1697;;;;;;:::i;:::-;;:::i;24000:189::-;;;;;;:::i;:::-;-1:-1:-1;;;;;24135:24:0;24103:7;24135:24;;;:13;:24;;;;;:46;;;;24000:189;883:25;;;;;-1:-1:-1;;;;;883:25:0;;;10052:580;;;;;;:::i;:::-;;:::i;13816:2697::-;;;;;;:::i;:::-;;:::i;1448:26::-;;;;;;1157:43;;;;;22309:299;;;:::i;2020:51::-;;;;;;25012:95;25088:11;;25012:95;;20297:100;20352:7;20379:10;-1:-1:-1;;;;;20379:10:0;20297:100;;25776:736;;;;;;:::i;:::-;-1:-1:-1;;;;;26123:29:0;25887:7;26123:29;;;:13;:29;;;;;26185:17;;26217:21;;;;26253;;;;26289:18;;;;26322:29;;;;26366:24;;;;26405:22;;;;26442;;;;26479:14;;;;;26185:17;;26217:21;;26253;;26289:18;;26322:29;;26366:24;;26405:22;;26479:14;;;;;25776:736;;;;;15375:25:1;;;15431:2;15416:18;;15409:34;;;;15459:18;;;15452:34;;;;15517:2;15502:18;;15495:34;;;;15560:3;15545:19;;15538:35;;;;15604:3;15589:19;;15582:35;15648:3;15633:19;;15626:35;15692:3;15677:19;;15670:35;15749:14;15742:22;15736:3;15721:19;;15714:51;15362:3;15347:19;25776:736:0;15329:442:1;20622:176:0;;;;;;:::i;:::-;20723:7;20755:17;;;:7;:17;;;;;:35;;20622:176;1371:25;;;;;;2157:30;;;;;;2360:27;;;;;;10794:511;;;;;;:::i;:::-;;:::i;976:30::-;;;;;2265:31;;;;;;1826:46;;1868:4;1826:46;;32075:210;;;;;;:::i;:::-;32201:7;32233:17;;;:7;:17;;;;;;;;:44;;;:32;;;;:44;;;;;;32075:210;19585:611;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;18906:260::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;17629:613::-;;;:::i;21013:1124::-;;;;;;:::i;:::-;;:::i;1523:48::-;;;;;26677:109;26760:18;;26677:109;;34039:199;;;;;;:::i;:::-;;:::i;7571:2209::-;;;;;;:::i;:::-;;:::i;27010:197::-;;;;;;:::i;:::-;;:::i;1704:49::-;;;;;33203:189;;;:::i;6954:495::-;;;;;;:::i;:::-;;:::i;23576:209::-;;;;;;:::i;:::-;23696:7;23728:17;;;:7;:17;;;;;;;;:49;;;:37;;;;:49;;;;;-1:-1:-1;;;;;23728:49:0;;23576:209;809:29;;;;;34407:80;34475:4;34407:80;;32428:99;32513:5;32428:99;;:::o;6386:392::-;6456:10;-1:-1:-1;;;;;6470:5:0;6456:19;;6448:69;;;;-1:-1:-1;;;6448:69:0;;10870:2:1;6448:69:0;;;10852:21:1;10909:2;10889:18;;;10882:30;10948:34;10928:18;;;10921:62;-1:-1:-1;;;10999:18:1;;;10992:35;11044:19;;6448:69:0;;;;;;;;;6558:1;6536:10;-1:-1:-1;;;;;6536:10:0;:24;6528:67;;;;-1:-1:-1;;;6528:67:0;;13507:2:1;6528:67:0;;;13489:21:1;13546:2;13526:18;;;13519:30;13585:32;13565:18;;;13558:60;13635:18;;6528:67:0;13479:180:1;6528:67:0;-1:-1:-1;;;;;6628:32:0;;6606:122;;;;-1:-1:-1;;;6606:122:0;;14621:2:1;6606:122:0;;;14603:21:1;14660:2;14640:18;;;14633:30;14699:34;14679:18;;;14672:62;-1:-1:-1;;;14750:18:1;;;14743:38;14798:19;;6606:122:0;14593:230:1;6606:122:0;6739:10;:31;;-1:-1:-1;;;;;;6739:31:0;-1:-1:-1;;;;;6739:31:0;;;;;;;;;;6386:392::o;27654:4071::-;27771:11;20755:17;;;:7;:17;;;;;:35;27771:11;;27883:10;;27879:3811;;27910:15;;;27988:10;27997:1;27988:6;:10;:::i;:::-;27973:25;;28013:13;28115:47;28145:8;28155:6;28115:29;:47::i;:::-;28107:55;;28190:10;28181:5;:19;28177:42;;28210:5;28217:1;28202:17;;;;;;;;;;;28177:42;28242:45;28272:8;28282:4;28242:29;:45::i;:::-;28234:53;;28314:10;28306:5;:18;28302:393;;;28345:173;33731:4;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;28351;;;;;28390:1;28383:4;:8;28351:40;28345:173;;;28416:6;;;;:::i;:::-;;;;28453:45;28483:8;28493:4;28453:29;:45::i;:::-;28445:53;;28345:173;;;28539:9;;:41;;;;-1:-1:-1;33731:4:0;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;28552:28;28536:106;;;28613:5;28620:1;28605:17;;;;;;;;;;;28536:106;-1:-1:-1;28668:4:0;;-1:-1:-1;28674:4:0;-1:-1:-1;28660:19:0;;-1:-1:-1;;;28660:19:0;28302:393;28853:6;28845:1;28828:13;28853:6;28828:4;:13;:::i;:::-;28827:19;;;;:::i;:::-;:23;;28849:1;28827:23;:::i;:::-;:32;;;;:::i;:::-;28817:42;;28886:48;28916:8;28926:7;28886:29;:48::i;:::-;28878:56;;28965:10;28957:5;:18;28953:2711;;;29048:17;29068:125;29124:8;29159:11;:7;29169:1;29159:11;:::i;29068:125::-;29048:145;;29233:10;29220:9;:23;29216:1019;;33731:4;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;29272:796;;29394:4;29400:7;29386:22;;;;;;;;;;;;29272:796;33731:4;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;29564:43;;;;;29606:1;29596:7;:11;29564:43;29558:218;;;29644:9;;;;:::i;:::-;;;;29696:48;29726:8;29736:7;29696:29;:48::i;:::-;29688:56;;29558:218;;;29809:12;;:44;;;;-1:-1:-1;33731:4:0;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;29825:28;29806:133;;;29898:5;29905:1;29890:17;;;;;;;;;;;;29806:133;30026:4;30032:7;30018:22;;;;;;;;;;;;29216:1019;30200:11;:7;30210:1;30200:11;:::i;:::-;30191:20;;28953:2711;;;;30283:17;30303:125;30359:8;30394:11;30404:1;30394:7;:11;:::i;30303:125::-;30283:145;;30467:10;30455:9;:22;30451:1194;;;33731:4;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;30506:973;;30636:4;30642:11;30636:4;30642:7;:11;:::i;:::-;30628:26;;;;;;;;;;;;30506:973;30804:9;;;;:::i;:::-;;;;30844:335;33731:4;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;30850:47;;;;;30896:1;30886:7;:11;30850:47;30844:335;;;30934:9;;;;:::i;:::-;;;;30990:157;31058:8;31105:7;30990:29;:157::i;:::-;30978:169;;30844:335;;;31212:12;;:48;;;;-1:-1:-1;33731:4:0;33760:17;;;:7;:17;;;;;;;;:40;;;:28;;:40;;;;;;;;31228:32;33624:184;30451:1194;31610:11;31620:1;31610:7;:11;:::i;:::-;31603:18;;28953:2711;;28785:2894;;27879:3811;31708:5;31715:1;31700:17;;;;;27654:4071;;;;;;:::o;24700:188::-;-1:-1:-1;;;;;24839:24:0;;24807:7;24839:24;;;:13;:24;;;;;:41;;;24700:188;;;;:::o;16662:869::-;16748:14;;16787:104;16815:24;16854:26;16872:8;16854:15;:26;:::i;16787:104::-;16747:144;;;;;16906:9;16902:622;;;16932:26;16972:4;16961:27;;;;;;;;;;;;:::i;:::-;16932:56;;17051:10;17029:18;:32;;:70;;;;;17086:13;17065:18;:34;17029:70;17003:159;;;;-1:-1:-1;;;17003:159:0;;8296:2:1;17003:159:0;;;8278:21:1;8335:2;8315:18;;;8308:30;8374:29;8354:18;;;8347:57;8421:18;;17003:159:0;8268:177:1;17003:159:0;17179:28;17245:18;17211:30;:23;17237:4;17211:30;:::i;:::-;17210:53;;;;:::i;:::-;17179:84;;17304:18;17281:20;:41;17278:188;;;17357:18;17343:11;:32;17278:188;;;17416:11;:34;;;17278:188;17485:27;17500:11;;17485:27;;;;6429:25:1;;6417:2;6402:18;;6384:76;17485:27:0;;;;;;;;16902:622;;;16662:869;;:::o;11724:1697::-;11822:20;11882:10;;-1:-1:-1;;;;;11882:10:0;11868;:24;11860:71;;;;-1:-1:-1;;;11860:71:0;;7893:2:1;11860:71:0;;;7875:21:1;7932:2;7912:18;;;7905:30;7971:34;7951:18;;;7944:62;-1:-1:-1;;;8022:18:1;;;8015:32;8064:19;;11860:71:0;7865:224:1;11860:71:0;-1:-1:-1;;;;;11970:24:0;;11942:25;11970:24;;;:13;:24;;;;;12030:21;;;;12087;;;;11970:24;;12030:21;;12087;12127:31;12087:21;12030;12127:31;:::i;:::-;:35;12119:67;;;;-1:-1:-1;;;12119:67:0;;11276:2:1;12119:67:0;;;11258:21:1;11315:2;11295:18;;;11288:30;-1:-1:-1;;;11334:18:1;;;11327:49;11393:18;;12119:67:0;11248:169:1;12119:67:0;12219:11;;12201:14;:29;12197:1089;;12347:11;;12332:26;;12398:11;;12373:7;:21;;;:36;;;;;;;:::i;:::-;;;;-1:-1:-1;;12438:11:0;;12424:10;:25;;:10;;:25;;12438:11;;12424:25;:::i;:::-;;;;-1:-1:-1;12197:1089:0;;-1:-1:-1;12197:1089:0;;12506:11;;12471:31;12488:14;12471;:31;:::i;:::-;:46;12467:819;;12707:11;;;-1:-1:-1;12733:134:0;12777:9;12823:28;12837:14;12707:11;12823:28;:::i;:::-;12805:47;;:14;:47;:::i;:::-;12733:25;:134::i;:::-;12896:14;12882:10;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;12949:1:0;12925:21;;;:25;12467:819;;;13106:31;13123:14;13106;:31;:::i;:::-;13091:46;;13166:14;13152:10;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;13195:39:0;;-1:-1:-1;13221:9:0;13232:1;13195:25;:39::i;:::-;13273:1;13249:21;;;:25;12467:819;13304:40;;-1:-1:-1;;;13304:40:0;;-1:-1:-1;;;;;5344:55:1;;;13304:40:0;;;5326:74:1;5416:18;;;5409:34;;;13304:5:0;:14;;;;5299:18:1;;13304:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13296:49;;;;;;13361:52;;;-1:-1:-1;;;;;5344:55:1;;;5326:74;;5431:2;5416:18;;5409:34;;;13361:52:0;;;;;5299:18:1;13361:52:0;;;;;;;11724:1697;;;;;;;:::o;10052:580::-;10153:10;;-1:-1:-1;;;;;10153:10:0;10139;:24;10131:70;;;;-1:-1:-1;;;10131:70:0;;8652:2:1;10131:70:0;;;8634:21:1;8691:2;8671:18;;;8664:30;8730:34;8710:18;;;8703:62;-1:-1:-1;;;8781:18:1;;;8774:31;8822:19;;10131:70:0;8624:223:1;10131:70:0;10212:22;10237:17;;;:7;:17;;;;;;;;10274:30;;;:18;;;:30;;;;;;;;;10273:31;10265:66;;;;-1:-1:-1;;;10265:66:0;;13866:2:1;10265:66:0;;;13848:21:1;13905:2;13885:18;;;13878:30;13944:24;13924:18;;;13917:52;13986:18;;10265:66:0;13838:172:1;10265:66:0;10342:14;10359:34;;;:22;;;:34;;;;;;10426:26;;10359:7;;:34;;10426:26;;;;-1:-1:-1;;;10426:26:0;;;;;;;;;;;;;;;;;10412:10;:40;10404:70;;;;-1:-1:-1;;;10404:70:0;;9054:2:1;10404:70:0;;;9036:21:1;9093:2;9073:18;;;9066:30;-1:-1:-1;;;9112:18:1;;;9105:47;9169:18;;10404:70:0;9026:167:1;10404:70:0;10485:41;;;;;;;;;;-1:-1:-1;10485:41:0;;;:36;;;:24;;;:36;;;;;;:41;;;;;;:::i;:::-;-1:-1:-1;10537:30:0;;;;:18;;;:30;;;;;;;:37;;-1:-1:-1;;10537:37:0;10570:4;10537:37;;;10590:34;;;;;10603:8;;10556:10;;6639:25:1;;;6695:2;6680:18;;6673:34;6627:2;6612:18;;6594:119;13816:2697:0;14013:13;14002:6;;13992:17;;;;;;;:::i;:::-;;;;;;;;:34;;13984:70;;;;-1:-1:-1;;;13984:70:0;;9747:2:1;13984:70:0;;;9729:21:1;9786:2;9766:18;;;9759:30;9825:25;9805:18;;;9798:53;9868:18;;13984:70:0;9719:173:1;13984:70:0;14065:22;14090:17;;;:7;:17;;;;;14150:25;;14140:35;;;:50;;-1:-1:-1;14179:11:0;;14140:50;14118:132;;;;-1:-1:-1;;;14118:132:0;;10099:2:1;14118:132:0;;;10081:21:1;;;10118:18;;;10111:30;10177:34;10157:18;;;10150:62;10229:18;;14118:132:0;10071:182:1;14118:132:0;14303:10;14261:25;14289;;;:13;:25;;;;;14372:11;;14347:21;;;;:36;;14325:127;;;;-1:-1:-1;;;14325:127:0;;10460:2:1;14325:127:0;;;10442:21:1;10499:2;10479:18;;;10472:30;10538:34;10518:18;;;10511:62;-1:-1:-1;;;10589:18:1;;;10582:39;10638:19;;14325:127:0;10432:231:1;14325:127:0;14673:11;;14649:7;:21;;;:35;;;;:::i;:::-;14624:20;:13;14640:4;14624:20;:::i;:::-;14623:62;;;;:::i;:::-;14566:29;;;;14548:47;;:15;:47;:::i;:::-;14547:56;;14599:4;14547:56;:::i;:::-;:138;14525:229;;;;-1:-1:-1;;;14525:229:0;;12741:2:1;14525:229:0;;;12723:21:1;12780:2;12760:18;;;12753:30;12819:34;12799:18;;;12792:62;-1:-1:-1;;;12870:18:1;;;12863:39;12919:19;;14525:229:0;12713:231:1;14525:229:0;14809:10;;14799:21;;;;;;;:::i;:::-;;;;;;;;14787:8;:33;14765:118;;;;-1:-1:-1;;;14765:118:0;;14217:2:1;14765:118:0;;;14199:21:1;14256:2;14236:18;;;14229:30;14295:34;14275:18;;;14268:62;-1:-1:-1;;;14346:18:1;;;14339:33;14389:19;;14765:118:0;14189:225:1;14765:118:0;14926:15;14894:29;;;:47;;;15087:1;15031:44;;;:27;;;:44;;;;;;-1:-1:-1;;;;;15031:44:0;:58;15009:138;;;;-1:-1:-1;;;15009:138:0;;12382:2:1;15009:138:0;;;12364:21:1;12421:2;12401:18;;;12394:30;12460:32;12440:18;;;12433:60;12510:18;;15009:138:0;12354:180:1;15009:138:0;15295:25;;15276:15;15295:18;15253:39;;;:22;;;;:39;;;;;;;;:67;;;15331:40;;;;;;;;;;;;;;;;;15382:41;;;:24;;;:41;;;;;:50;;15426:6;;15382:50;:::i;:::-;-1:-1:-1;15471:15:0;15443:44;;;;:27;;;:44;;;;;:57;;-1:-1:-1;;;;;;15443:57:0;15490:10;15443:57;;;15588:18;;15443:44;;15629:3;;1868:4;;15570:36;;15588:18;15570:36;:::i;:::-;15569:56;;;;:::i;:::-;15568:64;;;;:::i;:::-;15550:82;;15666:37;15809:10;;15785:21;;15766:16;;:40;;;;:::i;:::-;:53;;;;:::i;:::-;15719:30;;-1:-1:-1;;;15719:30:0;;15743:4;15719:30;;;4352:74:1;15719:5:0;-1:-1:-1;;;;;15719:15:0;;;;4325:18:1;;15719:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:101;;;;:::i;:::-;15666:154;;15867:1;15835:29;:33;:48;;;;;15882:1;15872:7;:11;15835:48;15831:293;;;15936:7;15904:29;:39;15900:213;;;15964:57;;-1:-1:-1;;;15964:57:0;;15979:10;15964:57;;;5326:74:1;5416:18;;;5409:34;;;15964:5:0;-1:-1:-1;;;;;15964:14:0;;;;5299:18:1;;15964:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;15900:213;;;16062:35;;-1:-1:-1;;;16062:35:0;;16077:10;16062:35;;;5326:74:1;5416:18;;;5409:34;;;16062:5:0;-1:-1:-1;;;;;16062:14:0;;;;5299:18:1;;16062:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;15900:213;16237:15;16216:18;:36;;;16287:24;;;:26;;;;;;16340:165;;16484:10;;16237:15;16364:8;;16340:165;;;;16417:6;;;;16438;;16459:10;;;;16340:165;:::i;:::-;;;;;;;;13816:2697;;;;;;;;;;:::o;22309:299::-;22372:7;22392:23;22526:15;;22506:4;22473:16;;22419:38;:36;:38::i;:::-;:70;;;;:::i;:::-;22418:92;;;;:::i;:::-;:123;;;;:::i;:::-;22392:149;;22584:15;22560:21;;:39;;;;:::i;:::-;22552:48;;;22309:299;:::o;10794:511::-;10905:10;10863:25;10891;;;:13;:25;;;;;10949:21;;;;:32;-1:-1:-1;10949:32:0;10927:109;;;;-1:-1:-1;;;10927:109:0;;13151:2:1;10927:109:0;;;13133:21:1;13190:2;13170:18;;;13163:30;13229:29;13209:18;;;13202:57;13276:18;;10927:109:0;13123:177:1;10927:109:0;11047:70;11073:10;11109:7;11085;:21;;;:31;;;;:::i;11047:70::-;11148:15;11128:35;;11174:21;;;:32;;11199:7;;11174:21;11128:17;;11174:32;;11199:7;;11174:32;:::i;:::-;;;;;;;;11231:7;11217:10;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;11254:43:0;;;11277:10;5326:74:1;;5431:2;5416:18;;5409:34;;;11254:43:0;;5299:18:1;11254:43:0;;;;;;;10794:511;;:::o;19585:611::-;19708:16;19739:19;19773:27;19829:11;19842:14;19860:80;19896:8;19919:10;19860:21;:80::i;:::-;19828:112;;;;19956:6;19951:41;;19972:5;19979:9;;;;;;;;;;;;19990:1;19964:28;;;;;;;;;;19951:41;20025:47;20055:8;20065:6;20025:29;:47::i;:::-;20003:69;;20092:43;20105:8;20115:19;20092:12;:43::i;:::-;20083:52;;20154:4;20146:42;;;;19585:611;;;;;;:::o;18906:260::-;18999:19;19036:12;19081:44;19095:8;19105:19;:15;19123:1;19105:19;:::i;19081:44::-;-1:-1:-1;19059:66:0;-1:-1:-1;19059:66:0;-1:-1:-1;19059:66:0;19136:23;;19149:8;;;19136:23;18906:260;;;;:::o;17629:613::-;17716:10;17674:25;17702;;;:13;:25;;;;;17848:17;;17869:6;;17830:35;;:15;:35;:::i;:::-;:45;;17808:113;;;;-1:-1:-1;;;17808:113:0;;9400:2:1;17808:113:0;;;9382:21:1;9439:2;9419:18;;;9412:30;-1:-1:-1;;;9458:18:1;;;9451:48;9516:18;;17808:113:0;9372:168:1;17808:113:0;17978:1;17954:7;:21;;;:25;17932:109;;;;-1:-1:-1;;;17932:109:0;;11979:2:1;17932:109:0;;;11961:21:1;12018:2;11998:18;;;11991:30;12057:34;12037:18;;;12030:62;-1:-1:-1;;;12108:18:1;;;12101:32;12150:19;;17932:109:0;11951:224:1;17932:109:0;18087:21;;;;18060:49;;-1:-1:-1;;;18060:49:0;;18075:10;18060:49;;;5326:74:1;5416:18;;;5409:34;;;;18060:5:0;-1:-1:-1;;;;;18060:14:0;;;;5299:18:1;;18060:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18052:58;;;;;;18135:7;:21;;;18121:10;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;;18191:1:0;18167:21;;;:25;18208:26;;18223:10;4352:74:1;;18208:26:0;;4340:2:1;4325:18;18208:26:0;;;;;;;17629:613;:::o;21013:1124::-;-1:-1:-1;;;;;21175:29:0;;21107:22;21175:29;;;:13;:29;;;;;21345:18;;;;21325:4;21270:38;:36;:38::i;:::-;21233:7;:21;;;:75;;;;:::i;:::-;21232:97;;;;:::i;:::-;:131;;;;:::i;:::-;21375:13;21418:10;;21448:41;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21448:41:0;-1:-1:-1;;;21448:41:0;;;21418:82;;21215:148;;-1:-1:-1;21375:13:0;;;;-1:-1:-1;;;;;21418:10:0;;;;:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21374:126;;;;21511:22;21548:8;21544:130;;;21640:7;:22;;;21613:11;21602:34;;;;;;;;;;;;:::i;:::-;21594:68;;;;:::i;:::-;21577:85;;21544:130;21688:18;;21684:446;;21752:10;;21790:72;;-1:-1:-1;;;;;4370:55:1;;;21790:72:0;;;4352:74:1;21752:10:0;;;;4325:18:1;;21790:72:0;;;-1:-1:-1;;21790:72:0;;;;;;;;;;;;;;-1:-1:-1;;;;;21790:72:0;-1:-1:-1;;;21790:72:0;;;21752:129;;;21790:72;21752:129;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21727:154:0;;-1:-1:-1;21727:154:0;-1:-1:-1;21900:219:0;;;;22085:14;22032:7;:22;;;22007:11;21996:33;;;;;;;;;;;;:::i;:::-;:58;;;;:::i;:::-;21978:77;;:14;:77;:::i;:::-;21977:122;;;;:::i;:::-;21935:164;;21900:219;21013:1124;;;;;;;:::o;34039:199::-;34184:17;;;;:7;:17;;;;;;;;:46;;;:34;;:46;;;;;34177:53;;34147:12;;34184:46;34177:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34039:199;;;;:::o;7571:2209::-;7660:1;7638:10;-1:-1:-1;;;;;7638:10:0;7630:63;;;;-1:-1:-1;;;7630:63:0;;11624:2:1;7630:63:0;;;11606:21:1;11663:2;11643:18;;;11636:30;11702:28;11682:18;;;11675:56;11748:18;;7630:63:0;11596:176:1;7630:63:0;7746:10;7704:25;7732;;;:13;:25;;;;;7793:21;;;;7850;;;;7886:18;;7882:1681;;7943:7;7925:14;:25;7921:714;;8073:7;8048;:21;;;:32;;;;;;;:::i;:::-;;;;;;;;8113:7;8099:10;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;7921:714:0;;-1:-1:-1;7921:714:0;;-1:-1:-1;;;;;8333:5:0;:18;;8378:10;8423:4;8455:24;8465:14;8455:7;:24;:::i;:::-;8333:169;;-1:-1:-1;;;;;;8333:169:0;;;;;;;-1:-1:-1;;;;;4718:15:1;;;8333:169:0;;;4700:34:1;4770:15;;;;4750:18;;;4743:43;4802:18;;;4795:34;4612:18;;8333:169:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8303:218;;;;;;8554:7;:21;;;8540:10;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;;8618:1:0;8594:21;;;:25;7921:714;7882:1681;;;8671:19;8667:807;;8873:13;8916:10;;8954:41;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8954:41:0;-1:-1:-1;;;8954:41:0;;;8916:98;;8873:13;;-1:-1:-1;;;;;8916:10:0;;:98;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8872:142;;;;9037:8;9033:125;;;9114:11;9103:34;;;;;;;;;;;;:::i;:::-;9070:22;;;:68;9033:125;9201:10;;9239:68;;9296:10;9239:68;;;4352:74:1;-1:-1:-1;;;;;9201:10:0;;;;4325:18:1;;9239:68:0;;;-1:-1:-1;;9239:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;9239:68:0;-1:-1:-1;;;9239:68:0;;;9201:125;;;9239:68;9201:125;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9176:150:0;;-1:-1:-1;9176:150:0;-1:-1:-1;9345:114:0;;;;9417:11;9406:33;;;;;;;;;;;;:::i;:::-;9380:22;;;:59;9345:114;8667:807;;;9496:54;;-1:-1:-1;;;9496:54:0;;9515:10;9496:54;;;4700:34:1;9535:4:0;4750:18:1;;;4743:43;4802:18;;;4795:34;;;9496:5:0;-1:-1:-1;;;;;9496:18:0;;;;4612::1;;9496:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9488:63;;;;;;9573;9599:10;9611:24;9628:7;9611:14;:24;:::i;9573:63::-;9667:15;9647:35;;9742:30;;9764:7;;9752:10;;9742:30;;9647:17;;9742:30;7571:2209;;;;:::o;27010:197::-;27131:7;27163:17;;;:7;:17;;;;;:36;;27192:6;;27163:36;;;;-1:-1:-1;;;27163:36:0;;;;;;;;;;;;;;;;;27156:43;;27010:197;;;;:::o;33203:189::-;33269:7;33373:10;;33349:21;;33330:16;;:40;;;;:::i;:::-;:53;;;;:::i;:::-;33296:30;;-1:-1:-1;;;33296:30:0;;33320:4;33296:30;;;4352:74:1;33296:5:0;-1:-1:-1;;;;;33296:15:0;;;;4325:18:1;;33296:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:88;;;;:::i;:::-;33289:95;;33203:189;:::o;6954:495::-;7026:54;;-1:-1:-1;;;7026:54:0;;7045:10;7026:54;;;4700:34:1;7065:4:0;4750:18:1;;;4743:43;4802:18;;;4795:34;;;7026:5:0;-1:-1:-1;;;;;7026:18:0;;;;4612::1;;7026:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7018:63;;;;;;7092:16;:14;:16::i;:::-;7144:7;7119:21;;:32;;;;;;;:::i;:::-;;;;;;;;7434:7;7401:15;;7373:4;7332:16;;7304:25;;:44;;;;:::i;:::-;7303:74;;;;:::i;:::-;:113;;;;:::i;:::-;7261:21;;:156;;;;:::i;:::-;7260:181;;;;:::i;:::-;7234:10;:207;-1:-1:-1;6954:495:0:o;36832:3088::-;36963:16;:14;:16::i;:::-;-1:-1:-1;;;;;37018:29:0;;36990:25;37018:29;;;:13;:29;;;;;37062:21;;;;:25;37058:1754;;37200:22;37337:7;:18;;;37313:4;37267:25;;37226:7;:21;;;:66;;;;:::i;:::-;37225:92;;;;:::i;:::-;:130;;;;:::i;:::-;37423:22;37504:10;;37538:41;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37538:41:0;-1:-1:-1;;;37538:41:0;;;37504:90;;37200:155;;-1:-1:-1;37423:22:0;;;;;;-1:-1:-1;;;;;37504:10:0;;:90;;37538:41;37504:90;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37460:134;;;;37613:8;37609:176;;;37747:7;:22;;;37699:11;37688:34;;;;;;;;;;;;:::i;:::-;37680:89;;;;:::i;:::-;37642:127;;37609:176;37803:18;;37799:774;;37948:10;;37986:72;;-1:-1:-1;;;;;4370:55:1;;;37986:72:0;;;4352:74:1;37948:10:0;;;;4325:18:1;;37986:72:0;;;-1:-1:-1;;37986:72:0;;;;;;;;;;;;;;-1:-1:-1;;;;;37986:72:0;-1:-1:-1;;;37986:72:0;;;37948:129;;;37986:72;37948:129;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37922:155:0;;-1:-1:-1;37922:155:0;-1:-1:-1;38096:462:0;;;;38131:18;38163:11;38152:33;;;;;;;;;;;;:::i;:::-;38131:54;;38208:26;38375:14;38323:7;:22;;;38310:10;:35;;;;:::i;:::-;38263:83;;:14;:83;:::i;:::-;38262:127;;;;:::i;:::-;38208:181;;38437:14;38416:18;:35;38412:127;;;38497:18;38480:35;;38412:127;38096:462;;;38612:14;38587:21;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;;38649:42:0;;-1:-1:-1;;;38649:42:0;;38664:10;38649:42;;;5326:74:1;5416:18;;;5409:34;;;38649:5:0;-1:-1:-1;;;;;38649:14:0;;;;5299:18:1;;38649:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38641:51;;;;;;38726:7;:18;;;38707:15;;:37;;;;;;;:::i;:::-;;;;-1:-1:-1;;38779:21:0;;;;38759:16;:41;;:16;;:41;;38779:21;;38759:41;:::i;:::-;;;;-1:-1:-1;;;;;;37058:1754:0;38822:21;;;:41;;;38936:11;;38911:36;;38907:348;;38968:14;;;;;;38964:78;;39012:12;:14;;;:12;:14;;;:::i;:::-;;;;;;38964:78;39056:14;;;:21;;-1:-1:-1;;39056:21:0;39073:4;39056:21;;;38907:348;;;39114:14;;;;;;:22;;:14;:22;:42;;;;;39155:1;39140:12;;:16;39114:42;39110:97;;;39177:12;:14;;;:12;:14;;;:::i;:::-;;;;;;39110:97;39221:14;;;:22;;-1:-1:-1;;39221:22:0;;;38907:348;39433:4;39391:25;;39367:7;:21;;;:49;;;;:::i;:::-;39366:71;;;;:::i;:::-;39332:18;;;:105;;;39448:15;:37;;:15;;:37;;39332:105;;39448:37;:::i;:::-;;;;-1:-1:-1;;39516:21:0;;;;39496:16;:41;;:16;;:41;;39516:21;;39496:41;:::i;:::-;;;;-1:-1:-1;;39662:10:0;;39659:254;;39894:7;39861:15;;39833:4;39792:16;;39764:25;;:44;;;;:::i;:::-;39763:74;;;;:::i;:::-;:113;;;;:::i;:::-;39721:21;;:156;;;;:::i;:::-;39720:181;;;;:::i;:::-;39694:10;:207;39659:254;36832:3088;;;:::o;40085:1046::-;40183:7;40212:16;;40232:1;40212:21;40208:86;;;-1:-1:-1;40257:25:0;;40250:32;;40208:86;40304:37;40463:16;;40429:10;;40405:20;;40387:15;:38;;;;:::i;:::-;40386:53;;;;:::i;:::-;:60;;40442:4;40386:60;:::i;:::-;40385:94;;;;:::i;:::-;40344:25;;:135;;;;:::i;:::-;40304:175;;40490:26;40618:15;;40598:4;40565:16;;40520:29;:61;;;;:::i;:::-;40519:83;;;;:::i;:::-;:114;;;;:::i;:::-;40490:143;;40670:21;;40648:18;:43;40644:433;;40708:26;40877:15;;40849:4;40808:16;;40780:25;;:44;;;;:::i;:::-;40779:74;;;;:::i;:::-;:113;;;;:::i;:::-;40737:21;;:156;;;;:::i;:::-;41049:16;;40708:185;;-1:-1:-1;41003:25:0;40708:185;41024:4;41003:25;:::i;:::-;41002:63;;;;:::i;:::-;40957:25;;:108;;;;:::i;:::-;40908:157;;40644:433;;-1:-1:-1;41094:29:0;-1:-1:-1;40085:1046:0;:::o;35011:1438::-;35085:15;35061:20;;:39;35057:78;;;35117:7;;35057:78;35149:16;;:21;;:40;;-1:-1:-1;35174:10:0;;:15;35149:40;35145:132;;;35229:15;35206:20;:38;35259:7;;35145:132;35345:37;35504:16;;35470:10;;35446:20;;35428:15;:38;;;;:::i;:::-;35427:53;;;;:::i;:::-;:60;;35483:4;35427:60;:::i;:::-;35426:94;;;;:::i;:::-;35385:25;;:135;;;;:::i;:::-;35345:175;;35607:26;35735:15;;35715:4;35682:16;;35637:29;:61;;;;:::i;:::-;35636:83;;;;:::i;:::-;:114;;;;:::i;:::-;35607:143;;35787:21;;35765:18;:43;35761:632;;35953:26;36122:15;;36094:4;36053:16;;36025:25;;:44;;;;:::i;:::-;36024:74;;;;:::i;:::-;:113;;;;:::i;:::-;35982:21;;:156;;;;:::i;:::-;36246:16;;35953:185;;-1:-1:-1;36200:25:0;35953:185;36221:4;36200:25;:::i;:::-;36199:63;;;;:::i;:::-;36153:25;;:109;;;;;;;:::i;:::-;;;;-1:-1:-1;;36290:1:0;36277:10;:14;-1:-1:-1;35761:632:0;;;36324:25;:57;;;35761:632;-1:-1:-1;;36426:15:0;36403:20;:38;35011:1438;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:196:1;82:20;;-1:-1:-1;;;;;131:54:1;;121:65;;111:2;;200:1;197;190:12;215:375;;;330:3;323:4;315:6;311:17;307:27;297:2;;355:8;345;338:26;297:2;-1:-1:-1;385:20:1;;428:18;417:30;;414:2;;;467:8;457;450:26;414:2;511:4;503:6;499:17;487:29;;563:3;556:4;547:6;539;535:19;531:30;528:39;525:2;;;580:1;577;570:12;595:196;;707:2;695:9;686:7;682:23;678:32;675:2;;;728:6;720;713:22;675:2;756:29;775:9;756:29;:::i;:::-;746:39;665:126;-1:-1:-1;;;665:126:1:o;796:270::-;;;925:2;913:9;904:7;900:23;896:32;893:2;;;946:6;938;931:22;893:2;974:29;993:9;974:29;:::i;:::-;964:39;;1022:38;1056:2;1045:9;1041:18;1022:38;:::i;:::-;1012:48;;883:183;;;;;:::o;1071:297::-;;1191:2;1179:9;1170:7;1166:23;1162:32;1159:2;;;1212:6;1204;1197:22;1159:2;1249:9;1243:16;1302:5;1295:13;1288:21;1281:5;1278:32;1268:2;;1329:6;1321;1314:22;1373:190;;1485:2;1473:9;1464:7;1460:23;1456:32;1453:2;;;1506:6;1498;1491:22;1453:2;-1:-1:-1;1534:23:1;;1443:120;-1:-1:-1;1443:120:1:o;1568:884::-;;;;;;;1769:3;1757:9;1748:7;1744:23;1740:33;1737:2;;;1791:6;1783;1776:22;1737:2;1832:9;1819:23;1809:33;;1893:2;1882:9;1878:18;1865:32;1916:18;1957:2;1949:6;1946:14;1943:2;;;1978:6;1970;1963:22;1943:2;2022:58;2072:7;2063:6;2052:9;2048:22;2022:58;:::i;:::-;2099:8;;-1:-1:-1;1996:84:1;-1:-1:-1;2181:2:1;2166:18;;2153:32;;-1:-1:-1;2238:2:1;2223:18;;2210:32;;-1:-1:-1;2254:16:1;;;2251:2;;;2288:6;2280;2273:22;2251:2;;2332:60;2384:7;2373:8;2362:9;2358:24;2332:60;:::i;:::-;1727:725;;;;-1:-1:-1;1727:725:1;;-1:-1:-1;1727:725:1;;2411:8;;1727:725;-1:-1:-1;;;1727:725:1:o;2457:258::-;;;2586:2;2574:9;2565:7;2561:23;2557:32;2554:2;;;2607:6;2599;2592:22;2554:2;-1:-1:-1;;2635:23:1;;;2705:2;2690:18;;;2677:32;;-1:-1:-1;2544:171:1:o;2915:194::-;;3038:2;3026:9;3017:7;3013:23;3009:32;3006:2;;;3059:6;3051;3044:22;3006:2;-1:-1:-1;3087:16:1;;2996:113;-1:-1:-1;2996:113:1:o;3114:268::-;;3202:6;3197:3;3190:19;3254:6;3247:5;3240:4;3235:3;3231:14;3218:43;3306:3;3299:4;3290:6;3285:3;3281:16;3277:27;3270:40;3371:4;3364:2;3360:7;3355:2;3347:6;3343:15;3339:29;3334:3;3330:39;3326:50;3319:57;;3180:202;;;;;:::o;3387:257::-;;3466:5;3460:12;3493:6;3488:3;3481:19;3509:63;3565:6;3558:4;3553:3;3549:14;3542:4;3535:5;3531:16;3509:63;:::i;:::-;3626:2;3605:15;-1:-1:-1;;3601:29:1;3592:39;;;;3633:4;3588:50;;3436:208;-1:-1:-1;;3436:208:1:o;3649:273::-;;3832:6;3824;3819:3;3806:33;3858:16;;3883:15;;;3858:16;3796:126;-1:-1:-1;3796:126:1:o;3927:274::-;;4094:6;4088:13;4110:53;4156:6;4151:3;4144:4;4136:6;4132:17;4110:53;:::i;:::-;4179:16;;;;;4064:137;-1:-1:-1;;4064:137:1:o;5646:369::-;;5857:6;5850:14;5843:22;5832:9;5825:41;5902:2;5897;5886:9;5882:18;5875:30;5922:44;5962:2;5951:9;5947:18;5939:6;5922:44;:::i;:::-;5914:52;;6002:6;5997:2;5986:9;5982:18;5975:34;5815:200;;;;;;:::o;6718:502::-;;6959:2;6948:9;6941:21;6985:61;7042:2;7031:9;7027:18;7019:6;7011;6985:61;:::i;:::-;7082:6;7077:2;7066:9;7062:18;7055:34;7137:9;7129:6;7125:22;7120:2;7109:9;7105:18;7098:50;7165:49;7207:6;7199;7191;7165:49;:::i;:::-;7157:57;6931:289;-1:-1:-1;;;;;;;;6931:289:1:o;7225:217::-;;7372:2;7361:9;7354:21;7392:44;7432:2;7421:9;7417:18;7409:6;7392:44;:::i;15776:128::-;;15847:1;15843:6;15840:1;15837:13;15834:2;;;15853:18;;:::i;:::-;-1:-1:-1;15889:9:1;;15824:80::o;15909:217::-;;15975:1;15965:2;;-1:-1:-1;;;16000:31:1;;16054:4;16051:1;16044:15;16082:4;16007:1;16072:15;15965:2;-1:-1:-1;16111:9:1;;15955:171::o;16131:168::-;;16237:1;16233;16229:6;16225:14;16222:1;16219:21;16214:1;16207:9;16200:17;16196:45;16193:2;;;16244:18;;:::i;:::-;-1:-1:-1;16284:9:1;;16183:116::o;16304:125::-;;16372:1;16369;16366:8;16363:2;;;16377:18;;:::i;:::-;-1:-1:-1;16414:9:1;;16353:76::o;16434:258::-;16506:1;16516:113;16530:6;16527:1;16524:13;16516:113;;;16606:11;;;16600:18;16587:11;;;16580:39;16552:2;16545:10;16516:113;;;16647:6;16644:1;16641:13;16638:2;;;16682:1;16673:6;16668:3;16664:16;16657:27;16638:2;;16487:205;;;:::o;16697:136::-;;16764:5;16754:2;;16773:18;;:::i;:::-;-1:-1:-1;;;16809:18:1;;16744:89::o;16838:380::-;16917:1;16913:12;;;;16960;;;16981:2;;17035:4;17027:6;17023:17;17013:27;;16981:2;17088;17080:6;17077:14;17057:18;17054:38;17051:2;;;17134:10;17129:3;17125:20;17122:1;17115:31;17169:4;17166:1;17159:15;17197:4;17194:1;17187:15;17223:135;;-1:-1:-1;;17283:17:1;;17280:2;;;17303:18;;:::i;:::-;-1:-1:-1;17350:1:1;17339:13;;17270:88::o;17363:127::-;17424:10;17419:3;17415:20;17412:1;17405:31;17455:4;17452:1;17445:15;17479:4;17476:1;17469:15
Swarm Source
ipfs://4d04a6a545bc4bdeecb3a12a978d0a416164adc4c7de1063c71ee786fd702f4a