Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
SynapseStaking
Compiler Version
v0.8.6+commit.11564f7e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.6; import { ReentrancyGuard } from "./external/openzeppelin/ReentrancyGuard.sol"; import { RewardsDistribution } from "./abstract/RewardsDistribution.sol"; import { StableMath } from "./libraries/StableMath.sol"; import { SafeERC20, IERC20 } from "./libraries/SafeERC20.sol"; import { Parameterized } from "./Parameterized.sol"; /** * @title SynapseStaking * @notice Rewards stakers of SNP token and a given LP token with rewards in form of SNP token, on a pro-rata basis. * @dev Uses an ever increasing 'rewardPerTokenStored' variable to distribute rewards * each time a write action is called in the contract. This allows for passive reward accrual. */ contract SynapseStaking is RewardsDistribution, ReentrancyGuard, Parameterized { using StableMath for uint256; using SafeERC20 for IERC20; /// @notice stake/reward token address address public tokenAddress; /// @notice LP stake token address address public liquidityAddress; /// @notice vesting contract address address public vestingAddress; /// @notice timestamp for current period finish uint256 public periodFinish; /// @notice timestamp for current super period finish uint256 public superPeriodFinish; struct Data { uint256 depositedTokens; // deposited tokens amount uint256 depositedLiquidity; // deposited lp amount uint256 totalRewardsAdded; // accumulated amount of rewards added to token and liquidity staking uint256 totalRewardsClaimed; // accumulated amount of rewards claimed uint256 totalRewardsFromFees; // accumulated amount of rewards collected from fee-on-transfer } Data public data; struct StakingData { uint256 rewardRate; // rewardRate for the rest of the period uint256 superRewardRate; // superRewardRate for the rest of the super period uint256 lastUpdateTime; // last time any user took action uint256 lastSuperUpdateTime; // last time super staker took action uint256 rewardPerTokenStored; // accumulated per token reward since the beginning of time uint256 superRewardPerTokenStored; // super accumulated per token reward since the beginning of time uint256 stakedTokens; // amount of tokens that is used in reward per token calculation uint256 stakedSuperTokens; // amount of tokens that is used in super reward per token calculation } StakingData public tokenStaking; StakingData public lpStaking; struct Stake { uint256 stakeStart; // timestamp of stake creation uint256 superStakerPossibleAt; // timestamp after which user can claim super staker status // uint256 rewardPerTokenPaid; // user accumulated per token rewards uint256 superRewardPerTokenPaid; // user accumulated per token super staker rewards // uint256 tokens; // total tokens staked by user snp or lp uint256 rewards; // current not-claimed rewards from last update // uint256 withdrawalPossibleAt; // timestamp after which stake can be removed without fee bool isWithdrawing; // true = user call to remove stake bool isSuperStaker; // true = user is super staker } /// @dev each holder have one stake /// @notice token stakes storage mapping(address => Stake) public tokenStake; /// @notice LP token stakes storage mapping(address => Stake) public liquidityStake; /// @dev events event Claimed(address indexed user, uint256 amount); event StakeAdded(address indexed user, uint256 amount); event StakeLiquidityAdded(address indexed user, uint256 amount); event StakeRemoveRequested(address indexed user); event StakeLiquidityRemoveRequested(address indexed user); event StakeRemoved(address indexed user, uint256 amount); event StakeLiquidityRemoved(address indexed user, uint256 amount); event Recalculation(uint256 reward, uint256 lpReward); event SuperRecalculation(uint256 superReward, uint256 superLpReward); /** * @param _timeToSuper time needed to become a super staker * @param _timeToUnstake time needed to unstake without fee */ constructor(uint256 _timeToSuper, uint256 _timeToUnstake) { timeToSuper.value = _timeToSuper; timeToUnstake.value = _timeToUnstake; timeToSuper.lastChange = block.timestamp; timeToUnstake.lastChange = block.timestamp; timeToSuper.minDelay = WEEK; timeToUnstake.minDelay = WEEK; unstakeFee.value = 1000; } /** * @dev One time initialization function * @param _token SNP token address * @param _liquidity SNP/USDC LP token address * @param _vesting public vesting contract address */ function init( address _token, address _liquidity, address _vesting ) external onlyOwner { require(_token != address(0), "_token address cannot be 0"); require(_liquidity != address(0), "_liquidity address cannot be 0"); require(_vesting != address(0), "_vesting address cannot be 0"); require(tokenAddress == address(0), "Init already done"); tokenAddress = _token; liquidityAddress = _liquidity; vestingAddress = _vesting; } /** * @dev Updates the reward for a given address, * for token and LP pool, before executing function * @param _account address of staker for which rewards will be updated */ modifier updateRewards(address _account) { _updateReward(_account, false); _updateReward(_account, true); _; } /** * @dev Updates the reward for a given address, * for given pool, before executing function * @param _account address for which rewards will be updated * @param _lp true=lpStaking, false=tokenStaking */ modifier updateReward(address _account, bool _lp) { _updateReward(_account, _lp); _; } /** * @dev Updates the super rewards for a given address, * for token and LP pool, before executing function * @param _account address of super staker for which super rewards will be updated */ modifier updateSuperRewards(address _account) { bool success = _updateSuperReward(_account, false); success = _updateSuperReward(_account, true) || success; if (success) { _calculateSuperRewardAmount(); } _; } /** * @dev guards that the given address has selected stake * @param _account address to check * @param _lp true=lpStaking, false=tokenStaking */ modifier hasPoolStake(address _account, bool _lp) { bool accountHasStake = _lp ? (liquidityStake[_account].tokens > 0) : (tokenStake[_account].tokens > 0); require(accountHasStake, "Nothing staked"); _; } /** * @dev guards that the msg.sender has token or LP stake */ modifier hasStake() { require((liquidityStake[msg.sender].tokens > 0) || (tokenStake[msg.sender].tokens > 0), "Nothing staked"); _; } /** * @dev guards that the given address can be a super staker in selected stake * @param _account address to check * @param _lp true=lpStaking, false=tokenStaking */ modifier canBeSuper(address _account, bool _lp) { Stake memory s = _lp ? liquidityStake[_account] : tokenStake[_account]; require(!s.isWithdrawing, "Cannot when withdrawing"); require(!s.isSuperStaker, "Already super staker"); require(block.timestamp >= s.superStakerPossibleAt, "Too soon"); _; } /** * @dev checks if the msg.sender can withdraw requested unstake */ modifier canUnstake() { require(_canUnstake(), "Cannot unstake"); _; } /** * @dev checks if for the msg.sender there is possibility to * withdraw staked tokens without fee. */ modifier cantUnstake() { require(!_canUnstake(), "Unstake first"); _; } /*************************************** ACTIONS ****************************************/ /** * @dev Updates reward in selected pool * @param _account address for which rewards will be updated * @param _lp true=lpStaking, false=tokenStaking */ function _updateReward(address _account, bool _lp) internal { uint256 newRewardPerTokenStored = currentRewardPerTokenStored(_lp); // if statement protects against loss in initialization case if (newRewardPerTokenStored > 0) { StakingData storage sd = _lp ? lpStaking : tokenStaking; sd.rewardPerTokenStored = newRewardPerTokenStored; sd.lastUpdateTime = lastTimeRewardApplicable(); // setting of personal vars based on new globals if (_account != address(0)) { Stake storage s = _lp ? liquidityStake[_account] : tokenStake[_account]; if (!s.isWithdrawing) { s.rewards = _earned(_account, _lp); s.rewardPerTokenPaid = newRewardPerTokenStored; } } } } /** * @dev Updates super reward in selected pool * @param _account address of super staker for which super rewards will be updated * @param _lp true=lpStaking, false=tokenStaking */ function _updateSuperReward(address _account, bool _lp) internal returns (bool success) { Stake storage s = _lp ? liquidityStake[_account] : tokenStake[_account]; // save gas for non super stakers if (s.isSuperStaker || _account == address(0)) { uint256 newSuperRewardPerTokenStored = currentSuperRewardPerTokenStored(_lp); // if statement protects against loss in initialization case if (newSuperRewardPerTokenStored > 0) { StakingData storage sd = _lp ? lpStaking : tokenStaking; sd.superRewardPerTokenStored = newSuperRewardPerTokenStored; sd.lastSuperUpdateTime = lastTimeSuperRewardApplicable(); // setting of personal vars based on new globals if (_account != address(0)) { // setting of personal vars based on new globals if (!s.isWithdrawing) { s.rewards = _earnedSuper(_account, _lp); s.superRewardPerTokenPaid = newSuperRewardPerTokenStored; } } } success = true; } } /** * @dev Add tokens for staking from vesting contract * @param _account address that call claimAndStake in vesting * @param _amount number of tokens sent to contract */ function onClaimAndStake(address _account, uint256 _amount) external nonReentrant updateReward(_account, false) updateSuperRewards(_account) { require(msg.sender == vestingAddress, "Only vesting contract"); require(!tokenStake[_account].isWithdrawing, "Cannot when withdrawing"); require(_amount > 0, "Zero Amount"); Stake storage s = tokenStake[_account]; StakingData storage sd = tokenStaking; if (s.stakeStart == 0) { // new stake s.stakeStart = block.timestamp; s.superStakerPossibleAt = s.stakeStart + timeToSuper.value; } // update account stake data s.tokens += _amount; // update pool staking data sd.stakedTokens += _amount; if (s.isSuperStaker) { sd.stakedSuperTokens += _amount; } // update global data data.depositedTokens += _amount; emit StakeAdded(_account, _amount); } /** * @dev Add tokens to staking contract * @param _amount of tokens to stake */ function addTokenStake(uint256 _amount) external { _addStake(msg.sender, _amount, false); emit StakeAdded(msg.sender, _amount); } /** * @dev Add tokens to staking contract by using permit to set allowance * @param _amount of tokens to stake * @param _deadline of permit signature * @param _approveMax allowance for the token */ function addTokenStakeWithPermit( uint256 _amount, uint256 _deadline, bool _approveMax, uint8 v, bytes32 r, bytes32 s ) external { uint256 value = _approveMax ? type(uint256).max : _amount; IERC20(tokenAddress).permit(msg.sender, address(this), value, _deadline, v, r, s); _addStake(msg.sender, _amount, false); emit StakeAdded(msg.sender, _amount); } /** * @dev Add liquidity tokens to staking contract * @param _amount of LP tokens to stake */ function addLiquidityStake(uint256 _amount) external { _addStake(msg.sender, _amount, true); emit StakeLiquidityAdded(msg.sender, _amount); } /** * @dev Add liquidity tokens to staking contract * @param _amount of tokens to stake * @param _deadline of permit signature * @param _approveMax allowance for the token */ function addLiquidityStakeWithPermit( uint256 _amount, uint256 _deadline, bool _approveMax, uint8 v, bytes32 r, bytes32 s ) external { uint256 value = _approveMax ? type(uint256).max : _amount; IERC20(liquidityAddress).permit(msg.sender, address(this), value, _deadline, v, r, s); _addStake(msg.sender, _amount, true); emit StakeLiquidityAdded(msg.sender, _amount); } /** * @dev Internal add stake function * @param _account selected staked tokens are credited to this address * @param _amount of staked tokens * @param _lp true=LP token, false=SNP token */ function _addStake( address _account, uint256 _amount, bool _lp ) internal nonReentrant updateReward(_account, _lp) updateSuperRewards(_account) { require(_amount > 0, "Zero Amount"); Stake storage s = _lp ? liquidityStake[_account] : tokenStake[_account]; require(!s.isWithdrawing, "Cannot when withdrawing"); address token = _lp ? liquidityAddress : tokenAddress; // check for fee-on-transfer and proceed with received amount _amount = _transferFrom(token, msg.sender, _amount); if (s.stakeStart == 0) { // new stake s.stakeStart = block.timestamp; s.superStakerPossibleAt = s.stakeStart + timeToSuper.value; } StakingData storage sd = _lp ? lpStaking : tokenStaking; // update account stake data s.tokens += _amount; // update pool staking data sd.stakedTokens += _amount; if (s.isSuperStaker) { sd.stakedSuperTokens += _amount; } // update global data if (_lp) { data.depositedLiquidity += _amount; } else { data.depositedTokens += _amount; } } /** * @dev Restake earned tokens and add them to token stake (instead of claiming) * If have LP stake but not token stake - token stake will be created. */ function restake() external hasStake updateRewards(msg.sender) updateSuperRewards(msg.sender) { Stake storage ts = tokenStake[msg.sender]; Stake storage ls = liquidityStake[msg.sender]; require(!ts.isWithdrawing, "Cannot when withdrawing"); uint256 rewards = ts.rewards + ls.rewards; require(rewards > 0, "Nothing to restake"); delete ts.rewards; delete ls.rewards; if (ts.stakeStart == 0) { // new stake ts.stakeStart = block.timestamp; ts.superStakerPossibleAt = ts.stakeStart + timeToSuper.value; } // update account stake data ts.tokens += rewards; // update pool staking data tokenStaking.stakedTokens += rewards; if (ts.isSuperStaker) { tokenStaking.stakedSuperTokens += rewards; } data.totalRewardsClaimed += rewards; data.depositedTokens += rewards; emit Claimed(msg.sender, rewards); emit StakeAdded(msg.sender, rewards); } /** * @dev Claims rewards for the msg.sender. */ function claim() external { _claim(msg.sender, msg.sender); } /** * @dev Claim msg.sender rewards to provided address * @param _recipient address where claimed tokens should be sent */ function claimTo(address _recipient) external { _claim(msg.sender, _recipient); } /** * @dev Internal claim function. First updates rewards in normal and super pools * and then transfers. * @param _account claim rewards for this address * @param _recipient claimed tokens are sent to this address */ function _claim(address _account, address _recipient) internal nonReentrant hasStake updateRewards(_account) updateSuperRewards(_account) { uint256 rewards = tokenStake[_account].rewards + liquidityStake[_account].rewards; require(rewards > 0, "Nothing to claim"); delete tokenStake[_account].rewards; delete liquidityStake[_account].rewards; data.totalRewardsClaimed += rewards; _transfer(tokenAddress, _recipient, rewards); emit Claimed(_account, rewards); } /** * @dev Request unstake for deposited tokens. Marks user token stake as withdrawing, * and start withdrawing period. */ function requestUnstake() external { _requestUnstake(msg.sender, false); emit StakeRemoveRequested(msg.sender); } /** * @dev Request unstake for deposited LP tokens. Marks user lp stake as withdrawing * and start withdrawing period. */ function requestUnstakeLp() external { _requestUnstake(msg.sender, true); emit StakeLiquidityRemoveRequested(msg.sender); } /** * @dev Internal request unstake function. Update normal and super rewards for the user first. * @param _account User address * @param _lp true=it is LP stake */ function _requestUnstake(address _account, bool _lp) internal hasPoolStake(_account, _lp) updateReward(_account, _lp) updateSuperRewards(_account) { Stake storage s = _lp ? liquidityStake[_account] : tokenStake[_account]; require(!s.isWithdrawing, "Cannot when withdrawing"); StakingData storage sd = _lp ? lpStaking : tokenStaking; // update account stake data s.isWithdrawing = true; s.withdrawalPossibleAt = block.timestamp + timeToUnstake.value; // update pool staking data sd.stakedTokens -= s.tokens; if (s.isSuperStaker) { delete s.isSuperStaker; sd.stakedSuperTokens -= s.tokens; } } /** * @dev Withdraw stake for msg.sender from both stakes (if possible) */ function unstake() external nonReentrant hasStake canUnstake { bool success; uint256 reward; uint256 tokens; uint256 rewards; (reward, success) = _unstake(msg.sender, false); rewards += reward; if (success) { tokens += tokenStake[msg.sender].tokens; data.depositedTokens -= tokenStake[msg.sender].tokens; emit StakeRemoved(msg.sender, tokenStake[msg.sender].tokens); delete tokenStake[msg.sender]; } (reward, success) = _unstake(msg.sender, true); rewards += reward; if (success) { delete liquidityStake[msg.sender]; } if (tokens + rewards > 0) { _transfer(tokenAddress, msg.sender, tokens + rewards); if (rewards > 0) { emit Claimed(msg.sender, rewards); } } } /** * @dev Internal unstake function, withdraw staked LP tokens * @param _account address of account to transfer LP tokens * @param _lp true = LP stake * @return stake rewards amount * @return bool true if success */ function _unstake(address _account, bool _lp) internal returns (uint256, bool) { Stake memory s = _lp ? liquidityStake[_account] : tokenStake[_account]; if (!s.isWithdrawing) return (0, false); if (s.withdrawalPossibleAt > block.timestamp) return (0, false); data.totalRewardsClaimed += s.rewards; // only LP stake if (_lp && s.tokens > 0) { data.depositedLiquidity -= s.tokens; _transfer(liquidityAddress, _account, s.tokens); emit StakeLiquidityRemoved(_account, s.tokens); } return (s.rewards, true); } /** * @dev Unstake requested stake at any time accepting 10% penalty fee */ function unstakeWithFee() external nonReentrant hasStake cantUnstake { Stake memory ts = tokenStake[msg.sender]; Stake memory ls = liquidityStake[msg.sender]; uint256 tokens; uint256 rewards; if (ls.isWithdrawing) { uint256 lpTokens = _minusFee(ls.tokens); //remaining tokens remain on the contract rewards += ls.rewards; data.totalRewardsClaimed += ls.rewards; data.depositedLiquidity -= ls.tokens; emit StakeLiquidityRemoved(msg.sender, ls.tokens); if (lpTokens > 0) { _transfer(liquidityAddress, msg.sender, lpTokens); } delete liquidityStake[msg.sender]; } if (ts.isWithdrawing) { tokens = _minusFee(ts.tokens); // remaining tokens goes to Super Stakers rewards += ts.rewards; data.totalRewardsClaimed += ts.rewards; data.depositedTokens -= ts.tokens; emit StakeRemoved(msg.sender, ts.tokens); delete tokenStake[msg.sender]; } if (tokens + rewards > 0) { _transfer(tokenAddress, msg.sender, tokens + rewards); if (rewards > 0) { emit Claimed(msg.sender, rewards); } } } /** * @dev Set Super Staker status for token pool stake if possible. */ function setSuperToken() external { _setSuper(msg.sender, false); } /** * @dev Set Super Staker status for LP pool stake if possible. */ function setSuperLp() external { _setSuper(msg.sender, true); } /** * @dev Set Super Staker status if possible for selected pool. * Update super reward pools. * @param _account address of account to set super * @param _lp true=LP stake super staker, false=token stake super staker */ function _setSuper(address _account, bool _lp) internal hasPoolStake(_account, _lp) canBeSuper(_account, _lp) updateSuperRewards(address(0)) { Stake storage s = _lp ? liquidityStake[_account] : tokenStake[_account]; StakingData storage sd = _lp ? lpStaking : tokenStaking; sd.stakedSuperTokens += s.tokens; s.isSuperStaker = true; s.superRewardPerTokenPaid = sd.superRewardPerTokenStored; } /*************************************** GETTERS ****************************************/ /** * @dev Gets the last applicable timestamp for this reward period */ function lastTimeRewardApplicable() public view returns (uint256) { return StableMath.min(block.timestamp, periodFinish); } /** * @dev Gets the last applicable timestamp for this super reward period */ function lastTimeSuperRewardApplicable() public view returns (uint256) { return StableMath.min(block.timestamp, superPeriodFinish); } /** * @dev Calculates the amount of unclaimed rewards per token since last update, * and sums with stored to give the new cumulative reward per token * @param _lp true=lpStaking, false=tokenStaking * @return 'Reward' per staked token */ function currentRewardPerTokenStored(bool _lp) public view returns (uint256) { StakingData memory sd = _lp ? lpStaking : tokenStaking; uint256 stakedTokens = sd.stakedTokens; uint256 rewardPerTokenStored = sd.rewardPerTokenStored; // If there is no staked tokens, avoid div(0) if (stakedTokens == 0) { return (rewardPerTokenStored); } // new reward units to distribute = rewardRate * timeSinceLastUpdate uint256 timeDelta = lastTimeRewardApplicable() - sd.lastUpdateTime; uint256 rewardUnitsToDistribute = sd.rewardRate * timeDelta; // new reward units per token = (rewardUnitsToDistribute * 1e18) / stakedTokens uint256 unitsToDistributePerToken = rewardUnitsToDistribute.divPrecisely(stakedTokens); // return summed rate return (rewardPerTokenStored + unitsToDistributePerToken); } /** * @dev Calculates the amount of unclaimed super rewards per token since last update, * and sums with stored to give the new cumulative reward per token * @param _lp true=lpStaking, false=tokenStaking * @return 'Reward' per staked token */ function currentSuperRewardPerTokenStored(bool _lp) public view returns (uint256) { StakingData memory sd = _lp ? lpStaking : tokenStaking; uint256 stakedSuperTokens = sd.stakedSuperTokens; uint256 superRewardPerTokenStored = sd.superRewardPerTokenStored; // If there is no staked tokens, avoid div(0) if (stakedSuperTokens == 0) { return (superRewardPerTokenStored); } // new reward units to distribute = superRewardRate * timeSinceLastSuperUpdate uint256 timeDelta = lastTimeSuperRewardApplicable() - sd.lastSuperUpdateTime; uint256 rewardUnitsToDistribute = sd.superRewardRate * timeDelta; // new reward units per token = (rewardUnitsToDistribute * 1e18) / totalSuperTokens uint256 unitsToDistributePerToken = rewardUnitsToDistribute.divPrecisely(stakedSuperTokens); // return summed rate return (superRewardPerTokenStored + unitsToDistributePerToken); } /** * @dev Calculates the amount of unclaimed rewards a user has earned * @param _account user address * @param _lp true=liquidityStake, false=tokenStake * @return Total reward amount earned */ function _earned(address _account, bool _lp) internal view returns (uint256) { Stake memory s = _lp ? liquidityStake[_account] : tokenStake[_account]; if (s.isWithdrawing) return s.rewards; // current rate per token - rate user previously received uint256 rewardPerTokenStored = currentRewardPerTokenStored(_lp); uint256 userRewardDelta = rewardPerTokenStored - s.rewardPerTokenPaid; uint256 userNewReward = s.tokens.mulTruncate(userRewardDelta); // add to previous rewards return (s.rewards + userNewReward); } /** * @dev Calculates the amount of unclaimed super rewards a user has earned * @param _account user address * @param _lp true=liquidityStake, false=tokenStake * @return Total reward amount earned */ function _earnedSuper(address _account, bool _lp) internal view returns (uint256) { Stake memory s = _lp ? liquidityStake[_account] : tokenStake[_account]; if (!s.isSuperStaker || s.isWithdrawing) return s.rewards; // current rate per token - rate user previously received uint256 superRewardPerTokenStored = currentSuperRewardPerTokenStored(_lp); uint256 superRewardDelta = superRewardPerTokenStored - s.superRewardPerTokenPaid; uint256 userNewSuperReward = s.tokens.mulTruncate(superRewardDelta); // add to previous rewards return (s.rewards + userNewSuperReward); } /** * @dev Calculates the claimable amounts for token and lp stake from normal and super rewards * @param _account user address * @return token - claimable reward amount for token stake * @return lp - claimable reward amount for lp stake */ function claimable(address _account) external view returns (uint256 token, uint256 lp) { token = _earned(_account, false) + _earnedSuper(_account, false) - tokenStake[_account].rewards; lp = _earned(_account, true) + _earnedSuper(_account, true) - liquidityStake[_account].rewards; } /** * @dev Check if staker can set super staker status on token or LP stake * @param _account address to check * @return token true if can set super staker on token stake * @return lp true if can set super staker on LP stake */ function canSetSuper(address _account) external view returns (bool token, bool lp) { Stake memory ts = tokenStake[_account]; Stake memory ls = liquidityStake[_account]; if (ts.tokens > 0 && block.timestamp >= ts.superStakerPossibleAt && !ts.isSuperStaker && !ts.isWithdrawing) token = true; if (ls.tokens > 0 && block.timestamp >= ls.superStakerPossibleAt && !ls.isSuperStaker && !ls.isWithdrawing) lp = true; } /** * @dev internal view to check if msg.sender can unstake * @return true if user requested unstake and time for unstake has passed */ function _canUnstake() private view returns (bool) { return (liquidityStake[msg.sender].isWithdrawing && block.timestamp >= liquidityStake[msg.sender].withdrawalPossibleAt) || (tokenStake[msg.sender].isWithdrawing && block.timestamp >= tokenStake[msg.sender].withdrawalPossibleAt); } /** * @dev external view to check if address can stake tokens * @return true if user can stake tokens */ function canStakeTokens(address _account) external view returns (bool) { return !tokenStake[_account].isWithdrawing; } /** * @dev external view to check if address can stake lp * @return true if user can stake lp */ function canStakeLp(address _account) external view returns (bool) { return !liquidityStake[_account].isWithdrawing; } /*************************************** REWARDER ****************************************/ /** * @dev Notifies the contract that new rewards have been added. * Calculates an updated rewardRate based on the rewards in period. * @param _reward Units of SNP token that have been added to the token pool * @param _lpReward Units of SNP token that have been added to the lp pool */ function notifyRewardAmount(uint256 _reward, uint256 _lpReward) external onlyRewardsDistributor updateRewards(address(0)) { uint256 currentTime = block.timestamp; // pull tokens require(_transferFrom(tokenAddress, msg.sender, _reward + _lpReward) == _reward + _lpReward, "Exclude Rewarder from fee"); // If previous period over, reset rewardRate if (currentTime >= periodFinish) { tokenStaking.rewardRate = _reward / WEEK; lpStaking.rewardRate = _lpReward / WEEK; } // If additional reward to existing period, calc sum else { uint256 remaining = periodFinish - currentTime; uint256 leftoverReward = remaining * tokenStaking.rewardRate; tokenStaking.rewardRate = (_reward + leftoverReward) / WEEK; uint256 leftoverLpReward = remaining * lpStaking.rewardRate; lpStaking.rewardRate = (_lpReward + leftoverLpReward) / WEEK; } tokenStaking.lastUpdateTime = currentTime; lpStaking.lastUpdateTime = currentTime; periodFinish = currentTime + WEEK; data.totalRewardsAdded += _reward + _lpReward; emit Recalculation(_reward, _lpReward); } /*************************************** SUPER STAKER ****************************************/ /** * @dev Notifies the contract that new super rewards have been added based on the collected fee. * Calculates an updated superRewardRate based on the rewards in period. * Function can be triggered by any super staker once a day. */ function _calculateSuperRewardAmount() internal { uint256 currentTime = block.timestamp; // Do nothing if less then a day from last calculation, save gas uint256 lastTime = superPeriodFinish > 0 ? superPeriodFinish - (MONTH - 1 days) : 0; if (currentTime >= lastTime) { uint256 contractBalance = _balance(tokenAddress, address(this)); uint256 feesCollected = contractBalance - data.depositedTokens - (data.totalRewardsAdded + data.totalRewardsFromFees - data.totalRewardsClaimed); data.totalRewardsFromFees += feesCollected; uint256 superRewards; unchecked { superRewards = feesCollected / 2; } // If previous period over, reset rewardRate if (currentTime >= superPeriodFinish) { tokenStaking.superRewardRate = superRewards / MONTH; lpStaking.superRewardRate = superRewards / MONTH; } // If additional reward to existing period, calc sum else { uint256 remaining = superPeriodFinish - currentTime; uint256 leftoverSuperReward = remaining * tokenStaking.superRewardRate; tokenStaking.superRewardRate = (superRewards + leftoverSuperReward) / MONTH; uint256 leftoverSuperLpReward = remaining * lpStaking.superRewardRate; lpStaking.superRewardRate = (superRewards + leftoverSuperLpReward) / MONTH; } tokenStaking.lastSuperUpdateTime = currentTime; lpStaking.lastSuperUpdateTime = currentTime; superPeriodFinish = currentTime + MONTH; emit SuperRecalculation(superRewards, superRewards); } } /*************************************** TOKEN ****************************************/ /** * @dev internal ERC20 tools */ function _balance(address token, address user) internal view returns (uint256) { return IERC20(token).balanceOf(user); } function _transferFrom( address token, address from, uint256 amount ) internal returns (uint256) { return IERC20(token).safeTransferFromDeluxe(from, amount); } function _transfer( address token, address to, uint256 amount ) internal { IERC20(token).safeTransfer(to, amount); } }
// SPDX-License-Identifier: MIT import { Ownable } from "./abstract/Ownable.sol"; pragma solidity 0.8.6; contract Parameterized is Ownable { uint256 internal constant WEEK = 7 days; uint256 internal constant MONTH = 30 days; struct StakeParameters { uint256 value; uint256 lastChange; uint256 minDelay; } /// @notice time to allow to be Super Staker (30*24*60*60) StakeParameters public timeToSuper; /// @notice time to wait for unstake (7*24*60*60) StakeParameters public timeToUnstake; /// @notice fee for premature unstake in 1/10 percent, /// @dev value 1000 = 10% StakeParameters public unstakeFee; function _minusFee(uint256 val) internal view returns (uint256) { return val - ((val * unstakeFee.value) / 10000); } function updateFee(uint256 val) external onlyOwner { require(block.timestamp > unstakeFee.lastChange + unstakeFee.minDelay, "Soon"); require(val <= 2500, "max fee is 25%"); unstakeFee.lastChange = block.timestamp; unstakeFee.value = val; } function updateTimeToUnstake(uint256 val) external onlyOwner { require(block.timestamp > timeToUnstake.lastChange + timeToUnstake.minDelay, "Soon"); require(val <= 2 * WEEK, "Max delay is 14 days"); timeToUnstake.lastChange = block.timestamp; timeToUnstake.value = val; } function updateTimeToSuper(uint256 val) external onlyOwner { require(block.timestamp > timeToSuper.lastChange + timeToSuper.minDelay, "Soon"); require(val <= 3 * MONTH && val >= WEEK, "Delay is 1 week - 3 months"); timeToSuper.lastChange = block.timestamp; timeToSuper.value = val; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.6; abstract contract OwnableData { address public owner; address public pendingOwner; } abstract contract Ownable is OwnableData { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev `owner` defaults to msg.sender on construction. */ constructor() { _setOwner(msg.sender); } /** * @dev Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner. * Can only be invoked by the current `owner`. * @param _newOwner Address of the new owner. * @param _direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`. */ function transferOwnership(address _newOwner, bool _direct) external onlyOwner { if (_direct) { require(_newOwner != address(0), "zero address"); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; pendingOwner = address(0); } else { pendingOwner = _newOwner; } } /** * @dev Needs to be called by `pendingOwner` to claim ownership. */ function claimOwnership() external { address _pendingOwner = pendingOwner; require(msg.sender == _pendingOwner, "caller != pending owner"); emit OwnershipTransferred(owner, _pendingOwner); owner = _pendingOwner; pendingOwner = address(0); } /** * @dev Throws if called by any account other than the Owner. */ modifier onlyOwner() { require(msg.sender == owner, "caller is not the owner"); _; } function _setOwner(address newOwner) internal { address oldOwner = owner; owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.6; import { Ownable } from "./Ownable.sol"; abstract contract RewardsDistributionData { address public rewardsDistributor; } abstract contract RewardsDistribution is Ownable, RewardsDistributionData { event RewardsDistributorChanged(address indexed previousDistributor, address indexed newDistributor); /** * @dev `rewardsDistributor` defaults to msg.sender on construction. */ constructor() { rewardsDistributor = msg.sender; emit RewardsDistributorChanged(address(0), msg.sender); } /** * @dev Throws if called by any account other than the Reward Distributor. */ modifier onlyRewardsDistributor() { require(msg.sender == rewardsDistributor, "caller is not reward distributor"); _; } /** * @dev Change the rewardsDistributor - only called by owner * @param _rewardsDistributor Address of the new distributor */ function setRewardsDistribution(address _rewardsDistributor) external onlyOwner { require(_rewardsDistributor != address(0), "zero address"); emit RewardsDistributorChanged(rewardsDistributor, _rewardsDistributor); rewardsDistributor = _rewardsDistributor; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.6; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.6; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function totalSupply() external view returns (uint256); function decimals() external view returns (uint8); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); // EIP 2612 // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); function nonces(address owner) external view returns (uint256); function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; function transferWithPermit(address target, address to, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.6; import { IERC20 } from "../interfaces/IERC20.sol"; library SafeERC20 { function safeSymbol(IERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x95d89b41)); return success && data.length > 0 ? abi.decode(data, (string)) : "???"; } function safeName(IERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x06fdde03)); return success && data.length > 0 ? abi.decode(data, (string)) : "???"; } function safeDecimals(IERC20 token) internal view returns (uint8) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x313ce567)); return success && data.length == 32 ? abi.decode(data, (uint8)) : 18; } function safeTransfer(IERC20 token, address to, uint256 amount) internal { // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0xa9059cbb, to, amount)); require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: Transfer failed"); } function safeTransferFrom(IERC20 token, address from, uint256 amount) internal { // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0x23b872dd, from, address(this), amount)); require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: TransferFrom failed"); } function safeTransferFromDeluxe(IERC20 token, address from, uint256 amount) internal returns (uint256) { uint256 preBalance = token.balanceOf(address(this)); safeTransferFrom(token, from, amount); uint256 postBalance = token.balanceOf(address(this)); return postBalance - preBalance; } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.6; // Based on StableMath from mStable // https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol library StableMath { /** * @dev Scaling unit for use in specific calculations, * where 1 * 10**18, or 1e18 represents a unit '1' */ uint256 private constant FULL_SCALE = 1e18; /** * @dev Provides an interface to the scaling unit * @return Scaling unit (1e18 or 1 * 10**18) */ function getFullScale() internal pure returns (uint256) { return FULL_SCALE; } /** * @dev Scales a given integer to the power of the full scale. * @param x Simple uint256 to scale * @return Scaled value a to an exact number */ function scaleInteger(uint256 x) internal pure returns (uint256) { return x * FULL_SCALE; } /*************************************** PRECISE ARITHMETIC ****************************************/ /** * @dev Multiplies two precise units, and then truncates by the full scale * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) { return mulTruncateScale(x, y, FULL_SCALE); } /** * @dev Multiplies two precise units, and then truncates by the given scale. For example, * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18 * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @param scale Scale unit * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncateScale( uint256 x, uint256 y, uint256 scale ) internal pure returns (uint256) { // e.g. assume scale = fullScale // z = 10e18 * 9e17 = 9e36 // return 9e36 / 1e18 = 9e18 return (x * y) / scale; } /** * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit, rounded up to the closest base unit. */ function mulTruncateCeil(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e17 * 17268172638 = 138145381104e17 uint256 scaled = x * y; // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17 uint256 ceil = scaled + FULL_SCALE - 1; // e.g. 13814538111.399...e18 / 1e18 = 13814538111 return ceil / FULL_SCALE; } /** * @dev Precisely divides two units, by first scaling the left hand operand. Useful * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17) * @param x Left hand input to division * @param y Right hand input to division * @return Result after multiplying the left operand by the scale, and * executing the division on the right hand input. */ function divPrecisely(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e18 * 1e18 = 8e36 // e.g. 8e36 / 10e18 = 8e17 return (x * FULL_SCALE) / y; } /*************************************** HELPERS ****************************************/ /** * @dev Calculates minimum of two numbers * @param x Left hand input * @param y Right hand input * @return Minimum of the two inputs */ function min(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? y : x; } /** * @dev Calculated maximum of two numbers * @param x Left hand input * @param y Right hand input * @return Maximum of the two inputs */ function max(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? x : y; } /** * @dev Clamps a value to an upper bound * @param x Left hand input * @param upperBound Maximum possible value to return * @return Input x clamped to a maximum value, upperBound */ function clamp(uint256 x, uint256 upperBound) internal pure returns (uint256) { return x > upperBound ? upperBound : x; } }
{ "evmVersion": "berlin", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 999999 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"_timeToSuper","type":"uint256"},{"internalType":"uint256","name":"_timeToUnstake","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpReward","type":"uint256"}],"name":"Recalculation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousDistributor","type":"address"},{"indexed":true,"internalType":"address","name":"newDistributor","type":"address"}],"name":"RewardsDistributorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeLiquidityAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"StakeLiquidityRemoveRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeLiquidityRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"StakeRemoveRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"superReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"superLpReward","type":"uint256"}],"name":"SuperRecalculation","type":"event"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addLiquidityStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"bool","name":"_approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"addLiquidityStakeWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addTokenStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"bool","name":"_approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"addTokenStakeWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"canSetSuper","outputs":[{"internalType":"bool","name":"token","type":"bool"},{"internalType":"bool","name":"lp","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"canStakeLp","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"canStakeTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"claimTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"lp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_lp","type":"bool"}],"name":"currentRewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_lp","type":"bool"}],"name":"currentSuperRewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"data","outputs":[{"internalType":"uint256","name":"depositedTokens","type":"uint256"},{"internalType":"uint256","name":"depositedLiquidity","type":"uint256"},{"internalType":"uint256","name":"totalRewardsAdded","type":"uint256"},{"internalType":"uint256","name":"totalRewardsClaimed","type":"uint256"},{"internalType":"uint256","name":"totalRewardsFromFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_liquidity","type":"address"},{"internalType":"address","name":"_vesting","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeSuperRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"liquidityStake","outputs":[{"internalType":"uint256","name":"stakeStart","type":"uint256"},{"internalType":"uint256","name":"superStakerPossibleAt","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenPaid","type":"uint256"},{"internalType":"uint256","name":"superRewardPerTokenPaid","type":"uint256"},{"internalType":"uint256","name":"tokens","type":"uint256"},{"internalType":"uint256","name":"rewards","type":"uint256"},{"internalType":"uint256","name":"withdrawalPossibleAt","type":"uint256"},{"internalType":"bool","name":"isWithdrawing","type":"bool"},{"internalType":"bool","name":"isSuperStaker","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpStaking","outputs":[{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"superRewardRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"lastSuperUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"superRewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"stakedTokens","type":"uint256"},{"internalType":"uint256","name":"stakedSuperTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reward","type":"uint256"},{"internalType":"uint256","name":"_lpReward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"onClaimAndStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestUnstakeLp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsDistributor","type":"address"}],"name":"setRewardsDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setSuperLp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setSuperToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"superPeriodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeToSuper","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"lastChange","type":"uint256"},{"internalType":"uint256","name":"minDelay","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeToUnstake","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"lastChange","type":"uint256"},{"internalType":"uint256","name":"minDelay","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenStake","outputs":[{"internalType":"uint256","name":"stakeStart","type":"uint256"},{"internalType":"uint256","name":"superStakerPossibleAt","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenPaid","type":"uint256"},{"internalType":"uint256","name":"superRewardPerTokenPaid","type":"uint256"},{"internalType":"uint256","name":"tokens","type":"uint256"},{"internalType":"uint256","name":"rewards","type":"uint256"},{"internalType":"uint256","name":"withdrawalPossibleAt","type":"uint256"},{"internalType":"bool","name":"isWithdrawing","type":"bool"},{"internalType":"bool","name":"isSuperStaker","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenStaking","outputs":[{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"superRewardRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"lastSuperUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"superRewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"stakedTokens","type":"uint256"},{"internalType":"uint256","name":"stakedSuperTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"},{"internalType":"bool","name":"_direct","type":"bool"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeFee","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"lastChange","type":"uint256"},{"internalType":"uint256","name":"minDelay","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unstakeWithFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"updateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"updateTimeToSuper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"updateTimeToUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vestingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162004c9c38038062004c9c8339810160408190526200003491620000fe565b6200003f33620000ae565b600280546001600160a01b031916339081179091556040516000907f52cd8e0a7f86e9df123b3357ab2ee1c4cd0f5ac84ca8c98d93beb2679b2bb806908290a3600160035560049190915560075542600581905560085562093a8060068190556009556103e8600a5562000123565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080604083850312156200011257600080fd5b505080516020909101519092909150565b614b6980620001336000396000f3fe608060405234801561001057600080fd5b506004361061030a5760003560e01c80639012c4a81161019c578063c18c7a7d116100ee578063e8d4ced011610097578063ee14613a11610071578063ee14613a14610865578063f4aac09d14610878578063fc63958e1461088057600080fd5b8063e8d4ced014610841578063eb4e495014610849578063ebe2b12b1461085c57600080fd5b8063db46cc3e116100c8578063db46cc3e146107e5578063dd3cc0ad1461080f578063e30c39781461082157600080fd5b8063c18c7a7d1461079f578063c77c7387146107b2578063d054472e146107d257600080fd5b8063ace2b91611610150578063ba2313f21161012a578063ba2313f214610770578063bac93f2014610783578063bf394ff71461079657600080fd5b8063ace2b9161461065b578063ad6a71a314610700578063b242e5341461075d57600080fd5b80639bf1401c116101815780639bf1401c146106025780639d76ea5814610628578063a262f5f81461064857600080fd5b80639012c4a8146105b257806395ba0bee146105c557600080fd5b806345837a961161026057806373d4a13a1161020957806380faa57d116101e357806380faa57d146105785780638da5cb5b146105805780638ea97d26146105a057600080fd5b806373d4a13a146104cd57806374ef2a961461050f5780637dc30ede1461051757600080fd5b80634f91440d1161023a5780634f91440d1461049c57806360f6b6e8146104a457806364beca15146104c557600080fd5b806345837a96146104795780634e71d92d1461048c5780634e71e0c81461049457600080fd5b80632d7e877f116102c2578063368cafc81161029c578063368cafc8146104045780633f2a554014610431578063402914f51461045157600080fd5b80632d7e877f146103655780632def6620146103b75780633221c93f146103bf57600080fd5b806319762143116102f3578063197621431461032c578063246132f91461033f57806329b31b391461035257600080fd5b80630f1fa81e1461030f578063184b955914610319575b600080fd5b610317610888565b005b610317610327366004614880565b610895565b61031761033a366004614865565b610b76565b61031761034d366004614990565b610d02565b6103176103603660046149b2565b610f53565b6103a2610373366004614865565b73ffffffffffffffffffffffffffffffffffffffff1660009081526028602052604090206007015460ff161590565b60405190151581526020015b60405180910390f35b61031761107c565b600e546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103ae565b60075460085460095461041692919083565b604080519384526020840192909252908201526060016103ae565b6002546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b61046461045f366004614865565b611422565b604080519283526020830191909152016103ae565b6103176104873660046149b2565b6114d3565b6103176115ef565b6103176115f9565b61031761170f565b6104b76104b2366004614924565b611a2a565b6040519081526020016103ae565b6104b7611afb565b6012546013546014546015546016546104e7949392919085565b604080519586526020860194909452928401919091526060830152608082015260a0016103ae565b610317611b0e565b601754601854601954601a54601b54601c54601d54601e5461053d979695949392919088565b604080519889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e0820152610100016103ae565b6104b7611b19565b6000546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b600a54600b54600c5461041692919083565b6103176105c036600461495e565b611b27565b6103a26105d3366004614865565b73ffffffffffffffffffffffffffffffffffffffff1660009081526027602052604090206007015460ff161590565b601f5460205460215460225460235460245460255460265461053d979695949392919088565b600d546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b610317610656366004614865565b611c97565b6106b8610669366004614865565b6028602052600090815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492939192909160ff8082169161010090041689565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c0840152151560e08301521515610100820152610120016103ae565b6106b861070e366004614865565b6027602052600090815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492939192909160ff8082169161010090041689565b61031761076b3660046148c3565b611ca4565b61031761077e36600461495e565b611e83565b61031761079136600461495e565b61200d565b6104b760115481565b6104b76107ad366004614924565b612052565b600f546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b6103176107e036600461495e565b6120fe565b6107f86107f3366004614865565b61213c565b6040805192151583529015156020830152016103ae565b60045460055460065461041692919083565b6001546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b61031761235a565b61031761085736600461495e565b612392565b6104b760105481565b6103176108733660046148fa565b61250d565b610317612855565b610317612da7565b610893336000612ddf565b565b60005473ffffffffffffffffffffffffffffffffffffffff16331461091b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316610998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5f746f6b656e20616464726573732063616e6e6f7420626520300000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff8216610a15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5f6c697175696469747920616464726573732063616e6e6f74206265203000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff8116610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5f76657374696e6720616464726573732063616e6e6f742062652030000000006044820152606401610912565b600d5473ffffffffffffffffffffffffffffffffffffffff1615610b12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e697420616c726561647920646f6e650000000000000000000000000000006044820152606401610912565b600d805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600e805493851693821693909317909255600f8054919093169116179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff8116610c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7a65726f206164647265737300000000000000000000000000000000000000006044820152606401610912565b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f52cd8e0a7f86e9df123b3357ab2ee1c4cd0f5ac84ca8c98d93beb2679b2bb80690600090a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60025473ffffffffffffffffffffffffffffffffffffffff163314610d83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616c6c6572206973206e6f7420726577617264206469737472696275746f726044820152606401610912565b6000610d908160006131bd565b610d9b8160016131bd565b42610da68385614a4f565b600d54610dd39073ffffffffffffffffffffffffffffffffffffffff1633610dce8789614a4f565b613299565b14610e3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4578636c7564652052657761726465722066726f6d20666565000000000000006044820152606401610912565b6010548110610e6857610e5062093a8085614a67565b601755610e6062093a8084614a67565b601f55610ed9565b600081601054610e789190614adf565b601754909150600090610e8b9083614aa2565b905062093a80610e9b8288614a4f565b610ea59190614a67565b601755601f54600090610eb89084614aa2565b905062093a80610ec88288614a4f565b610ed29190614a67565b601f555050505b60198190556021819055610ef062093a8082614a4f565b601055610efd8385614a4f565b60148054600090610f0f908490614a4f565b909155505060408051858152602081018590527f921b4a29d08cacb4cf0c6f947f21a44dbad2a9817be4327b7bbdc9ff505e557b910160405180910390a150505050565b600084610f605786610f82565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b600d546040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018390526064810189905260ff8716608482015260a4810186905260c4810185905291925073ffffffffffffffffffffffffffffffffffffffff169063d505accf9060e401600060405180830381600087803b15801561101957600080fd5b505af115801561102d573d6000803e3d6000fd5b5050505061103d338860006132c4565b60405187815233907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f906020015b60405180910390a250505050505050565b600260035414156110e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b60026003553360009081526028602052604090206004015415158061111f57503360009081526027602052604090206004015415155b611185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b61118d6135d8565b6111f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f7420756e7374616b650000000000000000000000000000000000006044820152606401610912565b600080600080611204336000613649565b945092506112128382614a4f565b9050831561131457336000908152602760205260409020600401546112379083614a4f565b33600090815260276020526040812060040154601280549395509092909190611261908490614adf565b9091555050336000818152602760209081526040918290206004015491519182527fa018dcbc822f59fb0d0c3e7a86c8e4259b9676cdea9e5fc26279b9c4c5d86eef910160405180910390a23360009081526027602052604081208181556001810182905560028101829055600381018290556004810182905560058101829055600681019190915560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555b61131f336001613649565b9450925061132d8382614a4f565b9050831561139c573360009081526028602052604081208181556001810182905560028101829055600381018290556004810182905560058101829055600681019190915560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555b60006113a88284614a4f565b111561141757600d546113db9073ffffffffffffffffffffffffffffffffffffffff16336113d68486614a4f565b613824565b80156114175760405181815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9060200160405180910390a25b505060016003555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526027602052604081206005015481906114578483613845565b611462856000613986565b61146c9190614a4f565b6114769190614adf565b73ffffffffffffffffffffffffffffffffffffffff84166000908152602860205260409020600501549092506114ad846001613845565b6114b8856001613986565b6114c29190614a4f565b6114cc9190614adf565b9050915091565b6000846114e05786611502565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b600e546040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018390526064810189905260ff8716608482015260a4810186905260c4810185905291925073ffffffffffffffffffffffffffffffffffffffff169063d505accf9060e401600060405180830381600087803b15801561159957600080fd5b505af11580156115ad573d6000803e3d6000fd5b505050506115bd338860016132c4565b60405187815233907f642e84c995db6386df09873e261eca65270d7b8bec64957fa3cba3a3878c25299060200161106b565b6108933333613a82565b60015473ffffffffffffffffffffffffffffffffffffffff1633811461167b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c657220213d2070656e64696e67206f776e65720000000000000000006044820152606401610912565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179055600180549091169055565b3360009081526028602052604090206004015415158061174057503360009081526027602052604090206004015415155b6117a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b336117b28160006131bd565b6117bd8160016131bd565b3360006117cb826000613d56565b90506117d8826001613d56565b806117e05750805b905080156117f0576117f0613e6a565b3360009081526027602090815260408083206028909252909120600782015460ff1615611879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b60008160050154836005015461188f9190614a4f565b9050600081116118fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f7468696e6720746f2072657374616b6500000000000000000000000000006044820152606401610912565b600060058085018290558301558254611924574280845560045461191e91614a4f565b60018401555b808360040160008282546119389190614a4f565b9091555050601d8054829190600090611952908490614a4f565b90915550506007830154610100900460ff161561198457806017600701600082825461197e9190614a4f565b90915550505b80601260030160008282546119999190614a4f565b9091555050601280548291906000906119b3908490614a4f565b909155505060405181815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9060200160405180910390a260405181815233907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f9060200160405180910390a2505050505050565b60008082611a39576017611a3c565b601f5b6040805161010081018252825481526001830154602082015260028301549181019190915260038201546060820152600482015460808201819052600583015460a0830152600683015460c0830181905260079093015460e083015290925081611aa857949350505050565b60008360400151611ab7611b19565b611ac19190614adf565b90506000818560000151611ad59190614aa2565b90506000611ae3828661401d565b9050611aef8185614a4f565b98975050505050505050565b6000611b0942601154614043565b905090565b610893336001612ddf565b6000611b0942601054614043565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ba8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b600c54600b54611bb89190614a4f565b4211611c22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109129060208082526004908201527f536f6f6e00000000000000000000000000000000000000000000000000000000604082015260600190565b6109c4811115611c8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6d617820666565206973203235250000000000000000000000000000000000006044820152606401610912565b42600b55600a55565b611ca13382613a82565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b8015611e3e5773ffffffffffffffffffffffffffffffffffffffff8216611da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7a65726f206164647265737300000000000000000000000000000000000000006044820152606401610912565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808616939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556001805490911690555050565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790555b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b600654600554611f149190614a4f565b4211611f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109129060208082526004908201527f536f6f6e00000000000000000000000000000000000000000000000000000000604082015260600190565b611f8c62278d006003614aa2565b8111158015611f9e575062093a808110155b612004576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f44656c61792069732031207765656b202d2033206d6f6e7468730000000000006044820152606401610912565b42600555600455565b612019338260016132c4565b60405181815233907f642e84c995db6386df09873e261eca65270d7b8bec64957fa3cba3a3878c2529906020015b60405180910390a250565b60008082612061576017612064565b601f5b604080516101008101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a08201819052600683015460c083015260079092015460e0820181905290925090816120d157949350505050565b600083606001516120e0611afb565b6120ea9190614adf565b90506000818560200151611ad59190614aa2565b61210a338260006132c4565b60405181815233907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f90602001612047565b6000806000602760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff16151515158152505090506000602860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff1615151515815250509050600082608001511180156122ed575081602001514210155b80156122fc5750816101000151155b801561230a57508160e00151155b1561231457600193505b6000816080015111801561232c575080602001514210155b801561233b5750806101000151155b801561234957508060e00151155b1561235357600192505b5050915091565b612365336001614058565b60405133907fa910809dd00789e69d04a11fbe59837fa35aec1429cb5d20048dfe9b0cc0eead90600090a2565b60005473ffffffffffffffffffffffffffffffffffffffff163314612413576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b6009546008546124239190614a4f565b421161248d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109129060208082526004908201527f536f6f6e00000000000000000000000000000000000000000000000000000000604082015260600190565b61249b62093a806002614aa2565b811115612504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4d61782064656c617920697320313420646179730000000000000000000000006044820152606401610912565b42600855600755565b6002600354141561257a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b600260035581600061258c82826131bd565b83600061259a826000613d56565b90506125a7826001613d56565b806125af5750805b905080156125bf576125bf613e6a565b600f5473ffffffffffffffffffffffffffffffffffffffff163314612640576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4f6e6c792076657374696e6720636f6e747261637400000000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff861660009081526027602052604090206007015460ff16156126d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b6000851161273d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f20416d6f756e740000000000000000000000000000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff861660009081526027602052604090208054601790612781574280835560045461277b91614a4f565b60018301555b868260040160008282546127959190614a4f565b92505081905550868160060160008282546127b09190614a4f565b90915550506007820154610100900460ff16156127e157868160070160008282546127db9190614a4f565b90915550505b86601260000160008282546127f69190614a4f565b909155505060405187815273ffffffffffffffffffffffffffffffffffffffff8916907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f9060200160405180910390a250506001600355505050505050565b600260035414156128c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b6002600355336000908152602860205260409020600401541515806128f857503360009081526027602052604090206004015415155b61295e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b6129666135d8565b156129cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f556e7374616b65206669727374000000000000000000000000000000000000006044820152606401610912565b6000602760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff16151515158152505090506000602860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff16151515158152505090506000808260e0015115612c99576000612b7f8460800151614308565b90508360a0015182612b919190614a4f565b91508360a0015160126003016000828254612bac9190614a4f565b9091555050608084015160138054600090612bc8908490614adf565b9091555050608084015160405190815233907fbb37929ba745d1c183522217faa28a183a44c70dd5fc0a135bb7242d1e4f97739060200160405180910390a28015612c3157600e54612c319073ffffffffffffffffffffffffffffffffffffffff163383613824565b503360009081526028602052604081208181556001810182905560028101829055600381018290556004810182905560058101829055600681019190915560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555b8360e001511561139c57612cb08460800151614308565b91508360a0015181612cc29190614a4f565b90508360a0015160126003016000828254612cdd9190614a4f565b9091555050608084015160128054600090612cf9908490614adf565b9091555050608084015160405190815233907fa018dcbc822f59fb0d0c3e7a86c8e4259b9676cdea9e5fc26279b9c4c5d86eef9060200160405180910390a233600090815260276020526040812081815560018101829055600281018290556003810182905560048101829055600581018290556006810182905560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556113a88284614a4f565b612db2336000614058565b60405133907fc0e0022681c64867610b70899a07bee5aa6e6c0d5e40cf3351a426fa9a81052990600090a2565b8181600081612e185773ffffffffffffffffffffffffffffffffffffffff83166000908152602760205260409020600401541515612e44565b73ffffffffffffffffffffffffffffffffffffffff831660009081526028602052604090206004015415155b905080612ead576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b8484600081612ee05773ffffffffffffffffffffffffffffffffffffffff83166000908152602760205260409020612f06565b73ffffffffffffffffffffffffffffffffffffffff831660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff80821615801560e085015261010092839004909116151591830191909152909150612fe2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b8061010001511561304f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f416c7265616479207375706572207374616b65720000000000000000000000006044820152606401610912565b80602001514210156130bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f546f6f20736f6f6e0000000000000000000000000000000000000000000000006044820152606401610912565b6000806130cb826000613d56565b90506130d8826001613d56565b806130e05750805b905080156130f0576130f0613e6a565b6000896131215773ffffffffffffffffffffffffffffffffffffffff8b166000908152602760205260409020613147565b73ffffffffffffffffffffffffffffffffffffffff8b1660009081526028602052604090205b905060008a61315757601761315a565b601f5b905081600401548160070160008282546131749190614a4f565b90915550506007820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790556005015460039091015550505050505050505050565b60006131c882611a2a565b90508015613294576000826131de5760176131e1565b601f5b6004810183905590506131f2611b19565b600282015573ffffffffffffffffffffffffffffffffffffffff841615613292576000836132445773ffffffffffffffffffffffffffffffffffffffff8516600090815260276020526040902061326a565b73ffffffffffffffffffffffffffffffffffffffff851660009081526028602052604090205b600781015490915060ff16613290576132838585613986565b6005820155600281018390555b505b505b505050565b60006132bc73ffffffffffffffffffffffffffffffffffffffff85168484614330565b949350505050565b60026003541415613331576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b6002600355828161334282826131bd565b846000613350826000613d56565b905061335d826001613d56565b806133655750805b9050801561337557613375613e6a565b600086116133df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f20416d6f756e740000000000000000000000000000000000000000006044820152606401610912565b6000856134105773ffffffffffffffffffffffffffffffffffffffff88166000908152602760205260409020613436565b73ffffffffffffffffffffffffffffffffffffffff881660009081526028602052604090205b600781015490915060ff16156134a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b6000866134cd57600d5473ffffffffffffffffffffffffffffffffffffffff166134e7565b600e5473ffffffffffffffffffffffffffffffffffffffff165b90506134f481338a613299565b8254909850613513574280835560045461350d91614a4f565b60018301555b600087613521576017613524565b601f5b90508883600401600082825461353a9190614a4f565b92505081905550888160060160008282546135559190614a4f565b90915550506007830154610100900460ff161561358657888160070160008282546135809190614a4f565b90915550505b87156135ac5788601260010160008282546135a19190614a4f565b909155506135c79050565b88601260000160008282546135c19190614a4f565b90915550505b505060016003555050505050505050565b3360009081526028602052604081206007015460ff16801561360c5750336000908152602860205260409020600601544210155b80611b0957503360009081526027602052604090206007015460ff168015611b095750503360009081526027602052604090206006015442101590565b60008060008361367d5773ffffffffffffffffffffffffffffffffffffffff851660009081526027602052604090206136a3565b73ffffffffffffffffffffffffffffffffffffffff851660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e084018190526101009283900490911615159183019190915290915061372b57600080925092505061381d565b428160c00151111561374457600080925092505061381d565b60a08101516015805460009061375b908490614a4f565b909155508490508015613772575060008160800151115b156138125760808101516013805460009061378e908490614adf565b9091555050600e5460808201516137bd9173ffffffffffffffffffffffffffffffffffffffff16908790613824565b8473ffffffffffffffffffffffffffffffffffffffff167fbb37929ba745d1c183522217faa28a183a44c70dd5fc0a135bb7242d1e4f9773826080015160405161380991815260200190565b60405180910390a25b60a001519150600190505b9250929050565b61329473ffffffffffffffffffffffffffffffffffffffff84168383614495565b600080826138775773ffffffffffffffffffffffffffffffffffffffff8416600090815260276020526040902061389d565b73ffffffffffffffffffffffffffffffffffffffff841660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e08401526101009182900416158015918301919091529091508061391d57508060e001515b1561392d5760a001519050613980565b600061393884612052565b9050600082606001518261394c9190614adf565b905060006139678285608001516145fe90919063ffffffff16565b9050808460a001516139799190614a4f565b9450505050505b92915050565b600080826139b85773ffffffffffffffffffffffffffffffffffffffff841660009081526027602052604090206139de565b73ffffffffffffffffffffffffffffffffffffffff841660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff80821615801560e085015261010092839004909116151591830191909152909150613a635760a001519050613980565b6000613a6e84611a2a565b9050600082604001518261394c9190614adf565b60026003541415613aef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b600260035533600090815260286020526040902060040154151580613b2557503360009081526027602052604090206004015415155b613b8b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b81613b978160006131bd565b613ba28160016131bd565b826000613bb0826000613d56565b9050613bbd826001613d56565b80613bc55750805b90508015613bd557613bd5613e6a565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260286020908152604080832060059081015460279093529083200154613c179190614a4f565b905060008111613c83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7468696e6720746f20636c61696d000000000000000000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff861660009081526027602090815260408083206005908101849055602890925282200181905560158054839290613cd0908490614a4f565b9091555050600d54613cf99073ffffffffffffffffffffffffffffffffffffffff168683613824565b8573ffffffffffffffffffffffffffffffffffffffff167fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a82604051613d4191815260200190565b60405180910390a25050600160035550505050565b60008082613d885773ffffffffffffffffffffffffffffffffffffffff84166000908152602760205260409020613dae565b73ffffffffffffffffffffffffffffffffffffffff841660009081526028602052604090205b6007810154909150610100900460ff1680613ddd575073ffffffffffffffffffffffffffffffffffffffff8416155b15613e63576000613ded84612052565b90508015613e5d57600084613e03576017613e06565b601f5b600581018390559050613e17611afb565b600382015573ffffffffffffffffffffffffffffffffffffffff861615613e5b57600783015460ff16613e5b57613e4e8686613845565b6005840155600383018290555b505b60019250505b5092915050565b6011544290600090613e7d576000613e9a565b613e8d6201518062278d00614adf565b601154613e9a9190614adf565b9050808210611e7f57600d54600090613ec99073ffffffffffffffffffffffffffffffffffffffff1630614613565b601554601654601454929350600092613ee29190614a4f565b613eec9190614adf565b601254613ef99084614adf565b613f039190614adf565b90508060126004016000828254613f1a9190614a4f565b909155505060115460028204908510613f5257613f3a62278d0082614a67565b601855613f4a62278d0082614a67565b602055613fc3565b600085601154613f629190614adf565b601854909150600090613f759083614aa2565b905062278d00613f858285614a4f565b613f8f9190614a67565b601855602054600090613fa29084614aa2565b905062278d00613fb28286614a4f565b613fbc9190614a67565b6020555050505b601a8590556022859055613fda62278d0086614a4f565b60115560408051828152602081018390527fb2e45d21bc3a556247a4a3ad6cd0b08145d486b943b9e671263fca15bef18b6d910160405180910390a15050505050565b600081614032670de0b6b3a764000085614aa2565b61403c9190614a67565b9392505050565b6000818311614052578261403c565b50919050565b81816000816140915773ffffffffffffffffffffffffffffffffffffffff831660009081526027602052604090206004015415156140bd565b73ffffffffffffffffffffffffffffffffffffffff831660009081526028602052604090206004015415155b905080614126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b848461413282826131bd565b866000614140826000613d56565b905061414d826001613d56565b806141555750805b9050801561416557614165613e6a565b6000886141965773ffffffffffffffffffffffffffffffffffffffff8a1660009081526027602052604090206141bc565b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526028602052604090205b600781015490915060ff161561422e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b60008961423c57601761423f565b601f5b600780840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555490915061427b9042614a4f565b8260060181905550816004015481600601600082825461429b9190614adf565b90915550506007820154610100900460ff16156142fb57600780830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055600483015490820180546000906142f5908490614adf565b90915550505b5050505050505050505050565b600a546000906127109061431c9084614aa2565b6143269190614a67565b6139809083614adf565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff8616906370a082319060240160206040518083038186803b15801561439a57600080fd5b505afa1580156143ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143d29190614977565b90506143df8585856146b6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a082319060240160206040518083038186803b15801561444757600080fd5b505afa15801561445b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061447f9190614977565b905061448b8282614adf565b9695505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161452c9190614a14565b6000604051808303816000865af19150503d8060008114614569576040519150601f19603f3d011682016040523d82523d6000602084013e61456e565b606091505b50915091508180156145985750805115806145985750808060200190518101906145989190614941565b613290576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a205472616e73666572206661696c65640000000000006044820152606401610912565b600061403c8383670de0b6b3a7640000614825565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908416906370a082319060240160206040518083038186803b15801561467e57600080fd5b505afa158015614692573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061403c9190614977565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152306044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908716916147539190614a14565b6000604051808303816000865af19150503d8060008114614790576040519150601f19603f3d011682016040523d82523d6000602084013e614795565b606091505b50915091508180156147bf5750805115806147bf5750808060200190518101906147bf9190614941565b613290576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5361666545524332303a205472616e7366657246726f6d206661696c656400006044820152606401610912565b6000816148328486614aa2565b6132bc9190614a67565b803573ffffffffffffffffffffffffffffffffffffffff8116811461486057600080fd5b919050565b60006020828403121561487757600080fd5b61403c8261483c565b60008060006060848603121561489557600080fd5b61489e8461483c565b92506148ac6020850161483c565b91506148ba6040850161483c565b90509250925092565b600080604083850312156148d657600080fd5b6148df8361483c565b915060208301356148ef81614b25565b809150509250929050565b6000806040838503121561490d57600080fd5b6149168361483c565b946020939093013593505050565b60006020828403121561493657600080fd5b813561403c81614b25565b60006020828403121561495357600080fd5b815161403c81614b25565b60006020828403121561497057600080fd5b5035919050565b60006020828403121561498957600080fd5b5051919050565b600080604083850312156149a357600080fd5b50508035926020909101359150565b60008060008060008060c087890312156149cb57600080fd5b863595506020870135945060408701356149e481614b25565b9350606087013560ff811681146149fa57600080fd5b9598949750929560808101359460a0909101359350915050565b6000825160005b81811015614a355760208186018101518583015201614a1b565b81811115614a44576000828501525b509190910192915050565b60008219821115614a6257614a62614af6565b500190565b600082614a9d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ada57614ada614af6565b500290565b600082821015614af157614af1614af6565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8015158114611ca157600080fdfea2646970667358221220ab857582abc76de18375965040d6e7cddc1fa05da9db05efc941556c24cbcc5864736f6c634300080600330000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000093a80
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061030a5760003560e01c80639012c4a81161019c578063c18c7a7d116100ee578063e8d4ced011610097578063ee14613a11610071578063ee14613a14610865578063f4aac09d14610878578063fc63958e1461088057600080fd5b8063e8d4ced014610841578063eb4e495014610849578063ebe2b12b1461085c57600080fd5b8063db46cc3e116100c8578063db46cc3e146107e5578063dd3cc0ad1461080f578063e30c39781461082157600080fd5b8063c18c7a7d1461079f578063c77c7387146107b2578063d054472e146107d257600080fd5b8063ace2b91611610150578063ba2313f21161012a578063ba2313f214610770578063bac93f2014610783578063bf394ff71461079657600080fd5b8063ace2b9161461065b578063ad6a71a314610700578063b242e5341461075d57600080fd5b80639bf1401c116101815780639bf1401c146106025780639d76ea5814610628578063a262f5f81461064857600080fd5b80639012c4a8146105b257806395ba0bee146105c557600080fd5b806345837a961161026057806373d4a13a1161020957806380faa57d116101e357806380faa57d146105785780638da5cb5b146105805780638ea97d26146105a057600080fd5b806373d4a13a146104cd57806374ef2a961461050f5780637dc30ede1461051757600080fd5b80634f91440d1161023a5780634f91440d1461049c57806360f6b6e8146104a457806364beca15146104c557600080fd5b806345837a96146104795780634e71d92d1461048c5780634e71e0c81461049457600080fd5b80632d7e877f116102c2578063368cafc81161029c578063368cafc8146104045780633f2a554014610431578063402914f51461045157600080fd5b80632d7e877f146103655780632def6620146103b75780633221c93f146103bf57600080fd5b806319762143116102f3578063197621431461032c578063246132f91461033f57806329b31b391461035257600080fd5b80630f1fa81e1461030f578063184b955914610319575b600080fd5b610317610888565b005b610317610327366004614880565b610895565b61031761033a366004614865565b610b76565b61031761034d366004614990565b610d02565b6103176103603660046149b2565b610f53565b6103a2610373366004614865565b73ffffffffffffffffffffffffffffffffffffffff1660009081526028602052604090206007015460ff161590565b60405190151581526020015b60405180910390f35b61031761107c565b600e546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103ae565b60075460085460095461041692919083565b604080519384526020840192909252908201526060016103ae565b6002546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b61046461045f366004614865565b611422565b604080519283526020830191909152016103ae565b6103176104873660046149b2565b6114d3565b6103176115ef565b6103176115f9565b61031761170f565b6104b76104b2366004614924565b611a2a565b6040519081526020016103ae565b6104b7611afb565b6012546013546014546015546016546104e7949392919085565b604080519586526020860194909452928401919091526060830152608082015260a0016103ae565b610317611b0e565b601754601854601954601a54601b54601c54601d54601e5461053d979695949392919088565b604080519889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e0820152610100016103ae565b6104b7611b19565b6000546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b600a54600b54600c5461041692919083565b6103176105c036600461495e565b611b27565b6103a26105d3366004614865565b73ffffffffffffffffffffffffffffffffffffffff1660009081526027602052604090206007015460ff161590565b601f5460205460215460225460235460245460255460265461053d979695949392919088565b600d546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b610317610656366004614865565b611c97565b6106b8610669366004614865565b6028602052600090815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492939192909160ff8082169161010090041689565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c0840152151560e08301521515610100820152610120016103ae565b6106b861070e366004614865565b6027602052600090815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492939192909160ff8082169161010090041689565b61031761076b3660046148c3565b611ca4565b61031761077e36600461495e565b611e83565b61031761079136600461495e565b61200d565b6104b760115481565b6104b76107ad366004614924565b612052565b600f546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b6103176107e036600461495e565b6120fe565b6107f86107f3366004614865565b61213c565b6040805192151583529015156020830152016103ae565b60045460055460065461041692919083565b6001546103df9073ffffffffffffffffffffffffffffffffffffffff1681565b61031761235a565b61031761085736600461495e565b612392565b6104b760105481565b6103176108733660046148fa565b61250d565b610317612855565b610317612da7565b610893336000612ddf565b565b60005473ffffffffffffffffffffffffffffffffffffffff16331461091b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316610998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5f746f6b656e20616464726573732063616e6e6f7420626520300000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff8216610a15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5f6c697175696469747920616464726573732063616e6e6f74206265203000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff8116610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5f76657374696e6720616464726573732063616e6e6f742062652030000000006044820152606401610912565b600d5473ffffffffffffffffffffffffffffffffffffffff1615610b12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e697420616c726561647920646f6e650000000000000000000000000000006044820152606401610912565b600d805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600e805493851693821693909317909255600f8054919093169116179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff8116610c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7a65726f206164647265737300000000000000000000000000000000000000006044820152606401610912565b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f52cd8e0a7f86e9df123b3357ab2ee1c4cd0f5ac84ca8c98d93beb2679b2bb80690600090a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60025473ffffffffffffffffffffffffffffffffffffffff163314610d83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616c6c6572206973206e6f7420726577617264206469737472696275746f726044820152606401610912565b6000610d908160006131bd565b610d9b8160016131bd565b42610da68385614a4f565b600d54610dd39073ffffffffffffffffffffffffffffffffffffffff1633610dce8789614a4f565b613299565b14610e3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4578636c7564652052657761726465722066726f6d20666565000000000000006044820152606401610912565b6010548110610e6857610e5062093a8085614a67565b601755610e6062093a8084614a67565b601f55610ed9565b600081601054610e789190614adf565b601754909150600090610e8b9083614aa2565b905062093a80610e9b8288614a4f565b610ea59190614a67565b601755601f54600090610eb89084614aa2565b905062093a80610ec88288614a4f565b610ed29190614a67565b601f555050505b60198190556021819055610ef062093a8082614a4f565b601055610efd8385614a4f565b60148054600090610f0f908490614a4f565b909155505060408051858152602081018590527f921b4a29d08cacb4cf0c6f947f21a44dbad2a9817be4327b7bbdc9ff505e557b910160405180910390a150505050565b600084610f605786610f82565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b600d546040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018390526064810189905260ff8716608482015260a4810186905260c4810185905291925073ffffffffffffffffffffffffffffffffffffffff169063d505accf9060e401600060405180830381600087803b15801561101957600080fd5b505af115801561102d573d6000803e3d6000fd5b5050505061103d338860006132c4565b60405187815233907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f906020015b60405180910390a250505050505050565b600260035414156110e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b60026003553360009081526028602052604090206004015415158061111f57503360009081526027602052604090206004015415155b611185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b61118d6135d8565b6111f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f7420756e7374616b650000000000000000000000000000000000006044820152606401610912565b600080600080611204336000613649565b945092506112128382614a4f565b9050831561131457336000908152602760205260409020600401546112379083614a4f565b33600090815260276020526040812060040154601280549395509092909190611261908490614adf565b9091555050336000818152602760209081526040918290206004015491519182527fa018dcbc822f59fb0d0c3e7a86c8e4259b9676cdea9e5fc26279b9c4c5d86eef910160405180910390a23360009081526027602052604081208181556001810182905560028101829055600381018290556004810182905560058101829055600681019190915560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555b61131f336001613649565b9450925061132d8382614a4f565b9050831561139c573360009081526028602052604081208181556001810182905560028101829055600381018290556004810182905560058101829055600681019190915560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555b60006113a88284614a4f565b111561141757600d546113db9073ffffffffffffffffffffffffffffffffffffffff16336113d68486614a4f565b613824565b80156114175760405181815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9060200160405180910390a25b505060016003555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526027602052604081206005015481906114578483613845565b611462856000613986565b61146c9190614a4f565b6114769190614adf565b73ffffffffffffffffffffffffffffffffffffffff84166000908152602860205260409020600501549092506114ad846001613845565b6114b8856001613986565b6114c29190614a4f565b6114cc9190614adf565b9050915091565b6000846114e05786611502565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b600e546040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018390526064810189905260ff8716608482015260a4810186905260c4810185905291925073ffffffffffffffffffffffffffffffffffffffff169063d505accf9060e401600060405180830381600087803b15801561159957600080fd5b505af11580156115ad573d6000803e3d6000fd5b505050506115bd338860016132c4565b60405187815233907f642e84c995db6386df09873e261eca65270d7b8bec64957fa3cba3a3878c25299060200161106b565b6108933333613a82565b60015473ffffffffffffffffffffffffffffffffffffffff1633811461167b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c657220213d2070656e64696e67206f776e65720000000000000000006044820152606401610912565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179055600180549091169055565b3360009081526028602052604090206004015415158061174057503360009081526027602052604090206004015415155b6117a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b336117b28160006131bd565b6117bd8160016131bd565b3360006117cb826000613d56565b90506117d8826001613d56565b806117e05750805b905080156117f0576117f0613e6a565b3360009081526027602090815260408083206028909252909120600782015460ff1615611879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b60008160050154836005015461188f9190614a4f565b9050600081116118fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f7468696e6720746f2072657374616b6500000000000000000000000000006044820152606401610912565b600060058085018290558301558254611924574280845560045461191e91614a4f565b60018401555b808360040160008282546119389190614a4f565b9091555050601d8054829190600090611952908490614a4f565b90915550506007830154610100900460ff161561198457806017600701600082825461197e9190614a4f565b90915550505b80601260030160008282546119999190614a4f565b9091555050601280548291906000906119b3908490614a4f565b909155505060405181815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9060200160405180910390a260405181815233907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f9060200160405180910390a2505050505050565b60008082611a39576017611a3c565b601f5b6040805161010081018252825481526001830154602082015260028301549181019190915260038201546060820152600482015460808201819052600583015460a0830152600683015460c0830181905260079093015460e083015290925081611aa857949350505050565b60008360400151611ab7611b19565b611ac19190614adf565b90506000818560000151611ad59190614aa2565b90506000611ae3828661401d565b9050611aef8185614a4f565b98975050505050505050565b6000611b0942601154614043565b905090565b610893336001612ddf565b6000611b0942601054614043565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ba8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b600c54600b54611bb89190614a4f565b4211611c22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109129060208082526004908201527f536f6f6e00000000000000000000000000000000000000000000000000000000604082015260600190565b6109c4811115611c8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6d617820666565206973203235250000000000000000000000000000000000006044820152606401610912565b42600b55600a55565b611ca13382613a82565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b8015611e3e5773ffffffffffffffffffffffffffffffffffffffff8216611da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7a65726f206164647265737300000000000000000000000000000000000000006044820152606401610912565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808616939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556001805490911690555050565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790555b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b600654600554611f149190614a4f565b4211611f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109129060208082526004908201527f536f6f6e00000000000000000000000000000000000000000000000000000000604082015260600190565b611f8c62278d006003614aa2565b8111158015611f9e575062093a808110155b612004576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f44656c61792069732031207765656b202d2033206d6f6e7468730000000000006044820152606401610912565b42600555600455565b612019338260016132c4565b60405181815233907f642e84c995db6386df09873e261eca65270d7b8bec64957fa3cba3a3878c2529906020015b60405180910390a250565b60008082612061576017612064565b601f5b604080516101008101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a08201819052600683015460c083015260079092015460e0820181905290925090816120d157949350505050565b600083606001516120e0611afb565b6120ea9190614adf565b90506000818560200151611ad59190614aa2565b61210a338260006132c4565b60405181815233907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f90602001612047565b6000806000602760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff16151515158152505090506000602860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff1615151515815250509050600082608001511180156122ed575081602001514210155b80156122fc5750816101000151155b801561230a57508160e00151155b1561231457600193505b6000816080015111801561232c575080602001514210155b801561233b5750806101000151155b801561234957508060e00151155b1561235357600192505b5050915091565b612365336001614058565b60405133907fa910809dd00789e69d04a11fbe59837fa35aec1429cb5d20048dfe9b0cc0eead90600090a2565b60005473ffffffffffffffffffffffffffffffffffffffff163314612413576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e65720000000000000000006044820152606401610912565b6009546008546124239190614a4f565b421161248d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109129060208082526004908201527f536f6f6e00000000000000000000000000000000000000000000000000000000604082015260600190565b61249b62093a806002614aa2565b811115612504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4d61782064656c617920697320313420646179730000000000000000000000006044820152606401610912565b42600855600755565b6002600354141561257a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b600260035581600061258c82826131bd565b83600061259a826000613d56565b90506125a7826001613d56565b806125af5750805b905080156125bf576125bf613e6a565b600f5473ffffffffffffffffffffffffffffffffffffffff163314612640576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4f6e6c792076657374696e6720636f6e747261637400000000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff861660009081526027602052604090206007015460ff16156126d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b6000851161273d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f20416d6f756e740000000000000000000000000000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff861660009081526027602052604090208054601790612781574280835560045461277b91614a4f565b60018301555b868260040160008282546127959190614a4f565b92505081905550868160060160008282546127b09190614a4f565b90915550506007820154610100900460ff16156127e157868160070160008282546127db9190614a4f565b90915550505b86601260000160008282546127f69190614a4f565b909155505060405187815273ffffffffffffffffffffffffffffffffffffffff8916907f7c717985ac273e663b7f3050f5b15a4388ff6ed952338954f650e2093e13937f9060200160405180910390a250506001600355505050505050565b600260035414156128c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b6002600355336000908152602860205260409020600401541515806128f857503360009081526027602052604090206004015415155b61295e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b6129666135d8565b156129cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f556e7374616b65206669727374000000000000000000000000000000000000006044820152606401610912565b6000602760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff16151515158152505090506000602860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180610120016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016007820160019054906101000a900460ff16151515158152505090506000808260e0015115612c99576000612b7f8460800151614308565b90508360a0015182612b919190614a4f565b91508360a0015160126003016000828254612bac9190614a4f565b9091555050608084015160138054600090612bc8908490614adf565b9091555050608084015160405190815233907fbb37929ba745d1c183522217faa28a183a44c70dd5fc0a135bb7242d1e4f97739060200160405180910390a28015612c3157600e54612c319073ffffffffffffffffffffffffffffffffffffffff163383613824565b503360009081526028602052604081208181556001810182905560028101829055600381018290556004810182905560058101829055600681019190915560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555b8360e001511561139c57612cb08460800151614308565b91508360a0015181612cc29190614a4f565b90508360a0015160126003016000828254612cdd9190614a4f565b9091555050608084015160128054600090612cf9908490614adf565b9091555050608084015160405190815233907fa018dcbc822f59fb0d0c3e7a86c8e4259b9676cdea9e5fc26279b9c4c5d86eef9060200160405180910390a233600090815260276020526040812081815560018101829055600281018290556003810182905560048101829055600581018290556006810182905560070180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556113a88284614a4f565b612db2336000614058565b60405133907fc0e0022681c64867610b70899a07bee5aa6e6c0d5e40cf3351a426fa9a81052990600090a2565b8181600081612e185773ffffffffffffffffffffffffffffffffffffffff83166000908152602760205260409020600401541515612e44565b73ffffffffffffffffffffffffffffffffffffffff831660009081526028602052604090206004015415155b905080612ead576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b8484600081612ee05773ffffffffffffffffffffffffffffffffffffffff83166000908152602760205260409020612f06565b73ffffffffffffffffffffffffffffffffffffffff831660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff80821615801560e085015261010092839004909116151591830191909152909150612fe2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b8061010001511561304f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f416c7265616479207375706572207374616b65720000000000000000000000006044820152606401610912565b80602001514210156130bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f546f6f20736f6f6e0000000000000000000000000000000000000000000000006044820152606401610912565b6000806130cb826000613d56565b90506130d8826001613d56565b806130e05750805b905080156130f0576130f0613e6a565b6000896131215773ffffffffffffffffffffffffffffffffffffffff8b166000908152602760205260409020613147565b73ffffffffffffffffffffffffffffffffffffffff8b1660009081526028602052604090205b905060008a61315757601761315a565b601f5b905081600401548160070160008282546131749190614a4f565b90915550506007820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790556005015460039091015550505050505050505050565b60006131c882611a2a565b90508015613294576000826131de5760176131e1565b601f5b6004810183905590506131f2611b19565b600282015573ffffffffffffffffffffffffffffffffffffffff841615613292576000836132445773ffffffffffffffffffffffffffffffffffffffff8516600090815260276020526040902061326a565b73ffffffffffffffffffffffffffffffffffffffff851660009081526028602052604090205b600781015490915060ff16613290576132838585613986565b6005820155600281018390555b505b505b505050565b60006132bc73ffffffffffffffffffffffffffffffffffffffff85168484614330565b949350505050565b60026003541415613331576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b6002600355828161334282826131bd565b846000613350826000613d56565b905061335d826001613d56565b806133655750805b9050801561337557613375613e6a565b600086116133df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f20416d6f756e740000000000000000000000000000000000000000006044820152606401610912565b6000856134105773ffffffffffffffffffffffffffffffffffffffff88166000908152602760205260409020613436565b73ffffffffffffffffffffffffffffffffffffffff881660009081526028602052604090205b600781015490915060ff16156134a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b6000866134cd57600d5473ffffffffffffffffffffffffffffffffffffffff166134e7565b600e5473ffffffffffffffffffffffffffffffffffffffff165b90506134f481338a613299565b8254909850613513574280835560045461350d91614a4f565b60018301555b600087613521576017613524565b601f5b90508883600401600082825461353a9190614a4f565b92505081905550888160060160008282546135559190614a4f565b90915550506007830154610100900460ff161561358657888160070160008282546135809190614a4f565b90915550505b87156135ac5788601260010160008282546135a19190614a4f565b909155506135c79050565b88601260000160008282546135c19190614a4f565b90915550505b505060016003555050505050505050565b3360009081526028602052604081206007015460ff16801561360c5750336000908152602860205260409020600601544210155b80611b0957503360009081526027602052604090206007015460ff168015611b095750503360009081526027602052604090206006015442101590565b60008060008361367d5773ffffffffffffffffffffffffffffffffffffffff851660009081526027602052604090206136a3565b73ffffffffffffffffffffffffffffffffffffffff851660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e084018190526101009283900490911615159183019190915290915061372b57600080925092505061381d565b428160c00151111561374457600080925092505061381d565b60a08101516015805460009061375b908490614a4f565b909155508490508015613772575060008160800151115b156138125760808101516013805460009061378e908490614adf565b9091555050600e5460808201516137bd9173ffffffffffffffffffffffffffffffffffffffff16908790613824565b8473ffffffffffffffffffffffffffffffffffffffff167fbb37929ba745d1c183522217faa28a183a44c70dd5fc0a135bb7242d1e4f9773826080015160405161380991815260200190565b60405180910390a25b60a001519150600190505b9250929050565b61329473ffffffffffffffffffffffffffffffffffffffff84168383614495565b600080826138775773ffffffffffffffffffffffffffffffffffffffff8416600090815260276020526040902061389d565b73ffffffffffffffffffffffffffffffffffffffff841660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e08401526101009182900416158015918301919091529091508061391d57508060e001515b1561392d5760a001519050613980565b600061393884612052565b9050600082606001518261394c9190614adf565b905060006139678285608001516145fe90919063ffffffff16565b9050808460a001516139799190614a4f565b9450505050505b92915050565b600080826139b85773ffffffffffffffffffffffffffffffffffffffff841660009081526027602052604090206139de565b73ffffffffffffffffffffffffffffffffffffffff841660009081526028602052604090205b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff80821615801560e085015261010092839004909116151591830191909152909150613a635760a001519050613980565b6000613a6e84611a2a565b9050600082604001518261394c9190614adf565b60026003541415613aef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610912565b600260035533600090815260286020526040902060040154151580613b2557503360009081526027602052604090206004015415155b613b8b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b81613b978160006131bd565b613ba28160016131bd565b826000613bb0826000613d56565b9050613bbd826001613d56565b80613bc55750805b90508015613bd557613bd5613e6a565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260286020908152604080832060059081015460279093529083200154613c179190614a4f565b905060008111613c83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7468696e6720746f20636c61696d000000000000000000000000000000006044820152606401610912565b73ffffffffffffffffffffffffffffffffffffffff861660009081526027602090815260408083206005908101849055602890925282200181905560158054839290613cd0908490614a4f565b9091555050600d54613cf99073ffffffffffffffffffffffffffffffffffffffff168683613824565b8573ffffffffffffffffffffffffffffffffffffffff167fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a82604051613d4191815260200190565b60405180910390a25050600160035550505050565b60008082613d885773ffffffffffffffffffffffffffffffffffffffff84166000908152602760205260409020613dae565b73ffffffffffffffffffffffffffffffffffffffff841660009081526028602052604090205b6007810154909150610100900460ff1680613ddd575073ffffffffffffffffffffffffffffffffffffffff8416155b15613e63576000613ded84612052565b90508015613e5d57600084613e03576017613e06565b601f5b600581018390559050613e17611afb565b600382015573ffffffffffffffffffffffffffffffffffffffff861615613e5b57600783015460ff16613e5b57613e4e8686613845565b6005840155600383018290555b505b60019250505b5092915050565b6011544290600090613e7d576000613e9a565b613e8d6201518062278d00614adf565b601154613e9a9190614adf565b9050808210611e7f57600d54600090613ec99073ffffffffffffffffffffffffffffffffffffffff1630614613565b601554601654601454929350600092613ee29190614a4f565b613eec9190614adf565b601254613ef99084614adf565b613f039190614adf565b90508060126004016000828254613f1a9190614a4f565b909155505060115460028204908510613f5257613f3a62278d0082614a67565b601855613f4a62278d0082614a67565b602055613fc3565b600085601154613f629190614adf565b601854909150600090613f759083614aa2565b905062278d00613f858285614a4f565b613f8f9190614a67565b601855602054600090613fa29084614aa2565b905062278d00613fb28286614a4f565b613fbc9190614a67565b6020555050505b601a8590556022859055613fda62278d0086614a4f565b60115560408051828152602081018390527fb2e45d21bc3a556247a4a3ad6cd0b08145d486b943b9e671263fca15bef18b6d910160405180910390a15050505050565b600081614032670de0b6b3a764000085614aa2565b61403c9190614a67565b9392505050565b6000818311614052578261403c565b50919050565b81816000816140915773ffffffffffffffffffffffffffffffffffffffff831660009081526027602052604090206004015415156140bd565b73ffffffffffffffffffffffffffffffffffffffff831660009081526028602052604090206004015415155b905080614126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f7468696e67207374616b65640000000000000000000000000000000000006044820152606401610912565b848461413282826131bd565b866000614140826000613d56565b905061414d826001613d56565b806141555750805b9050801561416557614165613e6a565b6000886141965773ffffffffffffffffffffffffffffffffffffffff8a1660009081526027602052604090206141bc565b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526028602052604090205b600781015490915060ff161561422e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207768656e207769746864726177696e670000000000000000006044820152606401610912565b60008961423c57601761423f565b601f5b600780840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555490915061427b9042614a4f565b8260060181905550816004015481600601600082825461429b9190614adf565b90915550506007820154610100900460ff16156142fb57600780830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055600483015490820180546000906142f5908490614adf565b90915550505b5050505050505050505050565b600a546000906127109061431c9084614aa2565b6143269190614a67565b6139809083614adf565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff8616906370a082319060240160206040518083038186803b15801561439a57600080fd5b505afa1580156143ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143d29190614977565b90506143df8585856146b6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a082319060240160206040518083038186803b15801561444757600080fd5b505afa15801561445b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061447f9190614977565b905061448b8282614adf565b9695505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161452c9190614a14565b6000604051808303816000865af19150503d8060008114614569576040519150601f19603f3d011682016040523d82523d6000602084013e61456e565b606091505b50915091508180156145985750805115806145985750808060200190518101906145989190614941565b613290576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a205472616e73666572206661696c65640000000000006044820152606401610912565b600061403c8383670de0b6b3a7640000614825565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908416906370a082319060240160206040518083038186803b15801561467e57600080fd5b505afa158015614692573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061403c9190614977565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152306044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908716916147539190614a14565b6000604051808303816000865af19150503d8060008114614790576040519150601f19603f3d011682016040523d82523d6000602084013e614795565b606091505b50915091508180156147bf5750805115806147bf5750808060200190518101906147bf9190614941565b613290576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5361666545524332303a205472616e7366657246726f6d206661696c656400006044820152606401610912565b6000816148328486614aa2565b6132bc9190614a67565b803573ffffffffffffffffffffffffffffffffffffffff8116811461486057600080fd5b919050565b60006020828403121561487757600080fd5b61403c8261483c565b60008060006060848603121561489557600080fd5b61489e8461483c565b92506148ac6020850161483c565b91506148ba6040850161483c565b90509250925092565b600080604083850312156148d657600080fd5b6148df8361483c565b915060208301356148ef81614b25565b809150509250929050565b6000806040838503121561490d57600080fd5b6149168361483c565b946020939093013593505050565b60006020828403121561493657600080fd5b813561403c81614b25565b60006020828403121561495357600080fd5b815161403c81614b25565b60006020828403121561497057600080fd5b5035919050565b60006020828403121561498957600080fd5b5051919050565b600080604083850312156149a357600080fd5b50508035926020909101359150565b60008060008060008060c087890312156149cb57600080fd5b863595506020870135945060408701356149e481614b25565b9350606087013560ff811681146149fa57600080fd5b9598949750929560808101359460a0909101359350915050565b6000825160005b81811015614a355760208186018101518583015201614a1b565b81811115614a44576000828501525b509190910192915050565b60008219821115614a6257614a62614af6565b500190565b600082614a9d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ada57614ada614af6565b500290565b600082821015614af157614af1614af6565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8015158114611ca157600080fdfea2646970667358221220ab857582abc76de18375965040d6e7cddc1fa05da9db05efc941556c24cbcc5864736f6c63430008060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000093a80
-----Decoded View---------------
Arg [0] : _timeToSuper (uint256): 2592000
Arg [1] : _timeToUnstake (uint256): 604800
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000278d00
Arg [1] : 0000000000000000000000000000000000000000000000000000000000093a80
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.