Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 8 from a total of 8 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Emergency Reward... | 15825039 | 810 days ago | IN | 0 ETH | 0.00053561 | ||||
Deposit Rewards | 15820201 | 811 days ago | IN | 0 ETH | 0.00168581 | ||||
Set Settings | 15820191 | 811 days ago | IN | 0 ETH | 0.00070585 | ||||
Add Lockup | 15820187 | 811 days ago | IN | 0 ETH | 0.00163662 | ||||
Add Lockup | 15820186 | 811 days ago | IN | 0 ETH | 0.00170387 | ||||
Add Lockup | 15820180 | 811 days ago | IN | 0 ETH | 0.00161286 | ||||
Add Lockup | 15820173 | 811 days ago | IN | 0 ETH | 0.00211253 | ||||
Initialize | 15820147 | 811 days ago | IN | 0 ETH | 0.00476663 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
IOFinacenPools
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// IO Finance Rewards Booster // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import '@openzeppelin/contracts/access/Ownable.sol'; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./interfaces/IUniRouter02.sol"; import "./interfaces/IWETH.sol"; interface IToken { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the token decimals. */ function decimals() external view returns (uint8); /** * @dev Returns the token symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the token name. */ function name() external view returns (string memory); } contract IOFinacenPools is Ownable, ReentrancyGuard { using SafeERC20 for IERC20; bool public isInitialized; uint256 public duration = 365; bool public hasUserLimit; uint256 public poolLimitPerUser; uint256 public startBlock; uint256 public bonusEndBlock; // swap router and path, slipPage uint256 public slippageFactor = 800; // 20% default slippage tolerance uint256 public constant slippageFactorUL = 995; address public uniRouterAddress; address[] public reflectionToStakedPath; address[] public earnedToStakedPath; address public walletA; address public buyBackWallet = 0xfA88c3283AE63D167a7E67964B00Dc3cBa7E1f34; uint256 public performanceFee = 0.00089 ether; // The precision factor uint256 public PRECISION_FACTOR; uint256 public PRECISION_FACTOR_REFLECTION; // The staked token IERC20 public stakingToken; // The earned token IERC20 public earnedToken; // The dividend token of staking token address public dividendToken; // Accrued token per share uint256 public accDividendPerShare; uint256 public totalStaked; uint256 private totalEarned; uint256 private totalReflections; uint256 private reflections; uint256 private paidRewards; uint256 private shouldTotalPaid; struct Lockup { uint8 stakeType; uint256 duration; uint256 depositFee; uint256 withdrawFee; uint256 rate; uint256 accTokenPerShare; uint256 lastRewardBlock; uint256 totalStaked; uint256 totalStakedLimit; } struct UserInfo { uint256 amount; // How many staked tokens the user has provided uint256 locked; uint256 available; } struct Stake { uint8 stakeType; uint256 amount; // amount to stake uint256 duration; // the lockup duration of the stake uint256 end; // when does the staking period end uint256 rewardDebt; // Reward debt uint256 reflectionDebt; // Reflection debt } uint256 constant MAX_STAKES = 256; Lockup[] public lockups; mapping(address => Stake[]) public userStakes; mapping(address => UserInfo) public userStaked; event Deposit(address indexed user, uint256 stakeType, uint256 amount); event Withdraw(address indexed user, uint256 stakeType, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 amount); event AdminTokenRecovered(address tokenRecovered, uint256 amount); event NewStartAndEndBlocks(uint256 startBlock, uint256 endBlock); event LockupUpdated(uint8 _type, uint256 _duration, uint256 _fee0, uint256 _fee1, uint256 _rate); event RewardsStop(uint256 blockNumber); event EndBlockUpdated(uint256 blockNumber); event UpdatePoolLimit(uint256 poolLimitPerUser, bool hasLimit); event ServiceInfoUpadted(address _addr, uint256 _fee); event DurationUpdated(uint256 _duration); event SetSettings( uint256 _slippageFactor, address _uniRouter, address[] _path0, address[] _path1, address _walletA ); constructor() {} /* * @notice Initialize the contract * @param _stakingToken: staked token address * @param _earnedToken: earned token address * @param _dividendToken: reflection token address * @param _uniRouter: uniswap router address for swap tokens * @param _earnedToStakedPath: swap path to compound (earned -> staking path) * @param _reflectionToStakedPath: swap path to compound (reflection -> staking path) */ function initialize( IERC20 _stakingToken, IERC20 _earnedToken, address _dividendToken, address _uniRouter, address[] memory _earnedToStakedPath, address[] memory _reflectionToStakedPath ) external onlyOwner { require(!isInitialized, "Already initialized"); isInitialized = true; stakingToken = _stakingToken; earnedToken = _earnedToken; dividendToken = _dividendToken; walletA = msg.sender; uint256 decimalsRewardToken = uint256(IToken(address(earnedToken)).decimals()); require(decimalsRewardToken < 30, "Must be inferior to 30"); PRECISION_FACTOR = uint256(10**(40 - decimalsRewardToken)); uint256 decimalsdividendToken = 18; if(address(dividendToken) != address(0x0)) { decimalsdividendToken = uint256(IToken(address(dividendToken)).decimals()); require(decimalsdividendToken < 30, "Must be inferior to 30"); } PRECISION_FACTOR_REFLECTION = uint256(10**(40 - decimalsRewardToken)); uniRouterAddress = _uniRouter; earnedToStakedPath = _earnedToStakedPath; reflectionToStakedPath = _reflectionToStakedPath; } function deposit(uint256 _amount, uint8 _stakeType) external payable nonReentrant { require(startBlock > 0 && startBlock < block.number, "Staking hasn't started yet"); require(_amount > 0, "Amount should be greator than 0"); require(_stakeType < lockups.length, "Invalid stake type"); _transferPerformanceFee(); _updatePool(_stakeType); UserInfo storage user = userStaked[msg.sender]; Stake[] storage stakes = userStakes[msg.sender]; Lockup storage lockup = lockups[_stakeType]; if(lockup.totalStakedLimit > 0) { require(lockup.totalStaked < lockup.totalStakedLimit, "Total staked limit exceeded"); if(lockup.totalStaked + _amount > lockup.totalStakedLimit) { _amount = lockup.totalStakedLimit - lockup.totalStaked; } } uint256 pending = 0; uint256 pendingReflection = 0; for(uint256 j = 0; j < stakes.length; j++) { Stake storage stake = stakes[j]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; pendingReflection = pendingReflection + ( stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION - stake.reflectionDebt ); uint256 _pending = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR - stake.rewardDebt; pending = pending + _pending; stake.rewardDebt = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR; stake.reflectionDebt = stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION; } if (pending > 0) { require(availableRewardTokens() >= pending, "Insufficient reward tokens"); earnedToken.safeTransfer(address(msg.sender), pending); _updateEarned(pending); paidRewards = paidRewards + pending; } pendingReflection = estimateDividendAmount(pendingReflection); if (pendingReflection > 0) { _transferToken(dividendToken, msg.sender, pendingReflection); totalReflections = totalReflections - pendingReflection; } uint256 beforeAmount = stakingToken.balanceOf(address(this)); stakingToken.safeTransferFrom(address(msg.sender), address(this), _amount); uint256 afterAmount = stakingToken.balanceOf(address(this)); uint256 realAmount = afterAmount - beforeAmount; if (hasUserLimit) { require( realAmount + user.amount <= poolLimitPerUser, "User amount above limit" ); } if (lockup.depositFee > 0) { uint256 fee = realAmount * lockup.depositFee / 10000; if (fee > 0) { stakingToken.safeTransfer(walletA, fee); realAmount = realAmount - fee; } } _addStake(_stakeType, msg.sender, lockup.duration, realAmount); user.amount = user.amount + realAmount; lockup.totalStaked = lockup.totalStaked + realAmount; totalStaked = totalStaked + realAmount; emit Deposit(msg.sender, _stakeType, realAmount); } function _addStake(uint8 _stakeType, address _account, uint256 _duration, uint256 _amount) internal { Stake[] storage stakes = userStakes[_account]; uint256 end = block.timestamp + _duration * 1 days; uint256 i = stakes.length; require(i < MAX_STAKES, "Max stakes"); stakes.push(); // grow the array // find the spot where we can insert the current stake // this should make an increasing list sorted by end while (i != 0 && stakes[i - 1].end > end) { // shift it back one stakes[i] = stakes[i - 1]; i -= 1; } Lockup storage lockup = lockups[_stakeType]; // insert the stake Stake storage newStake = stakes[i]; newStake.stakeType = _stakeType; newStake.duration = _duration; newStake.end = end; newStake.amount = _amount; newStake.rewardDebt = newStake.amount * lockup.accTokenPerShare / PRECISION_FACTOR; newStake.reflectionDebt = newStake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION; } /* * @notice Withdraw staked tokens and collect reward tokens * @param _amount: amount to withdraw (in earnedToken) */ function withdraw(uint256 _amount, uint8 _stakeType) external payable nonReentrant { require(_amount > 0, "Amount should be greator than 0"); require(_stakeType < lockups.length, "Invalid stake type"); _transferPerformanceFee(); _updatePool(_stakeType); UserInfo storage user = userStaked[msg.sender]; Stake[] storage stakes = userStakes[msg.sender]; Lockup storage lockup = lockups[_stakeType]; uint256 pending = 0; uint256 pendingReflection = 0; uint256 remained = _amount; for(uint256 j = 0; j < stakes.length; j++) { Stake storage stake = stakes[j]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; if(remained == 0) break; uint256 _pending = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR - stake.rewardDebt; pendingReflection = pendingReflection + ( stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION - stake.reflectionDebt ); pending = pending + _pending; if(stake.end < block.timestamp || bonusEndBlock < block.number) { if(stake.amount > remained) { stake.amount = stake.amount - remained; remained = 0; } else { remained = remained - stake.amount; stake.amount = 0; } } stake.rewardDebt = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR; stake.reflectionDebt = stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION; } if (pending > 0) { require(availableRewardTokens() >= pending, "Insufficient reward tokens"); earnedToken.safeTransfer(address(msg.sender), pending); _updateEarned(pending); paidRewards = paidRewards + pending; } if (pendingReflection > 0) { pendingReflection = estimateDividendAmount(pendingReflection); _transferToken(dividendToken, msg.sender, pendingReflection); totalReflections = totalReflections - pendingReflection; } uint256 realAmount = _amount - remained; user.amount = user.amount - realAmount; lockup.totalStaked = lockup.totalStaked - realAmount; totalStaked = totalStaked - realAmount; if(realAmount > 0) { if (lockup.withdrawFee > 0) { uint256 fee = realAmount * lockup.withdrawFee / 10000; stakingToken.safeTransfer(walletA, fee); realAmount = realAmount - fee; } stakingToken.safeTransfer(address(msg.sender), realAmount); } emit Withdraw(msg.sender, _stakeType, realAmount); } function claimReward(uint8 _stakeType) external payable nonReentrant { if(_stakeType >= lockups.length) return; if(startBlock == 0) return; _transferPerformanceFee(); _updatePool(_stakeType); Stake[] storage stakes = userStakes[msg.sender]; Lockup storage lockup = lockups[_stakeType]; uint256 pending = 0; for(uint256 j = 0; j < stakes.length; j++) { Stake storage stake = stakes[j]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; uint256 _pending = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR - stake.rewardDebt; pending = pending + _pending; stake.rewardDebt = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR; } if (pending > 0) { require(availableRewardTokens() >= pending, "Insufficient reward tokens"); earnedToken.safeTransfer(address(msg.sender), pending); _updateEarned(pending); paidRewards = paidRewards + pending; } } function claimDividend(uint8 _stakeType) external payable nonReentrant { if(_stakeType >= lockups.length) return; if(startBlock == 0) return; _transferPerformanceFee(); _updatePool(_stakeType); Stake[] storage stakes = userStakes[msg.sender]; uint256 pendingReflection = 0; for(uint256 j = 0; j < stakes.length; j++) { Stake storage stake = stakes[j]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; pendingReflection = pendingReflection + ( stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION - stake.reflectionDebt ); stake.reflectionDebt = stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION; } pendingReflection = estimateDividendAmount(pendingReflection); if (pendingReflection > 0) { _transferToken(dividendToken, msg.sender, pendingReflection); totalReflections = totalReflections - pendingReflection; } } function compoundReward(uint8 _stakeType) external payable nonReentrant { if(_stakeType >= lockups.length) return; if(startBlock == 0) return; _transferPerformanceFee(); _updatePool(_stakeType); UserInfo storage user = userStaked[msg.sender]; Stake[] storage stakes = userStakes[msg.sender]; Lockup storage lockup = lockups[_stakeType]; uint256 pending = 0; uint256 compounded = 0; for(uint256 j = 0; j < stakes.length; j++) { Stake storage stake = stakes[j]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; uint256 _pending = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR - stake.rewardDebt; pending = pending + _pending; if(address(stakingToken) != address(earnedToken) && _pending > 0) { uint256 _beforeAmount = stakingToken.balanceOf(address(this)); _safeSwap(_pending, earnedToStakedPath, address(this)); uint256 _afterAmount = stakingToken.balanceOf(address(this)); _pending = _afterAmount - _beforeAmount; } compounded = compounded + _pending; stake.amount = stake.amount + _pending; stake.rewardDebt = stake.amount * lockup.accTokenPerShare / PRECISION_FACTOR; stake.reflectionDebt = stake.reflectionDebt + _pending * accDividendPerShare / PRECISION_FACTOR_REFLECTION; } if (pending > 0) { require(availableRewardTokens() >= pending, "Insufficient reward tokens"); _updateEarned(pending); paidRewards = paidRewards + pending; user.amount = user.amount + compounded; lockup.totalStaked = lockup.totalStaked + compounded; totalStaked = totalStaked + compounded; emit Deposit(msg.sender, _stakeType, compounded); } } function compoundDividend(uint8 _stakeType) external payable nonReentrant { if(_stakeType >= lockups.length) return; if(startBlock == 0) return; _transferPerformanceFee(); _updatePool(_stakeType); UserInfo storage user = userStaked[msg.sender]; Stake[] storage stakes = userStakes[msg.sender]; Lockup storage lockup = lockups[_stakeType]; uint256 compounded = 0; for(uint256 j = 0; j < stakes.length; j++) { Stake storage stake = stakes[j]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; uint256 _pending = stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION - stake.reflectionDebt; _pending = estimateDividendAmount(_pending); totalReflections = totalReflections - _pending; if(address(stakingToken) != address(dividendToken) && _pending > 0) { if(address(dividendToken) == address(0x0)) { address wethAddress = IUniRouter02(uniRouterAddress).WETH(); IWETH(wethAddress).deposit{ value: _pending }(); } uint256 _beforeAmount = stakingToken.balanceOf(address(this)); _safeSwap(_pending, reflectionToStakedPath, address(this)); uint256 _afterAmount = stakingToken.balanceOf(address(this)); _pending = _afterAmount - _beforeAmount; } compounded = compounded + _pending; stake.amount = stake.amount + _pending; stake.rewardDebt = stake.rewardDebt + _pending * lockup.accTokenPerShare / PRECISION_FACTOR; stake.reflectionDebt = stake.amount * accDividendPerShare / PRECISION_FACTOR_REFLECTION; } if (compounded > 0) { user.amount = user.amount + compounded; lockup.totalStaked = lockup.totalStaked + compounded; totalStaked = totalStaked + compounded; emit Deposit(msg.sender, _stakeType, compounded); } } function _transferPerformanceFee() internal { require(msg.value >= performanceFee, 'should pay small gas to compound or harvest'); payable(buyBackWallet).transfer(performanceFee); if(msg.value > performanceFee) { payable(msg.sender).transfer(msg.value - performanceFee); } } function emergencyWithdraw(uint8 _stakeType) external nonReentrant { if(_stakeType >= lockups.length) return; UserInfo storage user = userStaked[msg.sender]; Stake[] storage stakes = userStakes[msg.sender]; Lockup storage lockup = lockups[_stakeType]; uint256 amountToTransfer = 0; for(uint256 j = 0; j < stakes.length; j++) { Stake storage stake = stakes[j]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; amountToTransfer = amountToTransfer + stake.amount; stake.amount = 0; stake.rewardDebt = 0; stake.reflectionDebt = 0; } if (amountToTransfer > 0) { stakingToken.safeTransfer(address(msg.sender), amountToTransfer); user.amount = user.amount - amountToTransfer; lockup.totalStaked = lockup.totalStaked - amountToTransfer; totalStaked = totalStaked - amountToTransfer; } emit EmergencyWithdraw(msg.sender, amountToTransfer); } function rewardPerBlock(uint8 _stakeType) external view returns (uint256) { if(_stakeType >= lockups.length) return 0; return lockups[_stakeType].rate; } /** * @notice Available amount of reward token */ function availableRewardTokens() public view returns (uint256) { if(address(earnedToken) == address(dividendToken)) return totalEarned; uint256 _amount = earnedToken.balanceOf(address(this)); if (address(earnedToken) == address(stakingToken)) { if (_amount < totalStaked) return 0; return _amount - totalStaked; } return _amount; } function availableDividendTokens() public view returns (uint256) { if(address(dividendToken) == address(0x0)) { return address(this).balance; } uint256 _amount = IERC20(dividendToken).balanceOf(address(this)); if(address(dividendToken) == address(earnedToken)) { if(_amount < totalEarned) return 0; _amount = _amount - totalEarned; } if(address(dividendToken) == address(stakingToken)) { if(_amount < totalStaked) return 0; _amount = _amount - totalStaked; } return _amount; } function insufficientRewards() external view returns (uint256) { uint256 adjustedShouldTotalPaid = shouldTotalPaid; uint256 remainRewards = availableRewardTokens() + paidRewards; for(uint i = 0; i < lockups.length; i++) { if(startBlock == 0) { adjustedShouldTotalPaid = adjustedShouldTotalPaid + lockups[i].rate * duration * 6426; } else { uint256 remainBlocks = _getMultiplier(lockups[i].lastRewardBlock, bonusEndBlock); adjustedShouldTotalPaid = adjustedShouldTotalPaid + lockups[i].rate * remainBlocks; } } if(remainRewards >= adjustedShouldTotalPaid) return 0; return adjustedShouldTotalPaid - remainRewards; } function userInfo(uint8 _stakeType, address _account) external view returns (uint256 amount, uint256 available, uint256 locked) { Stake[] memory stakes = userStakes[_account]; for(uint256 i = 0; i < stakes.length; i++) { Stake memory stake = stakes[i]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; amount = amount + stake.amount; if(block.timestamp > stake.end || bonusEndBlock < block.number) { available = available + stake.amount; } else { locked = locked + stake.amount; } } } function pendingReward(address _account, uint8 _stakeType) external view returns (uint256) { if(_stakeType >= lockups.length || startBlock == 0) return 0; Stake[] memory stakes = userStakes[_account]; Lockup memory lockup = lockups[_stakeType]; if(lockup.totalStaked == 0) return 0; uint256 adjustedTokenPerShare = lockup.accTokenPerShare; if (block.number > lockup.lastRewardBlock && lockup.totalStaked != 0 && lockup.lastRewardBlock > 0) { uint256 multiplier = _getMultiplier(lockup.lastRewardBlock, block.number); uint256 reward = multiplier * lockup.rate; adjustedTokenPerShare = lockup.accTokenPerShare + reward * PRECISION_FACTOR / lockup.totalStaked; } uint256 pending = 0; for(uint256 i = 0; i < stakes.length; i++) { Stake memory stake = stakes[i]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; pending = pending + ( stake.amount * adjustedTokenPerShare / PRECISION_FACTOR - stake.rewardDebt ); } return pending; } function pendingDividends(address _account, uint8 _stakeType) external view returns (uint256) { if(_stakeType >= lockups.length) return 0; if(startBlock == 0 || totalStaked == 0) return 0; Stake[] memory stakes = userStakes[_account]; uint256 reflectionAmount = availableDividendTokens(); if(reflectionAmount < totalReflections) { reflectionAmount = totalReflections; } uint256 sTokenBal = totalStaked; uint256 eTokenBal = availableRewardTokens(); if(address(stakingToken) == address(earnedToken)) { sTokenBal = sTokenBal + eTokenBal; } uint256 adjustedReflectionPerShare = accDividendPerShare + ( (reflectionAmount - totalReflections) * PRECISION_FACTOR_REFLECTION / sTokenBal ); uint256 pendingReflection = 0; for(uint256 i = 0; i < stakes.length; i++) { Stake memory stake = stakes[i]; if(stake.stakeType != _stakeType) continue; if(stake.amount == 0) continue; pendingReflection = pendingReflection + ( stake.amount * adjustedReflectionPerShare / PRECISION_FACTOR_REFLECTION - stake.reflectionDebt ); } return pendingReflection; } /************************ ** Admin Methods *************************/ function harvest() external onlyOwner { _updatePool(0); reflections = estimateDividendAmount(reflections); if(reflections > 0) { _transferToken(dividendToken, walletA, reflections); totalReflections = totalReflections - reflections; reflections = 0; } } function depositRewards(uint _amount) external onlyOwner nonReentrant { require(_amount > 0, "invalid amount"); uint256 beforeAmt = earnedToken.balanceOf(address(this)); earnedToken.safeTransferFrom(msg.sender, address(this), _amount); uint256 afterAmt = earnedToken.balanceOf(address(this)); totalEarned = totalEarned + afterAmt - beforeAmt; } function increaseEmissionRate(uint8 _stakeType, uint256 _amount) external onlyOwner { require(startBlock > 0, "pool is not started"); require(bonusEndBlock > block.number, "pool was already finished"); require(_amount > 0, "invalid amount"); _updatePool(_stakeType); uint256 beforeAmt = earnedToken.balanceOf(address(this)); earnedToken.safeTransferFrom(msg.sender, address(this), _amount); uint256 afterAmt = earnedToken.balanceOf(address(this)); totalEarned = totalEarned + afterAmt - beforeAmt; uint256 remainRewards = availableRewardTokens() + paidRewards; uint256 adjustedShouldTotalPaid = shouldTotalPaid; for(uint i = 0; i < lockups.length; i++) { if(i == _stakeType) continue; if(startBlock == 0) { adjustedShouldTotalPaid = adjustedShouldTotalPaid + lockups[i].rate * duration * 6426; } else { uint256 remainBlocks = _getMultiplier(lockups[i].lastRewardBlock, bonusEndBlock); adjustedShouldTotalPaid = adjustedShouldTotalPaid + lockups[i].rate * remainBlocks; } } if(remainRewards > shouldTotalPaid) { remainRewards = remainRewards - adjustedShouldTotalPaid; uint256 remainBlocks = bonusEndBlock - block.number; lockups[_stakeType].rate = remainRewards / remainBlocks; emit LockupUpdated(_stakeType, lockups[_stakeType].duration, lockups[_stakeType].depositFee, lockups[_stakeType].withdrawFee, lockups[_stakeType].rate); } } function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { require( block.number > bonusEndBlock, "Pool is running"); require(availableRewardTokens() >= _amount, "Insufficient reward tokens"); earnedToken.safeTransfer(address(msg.sender), _amount); if (totalEarned > 0) { if (_amount > totalEarned) { totalEarned = 0; } else { totalEarned = totalEarned - _amount; } } } function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { require( _tokenAddress != address(earnedToken), "Cannot be reward token" ); if(_tokenAddress == address(stakingToken)) { uint256 tokenBal = stakingToken.balanceOf(address(this)); require(_tokenAmount <= tokenBal - totalStaked, "Insufficient balance"); } if(_tokenAddress == address(0x0)) { payable(msg.sender).transfer(_tokenAmount); } else { IERC20(_tokenAddress).safeTransfer(address(msg.sender), _tokenAmount); } emit AdminTokenRecovered(_tokenAddress, _tokenAmount); } function startReward() external onlyOwner { require(startBlock == 0, "Pool was already started"); startBlock = block.number + 100; bonusEndBlock = startBlock + duration * 6426; for(uint256 i = 0; i < lockups.length; i++) { lockups[i].lastRewardBlock = startBlock; } emit NewStartAndEndBlocks(startBlock, bonusEndBlock); } function stopReward() external onlyOwner { for(uint8 i = 0; i < lockups.length; i++) { _updatePool(i); } uint256 remainRewards = availableRewardTokens() + paidRewards; if(remainRewards > shouldTotalPaid) { remainRewards = remainRewards - shouldTotalPaid; earnedToken.transfer(msg.sender, remainRewards); _updateEarned(remainRewards); } bonusEndBlock = block.number; emit RewardsStop(bonusEndBlock); } function updateEndBlock(uint256 _endBlock) external onlyOwner { require(startBlock > 0, "Pool is not started"); require(bonusEndBlock > block.number, "Pool was already finished"); require(_endBlock > block.number && _endBlock > startBlock, "Invalid end block"); bonusEndBlock = _endBlock; emit EndBlockUpdated(_endBlock); } function updatePoolLimitPerUser( bool _hasUserLimit, uint256 _poolLimitPerUser) external onlyOwner { if (_hasUserLimit) { require( _poolLimitPerUser > poolLimitPerUser, "New limit must be higher" ); poolLimitPerUser = _poolLimitPerUser; } else { poolLimitPerUser = 0; } hasUserLimit = _hasUserLimit; emit UpdatePoolLimit(poolLimitPerUser, _hasUserLimit); } function updateLockup(uint8 _stakeType, uint256 _duration, uint256 _depositFee, uint256 _withdrawFee, uint256 _rate, uint256 _totalStakedLimit) external onlyOwner { // require(block.number < startBlock, "Pool was already started"); require(_stakeType < lockups.length, "Lockup Not found"); require(_depositFee < 2000, "Invalid deposit fee"); require(_withdrawFee < 2000, "Invalid withdraw fee"); _updatePool(_stakeType); Lockup storage _lockup = lockups[_stakeType]; _lockup.duration = _duration; _lockup.depositFee = _depositFee; _lockup.withdrawFee = _withdrawFee; _lockup.rate = _rate; _lockup.totalStakedLimit = _totalStakedLimit; emit LockupUpdated(_stakeType, _duration, _depositFee, _withdrawFee, _rate); } function addLockup(uint256 _duration, uint256 _depositFee, uint256 _withdrawFee, uint256 _rate, uint256 _totalStakedLimit) external onlyOwner { require(_depositFee < 2000, "Invalid deposit fee"); require(_withdrawFee < 2000, "Invalid withdraw fee"); lockups.push(); Lockup storage _lockup = lockups[lockups.length - 1]; _lockup.duration = _duration; _lockup.depositFee = _depositFee; _lockup.withdrawFee = _withdrawFee; _lockup.rate = _rate; _lockup.lastRewardBlock = block.number; _lockup.totalStakedLimit = _totalStakedLimit; emit LockupUpdated(uint8(lockups.length - 1), _duration, _depositFee, _withdrawFee, _rate); } function setServiceInfo(address _addr, uint256 _fee) external { require(msg.sender == buyBackWallet, "setServiceInfo: FORBIDDEN"); require(_addr != address(0x0), "Invalid address"); require(_fee < 0.05 ether, "fee cannot exceed 0.05 ether"); buyBackWallet = _addr; performanceFee = _fee; emit ServiceInfoUpadted(_addr, _fee); } function setDuration(uint256 _duration) external onlyOwner { require(startBlock == 0, "Pool was already started"); require(_duration >= 30, "lower limit reached"); duration = _duration; emit DurationUpdated(_duration); } function setSettings( uint256 _slippageFactor, address _uniRouter, address[] memory _earnedToStakedPath, address[] memory _reflectionToStakedPath, address _feeAddr ) external onlyOwner { require(_slippageFactor <= slippageFactorUL, "_slippageFactor too high"); require(_feeAddr != address(0x0), "Invalid Address"); slippageFactor = _slippageFactor; uniRouterAddress = _uniRouter; reflectionToStakedPath = _reflectionToStakedPath; earnedToStakedPath = _earnedToStakedPath; walletA = _feeAddr; emit SetSettings(_slippageFactor, _uniRouter, _earnedToStakedPath, _reflectionToStakedPath, _feeAddr); } function _updatePool(uint8 _stakeType) internal { // calc reflection rate if(totalStaked > 0) { uint256 reflectionAmount = availableDividendTokens(); if(reflectionAmount < totalReflections) { reflectionAmount = totalReflections; } uint256 sTokenBal = totalStaked; uint256 eTokenBal = availableRewardTokens(); if(address(stakingToken) == address(earnedToken)) { sTokenBal = sTokenBal + eTokenBal; } accDividendPerShare = accDividendPerShare + ( (reflectionAmount - totalReflections) * PRECISION_FACTOR_REFLECTION / sTokenBal ); if(address(stakingToken) == address(earnedToken)) { reflections = reflections + (reflectionAmount - totalReflections) * eTokenBal / sTokenBal; } totalReflections = reflectionAmount; } Lockup storage lockup = lockups[_stakeType]; if (block.number <= lockup.lastRewardBlock || lockup.lastRewardBlock == 0) return; if (lockup.totalStaked == 0) { lockup.lastRewardBlock = block.number; return; } uint256 multiplier = _getMultiplier(lockup.lastRewardBlock, block.number); uint256 _reward = multiplier * lockup.rate; lockup.accTokenPerShare = lockup.accTokenPerShare + ( _reward * PRECISION_FACTOR / lockup.totalStaked ); lockup.lastRewardBlock = block.number; shouldTotalPaid = shouldTotalPaid + _reward; } function estimateDividendAmount(uint256 amount) internal view returns(uint256) { uint256 dTokenBal = availableDividendTokens(); if(amount > totalReflections) amount = totalReflections; if(amount > dTokenBal) amount = dTokenBal; return amount; } function _getMultiplier(uint256 _from, uint256 _to) internal view returns (uint256) { if (_to <= bonusEndBlock) { return _to - _from; } else if (_from >= bonusEndBlock) { return 0; } else { return bonusEndBlock - _from; } } function _transferToken(address _token, address _to, uint256 _amount) internal { if(_token == address(0x0)) { payable(_to).transfer(_amount); } else { IERC20(_token).transfer(_to, _amount); } } function _updateEarned(uint256 _amount) internal { if(totalEarned > _amount) { totalEarned = totalEarned - _amount; } else { totalEarned = 0; } } function _safeSwap( uint256 _amountIn, address[] memory _path, address _to ) internal { uint256[] memory amounts = IUniRouter02(uniRouterAddress).getAmountsOut(_amountIn, _path); uint256 amountOut = amounts[amounts.length - 1]; IERC20(_path[0]).safeApprove(uniRouterAddress, _amountIn); IUniRouter02(uniRouterAddress).swapExactTokensForTokensSupportingFeeOnTransferTokens( _amountIn, amountOut * slippageFactor / 1000, _path, _to, block.timestamp + 600 ); } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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.0; import "./IUniRouter01.sol"; interface IUniRouter02 is IUniRouter01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IUniRouter01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountToken, uint256 amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETHWithPermit( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external pure returns (uint256 amountB); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountOut); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountIn); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenRecovered","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminTokenRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"DurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"EndBlockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"_type","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"_duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"LockupUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewStartAndEndBlocks","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":"blockNumber","type":"uint256"}],"name":"RewardsStop","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"ServiceInfoUpadted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_slippageFactor","type":"uint256"},{"indexed":false,"internalType":"address","name":"_uniRouter","type":"address"},{"indexed":false,"internalType":"address[]","name":"_path0","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"_path1","type":"address[]"},{"indexed":false,"internalType":"address","name":"_walletA","type":"address"}],"name":"SetSettings","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"poolLimitPerUser","type":"uint256"},{"indexed":false,"internalType":"bool","name":"hasLimit","type":"bool"}],"name":"UpdatePoolLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"PRECISION_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION_FACTOR_REFLECTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accDividendPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"uint256","name":"_depositFee","type":"uint256"},{"internalType":"uint256","name":"_withdrawFee","type":"uint256"},{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"uint256","name":"_totalStakedLimit","type":"uint256"}],"name":"addLockup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"availableDividendTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableRewardTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonusEndBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyBackWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"claimDividend","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"claimReward","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"compoundDividend","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"compoundReward","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dividendToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"earnedToStakedPath","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"earnedToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"emergencyRewardWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"hasUserLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"increaseEmissionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_stakingToken","type":"address"},{"internalType":"contract IERC20","name":"_earnedToken","type":"address"},{"internalType":"address","name":"_dividendToken","type":"address"},{"internalType":"address","name":"_uniRouter","type":"address"},{"internalType":"address[]","name":"_earnedToStakedPath","type":"address[]"},{"internalType":"address[]","name":"_reflectionToStakedPath","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"insufficientRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockups","outputs":[{"internalType":"uint8","name":"stakeType","type":"uint8"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"depositFee","type":"uint256"},{"internalType":"uint256","name":"withdrawFee","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"uint256","name":"accTokenPerShare","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"totalStaked","type":"uint256"},{"internalType":"uint256","name":"totalStakedLimit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"pendingDividends","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLimitPerUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverWrongTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"reflectionToStakedPath","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"rewardPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setServiceInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_slippageFactor","type":"uint256"},{"internalType":"address","name":"_uniRouter","type":"address"},{"internalType":"address[]","name":"_earnedToStakedPath","type":"address[]"},{"internalType":"address[]","name":"_reflectionToStakedPath","type":"address[]"},{"internalType":"address","name":"_feeAddr","type":"address"}],"name":"setSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slippageFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"slippageFactorUL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniRouterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endBlock","type":"uint256"}],"name":"updateEndBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"uint256","name":"_depositFee","type":"uint256"},{"internalType":"uint256","name":"_withdrawFee","type":"uint256"},{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"uint256","name":"_totalStakedLimit","type":"uint256"}],"name":"updateLockup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_hasUserLimit","type":"bool"},{"internalType":"uint256","name":"_poolLimitPerUser","type":"uint256"}],"name":"updatePoolLimitPerUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"},{"internalType":"address","name":"_account","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"locked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userStaked","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"locked","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userStakes","outputs":[{"internalType":"uint8","name":"stakeType","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"reflectionDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"walletA","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint8","name":"_stakeType","type":"uint8"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405261016d600355610320600855600d80546001600160a01b03191673fa88c3283ae63d167a7e67964b00dc3cba7e1f341790556603297345d9a000600e5534801561004d57600080fd5b50600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060018055615ae080620000a36000396000f3fe60806040526004361061036e5760003560e01c806376fa17d2116101c6578063a0b40905116100f7578063e7a2fed711610095578063f6be71d11161006f578063f6be71d1146109da578063f8920ee7146109fa578063fbe32b3514610a1a578063ffbd3b1f14610a3a57600080fd5b8063e7a2fed714610985578063f2fde38b146109a5578063f3aeb31d146109c557600080fd5b8063b74cd242116100d1578063b74cd24214610919578063b77e7da01461092f578063c1e22a651461094f578063ccd34cd51461096f57600080fd5b8063a0b409051461086c578063acc3a9391461088c578063b5d5b5fa146108c857600080fd5b80638bdf67f211610164578063903d42961161013e578063903d42961461081457806392b46e5b1461082757806392e8990e1461083d5780639f94e2721461085757600080fd5b80638bdf67f21461076e5780638da5cb5b1461078e5780638e6f4fb7146107ac57600080fd5b8063817b1cd2116101a0578063817b1cd21461070c57806381b6194814610722578063877887821461074257806388bbb0c11461075857600080fd5b806376fa17d2146106a957806378d57eea146106e457806380dc0672146106f757600080fd5b806348cd4cb1116102a0578063689f16231161023e5780636e707b73116102185780636e707b731461063f578063715018a61461065f57806372f702f314610674578063746c8ae11461069457600080fd5b8063689f1623146105ec578063693a090b146105ff5780636becd6571461061f57600080fd5b8063595e173a1161027a578063595e173a1461058e5780635dde4a91146105ae578063654cfdff146105c357806366fe9f8a146105d657600080fd5b806348cd4cb114610538578063515bbf2c1461054e57806353314fae1461056e57600080fd5b80631aed65531161030d5780633279beab116102e75780633279beab146104b9578063392e53cd146104d95780633f138d4b146105035780634641257d1461052357600080fd5b80631aed6553146104705780631cd348c014610486578063304f807c146104a657600080fd5b806313c68f901161034957806313c68f90146103e5578063155622a4146103f85780631582358e14610418578063167d2dbe1461045057600080fd5b80626f02311461037a5780630bf8a6a41461039c5780630fb5a6b4146103bc57600080fd5b3661037557005b600080fd5b34801561038657600080fd5b5061039a6103953660046151d3565b610a50565b005b3480156103a857600080fd5b5061039a6103b73660046151ec565b610ba8565b3480156103c857600080fd5b506103d260035481565b6040519081526020015b60405180910390f35b61039a6103f3366004615236565b610d30565b34801561040457600080fd5b5061039a610413366004615236565b610e9c565b34801561042457600080fd5b50601354610438906001600160a01b031681565b6040516001600160a01b0390911681526020016103dc565b34801561045c57600080fd5b5061043861046b3660046151d3565b611040565b34801561047c57600080fd5b506103d260075481565b34801561049257600080fd5b50600d54610438906001600160a01b031681565b61039a6104b4366004615236565b61106a565b3480156104c557600080fd5b5061039a6104d43660046151d3565b611500565b3480156104e557600080fd5b506002546104f39060ff1681565b60405190151581526020016103dc565b34801561050f57600080fd5b5061039a61051e366004615268565b6115da565b34801561052f57600080fd5b5061039a6117d2565b34801561054457600080fd5b506103d260065481565b34801561055a57600080fd5b5061039a610569366004615368565b611856565b34801561057a57600080fd5b5061039a610589366004615415565b611b28565b34801561059a57600080fd5b5061039a6105a9366004615461565b611cd9565b3480156105ba57600080fd5b506103d2612160565b61039a6105d136600461547f565b612261565b3480156105e257600080fd5b506103d260055481565b61039a6105fa366004615236565b61289a565b34801561060b57600080fd5b50600954610438906001600160a01b031681565b34801561062b57600080fd5b506103d261063a3660046154af565b612a62565b34801561064b57600080fd5b50601254610438906001600160a01b031681565b34801561066b57600080fd5b5061039a612c72565b34801561068057600080fd5b50601154610438906001600160a01b031681565b3480156106a057600080fd5b5061039a612ce6565b3480156106b557600080fd5b506106c96106c43660046154dd565b612e1a565b604080519384526020840192909252908201526060016103dc565b61039a6106f2366004615236565b612f97565b34801561070357600080fd5b5061039a61338f565b34801561071857600080fd5b506103d260155481565b34801561072e57600080fd5b5061039a61073d366004615268565b6134cb565b34801561074e57600080fd5b506103d2600e5481565b34801561076457600080fd5b506103d260105481565b34801561077a57600080fd5b5061039a6107893660046151d3565b61361c565b34801561079a57600080fd5b506000546001600160a01b0316610438565b3480156107b857600080fd5b506107cc6107c73660046151d3565b6137c7565b6040805160ff909a168a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152610100820152610120016103dc565b61039a61082236600461547f565b613826565b34801561083357600080fd5b506103d260145481565b34801561084957600080fd5b506004546104f39060ff1681565b34801561086357600080fd5b506103d2613c78565b34801561087857600080fd5b5061039a610887366004615519565b613d47565b34801561089857600080fd5b506106c96108a7366004615537565b601d6020526000908152604090208054600182015460029092015490919083565b3480156108d457600080fd5b506108e86108e3366004615268565b613e23565b6040805160ff90971687526020870195909552938501929092526060840152608083015260a082015260c0016103dc565b34801561092557600080fd5b506103d26103e381565b34801561093b57600080fd5b50600c54610438906001600160a01b031681565b34801561095b57600080fd5b5061043861096a3660046151d3565b613e7b565b34801561097b57600080fd5b506103d2600f5481565b34801561099157600080fd5b5061039a6109a0366004615554565b613e8b565b3480156109b157600080fd5b5061039a6109c0366004615537565b613ff9565b3480156109d157600080fd5b506103d26140e3565b3480156109e657600080fd5b5061039a6109f53660046151d3565b6141f6565b348015610a0657600080fd5b506103d2610a15366004615236565b6142e7565b348015610a2657600080fd5b506103d2610a353660046154af565b61432d565b348015610a4657600080fd5b506103d260085481565b6000546001600160a01b03163314610a835760405162461bcd60e51b8152600401610a7a906155e9565b60405180910390fd5b600060065411610acb5760405162461bcd60e51b8152602060048201526013602482015272141bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b6044820152606401610a7a565b4360075411610b1c5760405162461bcd60e51b815260206004820152601960248201527f506f6f6c2077617320616c72656164792066696e6973686564000000000000006044820152606401610a7a565b4381118015610b2c575060065481115b610b6c5760405162461bcd60e51b8152602060048201526011602482015270496e76616c696420656e6420626c6f636b60781b6044820152606401610a7a565b60078190556040518181527f0972575658363b3e7c472ab3a6a918726742c853b732f6a4a2763e2e3a94c977906020015b60405180910390a150565b6000546001600160a01b03163314610bd25760405162461bcd60e51b8152600401610a7a906155e9565b6107d08410610c195760405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206465706f7369742066656560681b6044820152606401610a7a565b6107d08310610c615760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642077697468647261772066656560601b6044820152606401610a7a565b601b8054600190810180835560008381529291610c7d91615634565b81548110610c8d57610c8d61564b565b60009182526020909120600160099092020181810188905560028101879055600381018690556004810185905543600682015560088101849055601b549092507f2a9378497cb60e247e83eb6f2c7c371ba979e24ee25723c2e3275822b317175991610cf891615634565b6040805160ff9092168252602082018990528101879052606081018690526080810185905260a00160405180910390a1505050505050565b600260015403610d525760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e9557610d746145cf565b610d7d816146b7565b336000908152601c6020526040812090805b8254811015610e57576000838281548110610dac57610dac61564b565b60009182526020909120600690910201805490915060ff868116911614610dd35750610e45565b8060010154600003610de55750610e45565b80600501546010546014548360010154610dff9190615698565b610e0991906156b7565b610e139190615634565b610e1d90846156d9565b92506010546014548260010154610e349190615698565b610e3e91906156b7565b6005909101555b80610e4f816156f1565b915050610d8f565b50610e6181614868565b90508015610e9257601354610e80906001600160a01b03163383614898565b80601754610e8e9190615634565b6017555b50505b5060018055565b600260015403610ebe5760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e9557336000908152601d60209081526040808320601c9092528220601b80549293919260ff8616908110610f0457610f0461564b565b906000526020600020906009020190506000805b8354811015610fab576000848281548110610f3557610f3561564b565b60009182526020909120600690910201805490915060ff888116911614610f5c5750610f99565b8060010154600003610f6e5750610f99565b6001810154610f7d90846156d9565b6000600183018190556004830181905560059092019190915591505b80610fa3816156f1565b915050610f18565b508015610fff57601154610fc9906001600160a01b0316338361495a565b8354610fd6908290615634565b84556007820154610fe8908290615634565b6007830155601554610ffb908290615634565b6015555b60405181815233907f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd9695906020015b60405180910390a2505050505060018055565b600a818154811061105057600080fd5b6000918252602090912001546001600160a01b0316905081565b60026001540361108c5760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e95576110ae6145cf565b6110b7816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106110eb576110eb61564b565b906000526020600020906009020190506000805b835481101561147e57600084828154811061111c5761111c61564b565b60009182526020909120600690910201805490915060ff888116911614611143575061146c565b8060010154600003611155575061146c565b6000816005015460105460145484600101546111719190615698565b61117b91906156b7565b6111859190615634565b905061119081614868565b9050806017546111a09190615634565b6017556013546011546001600160a01b039081169116148015906111c45750600081115b156113f1576013546001600160a01b031661129f57600954604080516315ab88c960e31b815290516000926001600160a01b03169163ad5c46489160048083019260209291908290030181865afa158015611223573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611247919061570a565b9050806001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561128457600080fd5b505af1158015611298573d6000803e3d6000fd5b5050505050505b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156112e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130c9190615727565b905061137382600a80548060200260200160405190810160405280929190818152602001828054801561136857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161134a575b5050505050306149bd565b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156113bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e09190615727565b90506113ec8282615634565b925050505b6113fb81856156d9565b935080826001015461140d91906156d9565b6001830155600f5460058601546114249083615698565b61142e91906156b7565b826004015461143d91906156d9565b600483015560105460145460018401546114579190615698565b61146191906156b7565b826005018190555050505b80611476816156f1565b9150506110ff565b5080156114f55783546114929082906156d9565b845560078201546114a49082906156d9565b60078301556015546114b79082906156d9565b6015556040805160ff871681526020810183905233917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910161102d565b505050505060018055565b6000546001600160a01b0316331461152a5760405162461bcd60e51b8152600401610a7a906155e9565b600754431161156d5760405162461bcd60e51b815260206004820152600f60248201526e506f6f6c2069732072756e6e696e6760881b6044820152606401610a7a565b80611576613c78565b10156115945760405162461bcd60e51b8152600401610a7a90615740565b6012546115ab906001600160a01b0316338361495a565b601654156115d7576016548111156115c557600060165550565b806016546115d39190615634565b6016555b50565b6000546001600160a01b031633146116045760405162461bcd60e51b8152600401610a7a906155e9565b6012546001600160a01b039081169083160361165b5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103132903932bbb0b932103a37b5b2b760511b6044820152606401610a7a565b6011546001600160a01b0390811690831603611736576011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de9190615727565b9050601554816116ee9190615634565b8211156117345760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610a7a565b505b6001600160a01b03821661177757604051339082156108fc029083906000818181858888f19350505050158015611771573d6000803e3d6000fd5b5061178b565b61178b6001600160a01b038316338361495a565b604080516001600160a01b0384168152602081018390527f74f5dcd55c394cb1c6d3b9da22c2464bcc46c38cc3865bd629ed75823249b40b91015b60405180910390a15050565b6000546001600160a01b031633146117fc5760405162461bcd60e51b8152600401610a7a906155e9565b61180660006146b7565b611811601854614868565b60188190551561185457601354600c5460185461183b926001600160a01b03908116921690614898565b60185460175461184b9190615634565b60175560006018555b565b6000546001600160a01b031633146118805760405162461bcd60e51b8152600401610a7a906155e9565b60025460ff16156118c95760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610a7a565b6002805460ff19166001179055601180546001600160a01b038089166001600160a01b0319928316179092556012805488841690831681179091556013805493881693831693909317909255600c8054909116331790556040805163313ce56760e01b815290516000929163313ce5679160048083019260209291908290030181865afa15801561195e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119829190615777565b60ff169050601e81106119d05760405162461bcd60e51b815260206004820152601660248201527504d75737420626520696e666572696f7220746f2033360541b6044820152606401610a7a565b6119db816028615634565b6119e690600a615878565b600f556013546012906001600160a01b031615611ac257601360009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a749190615777565b60ff169050601e8110611ac25760405162461bcd60e51b815260206004820152601660248201527504d75737420626520696e666572696f7220746f2033360541b6044820152606401610a7a565b611acd826028615634565b611ad890600a615878565b601055600980546001600160a01b0319166001600160a01b0387161790558351611b0990600b906020870190615159565b508251611b1d90600a906020860190615159565b505050505050505050565b6000546001600160a01b03163314611b525760405162461bcd60e51b8152600401610a7a906155e9565b601b5460ff871610611b995760405162461bcd60e51b815260206004820152601060248201526f131bd8dadd5c08139bdd08199bdd5b9960821b6044820152606401610a7a565b6107d08410611be05760405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206465706f7369742066656560681b6044820152606401610a7a565b6107d08310611c285760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642077697468647261772066656560601b6044820152606401610a7a565b611c31866146b7565b6000601b8760ff1681548110611c4957611c4961564b565b600091825260209182902060099091020160018101889055600281018790556003810186905560048101859055600881018490556040805160ff8b1681529283018990528201879052606082018690526080820185905291507f2a9378497cb60e247e83eb6f2c7c371ba979e24ee25723c2e3275822b31717599060a0015b60405180910390a150505050505050565b6000546001600160a01b03163314611d035760405162461bcd60e51b8152600401610a7a906155e9565b600060065411611d4b5760405162461bcd60e51b81526020600482015260136024820152721c1bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b6044820152606401610a7a565b4360075411611d9c5760405162461bcd60e51b815260206004820152601960248201527f706f6f6c2077617320616c72656164792066696e6973686564000000000000006044820152606401610a7a565b60008111611ddd5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a7a565b611de6826146b7565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e539190615727565b601254909150611e6e906001600160a01b0316333085614b3d565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edb9190615727565b90508181601654611eec91906156d9565b611ef69190615634565b601655601954600090611f07613c78565b611f1191906156d9565b601a5490915060005b601b5481101561200b5760ff87168114611ff957600654600003611f8757600354601b8281548110611f4e57611f4e61564b565b906000526020600020906009020160040154611f6a9190615698565b611f769061191a615698565b611f8090836156d9565b9150611ff9565b6000611fb9601b8381548110611f9f57611f9f61564b565b906000526020600020906009020160060154600754614b75565b905080601b8381548110611fcf57611fcf61564b565b906000526020600020906009020160040154611feb9190615698565b611ff590846156d9565b9250505b80612003816156f1565b915050611f1a565b50601a54821115612158576120208183615634565b91506000436007546120329190615634565b905061203e81846156b7565b601b8860ff16815481106120545761205461564b565b9060005260206000209060090201600401819055507f2a9378497cb60e247e83eb6f2c7c371ba979e24ee25723c2e3275822b317175987601b8960ff16815481106120a1576120a161564b565b906000526020600020906009020160010154601b8a60ff16815481106120c9576120c961564b565b906000526020600020906009020160020154601b8b60ff16815481106120f1576120f161564b565b906000526020600020906009020160030154601b8c60ff16815481106121195761211961564b565b6000918252602091829020600460099092020101546040805160ff9097168752918601949094528401919091526060830152608082015260a001611cc8565b505050505050565b6013546000906001600160a01b031661217857504790565b6013546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156121c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e59190615727565b6012546013549192506001600160a01b039081169116036122225760165481101561221257600091505090565b60165461221f9082615634565b90505b6011546013546001600160a01b0391821691160361225c5760155481101561224c57600091505090565b6015546122599082615634565b90505b919050565b6002600154036122835760405162461bcd60e51b8152600401610a7a90615661565b60026001556006541580159061229a575043600654105b6122e65760405162461bcd60e51b815260206004820152601a60248201527f5374616b696e67206861736e27742073746172746564207965740000000000006044820152606401610a7a565b600082116123365760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e742073686f756c642062652067726561746f72207468616e2030006044820152606401610a7a565b601b5460ff82161061237f5760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964207374616b65207479706560701b6044820152606401610a7a565b6123876145cf565b612390816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106123c4576123c461564b565b9060005260206000209060090201905060008160080154111561246a5780600801548160070154106124385760405162461bcd60e51b815260206004820152601b60248201527f546f74616c207374616b6564206c696d697420657863656564656400000000006044820152606401610a7a565b806008015485826007015461244d91906156d9565b111561246a57806007015481600801546124679190615634565b94505b60008060005b84548110156125a257600085828154811061248d5761248d61564b565b60009182526020909120600690910201805490915060ff8981169116146124b45750612590565b80600101546000036124c65750612590565b806005015460105460145483600101546124e09190615698565b6124ea91906156b7565b6124f49190615634565b6124fe90846156d9565b925060008160040154600f548760050154846001015461251e9190615698565b61252891906156b7565b6125329190615634565b905061253e81866156d9565b9450600f54866005015483600101546125579190615698565b61256191906156b7565b6004830155601054601454600184015461257b9190615698565b61258591906156b7565b826005018190555050505b8061259a816156f1565b915050612470565b50811561260257816125b2613c78565b10156125d05760405162461bcd60e51b8152600401610a7a90615740565b6012546125e7906001600160a01b0316338461495a565b6125f082614bb0565b816019546125fe91906156d9565b6019555b61260b81614868565b9050801561263c5760135461262a906001600160a01b03163383614898565b806017546126389190615634565b6017555b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a99190615727565b6011549091506126c4906001600160a01b031633308b614b3d565b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561270d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127319190615727565b9050600061273f8383615634565b60045490915060ff16156127aa57600554885461275c90836156d9565b11156127aa5760405162461bcd60e51b815260206004820152601760248201527f5573657220616d6f756e742061626f7665206c696d69740000000000000000006044820152606401610a7a565b6002860154156128075760006127108760020154836127c99190615698565b6127d391906156b7565b9050801561280557600c546011546127f8916001600160a01b0391821691168361495a565b6128028183615634565b91505b505b6128178933886001015484614bd0565b87546128249082906156d9565b885560078601546128369082906156d9565b60078701556015546128499082906156d9565b6015556040805160ff8b1681526020810183905233917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910160405180910390a25050600180555050505050505050565b6002600154036128bc5760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e95576128de6145cf565b6128e7816146b7565b336000908152601c60205260408120601b805491929160ff85169081106129105761291061564b565b906000526020600020906009020190506000805b83548110156129f85760008482815481106129415761294161564b565b60009182526020909120600690910201805490915060ff87811691161461296857506129e6565b806001015460000361297a57506129e6565b60008160040154600f54866005015484600101546129989190615698565b6129a291906156b7565b6129ac9190615634565b90506129b881856156d9565b9350600f54856005015483600101546129d19190615698565b6129db91906156b7565b826004018190555050505b806129f0816156f1565b915050612924565b508015612a585780612a08613c78565b1015612a265760405162461bcd60e51b8152600401610a7a90615740565b601254612a3d906001600160a01b0316338361495a565b612a4681614bb0565b80601954612a5491906156d9565b6019555b5050505060018055565b601b5460009060ff831610612a7957506000612c6c565b6006541580612a885750601554155b15612a9557506000612c6c565b6001600160a01b0383166000908152601c6020908152604080832080548251818502810185019093528083529192909190849084015b82821015612b365760008481526020908190206040805160c08101825260068602909201805460ff1683526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460a08301529083529092019101612acb565b5050505090506000612b46612160565b9050601754811015612b5757506017545b6015546000612b64613c78565b6012546011549192506001600160a01b03908116911603612b8c57612b8981836156d9565b91505b60008260105460175486612ba09190615634565b612baa9190615698565b612bb491906156b7565b601454612bc191906156d9565b90506000805b8651811015612c63576000878281518110612be457612be461564b565b602002602001015190508960ff16816000015160ff1614612c055750612c51565b8060200151600003612c175750612c51565b8060a00151601054858360200151612c2f9190615698565b612c3991906156b7565b612c439190615634565b612c4d90846156d9565b9250505b80612c5b816156f1565b915050612bc7565b50955050505050505b92915050565b6000546001600160a01b03163314612c9c5760405162461bcd60e51b8152600401610a7a906155e9565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b03163314612d105760405162461bcd60e51b8152600401610a7a906155e9565b60065415612d5b5760405162461bcd60e51b8152602060048201526018602482015277141bdbdb081dd85cc8185b1c9958591e481cdd185c9d195960421b6044820152606401610a7a565b612d664360646156d9565b600655600354612d789061191a615698565b600654612d8591906156d9565b60075560005b601b54811015612dd157600654601b8281548110612dab57612dab61564b565b600091825260209091206006600990920201015580612dc9816156f1565b915050612d8b565b507f7cd0ab87d19036f3dfadadb232c78aa4879dda3f0c994a9d637532410ee2ce06600654600754604051612e10929190918252602082015260400190565b60405180910390a1565b600080600080601c6000866001600160a01b03166001600160a01b03168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015612ed05760008481526020908190206040805160c08101825260068602909201805460ff1683526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460a08301529083529092019101612e65565b50505050905060005b8151811015612f8e576000828281518110612ef657612ef661564b565b602002602001015190508760ff16816000015160ff1614612f175750612f7c565b8060200151600003612f295750612f7c565b6020810151612f3890876156d9565b95508060600151421180612f4d575043600754105b15612f68576020810151612f6190866156d9565b9450612f7a565b6020810151612f7790856156d9565b93505b505b80612f86816156f1565b915050612ed9565b50509250925092565b600260015403612fb95760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e9557612fdb6145cf565b612fe4816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106130185761301861564b565b9060005260206000209060090201905060008060005b84548110156132c757600085828154811061304b5761304b61564b565b60009182526020909120600690910201805490915060ff89811691161461307257506132b5565b806001015460000361308457506132b5565b60008160040154600f54876005015484600101546130a29190615698565b6130ac91906156b7565b6130b69190615634565b90506130c281866156d9565b6012546011549196506001600160a01b039182169116148015906130e65750600081115b1561323b576011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015613134573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131589190615727565b90506131bd82600b805480602002602001604051908101604052809291908181526020018280548015611368576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161134a575050505050306149bd565b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015613206573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322a9190615727565b90506132368282615634565b925050505b61324581856156d9565b935080826001015461325791906156d9565b60018301819055600f54600588015490916132729190615698565b61327c91906156b7565b60048301556010546014546132919083615698565b61329b91906156b7565b82600501546132aa91906156d9565b826005018190555050505b806132bf816156f1565b91505061302e565b50811561338357816132d7613c78565b10156132f55760405162461bcd60e51b8152600401610a7a90615740565b6132fe82614bb0565b8160195461330c91906156d9565b601955845461331c9082906156d9565b8555600783015461332e9082906156d9565b60078401556015546133419082906156d9565b6015556040805160ff881681526020810183905233917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910160405180910390a25b50505050505060018055565b6000546001600160a01b031633146133b95760405162461bcd60e51b8152600401610a7a906155e9565b60005b601b5460ff821610156133e4576133d2816146b7565b806133dc81615884565b9150506133bc565b5060006019546133f2613c78565b6133fc91906156d9565b9050601a5481111561349557601a546134159082615634565b60125460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015613467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348b91906158a3565b5061349581614bb0565b4360078190556040519081527ffed9fcb0ca3d1e761a4b929792bb24082fba92dca81252646ad306d30680656690602001610b9d565b600d546001600160a01b031633146135255760405162461bcd60e51b815260206004820152601960248201527f73657453657276696365496e666f3a20464f5242494444454e000000000000006044820152606401610a7a565b6001600160a01b03821661356d5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610a7a565b66b1a2bc2ec5000081106135c35760405162461bcd60e51b815260206004820152601c60248201527f6665652063616e6e6f742065786365656420302e3035206574686572000000006044820152606401610a7a565b600d80546001600160a01b0319166001600160a01b038416908117909155600e82905560408051918252602082018390527f232f2e6280d2064b1e439bf40ecdada042d84eefbb55039e4c49e8dc4f4c90c991016117c6565b6000546001600160a01b031633146136465760405162461bcd60e51b8152600401610a7a906155e9565b6002600154036136685760405162461bcd60e51b8152600401610a7a90615661565b6002600155806136ab5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a7a565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156136f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137189190615727565b601254909150613733906001600160a01b0316333085614b3d565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561377c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137a09190615727565b905081816016546137b191906156d9565b6137bb9190615634565b60165550506001805550565b601b81815481106137d757600080fd5b600091825260209091206009909102018054600182015460028301546003840154600485015460058601546006870154600788015460089098015460ff90971698509496939592949193909289565b6002600154036138485760405162461bcd60e51b8152600401610a7a90615661565b60026001558161389a5760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e742073686f756c642062652067726561746f72207468616e2030006044820152606401610a7a565b601b5460ff8216106138e35760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964207374616b65207479706560701b6044820152606401610a7a565b6138eb6145cf565b6138f4816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106139285761392861564b565b60009182526020822060099091020191508086815b8554811015613ad857600086828154811061395a5761395a61564b565b60009182526020909120600690910201805490915060ff8a81169116146139815750613ac6565b80600101546000036139935750613ac6565b826000036139a15750613ad8565b60008160040154600f54886005015484600101546139bf9190615698565b6139c991906156b7565b6139d39190615634565b9050816005015460105460145484600101546139ef9190615698565b6139f991906156b7565b613a039190615634565b613a0d90866156d9565b9450613a1981876156d9565b95504282600301541080613a2e575043600754105b15613a76578382600101541115613a5d57838260010154613a4f9190615634565b600183015560009350613a76565b6001820154613a6c9085615634565b6000600184015593505b600f5487600501548360010154613a8d9190615698565b613a9791906156b7565b60048301556010546014546001840154613ab19190615698565b613abb91906156b7565b826005018190555050505b80613ad0816156f1565b91505061393d565b508215613b385782613ae8613c78565b1015613b065760405162461bcd60e51b8152600401610a7a90615740565b601254613b1d906001600160a01b0316338561495a565b613b2683614bb0565b82601954613b3491906156d9565b6019555b8115613b7357613b4782614868565b601354909250613b61906001600160a01b03163384614898565b81601754613b6f9190615634565b6017555b6000613b7f828a615634565b8754909150613b8f908290615634565b87556007850154613ba1908290615634565b6007860155601554613bb4908290615634565b6015558015613c2b57600385015415613c14576000612710866003015483613bdc9190615698565b613be691906156b7565b600c54601154919250613c06916001600160a01b0390811691168361495a565b613c108183615634565b9150505b601154613c2b906001600160a01b0316338361495a565b6040805160ff8a1681526020810183905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a250506001805550505050505050565b6013546012546000916001600160a01b03908116911603613c9a575060165490565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015613ce3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d079190615727565b6011546012549192506001600160a01b0390811691160361225c57601554811015613d3457600091505090565b601554613d419082615634565b91505090565b6000546001600160a01b03163314613d715760405162461bcd60e51b8152600401610a7a906155e9565b8115613dd2576005548111613dc85760405162461bcd60e51b815260206004820152601860248201527f4e6577206c696d6974206d7573742062652068696768657200000000000000006044820152606401610a7a565b6005819055613dd8565b60006005555b6004805460ff19168315159081179091556005546040805191825260208201929092527f19a6e21b354f2502655dd03f5ac08375f296d713847fbfbf7eec539cd22c443991016117c6565b601c6020528160005260406000208181548110613e3f57600080fd5b600091825260209091206006909102018054600182015460028301546003840154600485015460059095015460ff909416965091945092909186565b600b818154811061105057600080fd5b6000546001600160a01b03163314613eb55760405162461bcd60e51b8152600401610a7a906155e9565b6103e3851115613f075760405162461bcd60e51b815260206004820152601860248201527f5f736c697070616765466163746f7220746f6f206869676800000000000000006044820152606401610a7a565b6001600160a01b038116613f4f5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964204164647265737360881b6044820152606401610a7a565b6008859055600980546001600160a01b0319166001600160a01b0386161790558151613f8290600a906020850190615159565b508251613f9690600b906020860190615159565b50600c80546001600160a01b0319166001600160a01b0383161790556040517f0fae0d0e8768c1e54ef03d02ab9a3aea954cb05c643b8650d09b989b2cb27ac790613fea9087908790879087908790615904565b60405180910390a15050505050565b6000546001600160a01b031633146140235760405162461bcd60e51b8152600401610a7a906155e9565b6001600160a01b0381166140885760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a7a565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080601a54905060006019546140f8613c78565b61410291906156d9565b905060005b601b548110156141d45760065460000361416a57600354601b82815481106141315761413161564b565b90600052602060002090600902016004015461414d9190615698565b6141599061191a615698565b61416390846156d9565b92506141c2565b6000614182601b8381548110611f9f57611f9f61564b565b905080601b83815481106141985761419861564b565b9060005260206000209060090201600401546141b49190615698565b6141be90856156d9565b9350505b806141cc816156f1565b915050614107565b508181106141e55760009250505090565b6141ef8183615634565b9250505090565b6000546001600160a01b031633146142205760405162461bcd60e51b8152600401610a7a906155e9565b6006541561426b5760405162461bcd60e51b8152602060048201526018602482015277141bdbdb081dd85cc8185b1c9958591e481cdd185c9d195960421b6044820152606401610a7a565b601e8110156142b25760405162461bcd60e51b81526020600482015260136024820152721b1bddd95c881b1a5b5a5d081c995858da1959606a1b6044820152606401610a7a565b60038190556040518181527f91abcc2d6823e3a3f11d31b208dd3065d2c6a791f1c7c9fe96a42ce12897eac590602001610b9d565b601b5460009060ff8316106142fe57506000919050565b601b8260ff16815481106143145761431461564b565b9060005260206000209060090201600401549050919050565b601b5460009060ff83161015806143445750600654155b1561435157506000612c6c565b6001600160a01b0383166000908152601c6020908152604080832080548251818502810185019093528083529192909190849084015b828210156143f25760008481526020908190206040805160c08101825260068602909201805460ff1683526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460a08301529083529092019101614387565b5050505090506000601b8460ff16815481106144105761441061564b565b6000918252602080832060408051610120810182526009909402909101805460ff1684526001810154928401929092526002820154908301526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460e08301819052600890910154610100830152909250900361449d57600092505050612c6c565b60a081015160c0820151431180156144b8575060e082015115155b80156144c8575060008260c00151115b156145245760006144dd8360c0015143614b75565b905060008360800151826144f19190615698565b90508360e00151600f54826145069190615698565b61451091906156b7565b8460a0015161451f91906156d9565b925050505b6000805b84518110156145c45760008582815181106145455761454561564b565b602002602001015190508760ff16816000015160ff161461456657506145b2565b806020015160000361457857506145b2565b8060800151600f548583602001516145909190615698565b61459a91906156b7565b6145a49190615634565b6145ae90846156d9565b9250505b806145bc816156f1565b915050614528565b509695505050505050565b600e543410156146355760405162461bcd60e51b815260206004820152602b60248201527f73686f756c642070617920736d616c6c2067617320746f20636f6d706f756e6460448201526a081bdc881a185c9d995cdd60aa1b6064820152608401610a7a565b600d54600e546040516001600160a01b039092169181156108fc0291906000818181858888f19350505050158015614671573d6000803e3d6000fd5b50600e5434111561185457600e5433906108fc9061468f9034615634565b6040518115909202916000818181858888f193505050501580156115d7573d6000803e3d6000fd5b601554156147985760006146c9612160565b90506017548110156146da57506017545b60155460006146e7613c78565b6012546011549192506001600160a01b0390811691160361470f5761470c81836156d9565b91505b81601054601754856147219190615634565b61472b9190615698565b61473591906156b7565b60145461474291906156d9565b6014556012546011546001600160a01b039182169116036147925781816017548561476d9190615634565b6147779190615698565b61478191906156b7565b60185461478e91906156d9565b6018555b50506017555b6000601b8260ff16815481106147b0576147b061564b565b906000526020600020906009020190508060060154431115806147d557506006810154155b156147de575050565b80600701546000036147f4574360069091015550565b6000614804826006015443614b75565b905060008260040154826148189190615698565b90508260070154600f548261482d9190615698565b61483791906156b7565b836005015461484691906156d9565b6005840155436006840155601a5461485f9082906156d9565b601a5550505050565b600080614873612160565b90506017548311156148855760175492505b80831115614891578092505b5090919050565b6001600160a01b0383166148e2576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156148dc573d6000803e3d6000fd5b50505050565b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015614931573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148dc91906158a3565b505050565b6040516001600160a01b03831660248201526044810182905261495590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614df8565b60095460405163d06ca61f60e01b81526000916001600160a01b03169063d06ca61f906149f09087908790600401615954565b600060405180830381865afa158015614a0d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052614a35919081019061596d565b905060008160018351614a489190615634565b81518110614a5857614a5861564b565b60200260200101519050614aaf600960009054906101000a90046001600160a01b03168686600081518110614a8f57614a8f61564b565b60200260200101516001600160a01b0316614eca9092919063ffffffff16565b6009546008546001600160a01b0390911690635c11d7959087906103e890614ad79086615698565b614ae191906156b7565b8787614aef426102586156d9565b6040518663ffffffff1660e01b8152600401614b0f9594939291906159f3565b600060405180830381600087803b158015614b2957600080fd5b505af1158015611b1d573d6000803e3d6000fd5b6040516001600160a01b03808516602483015283166044820152606481018290526148dc9085906323b872dd60e01b90608401614986565b60006007548211614b9157614b8a8383615634565b9050612c6c565b6007548310614ba257506000612c6c565b82600754614b8a9190615634565b806016541115614bc857806016546115d39190615634565b600060165550565b6001600160a01b0383166000908152601c6020526040812090614bf68462015180615698565b614c0090426156d9565b82549091506101008110614c435760405162461bcd60e51b815260206004820152600a6024820152694d6178207374616b657360b01b6044820152606401610a7a565b8254600101835560008390525b8015801590614c8b57508183614c67600184615634565b81548110614c7757614c7761564b565b906000526020600020906006020160030154115b15614d365782614c9c600183615634565b81548110614cac57614cac61564b565b9060005260206000209060060201838281548110614ccc57614ccc61564b565b600091825260209091208254600690920201805460ff191660ff909216919091178155600180830154818301556002808401549083015560038084015490830155600480840154908301556005928301549290910191909155614d2f9082615634565b9050614c50565b6000601b8860ff1681548110614d4e57614d4e61564b565b906000526020600020906009020190506000848381548110614d7257614d7261564b565b60009182526020909120600690910201805460ff191660ff8b16178155600281018890556003810185905560018101879055600f54600584015491925090614dba9088615698565b614dc491906156b7565b60048201556010546014546001830154614dde9190615698565b614de891906156b7565b6005909101555050505050505050565b6000614e4d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614fdf9092919063ffffffff16565b8051909150156149555780806020019051810190614e6b91906158a3565b6149555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a7a565b801580614f445750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015614f1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f429190615727565b155b614faf5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610a7a565b6040516001600160a01b03831660248201526044810182905261495590849063095ea7b360e01b90606401614986565b6060614fee8484600085614ff8565b90505b9392505050565b6060824710156150595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a7a565b843b6150a75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a7a565b600080866001600160a01b031685876040516150c39190615a5b565b60006040518083038185875af1925050503d8060008114615100576040519150601f19603f3d011682016040523d82523d6000602084013e615105565b606091505b5091509150615115828286615120565b979650505050505050565b6060831561512f575081614ff1565b82511561513f5782518084602001fd5b8160405162461bcd60e51b8152600401610a7a9190615a77565b8280548282559060005260206000209081019282156151ae579160200282015b828111156151ae57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615179565b506151ba9291506151be565b5090565b5b808211156151ba57600081556001016151bf565b6000602082840312156151e557600080fd5b5035919050565b600080600080600060a0868803121561520457600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60ff811681146115d757600080fd5b60006020828403121561524857600080fd5b8135614ff181615227565b6001600160a01b03811681146115d757600080fd5b6000806040838503121561527b57600080fd5b823561528681615253565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156152d3576152d3615294565b604052919050565b600067ffffffffffffffff8211156152f5576152f5615294565b5060051b60200190565b600082601f83011261531057600080fd5b81356020615325615320836152db565b6152aa565b82815260059290921b8401810191818101908684111561534457600080fd5b8286015b848110156145c457803561535b81615253565b8352918301918301615348565b60008060008060008060c0878903121561538157600080fd5b863561538c81615253565b9550602087013561539c81615253565b945060408701356153ac81615253565b935060608701356153bc81615253565b9250608087013567ffffffffffffffff808211156153d957600080fd5b6153e58a838b016152ff565b935060a08901359150808211156153fb57600080fd5b5061540889828a016152ff565b9150509295509295509295565b60008060008060008060c0878903121561542e57600080fd5b863561543981615227565b9860208801359850604088013597606081013597506080810135965060a00135945092505050565b6000806040838503121561547457600080fd5b823561528681615227565b6000806040838503121561549257600080fd5b8235915060208301356154a481615227565b809150509250929050565b600080604083850312156154c257600080fd5b82356154cd81615253565b915060208301356154a481615227565b600080604083850312156154f057600080fd5b82356154fb81615227565b915060208301356154a481615253565b80151581146115d757600080fd5b6000806040838503121561552c57600080fd5b82356152868161550b565b60006020828403121561554957600080fd5b8135614ff181615253565b600080600080600060a0868803121561556c57600080fd5b85359450602086013561557e81615253565b9350604086013567ffffffffffffffff8082111561559b57600080fd5b6155a789838a016152ff565b945060608801359150808211156155bd57600080fd5b506155ca888289016152ff565b92505060808601356155db81615253565b809150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156156465761564661561e565b500390565b634e487b7160e01b600052603260045260246000fd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60008160001904831182151516156156b2576156b261561e565b500290565b6000826156d457634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156156ec576156ec61561e565b500190565b6000600182016157035761570361561e565b5060010190565b60006020828403121561571c57600080fd5b8151614ff181615253565b60006020828403121561573957600080fd5b5051919050565b6020808252601a908201527f496e73756666696369656e742072657761726420746f6b656e73000000000000604082015260600190565b60006020828403121561578957600080fd5b8151614ff181615227565b600181815b808511156157cf5781600019048211156157b5576157b561561e565b808516156157c257918102915b93841c9390800290615799565b509250929050565b6000826157e657506001612c6c565b816157f357506000612c6c565b816001811461580957600281146158135761582f565b6001915050612c6c565b60ff8411156158245761582461561e565b50506001821b612c6c565b5060208310610133831016604e8410600b8410161715615852575081810a612c6c565b61585c8383615794565b80600019048211156158705761587061561e565b029392505050565b6000614ff183836157d7565b600060ff821660ff810361589a5761589a61561e565b60010192915050565b6000602082840312156158b557600080fd5b8151614ff18161550b565b600081518084526020808501945080840160005b838110156158f95781516001600160a01b0316875295820195908201906001016158d4565b509495945050505050565b858152600060018060a01b03808716602084015260a0604084015261592c60a08401876158c0565b838103606085015261593e81876158c0565b9250508084166080840152509695505050505050565b828152604060208201526000614fee60408301846158c0565b6000602080838503121561598057600080fd5b825167ffffffffffffffff81111561599757600080fd5b8301601f810185136159a857600080fd5b80516159b6615320826152db565b81815260059190911b820183019083810190878311156159d557600080fd5b928401925b82841015615115578351825292840192908401906159da565b85815284602082015260a060408201526000615a1260a08301866158c0565b6001600160a01b0394909416606083015250608001529392505050565b60005b83811015615a4a578181015183820152602001615a32565b838111156148dc5750506000910152565b60008251615a6d818460208701615a2f565b9190910192915050565b6020815260008251806020840152615a96816040850160208701615a2f565b601f01601f1916919091016040019291505056fea264697066735822122041db2571a471489d955b46aa95d8b05580d9f7233df7d900fc642d5ec884000164736f6c634300080f0033
Deployed Bytecode
0x60806040526004361061036e5760003560e01c806376fa17d2116101c6578063a0b40905116100f7578063e7a2fed711610095578063f6be71d11161006f578063f6be71d1146109da578063f8920ee7146109fa578063fbe32b3514610a1a578063ffbd3b1f14610a3a57600080fd5b8063e7a2fed714610985578063f2fde38b146109a5578063f3aeb31d146109c557600080fd5b8063b74cd242116100d1578063b74cd24214610919578063b77e7da01461092f578063c1e22a651461094f578063ccd34cd51461096f57600080fd5b8063a0b409051461086c578063acc3a9391461088c578063b5d5b5fa146108c857600080fd5b80638bdf67f211610164578063903d42961161013e578063903d42961461081457806392b46e5b1461082757806392e8990e1461083d5780639f94e2721461085757600080fd5b80638bdf67f21461076e5780638da5cb5b1461078e5780638e6f4fb7146107ac57600080fd5b8063817b1cd2116101a0578063817b1cd21461070c57806381b6194814610722578063877887821461074257806388bbb0c11461075857600080fd5b806376fa17d2146106a957806378d57eea146106e457806380dc0672146106f757600080fd5b806348cd4cb1116102a0578063689f16231161023e5780636e707b73116102185780636e707b731461063f578063715018a61461065f57806372f702f314610674578063746c8ae11461069457600080fd5b8063689f1623146105ec578063693a090b146105ff5780636becd6571461061f57600080fd5b8063595e173a1161027a578063595e173a1461058e5780635dde4a91146105ae578063654cfdff146105c357806366fe9f8a146105d657600080fd5b806348cd4cb114610538578063515bbf2c1461054e57806353314fae1461056e57600080fd5b80631aed65531161030d5780633279beab116102e75780633279beab146104b9578063392e53cd146104d95780633f138d4b146105035780634641257d1461052357600080fd5b80631aed6553146104705780631cd348c014610486578063304f807c146104a657600080fd5b806313c68f901161034957806313c68f90146103e5578063155622a4146103f85780631582358e14610418578063167d2dbe1461045057600080fd5b80626f02311461037a5780630bf8a6a41461039c5780630fb5a6b4146103bc57600080fd5b3661037557005b600080fd5b34801561038657600080fd5b5061039a6103953660046151d3565b610a50565b005b3480156103a857600080fd5b5061039a6103b73660046151ec565b610ba8565b3480156103c857600080fd5b506103d260035481565b6040519081526020015b60405180910390f35b61039a6103f3366004615236565b610d30565b34801561040457600080fd5b5061039a610413366004615236565b610e9c565b34801561042457600080fd5b50601354610438906001600160a01b031681565b6040516001600160a01b0390911681526020016103dc565b34801561045c57600080fd5b5061043861046b3660046151d3565b611040565b34801561047c57600080fd5b506103d260075481565b34801561049257600080fd5b50600d54610438906001600160a01b031681565b61039a6104b4366004615236565b61106a565b3480156104c557600080fd5b5061039a6104d43660046151d3565b611500565b3480156104e557600080fd5b506002546104f39060ff1681565b60405190151581526020016103dc565b34801561050f57600080fd5b5061039a61051e366004615268565b6115da565b34801561052f57600080fd5b5061039a6117d2565b34801561054457600080fd5b506103d260065481565b34801561055a57600080fd5b5061039a610569366004615368565b611856565b34801561057a57600080fd5b5061039a610589366004615415565b611b28565b34801561059a57600080fd5b5061039a6105a9366004615461565b611cd9565b3480156105ba57600080fd5b506103d2612160565b61039a6105d136600461547f565b612261565b3480156105e257600080fd5b506103d260055481565b61039a6105fa366004615236565b61289a565b34801561060b57600080fd5b50600954610438906001600160a01b031681565b34801561062b57600080fd5b506103d261063a3660046154af565b612a62565b34801561064b57600080fd5b50601254610438906001600160a01b031681565b34801561066b57600080fd5b5061039a612c72565b34801561068057600080fd5b50601154610438906001600160a01b031681565b3480156106a057600080fd5b5061039a612ce6565b3480156106b557600080fd5b506106c96106c43660046154dd565b612e1a565b604080519384526020840192909252908201526060016103dc565b61039a6106f2366004615236565b612f97565b34801561070357600080fd5b5061039a61338f565b34801561071857600080fd5b506103d260155481565b34801561072e57600080fd5b5061039a61073d366004615268565b6134cb565b34801561074e57600080fd5b506103d2600e5481565b34801561076457600080fd5b506103d260105481565b34801561077a57600080fd5b5061039a6107893660046151d3565b61361c565b34801561079a57600080fd5b506000546001600160a01b0316610438565b3480156107b857600080fd5b506107cc6107c73660046151d3565b6137c7565b6040805160ff909a168a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152610100820152610120016103dc565b61039a61082236600461547f565b613826565b34801561083357600080fd5b506103d260145481565b34801561084957600080fd5b506004546104f39060ff1681565b34801561086357600080fd5b506103d2613c78565b34801561087857600080fd5b5061039a610887366004615519565b613d47565b34801561089857600080fd5b506106c96108a7366004615537565b601d6020526000908152604090208054600182015460029092015490919083565b3480156108d457600080fd5b506108e86108e3366004615268565b613e23565b6040805160ff90971687526020870195909552938501929092526060840152608083015260a082015260c0016103dc565b34801561092557600080fd5b506103d26103e381565b34801561093b57600080fd5b50600c54610438906001600160a01b031681565b34801561095b57600080fd5b5061043861096a3660046151d3565b613e7b565b34801561097b57600080fd5b506103d2600f5481565b34801561099157600080fd5b5061039a6109a0366004615554565b613e8b565b3480156109b157600080fd5b5061039a6109c0366004615537565b613ff9565b3480156109d157600080fd5b506103d26140e3565b3480156109e657600080fd5b5061039a6109f53660046151d3565b6141f6565b348015610a0657600080fd5b506103d2610a15366004615236565b6142e7565b348015610a2657600080fd5b506103d2610a353660046154af565b61432d565b348015610a4657600080fd5b506103d260085481565b6000546001600160a01b03163314610a835760405162461bcd60e51b8152600401610a7a906155e9565b60405180910390fd5b600060065411610acb5760405162461bcd60e51b8152602060048201526013602482015272141bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b6044820152606401610a7a565b4360075411610b1c5760405162461bcd60e51b815260206004820152601960248201527f506f6f6c2077617320616c72656164792066696e6973686564000000000000006044820152606401610a7a565b4381118015610b2c575060065481115b610b6c5760405162461bcd60e51b8152602060048201526011602482015270496e76616c696420656e6420626c6f636b60781b6044820152606401610a7a565b60078190556040518181527f0972575658363b3e7c472ab3a6a918726742c853b732f6a4a2763e2e3a94c977906020015b60405180910390a150565b6000546001600160a01b03163314610bd25760405162461bcd60e51b8152600401610a7a906155e9565b6107d08410610c195760405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206465706f7369742066656560681b6044820152606401610a7a565b6107d08310610c615760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642077697468647261772066656560601b6044820152606401610a7a565b601b8054600190810180835560008381529291610c7d91615634565b81548110610c8d57610c8d61564b565b60009182526020909120600160099092020181810188905560028101879055600381018690556004810185905543600682015560088101849055601b549092507f2a9378497cb60e247e83eb6f2c7c371ba979e24ee25723c2e3275822b317175991610cf891615634565b6040805160ff9092168252602082018990528101879052606081018690526080810185905260a00160405180910390a1505050505050565b600260015403610d525760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e9557610d746145cf565b610d7d816146b7565b336000908152601c6020526040812090805b8254811015610e57576000838281548110610dac57610dac61564b565b60009182526020909120600690910201805490915060ff868116911614610dd35750610e45565b8060010154600003610de55750610e45565b80600501546010546014548360010154610dff9190615698565b610e0991906156b7565b610e139190615634565b610e1d90846156d9565b92506010546014548260010154610e349190615698565b610e3e91906156b7565b6005909101555b80610e4f816156f1565b915050610d8f565b50610e6181614868565b90508015610e9257601354610e80906001600160a01b03163383614898565b80601754610e8e9190615634565b6017555b50505b5060018055565b600260015403610ebe5760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e9557336000908152601d60209081526040808320601c9092528220601b80549293919260ff8616908110610f0457610f0461564b565b906000526020600020906009020190506000805b8354811015610fab576000848281548110610f3557610f3561564b565b60009182526020909120600690910201805490915060ff888116911614610f5c5750610f99565b8060010154600003610f6e5750610f99565b6001810154610f7d90846156d9565b6000600183018190556004830181905560059092019190915591505b80610fa3816156f1565b915050610f18565b508015610fff57601154610fc9906001600160a01b0316338361495a565b8354610fd6908290615634565b84556007820154610fe8908290615634565b6007830155601554610ffb908290615634565b6015555b60405181815233907f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd9695906020015b60405180910390a2505050505060018055565b600a818154811061105057600080fd5b6000918252602090912001546001600160a01b0316905081565b60026001540361108c5760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e95576110ae6145cf565b6110b7816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106110eb576110eb61564b565b906000526020600020906009020190506000805b835481101561147e57600084828154811061111c5761111c61564b565b60009182526020909120600690910201805490915060ff888116911614611143575061146c565b8060010154600003611155575061146c565b6000816005015460105460145484600101546111719190615698565b61117b91906156b7565b6111859190615634565b905061119081614868565b9050806017546111a09190615634565b6017556013546011546001600160a01b039081169116148015906111c45750600081115b156113f1576013546001600160a01b031661129f57600954604080516315ab88c960e31b815290516000926001600160a01b03169163ad5c46489160048083019260209291908290030181865afa158015611223573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611247919061570a565b9050806001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561128457600080fd5b505af1158015611298573d6000803e3d6000fd5b5050505050505b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156112e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130c9190615727565b905061137382600a80548060200260200160405190810160405280929190818152602001828054801561136857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161134a575b5050505050306149bd565b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156113bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e09190615727565b90506113ec8282615634565b925050505b6113fb81856156d9565b935080826001015461140d91906156d9565b6001830155600f5460058601546114249083615698565b61142e91906156b7565b826004015461143d91906156d9565b600483015560105460145460018401546114579190615698565b61146191906156b7565b826005018190555050505b80611476816156f1565b9150506110ff565b5080156114f55783546114929082906156d9565b845560078201546114a49082906156d9565b60078301556015546114b79082906156d9565b6015556040805160ff871681526020810183905233917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910161102d565b505050505060018055565b6000546001600160a01b0316331461152a5760405162461bcd60e51b8152600401610a7a906155e9565b600754431161156d5760405162461bcd60e51b815260206004820152600f60248201526e506f6f6c2069732072756e6e696e6760881b6044820152606401610a7a565b80611576613c78565b10156115945760405162461bcd60e51b8152600401610a7a90615740565b6012546115ab906001600160a01b0316338361495a565b601654156115d7576016548111156115c557600060165550565b806016546115d39190615634565b6016555b50565b6000546001600160a01b031633146116045760405162461bcd60e51b8152600401610a7a906155e9565b6012546001600160a01b039081169083160361165b5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103132903932bbb0b932103a37b5b2b760511b6044820152606401610a7a565b6011546001600160a01b0390811690831603611736576011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de9190615727565b9050601554816116ee9190615634565b8211156117345760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610a7a565b505b6001600160a01b03821661177757604051339082156108fc029083906000818181858888f19350505050158015611771573d6000803e3d6000fd5b5061178b565b61178b6001600160a01b038316338361495a565b604080516001600160a01b0384168152602081018390527f74f5dcd55c394cb1c6d3b9da22c2464bcc46c38cc3865bd629ed75823249b40b91015b60405180910390a15050565b6000546001600160a01b031633146117fc5760405162461bcd60e51b8152600401610a7a906155e9565b61180660006146b7565b611811601854614868565b60188190551561185457601354600c5460185461183b926001600160a01b03908116921690614898565b60185460175461184b9190615634565b60175560006018555b565b6000546001600160a01b031633146118805760405162461bcd60e51b8152600401610a7a906155e9565b60025460ff16156118c95760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610a7a565b6002805460ff19166001179055601180546001600160a01b038089166001600160a01b0319928316179092556012805488841690831681179091556013805493881693831693909317909255600c8054909116331790556040805163313ce56760e01b815290516000929163313ce5679160048083019260209291908290030181865afa15801561195e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119829190615777565b60ff169050601e81106119d05760405162461bcd60e51b815260206004820152601660248201527504d75737420626520696e666572696f7220746f2033360541b6044820152606401610a7a565b6119db816028615634565b6119e690600a615878565b600f556013546012906001600160a01b031615611ac257601360009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a749190615777565b60ff169050601e8110611ac25760405162461bcd60e51b815260206004820152601660248201527504d75737420626520696e666572696f7220746f2033360541b6044820152606401610a7a565b611acd826028615634565b611ad890600a615878565b601055600980546001600160a01b0319166001600160a01b0387161790558351611b0990600b906020870190615159565b508251611b1d90600a906020860190615159565b505050505050505050565b6000546001600160a01b03163314611b525760405162461bcd60e51b8152600401610a7a906155e9565b601b5460ff871610611b995760405162461bcd60e51b815260206004820152601060248201526f131bd8dadd5c08139bdd08199bdd5b9960821b6044820152606401610a7a565b6107d08410611be05760405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206465706f7369742066656560681b6044820152606401610a7a565b6107d08310611c285760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642077697468647261772066656560601b6044820152606401610a7a565b611c31866146b7565b6000601b8760ff1681548110611c4957611c4961564b565b600091825260209182902060099091020160018101889055600281018790556003810186905560048101859055600881018490556040805160ff8b1681529283018990528201879052606082018690526080820185905291507f2a9378497cb60e247e83eb6f2c7c371ba979e24ee25723c2e3275822b31717599060a0015b60405180910390a150505050505050565b6000546001600160a01b03163314611d035760405162461bcd60e51b8152600401610a7a906155e9565b600060065411611d4b5760405162461bcd60e51b81526020600482015260136024820152721c1bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b6044820152606401610a7a565b4360075411611d9c5760405162461bcd60e51b815260206004820152601960248201527f706f6f6c2077617320616c72656164792066696e6973686564000000000000006044820152606401610a7a565b60008111611ddd5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a7a565b611de6826146b7565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e539190615727565b601254909150611e6e906001600160a01b0316333085614b3d565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edb9190615727565b90508181601654611eec91906156d9565b611ef69190615634565b601655601954600090611f07613c78565b611f1191906156d9565b601a5490915060005b601b5481101561200b5760ff87168114611ff957600654600003611f8757600354601b8281548110611f4e57611f4e61564b565b906000526020600020906009020160040154611f6a9190615698565b611f769061191a615698565b611f8090836156d9565b9150611ff9565b6000611fb9601b8381548110611f9f57611f9f61564b565b906000526020600020906009020160060154600754614b75565b905080601b8381548110611fcf57611fcf61564b565b906000526020600020906009020160040154611feb9190615698565b611ff590846156d9565b9250505b80612003816156f1565b915050611f1a565b50601a54821115612158576120208183615634565b91506000436007546120329190615634565b905061203e81846156b7565b601b8860ff16815481106120545761205461564b565b9060005260206000209060090201600401819055507f2a9378497cb60e247e83eb6f2c7c371ba979e24ee25723c2e3275822b317175987601b8960ff16815481106120a1576120a161564b565b906000526020600020906009020160010154601b8a60ff16815481106120c9576120c961564b565b906000526020600020906009020160020154601b8b60ff16815481106120f1576120f161564b565b906000526020600020906009020160030154601b8c60ff16815481106121195761211961564b565b6000918252602091829020600460099092020101546040805160ff9097168752918601949094528401919091526060830152608082015260a001611cc8565b505050505050565b6013546000906001600160a01b031661217857504790565b6013546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156121c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e59190615727565b6012546013549192506001600160a01b039081169116036122225760165481101561221257600091505090565b60165461221f9082615634565b90505b6011546013546001600160a01b0391821691160361225c5760155481101561224c57600091505090565b6015546122599082615634565b90505b919050565b6002600154036122835760405162461bcd60e51b8152600401610a7a90615661565b60026001556006541580159061229a575043600654105b6122e65760405162461bcd60e51b815260206004820152601a60248201527f5374616b696e67206861736e27742073746172746564207965740000000000006044820152606401610a7a565b600082116123365760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e742073686f756c642062652067726561746f72207468616e2030006044820152606401610a7a565b601b5460ff82161061237f5760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964207374616b65207479706560701b6044820152606401610a7a565b6123876145cf565b612390816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106123c4576123c461564b565b9060005260206000209060090201905060008160080154111561246a5780600801548160070154106124385760405162461bcd60e51b815260206004820152601b60248201527f546f74616c207374616b6564206c696d697420657863656564656400000000006044820152606401610a7a565b806008015485826007015461244d91906156d9565b111561246a57806007015481600801546124679190615634565b94505b60008060005b84548110156125a257600085828154811061248d5761248d61564b565b60009182526020909120600690910201805490915060ff8981169116146124b45750612590565b80600101546000036124c65750612590565b806005015460105460145483600101546124e09190615698565b6124ea91906156b7565b6124f49190615634565b6124fe90846156d9565b925060008160040154600f548760050154846001015461251e9190615698565b61252891906156b7565b6125329190615634565b905061253e81866156d9565b9450600f54866005015483600101546125579190615698565b61256191906156b7565b6004830155601054601454600184015461257b9190615698565b61258591906156b7565b826005018190555050505b8061259a816156f1565b915050612470565b50811561260257816125b2613c78565b10156125d05760405162461bcd60e51b8152600401610a7a90615740565b6012546125e7906001600160a01b0316338461495a565b6125f082614bb0565b816019546125fe91906156d9565b6019555b61260b81614868565b9050801561263c5760135461262a906001600160a01b03163383614898565b806017546126389190615634565b6017555b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a99190615727565b6011549091506126c4906001600160a01b031633308b614b3d565b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561270d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127319190615727565b9050600061273f8383615634565b60045490915060ff16156127aa57600554885461275c90836156d9565b11156127aa5760405162461bcd60e51b815260206004820152601760248201527f5573657220616d6f756e742061626f7665206c696d69740000000000000000006044820152606401610a7a565b6002860154156128075760006127108760020154836127c99190615698565b6127d391906156b7565b9050801561280557600c546011546127f8916001600160a01b0391821691168361495a565b6128028183615634565b91505b505b6128178933886001015484614bd0565b87546128249082906156d9565b885560078601546128369082906156d9565b60078701556015546128499082906156d9565b6015556040805160ff8b1681526020810183905233917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910160405180910390a25050600180555050505050505050565b6002600154036128bc5760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e95576128de6145cf565b6128e7816146b7565b336000908152601c60205260408120601b805491929160ff85169081106129105761291061564b565b906000526020600020906009020190506000805b83548110156129f85760008482815481106129415761294161564b565b60009182526020909120600690910201805490915060ff87811691161461296857506129e6565b806001015460000361297a57506129e6565b60008160040154600f54866005015484600101546129989190615698565b6129a291906156b7565b6129ac9190615634565b90506129b881856156d9565b9350600f54856005015483600101546129d19190615698565b6129db91906156b7565b826004018190555050505b806129f0816156f1565b915050612924565b508015612a585780612a08613c78565b1015612a265760405162461bcd60e51b8152600401610a7a90615740565b601254612a3d906001600160a01b0316338361495a565b612a4681614bb0565b80601954612a5491906156d9565b6019555b5050505060018055565b601b5460009060ff831610612a7957506000612c6c565b6006541580612a885750601554155b15612a9557506000612c6c565b6001600160a01b0383166000908152601c6020908152604080832080548251818502810185019093528083529192909190849084015b82821015612b365760008481526020908190206040805160c08101825260068602909201805460ff1683526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460a08301529083529092019101612acb565b5050505090506000612b46612160565b9050601754811015612b5757506017545b6015546000612b64613c78565b6012546011549192506001600160a01b03908116911603612b8c57612b8981836156d9565b91505b60008260105460175486612ba09190615634565b612baa9190615698565b612bb491906156b7565b601454612bc191906156d9565b90506000805b8651811015612c63576000878281518110612be457612be461564b565b602002602001015190508960ff16816000015160ff1614612c055750612c51565b8060200151600003612c175750612c51565b8060a00151601054858360200151612c2f9190615698565b612c3991906156b7565b612c439190615634565b612c4d90846156d9565b9250505b80612c5b816156f1565b915050612bc7565b50955050505050505b92915050565b6000546001600160a01b03163314612c9c5760405162461bcd60e51b8152600401610a7a906155e9565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b03163314612d105760405162461bcd60e51b8152600401610a7a906155e9565b60065415612d5b5760405162461bcd60e51b8152602060048201526018602482015277141bdbdb081dd85cc8185b1c9958591e481cdd185c9d195960421b6044820152606401610a7a565b612d664360646156d9565b600655600354612d789061191a615698565b600654612d8591906156d9565b60075560005b601b54811015612dd157600654601b8281548110612dab57612dab61564b565b600091825260209091206006600990920201015580612dc9816156f1565b915050612d8b565b507f7cd0ab87d19036f3dfadadb232c78aa4879dda3f0c994a9d637532410ee2ce06600654600754604051612e10929190918252602082015260400190565b60405180910390a1565b600080600080601c6000866001600160a01b03166001600160a01b03168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015612ed05760008481526020908190206040805160c08101825260068602909201805460ff1683526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460a08301529083529092019101612e65565b50505050905060005b8151811015612f8e576000828281518110612ef657612ef661564b565b602002602001015190508760ff16816000015160ff1614612f175750612f7c565b8060200151600003612f295750612f7c565b6020810151612f3890876156d9565b95508060600151421180612f4d575043600754105b15612f68576020810151612f6190866156d9565b9450612f7a565b6020810151612f7790856156d9565b93505b505b80612f86816156f1565b915050612ed9565b50509250925092565b600260015403612fb95760405162461bcd60e51b8152600401610a7a90615661565b6002600155601b5460ff82161015610e955760065415610e9557612fdb6145cf565b612fe4816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106130185761301861564b565b9060005260206000209060090201905060008060005b84548110156132c757600085828154811061304b5761304b61564b565b60009182526020909120600690910201805490915060ff89811691161461307257506132b5565b806001015460000361308457506132b5565b60008160040154600f54876005015484600101546130a29190615698565b6130ac91906156b7565b6130b69190615634565b90506130c281866156d9565b6012546011549196506001600160a01b039182169116148015906130e65750600081115b1561323b576011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015613134573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131589190615727565b90506131bd82600b805480602002602001604051908101604052809291908181526020018280548015611368576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161134a575050505050306149bd565b6011546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015613206573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322a9190615727565b90506132368282615634565b925050505b61324581856156d9565b935080826001015461325791906156d9565b60018301819055600f54600588015490916132729190615698565b61327c91906156b7565b60048301556010546014546132919083615698565b61329b91906156b7565b82600501546132aa91906156d9565b826005018190555050505b806132bf816156f1565b91505061302e565b50811561338357816132d7613c78565b10156132f55760405162461bcd60e51b8152600401610a7a90615740565b6132fe82614bb0565b8160195461330c91906156d9565b601955845461331c9082906156d9565b8555600783015461332e9082906156d9565b60078401556015546133419082906156d9565b6015556040805160ff881681526020810183905233917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910160405180910390a25b50505050505060018055565b6000546001600160a01b031633146133b95760405162461bcd60e51b8152600401610a7a906155e9565b60005b601b5460ff821610156133e4576133d2816146b7565b806133dc81615884565b9150506133bc565b5060006019546133f2613c78565b6133fc91906156d9565b9050601a5481111561349557601a546134159082615634565b60125460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015613467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348b91906158a3565b5061349581614bb0565b4360078190556040519081527ffed9fcb0ca3d1e761a4b929792bb24082fba92dca81252646ad306d30680656690602001610b9d565b600d546001600160a01b031633146135255760405162461bcd60e51b815260206004820152601960248201527f73657453657276696365496e666f3a20464f5242494444454e000000000000006044820152606401610a7a565b6001600160a01b03821661356d5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610a7a565b66b1a2bc2ec5000081106135c35760405162461bcd60e51b815260206004820152601c60248201527f6665652063616e6e6f742065786365656420302e3035206574686572000000006044820152606401610a7a565b600d80546001600160a01b0319166001600160a01b038416908117909155600e82905560408051918252602082018390527f232f2e6280d2064b1e439bf40ecdada042d84eefbb55039e4c49e8dc4f4c90c991016117c6565b6000546001600160a01b031633146136465760405162461bcd60e51b8152600401610a7a906155e9565b6002600154036136685760405162461bcd60e51b8152600401610a7a90615661565b6002600155806136ab5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a7a565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156136f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137189190615727565b601254909150613733906001600160a01b0316333085614b3d565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561377c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137a09190615727565b905081816016546137b191906156d9565b6137bb9190615634565b60165550506001805550565b601b81815481106137d757600080fd5b600091825260209091206009909102018054600182015460028301546003840154600485015460058601546006870154600788015460089098015460ff90971698509496939592949193909289565b6002600154036138485760405162461bcd60e51b8152600401610a7a90615661565b60026001558161389a5760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e742073686f756c642062652067726561746f72207468616e2030006044820152606401610a7a565b601b5460ff8216106138e35760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964207374616b65207479706560701b6044820152606401610a7a565b6138eb6145cf565b6138f4816146b7565b336000908152601d60209081526040808320601c9092528220601b80549293919260ff86169081106139285761392861564b565b60009182526020822060099091020191508086815b8554811015613ad857600086828154811061395a5761395a61564b565b60009182526020909120600690910201805490915060ff8a81169116146139815750613ac6565b80600101546000036139935750613ac6565b826000036139a15750613ad8565b60008160040154600f54886005015484600101546139bf9190615698565b6139c991906156b7565b6139d39190615634565b9050816005015460105460145484600101546139ef9190615698565b6139f991906156b7565b613a039190615634565b613a0d90866156d9565b9450613a1981876156d9565b95504282600301541080613a2e575043600754105b15613a76578382600101541115613a5d57838260010154613a4f9190615634565b600183015560009350613a76565b6001820154613a6c9085615634565b6000600184015593505b600f5487600501548360010154613a8d9190615698565b613a9791906156b7565b60048301556010546014546001840154613ab19190615698565b613abb91906156b7565b826005018190555050505b80613ad0816156f1565b91505061393d565b508215613b385782613ae8613c78565b1015613b065760405162461bcd60e51b8152600401610a7a90615740565b601254613b1d906001600160a01b0316338561495a565b613b2683614bb0565b82601954613b3491906156d9565b6019555b8115613b7357613b4782614868565b601354909250613b61906001600160a01b03163384614898565b81601754613b6f9190615634565b6017555b6000613b7f828a615634565b8754909150613b8f908290615634565b87556007850154613ba1908290615634565b6007860155601554613bb4908290615634565b6015558015613c2b57600385015415613c14576000612710866003015483613bdc9190615698565b613be691906156b7565b600c54601154919250613c06916001600160a01b0390811691168361495a565b613c108183615634565b9150505b601154613c2b906001600160a01b0316338361495a565b6040805160ff8a1681526020810183905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a250506001805550505050505050565b6013546012546000916001600160a01b03908116911603613c9a575060165490565b6012546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015613ce3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d079190615727565b6011546012549192506001600160a01b0390811691160361225c57601554811015613d3457600091505090565b601554613d419082615634565b91505090565b6000546001600160a01b03163314613d715760405162461bcd60e51b8152600401610a7a906155e9565b8115613dd2576005548111613dc85760405162461bcd60e51b815260206004820152601860248201527f4e6577206c696d6974206d7573742062652068696768657200000000000000006044820152606401610a7a565b6005819055613dd8565b60006005555b6004805460ff19168315159081179091556005546040805191825260208201929092527f19a6e21b354f2502655dd03f5ac08375f296d713847fbfbf7eec539cd22c443991016117c6565b601c6020528160005260406000208181548110613e3f57600080fd5b600091825260209091206006909102018054600182015460028301546003840154600485015460059095015460ff909416965091945092909186565b600b818154811061105057600080fd5b6000546001600160a01b03163314613eb55760405162461bcd60e51b8152600401610a7a906155e9565b6103e3851115613f075760405162461bcd60e51b815260206004820152601860248201527f5f736c697070616765466163746f7220746f6f206869676800000000000000006044820152606401610a7a565b6001600160a01b038116613f4f5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964204164647265737360881b6044820152606401610a7a565b6008859055600980546001600160a01b0319166001600160a01b0386161790558151613f8290600a906020850190615159565b508251613f9690600b906020860190615159565b50600c80546001600160a01b0319166001600160a01b0383161790556040517f0fae0d0e8768c1e54ef03d02ab9a3aea954cb05c643b8650d09b989b2cb27ac790613fea9087908790879087908790615904565b60405180910390a15050505050565b6000546001600160a01b031633146140235760405162461bcd60e51b8152600401610a7a906155e9565b6001600160a01b0381166140885760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a7a565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080601a54905060006019546140f8613c78565b61410291906156d9565b905060005b601b548110156141d45760065460000361416a57600354601b82815481106141315761413161564b565b90600052602060002090600902016004015461414d9190615698565b6141599061191a615698565b61416390846156d9565b92506141c2565b6000614182601b8381548110611f9f57611f9f61564b565b905080601b83815481106141985761419861564b565b9060005260206000209060090201600401546141b49190615698565b6141be90856156d9565b9350505b806141cc816156f1565b915050614107565b508181106141e55760009250505090565b6141ef8183615634565b9250505090565b6000546001600160a01b031633146142205760405162461bcd60e51b8152600401610a7a906155e9565b6006541561426b5760405162461bcd60e51b8152602060048201526018602482015277141bdbdb081dd85cc8185b1c9958591e481cdd185c9d195960421b6044820152606401610a7a565b601e8110156142b25760405162461bcd60e51b81526020600482015260136024820152721b1bddd95c881b1a5b5a5d081c995858da1959606a1b6044820152606401610a7a565b60038190556040518181527f91abcc2d6823e3a3f11d31b208dd3065d2c6a791f1c7c9fe96a42ce12897eac590602001610b9d565b601b5460009060ff8316106142fe57506000919050565b601b8260ff16815481106143145761431461564b565b9060005260206000209060090201600401549050919050565b601b5460009060ff83161015806143445750600654155b1561435157506000612c6c565b6001600160a01b0383166000908152601c6020908152604080832080548251818502810185019093528083529192909190849084015b828210156143f25760008481526020908190206040805160c08101825260068602909201805460ff1683526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460a08301529083529092019101614387565b5050505090506000601b8460ff16815481106144105761441061564b565b6000918252602080832060408051610120810182526009909402909101805460ff1684526001810154928401929092526002820154908301526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460e08301819052600890910154610100830152909250900361449d57600092505050612c6c565b60a081015160c0820151431180156144b8575060e082015115155b80156144c8575060008260c00151115b156145245760006144dd8360c0015143614b75565b905060008360800151826144f19190615698565b90508360e00151600f54826145069190615698565b61451091906156b7565b8460a0015161451f91906156d9565b925050505b6000805b84518110156145c45760008582815181106145455761454561564b565b602002602001015190508760ff16816000015160ff161461456657506145b2565b806020015160000361457857506145b2565b8060800151600f548583602001516145909190615698565b61459a91906156b7565b6145a49190615634565b6145ae90846156d9565b9250505b806145bc816156f1565b915050614528565b509695505050505050565b600e543410156146355760405162461bcd60e51b815260206004820152602b60248201527f73686f756c642070617920736d616c6c2067617320746f20636f6d706f756e6460448201526a081bdc881a185c9d995cdd60aa1b6064820152608401610a7a565b600d54600e546040516001600160a01b039092169181156108fc0291906000818181858888f19350505050158015614671573d6000803e3d6000fd5b50600e5434111561185457600e5433906108fc9061468f9034615634565b6040518115909202916000818181858888f193505050501580156115d7573d6000803e3d6000fd5b601554156147985760006146c9612160565b90506017548110156146da57506017545b60155460006146e7613c78565b6012546011549192506001600160a01b0390811691160361470f5761470c81836156d9565b91505b81601054601754856147219190615634565b61472b9190615698565b61473591906156b7565b60145461474291906156d9565b6014556012546011546001600160a01b039182169116036147925781816017548561476d9190615634565b6147779190615698565b61478191906156b7565b60185461478e91906156d9565b6018555b50506017555b6000601b8260ff16815481106147b0576147b061564b565b906000526020600020906009020190508060060154431115806147d557506006810154155b156147de575050565b80600701546000036147f4574360069091015550565b6000614804826006015443614b75565b905060008260040154826148189190615698565b90508260070154600f548261482d9190615698565b61483791906156b7565b836005015461484691906156d9565b6005840155436006840155601a5461485f9082906156d9565b601a5550505050565b600080614873612160565b90506017548311156148855760175492505b80831115614891578092505b5090919050565b6001600160a01b0383166148e2576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156148dc573d6000803e3d6000fd5b50505050565b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015614931573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148dc91906158a3565b505050565b6040516001600160a01b03831660248201526044810182905261495590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614df8565b60095460405163d06ca61f60e01b81526000916001600160a01b03169063d06ca61f906149f09087908790600401615954565b600060405180830381865afa158015614a0d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052614a35919081019061596d565b905060008160018351614a489190615634565b81518110614a5857614a5861564b565b60200260200101519050614aaf600960009054906101000a90046001600160a01b03168686600081518110614a8f57614a8f61564b565b60200260200101516001600160a01b0316614eca9092919063ffffffff16565b6009546008546001600160a01b0390911690635c11d7959087906103e890614ad79086615698565b614ae191906156b7565b8787614aef426102586156d9565b6040518663ffffffff1660e01b8152600401614b0f9594939291906159f3565b600060405180830381600087803b158015614b2957600080fd5b505af1158015611b1d573d6000803e3d6000fd5b6040516001600160a01b03808516602483015283166044820152606481018290526148dc9085906323b872dd60e01b90608401614986565b60006007548211614b9157614b8a8383615634565b9050612c6c565b6007548310614ba257506000612c6c565b82600754614b8a9190615634565b806016541115614bc857806016546115d39190615634565b600060165550565b6001600160a01b0383166000908152601c6020526040812090614bf68462015180615698565b614c0090426156d9565b82549091506101008110614c435760405162461bcd60e51b815260206004820152600a6024820152694d6178207374616b657360b01b6044820152606401610a7a565b8254600101835560008390525b8015801590614c8b57508183614c67600184615634565b81548110614c7757614c7761564b565b906000526020600020906006020160030154115b15614d365782614c9c600183615634565b81548110614cac57614cac61564b565b9060005260206000209060060201838281548110614ccc57614ccc61564b565b600091825260209091208254600690920201805460ff191660ff909216919091178155600180830154818301556002808401549083015560038084015490830155600480840154908301556005928301549290910191909155614d2f9082615634565b9050614c50565b6000601b8860ff1681548110614d4e57614d4e61564b565b906000526020600020906009020190506000848381548110614d7257614d7261564b565b60009182526020909120600690910201805460ff191660ff8b16178155600281018890556003810185905560018101879055600f54600584015491925090614dba9088615698565b614dc491906156b7565b60048201556010546014546001830154614dde9190615698565b614de891906156b7565b6005909101555050505050505050565b6000614e4d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614fdf9092919063ffffffff16565b8051909150156149555780806020019051810190614e6b91906158a3565b6149555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a7a565b801580614f445750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015614f1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f429190615727565b155b614faf5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610a7a565b6040516001600160a01b03831660248201526044810182905261495590849063095ea7b360e01b90606401614986565b6060614fee8484600085614ff8565b90505b9392505050565b6060824710156150595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a7a565b843b6150a75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a7a565b600080866001600160a01b031685876040516150c39190615a5b565b60006040518083038185875af1925050503d8060008114615100576040519150601f19603f3d011682016040523d82523d6000602084013e615105565b606091505b5091509150615115828286615120565b979650505050505050565b6060831561512f575081614ff1565b82511561513f5782518084602001fd5b8160405162461bcd60e51b8152600401610a7a9190615a77565b8280548282559060005260206000209081019282156151ae579160200282015b828111156151ae57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615179565b506151ba9291506151be565b5090565b5b808211156151ba57600081556001016151bf565b6000602082840312156151e557600080fd5b5035919050565b600080600080600060a0868803121561520457600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60ff811681146115d757600080fd5b60006020828403121561524857600080fd5b8135614ff181615227565b6001600160a01b03811681146115d757600080fd5b6000806040838503121561527b57600080fd5b823561528681615253565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156152d3576152d3615294565b604052919050565b600067ffffffffffffffff8211156152f5576152f5615294565b5060051b60200190565b600082601f83011261531057600080fd5b81356020615325615320836152db565b6152aa565b82815260059290921b8401810191818101908684111561534457600080fd5b8286015b848110156145c457803561535b81615253565b8352918301918301615348565b60008060008060008060c0878903121561538157600080fd5b863561538c81615253565b9550602087013561539c81615253565b945060408701356153ac81615253565b935060608701356153bc81615253565b9250608087013567ffffffffffffffff808211156153d957600080fd5b6153e58a838b016152ff565b935060a08901359150808211156153fb57600080fd5b5061540889828a016152ff565b9150509295509295509295565b60008060008060008060c0878903121561542e57600080fd5b863561543981615227565b9860208801359850604088013597606081013597506080810135965060a00135945092505050565b6000806040838503121561547457600080fd5b823561528681615227565b6000806040838503121561549257600080fd5b8235915060208301356154a481615227565b809150509250929050565b600080604083850312156154c257600080fd5b82356154cd81615253565b915060208301356154a481615227565b600080604083850312156154f057600080fd5b82356154fb81615227565b915060208301356154a481615253565b80151581146115d757600080fd5b6000806040838503121561552c57600080fd5b82356152868161550b565b60006020828403121561554957600080fd5b8135614ff181615253565b600080600080600060a0868803121561556c57600080fd5b85359450602086013561557e81615253565b9350604086013567ffffffffffffffff8082111561559b57600080fd5b6155a789838a016152ff565b945060608801359150808211156155bd57600080fd5b506155ca888289016152ff565b92505060808601356155db81615253565b809150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156156465761564661561e565b500390565b634e487b7160e01b600052603260045260246000fd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60008160001904831182151516156156b2576156b261561e565b500290565b6000826156d457634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156156ec576156ec61561e565b500190565b6000600182016157035761570361561e565b5060010190565b60006020828403121561571c57600080fd5b8151614ff181615253565b60006020828403121561573957600080fd5b5051919050565b6020808252601a908201527f496e73756666696369656e742072657761726420746f6b656e73000000000000604082015260600190565b60006020828403121561578957600080fd5b8151614ff181615227565b600181815b808511156157cf5781600019048211156157b5576157b561561e565b808516156157c257918102915b93841c9390800290615799565b509250929050565b6000826157e657506001612c6c565b816157f357506000612c6c565b816001811461580957600281146158135761582f565b6001915050612c6c565b60ff8411156158245761582461561e565b50506001821b612c6c565b5060208310610133831016604e8410600b8410161715615852575081810a612c6c565b61585c8383615794565b80600019048211156158705761587061561e565b029392505050565b6000614ff183836157d7565b600060ff821660ff810361589a5761589a61561e565b60010192915050565b6000602082840312156158b557600080fd5b8151614ff18161550b565b600081518084526020808501945080840160005b838110156158f95781516001600160a01b0316875295820195908201906001016158d4565b509495945050505050565b858152600060018060a01b03808716602084015260a0604084015261592c60a08401876158c0565b838103606085015261593e81876158c0565b9250508084166080840152509695505050505050565b828152604060208201526000614fee60408301846158c0565b6000602080838503121561598057600080fd5b825167ffffffffffffffff81111561599757600080fd5b8301601f810185136159a857600080fd5b80516159b6615320826152db565b81815260059190911b820183019083810190878311156159d557600080fd5b928401925b82841015615115578351825292840192908401906159da565b85815284602082015260a060408201526000615a1260a08301866158c0565b6001600160a01b0394909416606083015250608001529392505050565b60005b83811015615a4a578181015183820152602001615a32565b838111156148dc5750506000910152565b60008251615a6d818460208701615a2f565b9190910192915050565b6020815260008251806020840152615a96816040850160208701615a2f565b601f01601f1916919091016040019291505056fea264697066735822122041db2571a471489d955b46aa95d8b05580d9f7233df7d900fc642d5ec884000164736f6c634300080f0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.