More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 5,922 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 17570177 | 368 days ago | IN | 0 ETH | 0.00209244 | ||||
Unstake | 17423989 | 388 days ago | IN | 0 ETH | 0.00521584 | ||||
Unstake | 16298078 | 546 days ago | IN | 0 ETH | 0.00265779 | ||||
Stake | 16294595 | 547 days ago | IN | 0 ETH | 0.00323275 | ||||
Unstake | 15999509 | 588 days ago | IN | 0 ETH | 0.00241109 | ||||
Stake | 15999502 | 588 days ago | IN | 0 ETH | 0.00316342 | ||||
Unstake | 15815292 | 614 days ago | IN | 0 ETH | 0.00206119 | ||||
Unstake | 15458406 | 666 days ago | IN | 0 ETH | 0.00214009 | ||||
Unstake | 14932053 | 751 days ago | IN | 0 ETH | 0.00490987 | ||||
Stake | 14795841 | 773 days ago | IN | 0 ETH | 0.0035863 | ||||
Stake | 14620666 | 801 days ago | IN | 0 ETH | 0.00709143 | ||||
Unstake | 14620660 | 801 days ago | IN | 0 ETH | 0.00620386 | ||||
Unstake | 14545231 | 812 days ago | IN | 0 ETH | 0.00432109 | ||||
Unstake | 14545230 | 812 days ago | IN | 0 ETH | 0.00672409 | ||||
Unstake | 14480296 | 823 days ago | IN | 0 ETH | 0.00451102 | ||||
Unstake | 14420614 | 832 days ago | IN | 0 ETH | 0.00240809 | ||||
Unstake | 14339266 | 845 days ago | IN | 0 ETH | 0.00323025 | ||||
Unstake | 14339258 | 845 days ago | IN | 0 ETH | 0.00388 | ||||
Unstake | 14324162 | 847 days ago | IN | 0 ETH | 0.00902444 | ||||
Stake | 14323733 | 847 days ago | IN | 0 ETH | 0.01429179 | ||||
Unstake | 14238829 | 860 days ago | IN | 0 ETH | 0.01014227 | ||||
Stake | 14038415 | 891 days ago | IN | 0 ETH | 0.0289169 | ||||
Unstake | 14036506 | 891 days ago | IN | 0 ETH | 0.01713868 | ||||
Unstake | 14023621 | 893 days ago | IN | 0 ETH | 0.01461745 | ||||
Unstake | 14021394 | 894 days ago | IN | 0 ETH | 0.01218186 |
Latest 3 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
11269810 | 1320 days ago | Contract Creation | 0 ETH | |||
11269810 | 1320 days ago | Contract Creation | 0 ETH | |||
11269810 | 1320 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
RewardPool
Compiler Version
v0.5.1+commit.c8a2cb62
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-11-17 */ // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see `ERC20Detailed`. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through `transferFrom`. This is * zero by default. * * This value changes when `approve` or `transferFrom` are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * > Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an `Approval` event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to `approve`. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: contracts/IStaking.sol pragma solidity 0.5.1; /** * @title Staking interface, as defined by EIP-900. * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-900.md */ contract IStaking { event Staked(address indexed user, uint256 amount, uint256 total, bytes data); event Unstaked(address indexed user, uint256 amount, uint256 total, bytes data); function stake(uint256 amount, bytes calldata data) external; function unstake(uint256 amount, bytes calldata data) external; function totalStakedFor(address addr) public view returns (uint256); function totalStaked() public view returns (uint256); function token() external view returns (address); /** * @return False. This application does not support staking history. */ function supportsHistory() external pure returns (bool) { return false; } } // File: openzeppelin-solidity/contracts/ownership/Ownable.sol pragma solidity ^0.5.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be aplied to your functions to restrict their use to * the owner. */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * > Note: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/TokenPool.sol pragma solidity 0.5.1; /** * @title A simple holder of tokens. * This is a simple contract to hold tokens. It's useful in the case where a separate contract * needs to hold multiple distinct pools of the same token. */ contract TokenPool is Ownable { IERC20 public token; constructor(IERC20 _token) public { token = _token; } function balance() public view returns (uint256) { return token.balanceOf(address(this)); } function transfer(address to, uint256 value) external onlyOwner returns (bool) { return token.transfer(to, value); } function rescueFunds(address tokenToRescue, address to, uint256 amount) external onlyOwner returns (bool) { require(address(token) != tokenToRescue, 'TokenPool: Cannot claim token held by the contract'); return IERC20(tokenToRescue).transfer(to, amount); } } // File: contracts/RewardPool.sol pragma solidity 0.5.1; /** * @title Reward Pool * @dev A smart-contract based mechanism to distribute tokens over time. Forked from Ampleforth's * geyser contract, but utilizing a second degree polynomial curve to calculate the bonus rewards. * * Distribution tokens are added to a locked pool in the contract and become unlocked over time * according to a once-configurable unlock schedule. Once unlocked, they are available to be * claimed by users. * * A user may deposit tokens to accrue ownership share over the unlocked pool. This owner share * is a function of the number of tokens deposited as well as the length of time deposited. * Specifically, a user's share of the currently-unlocked pool equals their "deposit-seconds" * divided by the global "deposit-seconds". This aligns the new token distribution with long * term supporters of the project, addressing one of the major drawbacks of simple airdrops. * */ contract RewardPool is IStaking { struct Accounting { uint256 globalTotalStakingShareSeconds; uint256 globalLastAccountingTimestampSec; uint256 globalLockedPoolBalance; uint256 globalUnlockedPoolBalance; } struct RewardData { uint256 stakingShareSecondsToBurn; uint256 sharesLeftToBurn; uint256 rewardAmount; } using SafeMath for uint256; event Staked( address indexed user, uint256 amount, uint256 total, bytes data ); event Unstaked( address indexed user, uint256 amount, uint256 total, bytes data ); event TokensClaimed(address indexed user, uint256 amount); event TokensLocked(uint256 amount, uint256 durationSec, uint256 total); // amount: Unlocked tokens, total: Total locked tokens event TokensUnlocked(uint256 amount, uint256 total); event AccountingUpdated(); TokenPool private _stakingPool; TokenPool private _unlockedPool; TokenPool private _lockedPool; // // Time-bonus params // uint256 public constant BONUS_DECIMALS = 4; uint256 public startBonus = 0; uint256 public bonusPeriodSec = 0; uint256 public growthParamX; uint256 public growthParamY; // // Global accounting state // uint256 public totalLockedShares = 0; uint256 public totalStakingShares = 0; uint256 public _totalStakingShareSeconds = 0; uint256 public _lastAccountingTimestampSec = now; uint256 public _maxUnlockSchedules = 0; uint256 public _initialSharesPerToken = 0; // // User accounting state // // Represents a single stake for a user. A user may have multiple. struct Stake { uint256 stakingShares; uint256 timestampSec; } // Caches aggregated values from the User->Stake[] map to save computation. // If lastAccountingTimestampSec is 0, there's no entry for that user. struct UserTotals { uint256 stakingShares; uint256 stakingShareSeconds; uint256 lastAccountingTimestampSec; } // Aggregated staking values per user mapping(address => UserTotals) public _userTotals; // The collection of stakes for each user. Ordered by timestamp, earliest to latest. mapping(address => Stake[]) public _userStakes; // // Locked/Unlocked Accounting state // struct UnlockSchedule { uint256 initialLockedShares; uint256 unlockedShares; uint256 lastUnlockTimestampSec; uint256 endAtSec; uint256 durationSec; } UnlockSchedule[] public unlockSchedules; /** * @param stakingToken The token users deposit as stake. * @param distributionToken The token users receive as they unstake. * @param maxUnlockSchedules Max number of unlock stages, to guard against hitting gas limit. * @param startBonus_ Starting time bonus, BONUS_DECIMALS fixed point. * e.g. 25 means user gets 25% of max distribution tokens. * @param bonusPeriodSec_ Length of time for bonus to increase linearly to max. * @param initialSharesPerToken Number of shares to mint per staking token on first stake. */ constructor( IERC20 stakingToken, IERC20 distributionToken, uint256 maxUnlockSchedules, uint256 startBonus_, uint256 bonusPeriodSec_, uint256 growthParamX_, uint256 growthParamY_, uint256 initialSharesPerToken ) public { // The start bonus must be some fraction of the max. (i.e. <= 100%) require( startBonus_ <= 10**BONUS_DECIMALS, "TokenGeyser: start bonus too high" ); // If no period is desired, instead set startBonus = 100% // and bonusPeriod to a small value like 1sec. require(bonusPeriodSec_ != 0, "TokenGeyser: bonus period is zero"); require( initialSharesPerToken > 0, "TokenGeyser: initialSharesPerToken is zero" ); _stakingPool = new TokenPool(stakingToken); _unlockedPool = new TokenPool(distributionToken); _lockedPool = new TokenPool(distributionToken); startBonus = startBonus_; bonusPeriodSec = bonusPeriodSec_; growthParamX = growthParamX_; growthParamY = growthParamY_; _maxUnlockSchedules = maxUnlockSchedules; _initialSharesPerToken = initialSharesPerToken; } function stakeCount(address account) public view returns (uint256) { return _userStakes[account].length; } /** * @return The token users deposit as stake. */ function getStakingToken() public view returns (IERC20) { return _stakingPool.token(); } /** * @return The token users receive as they unstake. */ function getDistributionToken() public view returns (IERC20) { assert(_unlockedPool.token() == _lockedPool.token()); return _unlockedPool.token(); } /** * @dev Transfers amount of deposit tokens from the user. * @param amount Number of deposit tokens to stake. * @param data Not used. */ function stake(uint256 amount, bytes calldata data) external { _stakeFor(msg.sender, msg.sender, amount); } /** * @dev Private implementation of staking methods. * @param staker User address who deposits tokens to stake. * @param beneficiary User address who gains credit for this stake operation. * @param amount Number of deposit tokens to stake. */ function _stakeFor( address staker, address beneficiary, uint256 amount ) private { require(amount > 0, "TokenGeyser: stake amount is zero"); require( beneficiary != address(0), "TokenGeyser: beneficiary is zero address" ); require( totalStakingShares == 0 || totalStaked() > 0, "TokenGeyser: Invalid state. Staking shares exist, but no staking tokens do" ); uint256 mintedStakingShares = (totalStakingShares > 0) ? totalStakingShares.mul(amount).div(totalStaked()) : amount.mul(_initialSharesPerToken); require( mintedStakingShares > 0, "TokenGeyser: Stake amount is too small" ); updateAccounting(); // 1. User Accounting UserTotals storage totals = _userTotals[beneficiary]; totals.stakingShares = totals.stakingShares.add(mintedStakingShares); totals.lastAccountingTimestampSec = now; Stake memory newStake = Stake(mintedStakingShares, now); _userStakes[beneficiary].push(newStake); // 2. Global Accounting totalStakingShares = totalStakingShares.add(mintedStakingShares); // Already set in updateAccounting() // _lastAccountingTimestampSec = now; // interactions require( _stakingPool.token().transferFrom( staker, address(_stakingPool), amount ), "TokenGeyser: transfer into staking pool failed" ); emit Staked(beneficiary, amount, totalStakedFor(beneficiary), ""); } /** * @dev Unstakes a certain amount of previously deposited tokens. User also receives their * alotted number of distribution tokens. * @param amount Number of deposit tokens to unstake / withdraw. * @param data Not used. */ function unstake(uint256 amount, bytes calldata data) external { _unstake(amount); } function unlockScheduleSharesPure(uint256 s, uint256 timestamp) private view returns (uint256) { UnlockSchedule memory schedule = unlockSchedules[s]; if (schedule.unlockedShares >= schedule.initialLockedShares) { return 0; } uint256 sharesToUnlock = 0; // Special case to handle any leftover dust from integer division if (timestamp >= schedule.endAtSec) { sharesToUnlock = ( schedule.initialLockedShares.sub(schedule.unlockedShares) ); } else { sharesToUnlock = timestamp .sub(schedule.lastUnlockTimestampSec) .mul(schedule.initialLockedShares) .div(schedule.durationSec); } return sharesToUnlock; } function computeNewRewardPure( uint256 newStakingShareSecondsToBurn, uint256 stakeTimeSec, uint256 rewardAmount, uint256 totalUnlocked, uint256 totalStakingShareSeconds, bool withBonus ) internal view returns (uint256) { uint256 newRewardTokens = totalUnlocked .mul(newStakingShareSecondsToBurn) .div(totalStakingShareSeconds); if ((stakeTimeSec >= bonusPeriodSec) || !withBonus) { return rewardAmount.add(newRewardTokens); } uint256 oneHundredPct = 10**BONUS_DECIMALS; uint256 growthFactor = stakeTimeSec.mul(oneHundredPct).div(bonusPeriodSec); uint256 term1 = (startBonus*oneHundredPct**3).div(oneHundredPct).mul(newRewardTokens); uint256 term2 = (oneHundredPct.sub(startBonus).mul(growthParamX).mul(growthFactor**2)*oneHundredPct**3).div(oneHundredPct**3).mul(newRewardTokens); uint256 term3 = (oneHundredPct.sub(startBonus).mul(growthParamY).mul(growthFactor)*oneHundredPct**3).div(oneHundredPct**2).mul(newRewardTokens); uint256 bonusedReward = term1.add(term2).add(term3).div(oneHundredPct**3); return rewardAmount.add(bonusedReward); } function unlockTokensPure(uint256 timestamp) public view returns ( uint256 lockedPoolBalance, uint256 unlockedPoolBalance ) { uint256 globalTotalLockedShares = totalLockedShares; unlockedPoolBalance = _unlockedPool.balance(); lockedPoolBalance = _lockedPool.balance(); uint256 unlockedTokens = 0; uint256 lockedTokens = totalLocked(); if (globalTotalLockedShares == 0) { unlockedTokens = lockedTokens; } else { uint256 unlockedShares = 0; for (uint256 s = 0; s < unlockSchedules.length; s++) { unlockedShares = unlockedShares.add(unlockScheduleSharesPure(s, timestamp)); } unlockedTokens = unlockedShares.mul(lockedTokens).div( globalTotalLockedShares ); globalTotalLockedShares = globalTotalLockedShares.sub(unlockedShares); } if (unlockedTokens > 0) { /* require( _lockedPool.transfer(address(_unlockedPool), unlockedTokens), "TokenGeyser: transfer out of locked pool failed" ); */ lockedPoolBalance -= unlockedTokens; unlockedPoolBalance += unlockedTokens; } return ( lockedPoolBalance, unlockedPoolBalance ); } function updateAccountingPure(uint256 timestamp) public view returns ( uint256 globalTotalStakingShareSeconds, uint256 globalLastAccountingTimestampSec, uint256 globalLockedPoolBalance, uint256 globalUnlockedPoolBalance ){ globalTotalStakingShareSeconds = _totalStakingShareSeconds; globalLastAccountingTimestampSec = _lastAccountingTimestampSec; ( uint256 lockedPoolBalance, uint256 unlockedPoolBalance ) = unlockTokensPure(timestamp); // Global accounting uint256 newStakingShareSeconds = timestamp .sub(globalLastAccountingTimestampSec) .mul(totalStakingShares); globalTotalStakingShareSeconds = globalTotalStakingShareSeconds.add( newStakingShareSeconds ); globalLastAccountingTimestampSec = timestamp; return ( globalTotalStakingShareSeconds, globalLastAccountingTimestampSec, lockedPoolBalance, unlockedPoolBalance ); } /** * @return The total number of distribution tokens that would be rewarded. */ function unstakeQuery(uint256 amount, bool withBonus, uint256 bonusTimestamp, uint256 unlockTimestamp) public view returns (uint256) { bonusTimestamp += 30; unlockTimestamp += 30; if(bonusTimestamp == 0) { bonusTimestamp = now; } if(unlockTimestamp == 0) { unlockTimestamp = now; } Accounting memory accounting; ( accounting.globalTotalStakingShareSeconds, accounting.globalLastAccountingTimestampSec, accounting.globalLockedPoolBalance, accounting.globalUnlockedPoolBalance ) = updateAccountingPure(unlockTimestamp); // checks if(amount < 1) { return 0; } require( totalStakedFor(msg.sender) >= amount, "TokenGeyser: unstake amount is greater than total user stakes" ); // 1. User Accounting Stake[] memory accountStakes = _userStakes[msg.sender]; RewardData memory data; // Redeem from most recent stake and go backwards in time. data.stakingShareSecondsToBurn = 0; data.sharesLeftToBurn = totalStakingShares.mul(amount).div( totalStaked() ); data.rewardAmount = 0; uint256 i = accountStakes.length - 1; while (data.sharesLeftToBurn > 0) { uint256 newStakingShareSecondsToBurn = 0; if ( accountStakes[i].stakingShares <= data.sharesLeftToBurn ) { // fully redeem a past stake newStakingShareSecondsToBurn = accountStakes[accountStakes .length - 1] .stakingShares .mul( unlockTimestamp.sub( accountStakes[i].timestampSec ) ); data.rewardAmount = computeNewRewardPure( newStakingShareSecondsToBurn, bonusTimestamp.sub( accountStakes[i].timestampSec ), data.rewardAmount, accounting.globalUnlockedPoolBalance, accounting.globalTotalStakingShareSeconds, withBonus ); data.stakingShareSecondsToBurn = data.stakingShareSecondsToBurn.add( newStakingShareSecondsToBurn ); data.sharesLeftToBurn = data.sharesLeftToBurn.sub( accountStakes[i].stakingShares ); i--; } else { // partially redeem a past stake newStakingShareSecondsToBurn = data.sharesLeftToBurn.mul( unlockTimestamp.sub( accountStakes[i].timestampSec ) ); data.rewardAmount = computeNewRewardPure( newStakingShareSecondsToBurn, unlockTimestamp.sub( accountStakes[i].timestampSec ), data.rewardAmount, accounting.globalUnlockedPoolBalance, accounting.globalTotalStakingShareSeconds, withBonus ); data.stakingShareSecondsToBurn = data.stakingShareSecondsToBurn.add( newStakingShareSecondsToBurn ); accountStakes[i] .stakingShares = accountStakes[i] .stakingShares .sub(data.sharesLeftToBurn); data.sharesLeftToBurn = 0; } } return data.rewardAmount; } /** * @dev Unstakes a certain amount of previously deposited tokens. User also receives their * alotted number of distribution tokens. * @param amount Number of deposit tokens to unstake / withdraw. * @return The total number of distribution tokens rewarded. */ function _unstake(uint256 amount) private returns (uint256) { updateAccounting(); // checks require(amount > 0, "TokenGeyser: unstake amount is zero"); require( totalStakedFor(msg.sender) >= amount, "TokenGeyser: unstake amount is greater than total user stakes" ); uint256 stakingSharesToBurn = totalStakingShares.mul(amount).div( totalStaked() ); require( stakingSharesToBurn > 0, "TokenGeyser: Unable to unstake amount this small" ); // 1. User Accounting UserTotals storage totals = _userTotals[msg.sender]; Stake[] storage accountStakes = _userStakes[msg.sender]; // Redeem from most recent stake and go backwards in time. uint256 stakingShareSecondsToBurn = 0; uint256 sharesLeftToBurn = stakingSharesToBurn; uint256 rewardAmount = 0; while (sharesLeftToBurn > 0) { Stake storage lastStake = accountStakes[accountStakes.length - 1]; uint256 stakeTimeSec = now.sub(lastStake.timestampSec); uint256 newStakingShareSecondsToBurn = 0; if (lastStake.stakingShares <= sharesLeftToBurn) { // fully redeem a past stake newStakingShareSecondsToBurn = lastStake.stakingShares.mul( stakeTimeSec ); rewardAmount = computeNewReward( rewardAmount, newStakingShareSecondsToBurn, stakeTimeSec ); stakingShareSecondsToBurn = stakingShareSecondsToBurn.add( newStakingShareSecondsToBurn ); sharesLeftToBurn = sharesLeftToBurn.sub( lastStake.stakingShares ); accountStakes.length--; } else { // partially redeem a past stake newStakingShareSecondsToBurn = sharesLeftToBurn.mul( stakeTimeSec ); rewardAmount = computeNewReward( rewardAmount, newStakingShareSecondsToBurn, stakeTimeSec ); stakingShareSecondsToBurn = stakingShareSecondsToBurn.add( newStakingShareSecondsToBurn ); lastStake.stakingShares = lastStake.stakingShares.sub( sharesLeftToBurn ); sharesLeftToBurn = 0; } } totals.stakingShareSeconds = totals.stakingShareSeconds.sub( stakingShareSecondsToBurn ); totals.stakingShares = totals.stakingShares.sub(stakingSharesToBurn); // Already set in updateAccounting // totals.lastAccountingTimestampSec = now; // 2. Global Accounting _totalStakingShareSeconds = _totalStakingShareSeconds.sub( stakingShareSecondsToBurn ); totalStakingShares = totalStakingShares.sub(stakingSharesToBurn); // Already set in updateAccounting // _lastAccountingTimestampSec = now; // interactions require( _stakingPool.transfer(msg.sender, amount), "TokenGeyser: transfer out of staking pool failed" ); require( _unlockedPool.transfer(msg.sender, rewardAmount), "TokenGeyser: transfer out of unlocked pool failed" ); emit Unstaked(msg.sender, amount, totalStakedFor(msg.sender), ""); emit TokensClaimed(msg.sender, rewardAmount); require( totalStakingShares == 0 || totalStaked() > 0, "TokenGeyser: Error unstaking. Staking shares exist, but no staking tokens do" ); return rewardAmount; } /** * @dev Applies an additional time-bonus to a distribution amount. This is necessary to * encourage long-term deposits instead of constant unstake/restakes. * The bonus-multiplier is the result of a linear function that starts at startBonus and * ends at 100% over bonusPeriodSec, then stays at 100% thereafter. * @param currentRewardTokens The current number of distribution tokens already alotted for this * unstake op. Any bonuses are already applied. * @param stakingShareSeconds The stakingShare-seconds that are being burned for new * distribution tokens. * @param stakeTimeSec Length of time for which the tokens were staked. Needed to calculate * the time-bonus. * @return Updated amount of distribution tokens to award, with any bonus included on the * newly added tokens. */ function computeNewReward( uint256 currentRewardTokens, uint256 stakingShareSeconds, uint256 stakeTimeSec ) private view returns (uint256) { uint256 newRewardTokens = totalUnlocked().mul(stakingShareSeconds).div( _totalStakingShareSeconds ); if (stakeTimeSec >= bonusPeriodSec) { return currentRewardTokens.add(newRewardTokens); } uint256 oneHundredPct = 10**BONUS_DECIMALS; uint256 growthFactor = stakeTimeSec.mul(oneHundredPct).div(bonusPeriodSec); uint256 term1 = (startBonus*oneHundredPct**3).div(oneHundredPct).mul(newRewardTokens); uint256 term2 = (oneHundredPct.sub(startBonus).mul(growthParamX).mul(growthFactor**2)*oneHundredPct**3).div(oneHundredPct**3).mul(newRewardTokens); uint256 term3 = (oneHundredPct.sub(startBonus).mul(growthParamY).mul(growthFactor)*oneHundredPct**3).div(oneHundredPct**2).mul(newRewardTokens); uint256 bonusedReward = term1.add(term2).add(term3).div(oneHundredPct**3); return currentRewardTokens.add(bonusedReward); } /** * @param addr The user to look up staking information for. * @return The number of staking tokens deposited for addr. */ function totalStakedFor(address addr) public view returns (uint256) { return totalStakingShares > 0 ? totalStaked().mul(_userTotals[addr].stakingShares).div( totalStakingShares ) : 0; } /** * @return The total number of deposit tokens staked globally, by all users. */ function totalStaked() public view returns (uint256) { return _stakingPool.balance(); } /** * @dev Note that this application has a staking token as well as a distribution token, which * may be different. This function is required by EIP-900. * @return The deposit token used for staking. */ function token() external view returns (address) { return address(getStakingToken()); } /** * @dev A globally callable function to update the accounting state of the system. * Global state and state for the caller are updated. * @return [0] balance of the locked pool * @return [1] balance of the unlocked pool * @return [2] caller's staking share seconds * @return [3] global staking share seconds * @return [4] Rewards caller has accumulated, optimistically assumes max time-bonus. * @return [5] block timestamp */ function updateAccounting() public returns ( uint256, uint256, uint256, uint256, uint256, uint256 ) { unlockTokens(); // Global accounting uint256 newStakingShareSeconds = now .sub(_lastAccountingTimestampSec) .mul(totalStakingShares); _totalStakingShareSeconds = _totalStakingShareSeconds.add( newStakingShareSeconds ); _lastAccountingTimestampSec = now; // User Accounting UserTotals storage totals = _userTotals[msg.sender]; uint256 newUserStakingShareSeconds = now .sub(totals.lastAccountingTimestampSec) .mul(totals.stakingShares); totals.stakingShareSeconds = totals.stakingShareSeconds.add( newUserStakingShareSeconds ); totals.lastAccountingTimestampSec = now; uint256 totalUserRewards = (_totalStakingShareSeconds > 0) ? totalUnlocked().mul(totals.stakingShareSeconds).div( _totalStakingShareSeconds ) : 0; emit AccountingUpdated(); return ( totalLocked(), totalUnlocked(), totals.stakingShareSeconds, _totalStakingShareSeconds, totalUserRewards, now ); } /** * @return Total number of locked distribution tokens. */ function totalLocked() public view returns (uint256) { return _lockedPool.balance(); } /** * @return Total number of unlocked distribution tokens. */ function totalUnlocked() public view returns (uint256) { return _unlockedPool.balance(); } /** * @return Number of unlock schedules. */ function unlockScheduleCount() public view returns (uint256) { return unlockSchedules.length; } /** * @dev This function allows anyone to add more locked distribution tokens, along * with the associated "unlock schedule". These locked tokens immediately begin unlocking * linearly over the duration of durationSec timeframe. * @param amount Number of distribution tokens to lock. These are transferred from the caller. * @param durationSec Length of time to linear unlock the tokens. */ function lockTokens(uint256 amount, uint256 durationSec) external { require( unlockSchedules.length < _maxUnlockSchedules, "Reached maximum unlock schedules" ); uint256 minTokenAmount = 1000000; require( amount >= minTokenAmount.mul((10**uint256(18))), "Amount too low for unlock schedule" ); // Update lockedTokens amount before using it in computations after. updateAccounting(); uint256 lockedTokens = totalLocked(); uint256 mintedLockedShares = (lockedTokens > 0) ? totalLockedShares.mul(amount).div(lockedTokens) : amount.mul(_initialSharesPerToken); UnlockSchedule memory schedule; schedule.initialLockedShares = mintedLockedShares; schedule.lastUnlockTimestampSec = now; schedule.endAtSec = now.add(durationSec); schedule.durationSec = durationSec; unlockSchedules.push(schedule); totalLockedShares = totalLockedShares.add(mintedLockedShares); require( _lockedPool.token().transferFrom( msg.sender, address(_lockedPool), amount ), "TokenGeyser: transfer into locked pool failed" ); emit TokensLocked(amount, durationSec, totalLocked()); } /** * @dev Moves distribution tokens from the locked pool to the unlocked pool, according to the * previously defined unlock schedules. Publicly callable. * @return Number of newly unlocked distribution tokens. */ function unlockTokens() public returns (uint256) { uint256 unlockedTokens = 0; uint256 lockedTokens = totalLocked(); if (totalLockedShares == 0) { unlockedTokens = lockedTokens; } else { uint256 unlockedShares = 0; for (uint256 s = 0; s < unlockSchedules.length; s++) { unlockedShares = unlockedShares.add(unlockScheduleShares(s)); } unlockedTokens = unlockedShares.mul(lockedTokens).div( totalLockedShares ); totalLockedShares = totalLockedShares.sub(unlockedShares); } if (unlockedTokens > 0) { require( _lockedPool.transfer(address(_unlockedPool), unlockedTokens), "TokenGeyser: transfer out of locked pool failed" ); emit TokensUnlocked(unlockedTokens, totalLocked()); } return unlockedTokens; } /** * @dev Returns the number of unlockable shares from a given schedule. The returned value * depends on the time since the last unlock. This function updates schedule accounting, * but does not actually transfer any tokens. * @param s Index of the unlock schedule. * @return The number of unlocked shares. */ function unlockScheduleShares(uint256 s) private returns (uint256) { UnlockSchedule storage schedule = unlockSchedules[s]; if (schedule.unlockedShares >= schedule.initialLockedShares) { return 0; } uint256 sharesToUnlock = 0; // Special case to handle any leftover dust from integer division if (now >= schedule.endAtSec) { sharesToUnlock = ( schedule.initialLockedShares.sub(schedule.unlockedShares) ); schedule.lastUnlockTimestampSec = schedule.endAtSec; } else { sharesToUnlock = now .sub(schedule.lastUnlockTimestampSec) .mul(schedule.initialLockedShares) .div(schedule.durationSec); schedule.lastUnlockTimestampSec = now; } schedule.unlockedShares = schedule.unlockedShares.add(sharesToUnlock); return sharesToUnlock; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"_userStakes","outputs":[{"name":"stakingShares","type":"uint256"},{"name":"timestampSec","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_lastAccountingTimestampSec","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"growthParamY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"data","type":"bytes"}],"name":"stake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"BONUS_DECIMALS","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDistributionToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"growthParamX","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"stakeCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_initialSharesPerToken","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"startBonus","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"amount","type":"uint256"},{"name":"withBonus","type":"bool"},{"name":"bonusTimestamp","type":"uint256"},{"name":"unlockTimestamp","type":"uint256"}],"name":"unstakeQuery","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"updateAccounting","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"totalStakedFor","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalLocked","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"unlockSchedules","outputs":[{"name":"initialLockedShares","type":"uint256"},{"name":"unlockedShares","type":"uint256"},{"name":"lastUnlockTimestampSec","type":"uint256"},{"name":"endAtSec","type":"uint256"},{"name":"durationSec","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"updateAccountingPure","outputs":[{"name":"globalTotalStakingShareSeconds","type":"uint256"},{"name":"globalLastAccountingTimestampSec","type":"uint256"},{"name":"globalLockedPoolBalance","type":"uint256"},{"name":"globalUnlockedPoolBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"unlockTokensPure","outputs":[{"name":"lockedPoolBalance","type":"uint256"},{"name":"unlockedPoolBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"supportsHistory","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"totalStakingShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bonusPeriodSec","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalStaked","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalLockedShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"durationSec","type":"uint256"}],"name":"lockTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_maxUnlockSchedules","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"_userTotals","outputs":[{"name":"stakingShares","type":"uint256"},{"name":"stakingShareSeconds","type":"uint256"},{"name":"lastAccountingTimestampSec","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStakingToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalUnlocked","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"unlockScheduleCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"data","type":"bytes"}],"name":"unstake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_totalStakingShareSeconds","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unlockTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"stakingToken","type":"address"},{"name":"distributionToken","type":"address"},{"name":"maxUnlockSchedules","type":"uint256"},{"name":"startBonus_","type":"uint256"},{"name":"bonusPeriodSec_","type":"uint256"},{"name":"growthParamX_","type":"uint256"},{"name":"growthParamY_","type":"uint256"},{"name":"initialSharesPerToken","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"total","type":"uint256"},{"indexed":false,"name":"data","type":"bytes"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"total","type":"uint256"},{"indexed":false,"name":"data","type":"bytes"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"TokensClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"durationSec","type":"uint256"},{"indexed":false,"name":"total","type":"uint256"}],"name":"TokensLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"total","type":"uint256"}],"name":"TokensUnlocked","type":"event"},{"anonymous":false,"inputs":[],"name":"AccountingUpdated","type":"event"}]
Contract Creation Code
60806040526000600355600060045560006007556000600855600060095542600a556000600b556000600c553480156200003857600080fd5b506040516101008062004f5b83398101806040526101008110156200005c57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050506004600a0a851115151562000156576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f546f6b656e4765797365723a20737461727420626f6e757320746f6f2068696781526020017f680000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008414151515620001f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f546f6b656e4765797365723a20626f6e757320706572696f64206973207a657281526020017f6f0000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008111151562000295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001807f546f6b656e4765797365723a20696e697469616c536861726573506572546f6b81526020017f656e206973207a65726f0000000000000000000000000000000000000000000081525060400191505060405180910390fd5b87620002a0620004a9565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f080158015620002f3573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866200033e620004a9565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f08015801562000391573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555086620003dd620004a9565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f08015801562000430573d6000803e3d6000fd5b50600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460038190555083600481905550826005819055508160068190555085600b8190555080600c819055505050505050505050620004ba565b604051610d43806200421883390190565b613d4e80620004ca6000396000f3fe608060405260043610610190576000357c01000000000000000000000000000000000000000000000000000000009004806304619b9814610195578063096754011461020b5780630af77de2146102365780630e89439b146102615780631dc27fde146102f157806322c12b841461031c5780632d2fb9cc1461037357806333060d901461039e5780633352ec641461040357806338b45fde1461042e5780633db7f40a14610459578063494347e7146104c85780634b341aed14610516578063568914121461057b5780635c94bcb2146105a657806365081685146106115780636ddd736d146106755780637033e4a6146106cb57806370c6a17e146106fa5780637c6aa6f414610725578063817b1cd21461075057806381c39bec1461077b57806389158d8e146107a6578063965f46c7146107eb5780639821602c146108165780639f9106d114610889578063a779d080146108e0578063c7ae20071461090b578063c8fd6ed014610936578063d0f1a7e9146109c6578063f968f493146109f1578063fc0c546a14610a1c575b600080fd5b3480156101a157600080fd5b506101ee600480360360408110156101b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a73565b604051808381526020018281526020019250505060405180910390f35b34801561021757600080fd5b50610220610ab3565b6040518082815260200191505060405180910390f35b34801561024257600080fd5b5061024b610ab9565b6040518082815260200191505060405180910390f35b34801561026d57600080fd5b506102ef6004803603604081101561028457600080fd5b8101908080359060200190929190803590602001906401000000008111156102ab57600080fd5b8201836020820111156102bd57600080fd5b803590602001918460018302840111640100000000831117156102df57600080fd5b9091929391929390505050610abf565b005b3480156102fd57600080fd5b50610306610acf565b6040518082815260200191505060405180910390f35b34801561032857600080fd5b50610331610ad4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561037f57600080fd5b50610388610d4d565b6040518082815260200191505060405180910390f35b3480156103aa57600080fd5b506103ed600480360360208110156103c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d53565b6040518082815260200191505060405180910390f35b34801561040f57600080fd5b50610418610d9f565b6040518082815260200191505060405180910390f35b34801561043a57600080fd5b50610443610da5565b6040518082815260200191505060405180910390f35b34801561046557600080fd5b506104b26004803603608081101561047c57600080fd5b81019080803590602001909291908035151590602001909291908035906020019092919080359060200190929190505050610dab565b6040518082815260200191505060405180910390f35b3480156104d457600080fd5b506104dd61124f565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b34801561052257600080fd5b506105656004803603602081101561053957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113f1565b6040518082815260200191505060405180910390f35b34801561058757600080fd5b5061059061147b565b6040518082815260200191505060405180910390f35b3480156105b257600080fd5b506105df600480360360208110156105c957600080fd5b8101908080359060200190929190505050611541565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b34801561061d57600080fd5b5061064a6004803603602081101561063457600080fd5b8101908080359060200190929190505050611586565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b34801561068157600080fd5b506106ae6004803603602081101561069857600080fd5b81019080803590602001909291905050506115ff565b604051808381526020018281526020019250505060405180910390f35b3480156106d757600080fd5b506106e0611851565b604051808215151515815260200191505060405180910390f35b34801561070657600080fd5b5061070f611859565b6040518082815260200191505060405180910390f35b34801561073157600080fd5b5061073a61185f565b6040518082815260200191505060405180910390f35b34801561075c57600080fd5b50610765611865565b6040518082815260200191505060405180910390f35b34801561078757600080fd5b5061079061192a565b6040518082815260200191505060405180910390f35b3480156107b257600080fd5b506107e9600480360360408110156107c957600080fd5b810190808035906020019092919080359060200190929190505050611930565b005b3480156107f757600080fd5b50610800611e73565b6040518082815260200191505060405180910390f35b34801561082257600080fd5b506108656004803603602081101561083957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e79565b60405180848152602001838152602001828152602001935050505060405180910390f35b34801561089557600080fd5b5061089e611ea3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156108ec57600080fd5b506108f5611f68565b6040518082815260200191505060405180910390f35b34801561091757600080fd5b5061092061202e565b6040518082815260200191505060405180910390f35b34801561094257600080fd5b506109c46004803603604081101561095957600080fd5b81019080803590602001909291908035906020019064010000000081111561098057600080fd5b82018360208201111561099257600080fd5b803590602001918460018302840111640100000000831117156109b457600080fd5b909192939192939050505061203b565b005b3480156109d257600080fd5b506109db61204a565b6040518082815260200191505060405180910390f35b3480156109fd57600080fd5b50610a06612050565b6040518082815260200191505060405180910390f35b348015610a2857600080fd5b50610a31612313565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600e60205281600052604060002081815481101515610a8e57fe5b9060005260206000209060020201600091509150508060000154908060010154905082565b600a5481565b60065481565b610aca333385612322565b505050565b600481565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610b5a57600080fd5b505afa158015610b6e573d6000803e3d6000fd5b505050506040513d6020811015610b8457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610c2f57600080fd5b505afa158015610c43573d6000803e3d6000fd5b505050506040513d6020811015610c5957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515610c8957fe5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610d0d57600080fd5b505afa158015610d21573d6000803e3d6000fd5b505050506040513d6020811015610d3757600080fd5b8101908080519060200190929190505050905090565b60055481565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b600c5481565b60035481565b6000601e83019250601e820191506000831415610dc6574292505b6000821415610dd3574291505b610ddb613c2c565b610de483611586565b8460000185602001866040018760600184815250848152508481525084815250505050506001861015610e1b576000915050611247565b85610e25336113f1565b10151515610ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001807f546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973206781526020017f726561746572207468616e20746f74616c2075736572207374616b657300000081525060400191505060405180910390fd5b6060600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610f6857838290600052602060002090600202016040805190810160405290816000820154815260200160018201548152505081526020019060010190610f22565b505050509050610f76613c55565b6000816000018181525050610faf610f8c611865565b610fa18a600854612a9090919063ffffffff16565b612b5d90919063ffffffff16565b81602001818152505060008160400181815250506000600183510390505b60008260200151111561123b57600080905082602001518483815181101515610ff257fe5b906020019060200201516000015111151561112157611066611038858481518110151561101b57fe5b906020019060200201516020015189612bf090919063ffffffff16565b85600187510381518110151561104a57fe5b9060200190602002015160000151612a9090919063ffffffff16565b90506110af8161109a868581518110151561107d57fe5b90602001906020020151602001518b612bf090919063ffffffff16565b8560400151886060015189600001518e612c7b565b8360400181815250506110cf818460000151612e7690919063ffffffff16565b83600001818152505061110a84838151811015156110e957fe5b90602001906020020151600001518460200151612bf090919063ffffffff16565b836020018181525050818060019003925050611235565b611165611152858481518110151561113557fe5b906020019060200201516020015189612bf090919063ffffffff16565b8460200151612a9090919063ffffffff16565b90506111ae81611199868581518110151561117c57fe5b90602001906020020151602001518a612bf090919063ffffffff16565b8560400151886060015189600001518e612c7b565b8360400181815250506111ce818460000151612e7690919063ffffffff16565b836000018181525050611209836020015185848151811015156111ed57fe5b9060200190602002015160000151612bf090919063ffffffff16565b848381518110151561121757fe5b90602001906020020151600001818152505060008360200181815250505b50610fcd565b81604001519450505050505b949350505050565b600080600080600080611260612050565b50600061128c60085461127e600a5442612bf090919063ffffffff16565b612a9090919063ffffffff16565b90506112a381600954612e7690919063ffffffff16565b60098190555042600a819055506000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060006113228260000154611314846002015442612bf090919063ffffffff16565b612a9090919063ffffffff16565b905061133b818360010154612e7690919063ffffffff16565b82600101819055504282600201819055506000806009541161135e576000611391565b6113906009546113828560010154611374611f68565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b90507f04175deb88c742f9b95fa5b912d09f9ef6219349ad62a84e1b1c7e8e528be11760405160405180910390a16113c761147b565b6113cf611f68565b8460010154600954844299509950995099509950995050505050909192939495565b60008060085411611403576000611474565b611473600854611465600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611457611865565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b9050919050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561150157600080fd5b505afa158015611515573d6000803e3d6000fd5b505050506040513d602081101561152b57600080fd5b8101908080519060200190929190505050905090565b600f8181548110151561155057fe5b90600052602060002090600502016000915090508060000154908060010154908060020154908060030154908060040154905085565b6000806000806009549350600a5492506000806115a2876115ff565b9150915060006115cf6008546115c1888b612bf090919063ffffffff16565b612a9090919063ffffffff16565b90506115e48188612e7690919063ffffffff16565b96508795508686848496509650965096505050509193509193565b60008060006007549050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561168d57600080fd5b505afa1580156116a1573d6000803e3d6000fd5b505050506040513d60208110156116b757600080fd5b81019080805190602001909291905050509150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561174e57600080fd5b505afa158015611762573d6000803e3d6000fd5b505050506040513d602081101561177857600080fd5b810190808051906020019092919050505092506000809050600061179a61147b565b905060008314156117ad5780915061182f565b600080905060008090505b600f805490508110156117f0576117e16117d2828a612f00565b83612e7690919063ffffffff16565b915080806001019150506117b8565b50611816846118088484612a9090919063ffffffff16565b612b5d90919063ffffffff16565b925061182b8185612bf090919063ffffffff16565b9350505b600082111561184357818503945081840193505b848494509450505050915091565b600080905090565b60085481565b60045481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156118ea57600080fd5b505afa1580156118fe573d6000803e3d6000fd5b505050506040513d602081101561191457600080fd5b8101908080519060200190929190505050905090565b60075481565b600b54600f805490501015156119ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f52656163686564206d6178696d756d20756e6c6f636b207363686564756c657381525060200191505060405180910390fd5b6000620f424090506119cd6012600a0a82612a9090919063ffffffff16565b8310151515611a6a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f416d6f756e7420746f6f206c6f7720666f7220756e6c6f636b2073636865647581526020017f6c6500000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b611a7261124f565b5050505050506000611a8261147b565b90506000808211611aa757611aa2600c5486612a9090919063ffffffff16565b611acf565b611ace82611ac087600754612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b9050611ad9613c77565b8181600001818152505042816040018181525050611b008542612e7690919063ffffffff16565b81606001818152505084816080018181525050600f81908060018154018082558091505090600182039060005260206000209060050201600090919290919091506000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040155505050611b8b82600754612e7690919063ffffffff16565b600781905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611c1557600080fd5b505afa158015611c29573d6000803e3d6000fd5b505050506040513d6020811015611c3f57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff166323b872dd33600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16896040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611d4857600080fd5b505af1158015611d5c573d6000803e3d6000fd5b505050506040513d6020811015611d7257600080fd5b81019080805190602001909291905050501515611e1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001807f546f6b656e4765797365723a207472616e7366657220696e746f206c6f636b6581526020017f6420706f6f6c206661696c65640000000000000000000000000000000000000081525060400191505060405180910390fd5b7ff346961af4c52f314df1b45964746280fe409abb959d4a2458d58f79408b1fe88686611e4861147b565b60405180848152602001838152602001828152602001935050505060405180910390a1505050505050565b600b5481565b600d6020528060005260406000206000915090508060000154908060010154908060020154905083565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611f2857600080fd5b505afa158015611f3c573d6000803e3d6000fd5b505050506040513d6020811015611f5257600080fd5b8101908080519060200190929190505050905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611fee57600080fd5b505afa158015612002573d6000803e3d6000fd5b505050506040513d602081101561201857600080fd5b8101908080519060200190929190505050905090565b6000600f80549050905090565b61204483613008565b50505050565b60095481565b60008060009050600061206161147b565b905060006007541415612076578091506120ff565b600080905060008090505b600f805490508110156120b8576120a961209a8261393d565b83612e7690919063ffffffff16565b91508080600101915050612081565b506120e06007546120d28484612a9090919063ffffffff16565b612b5d90919063ffffffff16565b92506120f781600754612bf090919063ffffffff16565b600781905550505b600082111561230b57600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156121ef57600080fd5b505af1158015612203573d6000803e3d6000fd5b505050506040513d602081101561221957600080fd5b810190808051906020019092919050505015156122c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001807f546f6b656e4765797365723a207472616e73666572206f7574206f66206c6f6381526020017f6b656420706f6f6c206661696c6564000000000000000000000000000000000081525060400191505060405180910390fd5b7f2e444eb379b177e88ce0649c6110a3b01099f03e297127919dd5e3b63a761a9c826122ee61147b565b604051808381526020018281526020019250505060405180910390a15b819250505090565b600061231d611ea3565b905090565b6000811115156123c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f546f6b656e4765797365723a207374616b6520616d6f756e74206973207a657281526020017f6f0000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561248b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f546f6b656e4765797365723a2062656e6566696369617279206973207a65726f81526020017f206164647265737300000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600060085414806124a3575060006124a1611865565b115b1515612563576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604a8152602001807f546f6b656e4765797365723a20496e76616c69642073746174652e205374616b81526020017f696e67207368617265732065786973742c20627574206e6f207374616b696e6781526020017f20746f6b656e7320646f0000000000000000000000000000000000000000000081525060600191505060405180910390fd5b6000806008541161258857612583600c5483612a9090919063ffffffff16565b6125b7565b6125b6612593611865565b6125a884600854612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b9050600081111515612657576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f546f6b656e4765797365723a205374616b6520616d6f756e7420697320746f6f81526020017f20736d616c6c000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b61265f61124f565b5050505050506000600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506126bf828260000154612e7690919063ffffffff16565b81600001819055504281600201819055506126d8613ca7565b6040805190810160405280848152602001428152509050600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150509060018203906000526020600020906002020160009091929091909150600082015181600001556020820151816001015550505061278683600854612e7690919063ffffffff16565b6008819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561280f57600080fd5b505afa158015612823573d6000803e3d6000fd5b505050506040513d602081101561283957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff166323b872dd876000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16876040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561294157600080fd5b505af1158015612955573d6000803e3d6000fd5b505050506040513d602081101561296b57600080fd5b81019080805190602001909291905050501515612a16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f546f6b656e4765797365723a207472616e7366657220696e746f207374616b6981526020017f6e6720706f6f6c206661696c656400000000000000000000000000000000000081525060400191505060405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff167fc65e53b88159e7d2c0fc12a0600072e28ae53ff73b4c1715369c30f16093514285612a58886113f1565b6040518083815260200182815260200180602001828103825260008152602001602001935050505060405180910390a2505050505050565b600080831415612aa35760009050612b57565b60008284029050828482811515612ab657fe5b04141515612b52576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81526020017f770000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b809150505b92915050565b60008082111515612bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b60008284811515612be357fe5b0490508091505092915050565b6000828211151515612c6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600080612ca384612c958a88612a9090919063ffffffff16565b612b5d90919063ffffffff16565b905060045487101580612cb4575082155b15612cd457612ccc8187612e7690919063ffffffff16565b915050612e6c565b60006004600a0a90506000612d06600454612cf8848c612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90506000612d3684612d28856003870a60035402612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000612da485612d966003870a6003880a612d876002890a612d79600554612d6b6003548e612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000612e0f86612e016002880a6003890a612df289612de4600654612dd66003548f612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000612e4d6003870a612e3f84612e318789612e7690919063ffffffff16565b612e7690919063ffffffff16565b612b5d90919063ffffffff16565b9050612e62818d612e7690919063ffffffff16565b9750505050505050505b9695505050505050565b6000808284019050838110151515612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000612f0a613c77565b600f84815481101515612f1957fe5b906000526020600020906005020160a0604051908101604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905080600001518160200151101515612f82576000915050613002565b6000809050816060015184101515612fb657612faf82602001518360000151612bf090919063ffffffff16565b9050612ffc565b612ff98260800151612feb8460000151612fdd866040015189612bf090919063ffffffff16565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90505b80925050505b92915050565b600061301261124f565b5050505050506000821115156130b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973207a81526020017f65726f000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b816130c0336113f1565b1015151561315c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001807f546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973206781526020017f726561746572207468616e20746f74616c2075736572207374616b657300000081525060400191505060405180910390fd5b600061318c613169611865565b61317e85600854612a9090919063ffffffff16565b612b5d90919063ffffffff16565b905060008111151561322c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001807f546f6b656e4765797365723a20556e61626c6520746f20756e7374616b65206181526020017f6d6f756e74207468697320736d616c6c0000000000000000000000000000000081525060400191505060405180910390fd5b6000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000809050600084905060008090505b60008211156133f05760008460018680549050038154811015156132e257fe5b90600052602060002090600202019050600061330b826001015442612bf090919063ffffffff16565b9050600080905084836000015411151561338d57613336828460000154612a9090919063ffffffff16565b9050613343848284613a34565b93506133588187612e7690919063ffffffff16565b9550613371836000015486612bf090919063ffffffff16565b9450868054809190600190036133879190613cc1565b506133e8565b6133a08286612a9090919063ffffffff16565b90506133ad848284613a34565b93506133c28187612e7690919063ffffffff16565b95506133db858460000154612bf090919063ffffffff16565b8360000181905550600094505b5050506132c2565b613407838660010154612bf090919063ffffffff16565b8560010181905550613426868660000154612bf090919063ffffffff16565b856000018190555061344383600954612bf090919063ffffffff16565b60098190555061345e86600854612bf090919063ffffffff16565b6008819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338a6040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561352857600080fd5b505af115801561353c573d6000803e3d6000fd5b505050506040513d602081101561355257600080fd5b810190808051906020019092919050505015156135fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001807f546f6b656e4765797365723a207472616e73666572206f7574206f662073746181526020017f6b696e6720706f6f6c206661696c65640000000000000000000000000000000081525060400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156136c257600080fd5b505af11580156136d6573d6000803e3d6000fd5b505050506040513d60208110156136ec57600080fd5b81019080805190602001909291905050501515613797576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001807f546f6b656e4765797365723a207472616e73666572206f7574206f6620756e6c81526020017f6f636b656420706f6f6c206661696c656400000000000000000000000000000081525060400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167faf01bfc8475df280aca00b578c4a948e6d95700f0db8c13365240f7f973c8754896137d9336113f1565b6040518083815260200182815260200180602001828103825260008152602001602001935050505060405180910390a23373ffffffffffffffffffffffffffffffffffffffff167f896e034966eaaf1adc54acc0f257056febbd300c9e47182cf761982cf1f5e430826040518082815260200191505060405180910390a26000600854148061386f5750600061386d611865565b115b151561392f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604c8152602001807f546f6b656e4765797365723a204572726f7220756e7374616b696e672e20537481526020017f616b696e67207368617265732065786973742c20627574206e6f207374616b6981526020017f6e6720746f6b656e7320646f000000000000000000000000000000000000000081525060600191505060405180910390fd5b809650505050505050919050565b600080600f8381548110151561394f57fe5b906000526020600020906005020190508060000154816001015410151561397a576000915050613a2f565b60008090508160030154421015156139bb576139a782600101548360000154612bf090919063ffffffff16565b905081600301548260020181905550613a0a565b6139fe82600401546139f084600001546139e2866002015442612bf090919063ffffffff16565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90504282600201819055505b613a21818360010154612e7690919063ffffffff16565b826001018190555080925050505b919050565b600080613a65600954613a5786613a49611f68565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b905060045483101515613a8d57613a858186612e7690919063ffffffff16565b915050613c25565b60006004600a0a90506000613abf600454613ab18488612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90506000613aef84613ae1856003870a60035402612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000613b5d85613b4f6003870a6003880a613b406002890a613b32600554613b246003548e612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000613bc886613bba6002880a6003890a613bab89613b9d600654613b8f6003548f612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000613c066003870a613bf884613bea8789612e7690919063ffffffff16565b612e7690919063ffffffff16565b612b5d90919063ffffffff16565b9050613c1b818c612e7690919063ffffffff16565b9750505050505050505b9392505050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b6060604051908101604052806000815260200160008152602001600081525090565b60a06040519081016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080519081016040528060008152602001600081525090565b815481835581811115613cee57600202816002028360005260206000209182019101613ced9190613cf3565b5b505050565b613d1f91905b80821115613d1b57600080820160009055600182016000905550600201613cf9565b5090565b9056fea165627a7a7230582047f2f7b482f1b81b2b43b389cb5e8cff03f75fc41b09003f043b67b7dbeb718e0029608060405234801561001057600080fd5b50604051602080610d438339810180604052602081101561003057600080fd5b8101908080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610bf58061014e6000396000f3fe608060405260043610610088576000357c0100000000000000000000000000000000000000000000000000000000900480636ccae0541461008d578063715018a6146101205780638da5cb5b146101375780638f32d59b1461018e578063a9059cbb146101bd578063b69ef8a814610230578063f2fde38b1461025b578063fc0c546a146102ac575b600080fd5b34801561009957600080fd5b50610106600480360360608110156100b057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610303565b604051808215151515815260200191505060405180910390f35b34801561012c57600080fd5b50610135610554565b005b34801561014357600080fd5b5061014c61068f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561019a57600080fd5b506101a36106b8565b604051808215151515815260200191505060405180910390f35b3480156101c957600080fd5b50610216600480360360408110156101e057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061070f565b604051808215151515815260200191505060405180910390f35b34801561023c57600080fd5b50610245610895565b6040518082815260200191505060405180910390f35b34801561026757600080fd5b506102aa6004803603602081101561027e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610992565b005b3480156102b857600080fd5b506102c1610a1a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600061030d6106b8565b1515610381576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561046d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f546f6b656e506f6f6c3a2043616e6e6f7420636c61696d20746f6b656e20686581526020017f6c642062792074686520636f6e7472616374000000000000000000000000000081525060400191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561051057600080fd5b505af1158015610524573d6000803e3d6000fd5b505050506040513d602081101561053a57600080fd5b810190808051906020019092919050505090509392505050565b61055c6106b8565b15156105d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b60006107196106b8565b151561078d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561085257600080fd5b505af1158015610866573d6000803e3d6000fd5b505050506040513d602081101561087c57600080fd5b8101908080519060200190929190505050905092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561095257600080fd5b505afa158015610966573d6000803e3d6000fd5b505050506040513d602081101561097c57600080fd5b8101908080519060200190929190505050905090565b61099a6106b8565b1515610a0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610a1781610a40565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610b0b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526020017f646472657373000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea165627a7a72305820486751213e35addde1542aa9eddbc3e6d7765651f535bb6cbba6017bcf84fc580029000000000000000000000000684b00a5773679f88598a19976fbeb25a68e9a5f0000000000000000000000006468e79a80c0eab0f9a2b574c8d5bc374af5941400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000683000000000000000000000000000000000000000000000000000000000076a700000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x608060405260043610610190576000357c01000000000000000000000000000000000000000000000000000000009004806304619b9814610195578063096754011461020b5780630af77de2146102365780630e89439b146102615780631dc27fde146102f157806322c12b841461031c5780632d2fb9cc1461037357806333060d901461039e5780633352ec641461040357806338b45fde1461042e5780633db7f40a14610459578063494347e7146104c85780634b341aed14610516578063568914121461057b5780635c94bcb2146105a657806365081685146106115780636ddd736d146106755780637033e4a6146106cb57806370c6a17e146106fa5780637c6aa6f414610725578063817b1cd21461075057806381c39bec1461077b57806389158d8e146107a6578063965f46c7146107eb5780639821602c146108165780639f9106d114610889578063a779d080146108e0578063c7ae20071461090b578063c8fd6ed014610936578063d0f1a7e9146109c6578063f968f493146109f1578063fc0c546a14610a1c575b600080fd5b3480156101a157600080fd5b506101ee600480360360408110156101b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a73565b604051808381526020018281526020019250505060405180910390f35b34801561021757600080fd5b50610220610ab3565b6040518082815260200191505060405180910390f35b34801561024257600080fd5b5061024b610ab9565b6040518082815260200191505060405180910390f35b34801561026d57600080fd5b506102ef6004803603604081101561028457600080fd5b8101908080359060200190929190803590602001906401000000008111156102ab57600080fd5b8201836020820111156102bd57600080fd5b803590602001918460018302840111640100000000831117156102df57600080fd5b9091929391929390505050610abf565b005b3480156102fd57600080fd5b50610306610acf565b6040518082815260200191505060405180910390f35b34801561032857600080fd5b50610331610ad4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561037f57600080fd5b50610388610d4d565b6040518082815260200191505060405180910390f35b3480156103aa57600080fd5b506103ed600480360360208110156103c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d53565b6040518082815260200191505060405180910390f35b34801561040f57600080fd5b50610418610d9f565b6040518082815260200191505060405180910390f35b34801561043a57600080fd5b50610443610da5565b6040518082815260200191505060405180910390f35b34801561046557600080fd5b506104b26004803603608081101561047c57600080fd5b81019080803590602001909291908035151590602001909291908035906020019092919080359060200190929190505050610dab565b6040518082815260200191505060405180910390f35b3480156104d457600080fd5b506104dd61124f565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b34801561052257600080fd5b506105656004803603602081101561053957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113f1565b6040518082815260200191505060405180910390f35b34801561058757600080fd5b5061059061147b565b6040518082815260200191505060405180910390f35b3480156105b257600080fd5b506105df600480360360208110156105c957600080fd5b8101908080359060200190929190505050611541565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b34801561061d57600080fd5b5061064a6004803603602081101561063457600080fd5b8101908080359060200190929190505050611586565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b34801561068157600080fd5b506106ae6004803603602081101561069857600080fd5b81019080803590602001909291905050506115ff565b604051808381526020018281526020019250505060405180910390f35b3480156106d757600080fd5b506106e0611851565b604051808215151515815260200191505060405180910390f35b34801561070657600080fd5b5061070f611859565b6040518082815260200191505060405180910390f35b34801561073157600080fd5b5061073a61185f565b6040518082815260200191505060405180910390f35b34801561075c57600080fd5b50610765611865565b6040518082815260200191505060405180910390f35b34801561078757600080fd5b5061079061192a565b6040518082815260200191505060405180910390f35b3480156107b257600080fd5b506107e9600480360360408110156107c957600080fd5b810190808035906020019092919080359060200190929190505050611930565b005b3480156107f757600080fd5b50610800611e73565b6040518082815260200191505060405180910390f35b34801561082257600080fd5b506108656004803603602081101561083957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e79565b60405180848152602001838152602001828152602001935050505060405180910390f35b34801561089557600080fd5b5061089e611ea3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156108ec57600080fd5b506108f5611f68565b6040518082815260200191505060405180910390f35b34801561091757600080fd5b5061092061202e565b6040518082815260200191505060405180910390f35b34801561094257600080fd5b506109c46004803603604081101561095957600080fd5b81019080803590602001909291908035906020019064010000000081111561098057600080fd5b82018360208201111561099257600080fd5b803590602001918460018302840111640100000000831117156109b457600080fd5b909192939192939050505061203b565b005b3480156109d257600080fd5b506109db61204a565b6040518082815260200191505060405180910390f35b3480156109fd57600080fd5b50610a06612050565b6040518082815260200191505060405180910390f35b348015610a2857600080fd5b50610a31612313565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600e60205281600052604060002081815481101515610a8e57fe5b9060005260206000209060020201600091509150508060000154908060010154905082565b600a5481565b60065481565b610aca333385612322565b505050565b600481565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610b5a57600080fd5b505afa158015610b6e573d6000803e3d6000fd5b505050506040513d6020811015610b8457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610c2f57600080fd5b505afa158015610c43573d6000803e3d6000fd5b505050506040513d6020811015610c5957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515610c8957fe5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610d0d57600080fd5b505afa158015610d21573d6000803e3d6000fd5b505050506040513d6020811015610d3757600080fd5b8101908080519060200190929190505050905090565b60055481565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b600c5481565b60035481565b6000601e83019250601e820191506000831415610dc6574292505b6000821415610dd3574291505b610ddb613c2c565b610de483611586565b8460000185602001866040018760600184815250848152508481525084815250505050506001861015610e1b576000915050611247565b85610e25336113f1565b10151515610ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001807f546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973206781526020017f726561746572207468616e20746f74616c2075736572207374616b657300000081525060400191505060405180910390fd5b6060600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610f6857838290600052602060002090600202016040805190810160405290816000820154815260200160018201548152505081526020019060010190610f22565b505050509050610f76613c55565b6000816000018181525050610faf610f8c611865565b610fa18a600854612a9090919063ffffffff16565b612b5d90919063ffffffff16565b81602001818152505060008160400181815250506000600183510390505b60008260200151111561123b57600080905082602001518483815181101515610ff257fe5b906020019060200201516000015111151561112157611066611038858481518110151561101b57fe5b906020019060200201516020015189612bf090919063ffffffff16565b85600187510381518110151561104a57fe5b9060200190602002015160000151612a9090919063ffffffff16565b90506110af8161109a868581518110151561107d57fe5b90602001906020020151602001518b612bf090919063ffffffff16565b8560400151886060015189600001518e612c7b565b8360400181815250506110cf818460000151612e7690919063ffffffff16565b83600001818152505061110a84838151811015156110e957fe5b90602001906020020151600001518460200151612bf090919063ffffffff16565b836020018181525050818060019003925050611235565b611165611152858481518110151561113557fe5b906020019060200201516020015189612bf090919063ffffffff16565b8460200151612a9090919063ffffffff16565b90506111ae81611199868581518110151561117c57fe5b90602001906020020151602001518a612bf090919063ffffffff16565b8560400151886060015189600001518e612c7b565b8360400181815250506111ce818460000151612e7690919063ffffffff16565b836000018181525050611209836020015185848151811015156111ed57fe5b9060200190602002015160000151612bf090919063ffffffff16565b848381518110151561121757fe5b90602001906020020151600001818152505060008360200181815250505b50610fcd565b81604001519450505050505b949350505050565b600080600080600080611260612050565b50600061128c60085461127e600a5442612bf090919063ffffffff16565b612a9090919063ffffffff16565b90506112a381600954612e7690919063ffffffff16565b60098190555042600a819055506000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060006113228260000154611314846002015442612bf090919063ffffffff16565b612a9090919063ffffffff16565b905061133b818360010154612e7690919063ffffffff16565b82600101819055504282600201819055506000806009541161135e576000611391565b6113906009546113828560010154611374611f68565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b90507f04175deb88c742f9b95fa5b912d09f9ef6219349ad62a84e1b1c7e8e528be11760405160405180910390a16113c761147b565b6113cf611f68565b8460010154600954844299509950995099509950995050505050909192939495565b60008060085411611403576000611474565b611473600854611465600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611457611865565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b9050919050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561150157600080fd5b505afa158015611515573d6000803e3d6000fd5b505050506040513d602081101561152b57600080fd5b8101908080519060200190929190505050905090565b600f8181548110151561155057fe5b90600052602060002090600502016000915090508060000154908060010154908060020154908060030154908060040154905085565b6000806000806009549350600a5492506000806115a2876115ff565b9150915060006115cf6008546115c1888b612bf090919063ffffffff16565b612a9090919063ffffffff16565b90506115e48188612e7690919063ffffffff16565b96508795508686848496509650965096505050509193509193565b60008060006007549050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561168d57600080fd5b505afa1580156116a1573d6000803e3d6000fd5b505050506040513d60208110156116b757600080fd5b81019080805190602001909291905050509150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561174e57600080fd5b505afa158015611762573d6000803e3d6000fd5b505050506040513d602081101561177857600080fd5b810190808051906020019092919050505092506000809050600061179a61147b565b905060008314156117ad5780915061182f565b600080905060008090505b600f805490508110156117f0576117e16117d2828a612f00565b83612e7690919063ffffffff16565b915080806001019150506117b8565b50611816846118088484612a9090919063ffffffff16565b612b5d90919063ffffffff16565b925061182b8185612bf090919063ffffffff16565b9350505b600082111561184357818503945081840193505b848494509450505050915091565b600080905090565b60085481565b60045481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156118ea57600080fd5b505afa1580156118fe573d6000803e3d6000fd5b505050506040513d602081101561191457600080fd5b8101908080519060200190929190505050905090565b60075481565b600b54600f805490501015156119ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f52656163686564206d6178696d756d20756e6c6f636b207363686564756c657381525060200191505060405180910390fd5b6000620f424090506119cd6012600a0a82612a9090919063ffffffff16565b8310151515611a6a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f416d6f756e7420746f6f206c6f7720666f7220756e6c6f636b2073636865647581526020017f6c6500000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b611a7261124f565b5050505050506000611a8261147b565b90506000808211611aa757611aa2600c5486612a9090919063ffffffff16565b611acf565b611ace82611ac087600754612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b9050611ad9613c77565b8181600001818152505042816040018181525050611b008542612e7690919063ffffffff16565b81606001818152505084816080018181525050600f81908060018154018082558091505090600182039060005260206000209060050201600090919290919091506000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040155505050611b8b82600754612e7690919063ffffffff16565b600781905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611c1557600080fd5b505afa158015611c29573d6000803e3d6000fd5b505050506040513d6020811015611c3f57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff166323b872dd33600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16896040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611d4857600080fd5b505af1158015611d5c573d6000803e3d6000fd5b505050506040513d6020811015611d7257600080fd5b81019080805190602001909291905050501515611e1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001807f546f6b656e4765797365723a207472616e7366657220696e746f206c6f636b6581526020017f6420706f6f6c206661696c65640000000000000000000000000000000000000081525060400191505060405180910390fd5b7ff346961af4c52f314df1b45964746280fe409abb959d4a2458d58f79408b1fe88686611e4861147b565b60405180848152602001838152602001828152602001935050505060405180910390a1505050505050565b600b5481565b600d6020528060005260406000206000915090508060000154908060010154908060020154905083565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611f2857600080fd5b505afa158015611f3c573d6000803e3d6000fd5b505050506040513d6020811015611f5257600080fd5b8101908080519060200190929190505050905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611fee57600080fd5b505afa158015612002573d6000803e3d6000fd5b505050506040513d602081101561201857600080fd5b8101908080519060200190929190505050905090565b6000600f80549050905090565b61204483613008565b50505050565b60095481565b60008060009050600061206161147b565b905060006007541415612076578091506120ff565b600080905060008090505b600f805490508110156120b8576120a961209a8261393d565b83612e7690919063ffffffff16565b91508080600101915050612081565b506120e06007546120d28484612a9090919063ffffffff16565b612b5d90919063ffffffff16565b92506120f781600754612bf090919063ffffffff16565b600781905550505b600082111561230b57600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156121ef57600080fd5b505af1158015612203573d6000803e3d6000fd5b505050506040513d602081101561221957600080fd5b810190808051906020019092919050505015156122c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001807f546f6b656e4765797365723a207472616e73666572206f7574206f66206c6f6381526020017f6b656420706f6f6c206661696c6564000000000000000000000000000000000081525060400191505060405180910390fd5b7f2e444eb379b177e88ce0649c6110a3b01099f03e297127919dd5e3b63a761a9c826122ee61147b565b604051808381526020018281526020019250505060405180910390a15b819250505090565b600061231d611ea3565b905090565b6000811115156123c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f546f6b656e4765797365723a207374616b6520616d6f756e74206973207a657281526020017f6f0000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561248b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f546f6b656e4765797365723a2062656e6566696369617279206973207a65726f81526020017f206164647265737300000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600060085414806124a3575060006124a1611865565b115b1515612563576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604a8152602001807f546f6b656e4765797365723a20496e76616c69642073746174652e205374616b81526020017f696e67207368617265732065786973742c20627574206e6f207374616b696e6781526020017f20746f6b656e7320646f0000000000000000000000000000000000000000000081525060600191505060405180910390fd5b6000806008541161258857612583600c5483612a9090919063ffffffff16565b6125b7565b6125b6612593611865565b6125a884600854612a9090919063ffffffff16565b612b5d90919063ffffffff16565b5b9050600081111515612657576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f546f6b656e4765797365723a205374616b6520616d6f756e7420697320746f6f81526020017f20736d616c6c000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b61265f61124f565b5050505050506000600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506126bf828260000154612e7690919063ffffffff16565b81600001819055504281600201819055506126d8613ca7565b6040805190810160405280848152602001428152509050600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150509060018203906000526020600020906002020160009091929091909150600082015181600001556020820151816001015550505061278683600854612e7690919063ffffffff16565b6008819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561280f57600080fd5b505afa158015612823573d6000803e3d6000fd5b505050506040513d602081101561283957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff166323b872dd876000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16876040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561294157600080fd5b505af1158015612955573d6000803e3d6000fd5b505050506040513d602081101561296b57600080fd5b81019080805190602001909291905050501515612a16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f546f6b656e4765797365723a207472616e7366657220696e746f207374616b6981526020017f6e6720706f6f6c206661696c656400000000000000000000000000000000000081525060400191505060405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff167fc65e53b88159e7d2c0fc12a0600072e28ae53ff73b4c1715369c30f16093514285612a58886113f1565b6040518083815260200182815260200180602001828103825260008152602001602001935050505060405180910390a2505050505050565b600080831415612aa35760009050612b57565b60008284029050828482811515612ab657fe5b04141515612b52576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81526020017f770000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b809150505b92915050565b60008082111515612bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b60008284811515612be357fe5b0490508091505092915050565b6000828211151515612c6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600080612ca384612c958a88612a9090919063ffffffff16565b612b5d90919063ffffffff16565b905060045487101580612cb4575082155b15612cd457612ccc8187612e7690919063ffffffff16565b915050612e6c565b60006004600a0a90506000612d06600454612cf8848c612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90506000612d3684612d28856003870a60035402612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000612da485612d966003870a6003880a612d876002890a612d79600554612d6b6003548e612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000612e0f86612e016002880a6003890a612df289612de4600654612dd66003548f612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000612e4d6003870a612e3f84612e318789612e7690919063ffffffff16565b612e7690919063ffffffff16565b612b5d90919063ffffffff16565b9050612e62818d612e7690919063ffffffff16565b9750505050505050505b9695505050505050565b6000808284019050838110151515612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000612f0a613c77565b600f84815481101515612f1957fe5b906000526020600020906005020160a0604051908101604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905080600001518160200151101515612f82576000915050613002565b6000809050816060015184101515612fb657612faf82602001518360000151612bf090919063ffffffff16565b9050612ffc565b612ff98260800151612feb8460000151612fdd866040015189612bf090919063ffffffff16565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90505b80925050505b92915050565b600061301261124f565b5050505050506000821115156130b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973207a81526020017f65726f000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b816130c0336113f1565b1015151561315c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001807f546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973206781526020017f726561746572207468616e20746f74616c2075736572207374616b657300000081525060400191505060405180910390fd5b600061318c613169611865565b61317e85600854612a9090919063ffffffff16565b612b5d90919063ffffffff16565b905060008111151561322c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001807f546f6b656e4765797365723a20556e61626c6520746f20756e7374616b65206181526020017f6d6f756e74207468697320736d616c6c0000000000000000000000000000000081525060400191505060405180910390fd5b6000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000809050600084905060008090505b60008211156133f05760008460018680549050038154811015156132e257fe5b90600052602060002090600202019050600061330b826001015442612bf090919063ffffffff16565b9050600080905084836000015411151561338d57613336828460000154612a9090919063ffffffff16565b9050613343848284613a34565b93506133588187612e7690919063ffffffff16565b9550613371836000015486612bf090919063ffffffff16565b9450868054809190600190036133879190613cc1565b506133e8565b6133a08286612a9090919063ffffffff16565b90506133ad848284613a34565b93506133c28187612e7690919063ffffffff16565b95506133db858460000154612bf090919063ffffffff16565b8360000181905550600094505b5050506132c2565b613407838660010154612bf090919063ffffffff16565b8560010181905550613426868660000154612bf090919063ffffffff16565b856000018190555061344383600954612bf090919063ffffffff16565b60098190555061345e86600854612bf090919063ffffffff16565b6008819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338a6040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561352857600080fd5b505af115801561353c573d6000803e3d6000fd5b505050506040513d602081101561355257600080fd5b810190808051906020019092919050505015156135fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001807f546f6b656e4765797365723a207472616e73666572206f7574206f662073746181526020017f6b696e6720706f6f6c206661696c65640000000000000000000000000000000081525060400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156136c257600080fd5b505af11580156136d6573d6000803e3d6000fd5b505050506040513d60208110156136ec57600080fd5b81019080805190602001909291905050501515613797576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001807f546f6b656e4765797365723a207472616e73666572206f7574206f6620756e6c81526020017f6f636b656420706f6f6c206661696c656400000000000000000000000000000081525060400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167faf01bfc8475df280aca00b578c4a948e6d95700f0db8c13365240f7f973c8754896137d9336113f1565b6040518083815260200182815260200180602001828103825260008152602001602001935050505060405180910390a23373ffffffffffffffffffffffffffffffffffffffff167f896e034966eaaf1adc54acc0f257056febbd300c9e47182cf761982cf1f5e430826040518082815260200191505060405180910390a26000600854148061386f5750600061386d611865565b115b151561392f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604c8152602001807f546f6b656e4765797365723a204572726f7220756e7374616b696e672e20537481526020017f616b696e67207368617265732065786973742c20627574206e6f207374616b6981526020017f6e6720746f6b656e7320646f000000000000000000000000000000000000000081525060600191505060405180910390fd5b809650505050505050919050565b600080600f8381548110151561394f57fe5b906000526020600020906005020190508060000154816001015410151561397a576000915050613a2f565b60008090508160030154421015156139bb576139a782600101548360000154612bf090919063ffffffff16565b905081600301548260020181905550613a0a565b6139fe82600401546139f084600001546139e2866002015442612bf090919063ffffffff16565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90504282600201819055505b613a21818360010154612e7690919063ffffffff16565b826001018190555080925050505b919050565b600080613a65600954613a5786613a49611f68565b612a9090919063ffffffff16565b612b5d90919063ffffffff16565b905060045483101515613a8d57613a858186612e7690919063ffffffff16565b915050613c25565b60006004600a0a90506000613abf600454613ab18488612a9090919063ffffffff16565b612b5d90919063ffffffff16565b90506000613aef84613ae1856003870a60035402612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000613b5d85613b4f6003870a6003880a613b406002890a613b32600554613b246003548e612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000613bc886613bba6002880a6003890a613bab89613b9d600654613b8f6003548f612bf090919063ffffffff16565b612a9090919063ffffffff16565b612a9090919063ffffffff16565b02612b5d90919063ffffffff16565b612a9090919063ffffffff16565b90506000613c066003870a613bf884613bea8789612e7690919063ffffffff16565b612e7690919063ffffffff16565b612b5d90919063ffffffff16565b9050613c1b818c612e7690919063ffffffff16565b9750505050505050505b9392505050565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b6060604051908101604052806000815260200160008152602001600081525090565b60a06040519081016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080519081016040528060008152602001600081525090565b815481835581811115613cee57600202816002028360005260206000209182019101613ced9190613cf3565b5b505050565b613d1f91905b80821115613d1b57600080820160009055600182016000905550600201613cf9565b5090565b9056fea165627a7a7230582047f2f7b482f1b81b2b43b389cb5e8cff03f75fc41b09003f043b67b7dbeb718e0029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000684b00a5773679f88598a19976fbeb25a68e9a5f0000000000000000000000006468e79a80c0eab0f9a2b574c8d5bc374af5941400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000683000000000000000000000000000000000000000000000000000000000076a700000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : stakingToken (address): 0x684B00a5773679f88598A19976fBeb25a68E9a5f
Arg [1] : distributionToken (address): 0x6468e79A80C0eaB0F9A2B574c8d5bC374Af59414
Arg [2] : maxUnlockSchedules (uint256): 20
Arg [3] : startBonus_ (uint256): 1667
Arg [4] : bonusPeriodSec_ (uint256): 7776000
Arg [5] : growthParamX_ (uint256): 1
Arg [6] : growthParamY_ (uint256): 0
Arg [7] : initialSharesPerToken (uint256): 1
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000684b00a5773679f88598a19976fbeb25a68e9a5f
Arg [1] : 0000000000000000000000006468e79a80c0eab0f9a2b574c8d5bc374af59414
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000683
Arg [4] : 000000000000000000000000000000000000000000000000000000000076a700
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode Sourcemap
11941:30867:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14345:46;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14345:46:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;14345:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;13488:48;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13488:48:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;13266:27;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13266:27:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;17312:121;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17312:121:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17312:121:0;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;17312:121:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;17312:121:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;17312:121:0;;;;;;;;;;;;:::i;:::-;;13107:42;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13107:42:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16965:171;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16965:171:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;13232:27;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13232:27:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16584:120;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16584:120:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;16584:120:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;13588:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13588:41:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;13156:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13156:29:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;24529:3949;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24529:3949:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;24529:3949:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;36359:1445;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36359:1445:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35023:284;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35023:284:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;35023:284:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;37890:100;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37890:100:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;14664:39;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14664:39:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;14664:39:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23330:1093;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23330:1093:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;23330:1093:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21895:1427;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21895:1427:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;21895:1427:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;7387:87;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7387:87:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;13393:37;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13393:37:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;13192:33;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13192:33:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;35415:101;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35415:101:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;13350:36;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13350:36:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;38811:1417;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38811:1417:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;38811:1417:0;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;13543:38;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13543:38:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;14197:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14197:49:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;14197:49:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16780:102;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16780:102:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;38078:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38078:104:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;38252:109;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38252:109:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;19714:98;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19714:98:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;19714:98:0;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;19714:98:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;19714:98:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;19714:98:0;;;;;;;;;;;;:::i;:::-;;13437:44;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13437:44:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;40484:980;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40484:980:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;35757:101;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35757:101:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;14345:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;13488:48::-;;;;:::o;13266:27::-;;;;:::o;17312:121::-;17384:41;17394:10;17406;17418:6;17384:9;:41::i;:::-;17312:121;;;:::o;13107:42::-;13148:1;13107:42;:::o;16965:171::-;17018:6;17069:11;;;;;;;;;;;:17;;;:19;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17069:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17069:19:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17069:19:0;;;;;;;;;;;;;;;;17044:44;;:13;;;;;;;;;;;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17044:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17044:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17044:21:0;;;;;;;;;;;;;;;;:44;;;17037:52;;;;;;17107:13;;;;;;;;;;;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17107:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17107:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17107:21:0;;;;;;;;;;;;;;;;17100:28;;16965:171;:::o;13232:27::-;;;;:::o;16584:120::-;16642:7;16669:11;:20;16681:7;16669:20;;;;;;;;;;;;;;;:27;;;;16662:34;;16584:120;;;:::o;13588:41::-;;;;:::o;13156:29::-;;;;:::o;24529:3949::-;24653:7;24691:2;24673:20;;;;24723:2;24704:21;;;;24759:1;24741:14;:19;24738:71;;;24794:3;24777:20;;24738:71;24843:1;24824:15;:20;24821:73;;;24879:3;24861:21;;24821:73;24906:28;;:::i;:::-;25175:37;25196:15;25175:20;:37::i;:::-;24962:10;:41;;25018:10;:43;;25076:10;:34;;25125:10;:36;;24947:265;;;;;;;;;;;;;;;;;;;;25266:1;25257:6;:10;25254:50;;;25291:1;25284:8;;;;;25254:50;25376:6;25346:26;25361:10;25346:14;:26::i;:::-;:36;;25324:147;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25515:28;25546:11;:23;25558:10;25546:23;;;;;;;;;;;;;;;25515:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25582:22;;:::i;:::-;25718:1;25685:4;:30;;:34;;;;;25754:73;25803:13;:11;:13::i;:::-;25754:30;25777:6;25754:18;;:22;;:30;;;;:::i;:::-;:34;;:73;;;;:::i;:::-;25730:4;:21;;:97;;;;;25858:1;25838:4;:17;;:21;;;;;25872:9;25907:1;25884:13;:20;:24;25872:36;;25921:2513;25952:1;25928:4;:21;;;:25;25921:2513;;;25970:36;26009:1;25970:40;;26100:4;:21;;;26049:13;26063:1;26049:16;;;;;;;;;;;;;;;;;;:30;;;:72;;26027:2396;;;26233:263;26379:98;26425:13;26439:1;26425:16;;;;;;;;;;;;;;;;;;:29;;;26379:15;:19;;:98;;;;:::i;:::-;26233:13;26292:1;26247:13;:42;:46;26233:61;;;;;;;;;;;;;;;;;;:97;;;:123;;:263;;;;:::i;:::-;26202:294;;26555:405;26598:28;26649:97;26694:13;26708:1;26694:16;;;;;;;;;;;;;;;;;;:29;;;26649:14;:18;;:97;;;;:::i;:::-;26769:4;:17;;;26809:10;:36;;;26868:10;:41;;;26932:9;26555:20;:405::i;:::-;26535:4;:17;;:425;;;;;27030:104;27087:28;27030:4;:30;;;:34;;:104;;;;:::i;:::-;26997:4;:30;;:137;;;;;27177:97;27225:13;27239:1;27225:16;;;;;;;;;;;;;;;;;;:30;;;27177:4;:21;;;:25;;:97;;;;:::i;:::-;27153:4;:21;;:121;;;;;27293:3;;;;;;;;26027:2396;;;27418:165;27466:98;27512:13;27526:1;27512:16;;;;;;;;;;;;;;;;;;:29;;;27466:15;:19;;:98;;;;:::i;:::-;27418:4;:21;;;:25;;:165;;;;:::i;:::-;27387:196;;27624:406;27667:28;27718:98;27764:13;27778:1;27764:16;;;;;;;;;;;;;;;;;;:29;;;27718:15;:19;;:98;;;;:::i;:::-;27839:4;:17;;;27879:10;:36;;;27938:10;:41;;;28002:9;27624:20;:406::i;:::-;27604:4;:17;;:426;;;;;28084:104;28141:28;28084:4;:30;;;:34;;:104;;;;:::i;:::-;28051:4;:30;;:137;;;;;28262:101;28341:4;:21;;;28262:13;28276:1;28262:16;;;;;;;;;;;;;;;;;;:52;;;:78;;:101;;;;:::i;:::-;28207:13;28221:1;28207:16;;;;;;;;;;;;;;;;;;:52;;:156;;;;;28406:1;28382:4;:21;;:25;;;;;26027:2396;25921:2513;;;;28453:4;:17;;;28446:24;;;;;;24529:3949;;;;;;;:::o;36359:1445::-;36435:7;36457;36479;36501;36523;36545;36580:14;:12;:14::i;:::-;;36637:30;36670:88;36739:18;;36670:50;36692:27;;36670:3;:21;;:50;;;;:::i;:::-;:68;;:88;;;;:::i;:::-;36637:121;;36797:77;36841:22;36797:25;;:29;;:77;;;;:::i;:::-;36769:25;:105;;;;36915:3;36885:27;:33;;;;36959:25;36987:11;:23;36999:10;36987:23;;;;;;;;;;;;;;;36959:51;;37021:34;37058:96;37133:6;:20;;;37058:56;37080:6;:33;;;37058:3;:21;;:56;;;;:::i;:::-;:74;;:96;;;;:::i;:::-;37021:133;;37194:82;37239:26;37194:6;:26;;;:30;;:82;;;;:::i;:::-;37165:6;:26;;:111;;;;37323:3;37287:6;:33;;:39;;;;37339:24;37395:1;37367:25;;:29;37366:174;;37539:1;37366:174;;;37413:110;37483:25;;37413:47;37433:6;:26;;;37413:15;:13;:15::i;:::-;:19;;:47;;;;:::i;:::-;:51;;:110;;;;:::i;:::-;37366:174;37339:201;;37558:19;;;;;;;;;;37612:13;:11;:13::i;:::-;37640:15;:13;:15::i;:::-;37670:6;:26;;;37711:25;;37751:16;37782:3;37590:206;;;;;;;;;;;;;;;;36359:1445;;;;;;:::o;35023:284::-;35082:7;35143:1;35122:18;;:22;:177;;35298:1;35122:177;;;35164:114;35241:18;;35164:50;35182:11;:17;35194:4;35182:17;;;;;;;;;;;;;;;:31;;;35164:13;:11;:13::i;:::-;:17;;:50;;;;:::i;:::-;:54;;:114;;;;:::i;:::-;35122:177;35102:197;;35023:284;;;:::o;37890:100::-;37934:7;37961:11;;;;;;;;;;;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37961:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37961:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;37961:21:0;;;;;;;;;;;;;;;;37954:28;;37890:100;:::o;14664:39::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;23330:1093::-;23410:38;23459:40;23510:31;23552:33;23636:25;;23603:58;;23707:27;;23672:62;;23762:25;23802:27;23843;23860:9;23843:16;:27::i;:::-;23747:123;;;;23913:30;23946:99;24026:18;;23946:61;23974:32;23946:9;:27;;:61;;;;:::i;:::-;:79;;:99;;;;:::i;:::-;23913:132;;24089:82;24138:22;24089:30;:34;;:82;;;;:::i;:::-;24056:115;;24217:9;24182:44;;24261:30;24306:32;24353:17;24385:19;24239:176;;;;;;;;;;;23330:1093;;;;;:::o;21895:1427::-;21971:25;22007:27;22053:31;22087:17;;22053:51;;22137:13;;;;;;;;;;;:21;;;:23;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22137:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22137:23:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;22137:23:0;;;;;;;;;;;;;;;;22115:45;;22191:11;;;;;;;;;;;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22191:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22191:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;22191:21:0;;;;;;;;;;;;;;;;22171:41;;22223:22;22248:1;22223:26;;22260:20;22283:13;:11;:13::i;:::-;22260:36;;22348:1;22321:23;:28;22317:535;;;22383:12;22366:29;;22317:535;;;22428:22;22453:1;22428:26;;22474:9;22486:1;22474:13;;22469:163;22493:15;:22;;;;22489:1;:26;22469:163;;;22558:58;22577:38;22602:1;22605:9;22577:24;:38::i;:::-;22558:14;:18;;:58;;;;:::i;:::-;22541:75;;22517:3;;;;;;;22469:163;;;;22663:93;22718:23;22663:32;22682:12;22663:14;:18;;:32;;;;:::i;:::-;:36;;:93;;;;:::i;:::-;22646:110;;22797:43;22825:14;22797:23;:27;;:43;;;;:::i;:::-;22771:69;;22317:535;;22885:1;22868:14;:18;22864:354;;;23140:14;23119:35;;;;23192:14;23169:37;;;;22864:354;23252:17;23284:19;23230:84;;;;;;;21895:1427;;;:::o;7387:87::-;7437:4;7461:5;7454:12;;7387:87;:::o;13393:37::-;;;;:::o;13192:33::-;;;;:::o;35415:101::-;35459:7;35486:12;;;;;;;;;;;:20;;;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35486:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;35486:22:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;35486:22:0;;;;;;;;;;;;;;;;35479:29;;35415:101;:::o;13350:36::-;;;;:::o;38811:1417::-;38949:19;;38924:15;:22;;;;:44;38902:126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39041:22;39066:7;39041:32;;39118:37;39150:2;39138;:15;39118:14;:18;;:37;;;;:::i;:::-;39108:6;:47;;39086:131;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39308:18;:16;:18::i;:::-;;;;;;;39339:20;39362:13;:11;:13::i;:::-;39339:36;;39386:26;39431:1;39416:12;:16;39415:131;;39512:34;39523:22;;39512:6;:10;;:34;;;;:::i;:::-;39415:131;;;39449:47;39483:12;39449:29;39471:6;39449:17;;:21;;:29;;;;:::i;:::-;:33;;:47;;;;:::i;:::-;39415:131;39386:160;;39559:30;;:::i;:::-;39631:18;39600:8;:28;;:49;;;;;39694:3;39660:8;:31;;:37;;;;;39728:20;39736:11;39728:3;:7;;:20;;;;:::i;:::-;39708:8;:17;;:40;;;;;39782:11;39759:8;:20;;:34;;;;;39804:15;39825:8;39804:30;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;39804:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39867:41;39889:18;39867:17;;:21;;:41;;;;:::i;:::-;39847:17;:61;;;;39943:11;;;;;;;;;;;:17;;;:19;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39943:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;39943:19:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;39943:19:0;;;;;;;;;;;;;;;;:32;;;39994:10;40031:11;;;;;;;;;;;40062:6;39943:140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39943:140:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;39943:140:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;39943:140:0;;;;;;;;;;;;;;;;39921:235;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40172:48;40185:6;40193:11;40206:13;:11;:13::i;:::-;40172:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38811:1417;;;;;;:::o;13543:38::-;;;;:::o;14197:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16780:102::-;16828:6;16854:12;;;;;;;;;;;:18;;;:20;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16854:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;16854:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;16854:20:0;;;;;;;;;;;;;;;;16847:27;;16780:102;:::o;38078:104::-;38124:7;38151:13;;;;;;;;;;;:21;;;:23;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38151:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38151:23:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;38151:23:0;;;;;;;;;;;;;;;;38144:30;;38078:104;:::o;38252:109::-;38304:7;38331:15;:22;;;;38324:29;;38252:109;:::o;19714:98::-;19788:16;19797:6;19788:8;:16::i;:::-;;19714:98;;;:::o;13437:44::-;;;;:::o;40484:980::-;40524:7;40544:22;40569:1;40544:26;;40581:20;40604:13;:11;:13::i;:::-;40581:36;;40655:1;40634:17;;:22;40630:496;;;40690:12;40673:29;;40630:496;;;40735:22;40760:1;40735:26;;40781:9;40793:1;40781:13;;40776:148;40800:15;:22;;;;40796:1;:26;40776:148;;;40865:43;40884:23;40905:1;40884:20;:23::i;:::-;40865:14;:18;;:43;;;;:::i;:::-;40848:60;;40824:3;;;;;;;40776:148;;;;40955:87;41010:17;;40955:32;40974:12;40955:14;:18;;:32;;;;:::i;:::-;:36;;:87;;;;:::i;:::-;40938:104;;41077:37;41099:14;41077:17;;:21;;:37;;;;:::i;:::-;41057:17;:57;;;;40630:496;;41159:1;41142:14;:18;41138:285;;;41203:11;;;;;;;;;;;:20;;;41232:13;;;;;;;;;;;41248:14;41203:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41203:60:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41203:60:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;41203:60:0;;;;;;;;;;;;;;;;41177:169;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41366:45;41381:14;41397:13;:11;:13::i;:::-;41366:45;;;;;;;;;;;;;;;;;;;;;;;;41138:285;41442:14;41435:21;;;;40484:980;:::o;35757:101::-;35797:7;35832:17;:15;:17::i;:::-;35817:33;;35757:101;:::o;17720:1725::-;17862:1;17853:6;:10;17845:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17957:1;17934:25;;:11;:25;;;;17912:115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18082:1;18060:18;;:23;:44;;;;18103:1;18087:13;:11;:13::i;:::-;:17;18060:44;18038:168;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18219:27;18271:1;18250:18;;:22;18249:139;;18354:34;18365:22;;18354:6;:10;;:34;;;;:::i;:::-;18249:139;;;18289:49;18324:13;:11;:13::i;:::-;18289:30;18312:6;18289:18;;:22;;:30;;;;:::i;:::-;:34;;:49;;;;:::i;:::-;18249:139;18219:169;;18443:1;18421:19;:23;18399:111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18523:18;:16;:18::i;:::-;;;;;;;18585:25;18613:11;:24;18625:11;18613:24;;;;;;;;;;;;;;;18585:52;;18671:45;18696:19;18671:6;:20;;;:24;;:45;;;;:::i;:::-;18648:6;:20;;:68;;;;18763:3;18727:6;:33;;:39;;;;18779:21;;:::i;:::-;18803:31;;;;;;;;;18809:19;18803:31;;;;18830:3;18803:31;;;18779:55;;18845:11;:24;18857:11;18845:24;;;;;;;;;;;;;;;18875:8;18845:39;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;18845:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18951:43;18974:19;18951:18;;:22;;:43;;;;:::i;:::-;18930:18;:64;;;;19147:12;;;;;;;;;;;:18;;;:20;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19147:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;19147:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;19147:20:0;;;;;;;;;;;;;;;;:33;;;19199:6;19232:12;;;;;;;;;;;19264:6;19147:138;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19147:138:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;19147:138:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;19147:138:0;;;;;;;;;;;;;;;;19125:234;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19384:11;19377:60;;;19397:6;19405:27;19420:11;19405:14;:27::i;:::-;19377:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17720:1725;;;;;;:::o;1812:470::-;1870:7;2119:1;2114;:6;2110:47;;;2144:1;2137:8;;;;2110:47;2169:9;2185:1;2181;:5;2169:17;;2214:1;2209;2205;:5;;;;;;;;:10;2197:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2273:1;2266:8;;;1812:470;;;;;:::o;2750:333::-;2808:7;2907:1;2903;:5;2895:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2950:9;2966:1;2962;:5;;;;;;;;2950:17;;3074:1;3067:8;;;2750:333;;;;:::o;1377:184::-;1435:7;1468:1;1463;:6;;1455:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1515:9;1531:1;1527;:5;1515:17;;1552:1;1545:8;;;1377:184;;;;:::o;20640:1247::-;20909:7;20929:23;20955:105;21035:24;20955:61;20987:28;20955:13;:31;;:61;;;;:::i;:::-;:79;;:105;;;;:::i;:::-;20929:131;;21094:14;;21078:12;:30;;21077:46;;;;21114:9;21113:10;21077:46;21073:119;;;21147:33;21164:15;21147:12;:16;;:33;;;;:::i;:::-;21140:40;;;;;21073:119;21204:21;13148:1;21228:2;:18;21204:42;;21259:20;21282:51;21318:14;;21282:31;21299:13;21282:12;:16;;:31;;;;:::i;:::-;:35;;:51;;;;:::i;:::-;21259:74;;21346:13;21362:69;21415:15;21362:48;21396:13;21389:1;21374:13;:16;21363:10;;:27;21362:33;;:48;;;;:::i;:::-;:52;;:69;;;;:::i;:::-;21346:85;;21442:13;21458:130;21572:15;21458:109;21565:1;21550:13;:16;21543:1;21528:13;:16;21459:68;21525:1;21511:12;:15;21459:47;21493:12;;21459:29;21477:10;;21459:13;:17;;:29;;;;:::i;:::-;:33;;:47;;;;:::i;:::-;:51;;:68;;;;:::i;:::-;:85;21458:91;;:109;;;;:::i;:::-;:113;;:130;;;;:::i;:::-;21442:146;;21599:13;21615:127;21726:15;21615:106;21719:1;21704:13;:16;21697:1;21682:13;:16;21616:65;21668:12;21616:47;21650:12;;21616:29;21634:10;;21616:13;:17;;:29;;;;:::i;:::-;:33;;:47;;;;:::i;:::-;:51;;:65;;;;:::i;:::-;:82;21615:88;;:106;;;;:::i;:::-;:110;;:127;;;;:::i;:::-;21599:143;;21755:21;21779:49;21826:1;21811:13;:16;21779:27;21800:5;21779:16;21789:5;21779;:9;;:16;;;;:::i;:::-;:20;;:27;;;;:::i;:::-;:31;;:49;;;;:::i;:::-;21755:73;;21848:31;21865:13;21848:12;:16;;:31;;;;:::i;:::-;21841:38;;;;;;;;;20640:1247;;;;;;;;;:::o;921:181::-;979:7;999:9;1015:1;1011;:5;999:17;;1040:1;1035;:6;;1027:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1093:1;1086:8;;;921:181;;;;:::o;19820:812::-;19906:7;19926:30;;:::i;:::-;19959:15;19975:1;19959:18;;;;;;;;;;;;;;;;;;;;19926:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20021:8;:28;;;19994:8;:23;;;:55;;19990:96;;;20073:1;20066:8;;;;;19990:96;20098:22;20123:1;20098:26;;20227:8;:17;;;20214:9;:30;;20210:381;;;20297:57;20330:8;:23;;;20297:8;:28;;;:32;;:57;;;;:::i;:::-;20261:108;;20210:381;;;20419:160;20558:8;:20;;;20419:116;20506:8;:28;;;20419:64;20451:8;:31;;;20419:9;:31;;:64;;;;:::i;:::-;:86;;:116;;;;:::i;:::-;:138;;:160;;;;:::i;:::-;20402:177;;20210:381;20610:14;20603:21;;;;19820:812;;;;;:::o;28783:3980::-;28834:7;28854:18;:16;:18::i;:::-;;;;;;;28921:1;28912:6;:10;28904:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29025:6;28995:26;29010:10;28995:14;:26::i;:::-;:36;;28973:147;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29133:27;29163:73;29212:13;:11;:13::i;:::-;29163:30;29186:6;29163:18;;:22;;:30;;;;:::i;:::-;:34;;:73;;;;:::i;:::-;29133:103;;29291:1;29269:19;:23;29247:121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29412:25;29440:11;:23;29452:10;29440:23;;;;;;;;;;;;;;;29412:51;;29474:29;29506:11;:23;29518:10;29506:23;;;;;;;;;;;;;;;29474:55;;29610:33;29646:1;29610:37;;29658:24;29685:19;29658:46;;29715:20;29738:1;29715:24;;29750:1708;29776:1;29757:16;:20;29750:1708;;;29794:23;29820:13;29857:1;29834:13;:20;;;;:24;29820:39;;;;;;;;;;;;;;;;;;;;29794:65;;29874:20;29897:31;29905:9;:22;;;29897:3;:7;;:31;;;;:::i;:::-;29874:54;;29943:36;29982:1;29943:40;;30031:16;30004:9;:23;;;:43;;30000:1447;;;30145:81;30195:12;30145:9;:23;;;:27;;:81;;;;:::i;:::-;30114:112;;30262:156;30301:12;30336:28;30387:12;30262:16;:156::i;:::-;30247:171;;30465:99;30517:28;30465:25;:29;;:99;;;;:::i;:::-;30437:127;;30602:85;30645:9;:23;;;30602:16;:20;;:85;;;;:::i;:::-;30583:104;;30706:13;:22;;;;;;;;;;;;:::i;:::-;;30000:1447;;;30850:74;30893:12;30850:16;:20;;:74;;;;:::i;:::-;30819:105;;30958:156;30997:12;31032:28;31083:12;30958:16;:156::i;:::-;30943:171;;31163:99;31215:28;31163:25;:29;;:99;;;;:::i;:::-;31135:127;;31307:85;31357:16;31307:9;:23;;;:27;;:85;;;;:::i;:::-;31281:9;:23;;:111;;;;31430:1;31411:20;;30000:1447;29750:1708;;;;;;31497:81;31542:25;31497:6;:26;;;:30;;:81;;;;:::i;:::-;31468:6;:26;;:110;;;;31612:45;31637:19;31612:6;:20;;;:24;;:45;;;;:::i;:::-;31589:6;:20;;:68;;;;31828:80;31872:25;31828;;:29;;:80;;;;:::i;:::-;31800:25;:108;;;;31940:43;31963:19;31940:18;;:22;;:43;;;;:::i;:::-;31919:18;:64;;;;32134:12;;;;;;;;;;;:21;;;32156:10;32168:6;32134:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32134:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32134:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;32134:41:0;;;;;;;;;;;;;;;;32112:139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32284:13;;;;;;;;;;;:22;;;32307:10;32319:12;32284:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32284:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32284:48:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;32284:48:0;;;;;;;;;;;;;;;;32262:147;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32436:10;32427:60;;;32448:6;32456:26;32471:10;32456:14;:26::i;:::-;32427:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32517:10;32503:39;;;32529:12;32503:39;;;;;;;;;;;;;;;;;;32599:1;32577:18;;:23;:44;;;;32620:1;32604:13;:11;:13::i;:::-;:17;32577:44;32555:170;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32743:12;32736:19;;;;;;;;28783:3980;;;:::o;41834:971::-;41892:7;41912:31;41946:15;41962:1;41946:18;;;;;;;;;;;;;;;;;;;;41912:52;;42008:8;:28;;;41981:8;:23;;;:55;;41977:96;;;42060:1;42053:8;;;;;41977:96;42085:22;42110:1;42085:26;;42208:8;:17;;;42201:3;:24;;42197:487;;;42278:57;42311:8;:23;;;42278:8;:28;;;:32;;:57;;;;:::i;:::-;42242:108;;42399:8;:17;;;42365:8;:31;;:51;;;;42197:487;;;42466:154;42599:8;:20;;;42466:110;42547:8;:28;;;42466:58;42492:8;:31;;;42466:3;:25;;:58;;;;:::i;:::-;:80;;:110;;;;:::i;:::-;:132;;:154;;;;:::i;:::-;42449:171;;42669:3;42635:8;:31;;:37;;;;42197:487;42722:43;42750:14;42722:8;:23;;;:27;;:43;;;;:::i;:::-;42696:8;:23;;:69;;;;42783:14;42776:21;;;;41834:971;;;;:::o;33739:1128::-;33901:7;33921:23;33947:95;34006:25;;33947:40;33967:19;33947:15;:13;:15::i;:::-;:19;;:40;;;;:::i;:::-;:44;;:95;;;;:::i;:::-;33921:121;;34075:14;;34059:12;:30;;34055:110;;;34113:40;34137:15;34113:19;:23;;:40;;;;:::i;:::-;34106:47;;;;;34055:110;34177:21;13148:1;34201:2;:18;34177:42;;34232:20;34255:51;34291:14;;34255:31;34272:13;34255:12;:16;;:31;;;;:::i;:::-;:35;;:51;;;;:::i;:::-;34232:74;;34319:13;34335:69;34388:15;34335:48;34369:13;34362:1;34347:13;:16;34336:10;;:27;34335:33;;:48;;;;:::i;:::-;:52;;:69;;;;:::i;:::-;34319:85;;34415:13;34431:130;34545:15;34431:109;34538:1;34523:13;:16;34516:1;34501:13;:16;34432:68;34498:1;34484:12;:15;34432:47;34466:12;;34432:29;34450:10;;34432:13;:17;;:29;;;;:::i;:::-;:33;;:47;;;;:::i;:::-;:51;;:68;;;;:::i;:::-;:85;34431:91;;:109;;;;:::i;:::-;:113;;:130;;;;:::i;:::-;34415:146;;34572:13;34588:127;34699:15;34588:106;34692:1;34677:13;:16;34670:1;34655:13;:16;34589:65;34641:12;34589:47;34623:12;;34589:29;34607:10;;34589:13;:17;;:29;;;;:::i;:::-;:33;;:47;;;;:::i;:::-;:51;;:65;;;;:::i;:::-;:82;34588:88;;:106;;;;:::i;:::-;:110;;:127;;;;:::i;:::-;34572:143;;34728:21;34752:49;34799:1;34784:13;:16;34752:27;34773:5;34752:16;34762:5;34752;:9;;:16;;;;:::i;:::-;:20;;:27;;;;:::i;:::-;:31;;:49;;;;:::i;:::-;34728:73;;34821:38;34845:13;34821:19;:23;;:38;;;;:::i;:::-;34814:45;;;;;;;;;33739:1128;;;;;;:::o;11941:30867::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
bzzr://486751213e35addde1542aa9eddbc3e6d7765651f535bb6cbba6017bcf84fc58
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.