Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- SoyStaking
- Optimization enabled
- true
- Compiler version
- v0.8.7+commit.e28d00a7
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:34:27.333986Z
Constructor Arguments
0x0000000000000000000000000000000000000000000000000000000000093a80
Arg [0] (uint256) : 604800
Contract source code
// SPDX-License-Identifier: No License (None) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * 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 { address internal _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { _owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } /** * @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() == msg.sender, "Ownable: caller is not the owner"); _; } /** * @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; } } interface ISimplifiedGlobalFarm { function mintFarmingReward(address _localFarm) external; function getAllocationX1000(address _farm) external view returns (uint256); function getRewardPerSecond() external view returns (uint256); function rewardMintingAvailable(address _farm) external view returns (bool); function farmExists(address _farmAddress) external view returns (bool); } interface IERC223 { /** * @dev Returns the balance of the `who` address. */ function balanceOf(address who) external view returns (uint256); /** * @dev Transfers `value` tokens from `msg.sender` to `to` address * and returns `true` on success. */ function transfer(address to, uint256 value) external returns (bool success); /** * @dev Transfers `value` tokens from `msg.sender` to `to` address with `data` parameter * and returns `true` on success. */ function transfer( address to, uint256 value, bytes memory data ) external returns (bool success); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function approve(address spender, uint256 amount) external returns (bool); function burn(uint256 amount) external returns (bool); /** * @dev Event that is fired on successful transfer. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Additional event that is fired on successful transfer and logs transfer metadata, * this event is implemented to keep Transfer event compatible with ERC20. */ event TransferData(bytes data); } contract SoyStaking is Ownable { address public constant SOY_TOKEN = 0x9FaE2529863bD691B4A7171bDfCf33C7ebB10a65; address public constant globalFarm = 0xd91531bdE4A60EBeaAA4A04C32f29c9f19EC77d8; // GlobalStaking contract uint256 public constant TIME_RESOLUTION = 1 hours; // rewards calculates per each TIME_RESOLUTION uint256 public constant BONUS_LIMIT = 10; // maximum bonus percentage can be bought address public bonusToken; // token address uint256[] internal bonusPrice; // bonus percentage = index + 1 (i.e. 1% = index 0), value price in bonusToken (from lower to higher) //========== TESTNET VALUES =========== //uint256 public constant TIME_RESOLUTION = 5 minutes; // rewards calculates per each TIME_RESOLUTION //https://github.com/SoyFinance/smart-contracts/tree/main/Farming#testsoy223-token //address public constant SOY_TOKEN = 0x4c20231BCc5dB8D805DB9197C84c8BA8287CbA92; // https://github.com/SoyFinance/smart-contracts/tree/main/Farming#test-global-farm-contract-3-minutes //address public constant globalFarm = 0x9F66541abc036503Ae074E1E28638b0Cb6165458; //========== END TEST VALUES ========== bool public isEnabled; uint256 public totalShares; // effective total shares included bonuses uint256 public totalStaked; // total staked amount on contract struct Staker { uint256 amount; uint256 rewardPerSharePaid; uint64 endTime; // Time when staking ends and user may withdraw. After this time user will not receive rewards. uint64 index; // Balances indexed uint64 bonus; // percent of bonus applied uint32 affiliatePercent; // percent of user's rewards that will be transferred to affiliate, i.e. 5% uint32 noAffiliatePercent; // percent of user's rewards will be paid if no affiliate. address affiliate; // address of affiliate } mapping(address => Staker) public staker; struct Balance { uint256 atTime; // time when reduce balance uint256 balanceReduceOrRewardPerShare; // amount to reduce balance or reward per share at time //uint256 rewardPerShare; // reward per share at time } Balance[] public balances; uint256 public startIndex; // start index of unprocessed balances records uint256 public accumulatedRewardPerShare; uint256 public lastRewardTimestamp; uint256 public lockTime; // in seconds, time that tokens should be locked when user call unlock() uint256 public affiliatePercent; // percent of user's rewards that will be transferred to affiliate, i.e. 5% uint256 public noAffiliatePercent; // percent of user's rewards will be paid if no affiliate. // i.e. 90% means that user will receive only 90% of his rewards if it come without affiliate, // but if there is affiliate (with 5%) than user will receive 95% and affiliate receive 5% of reward. uint256 private unsplitReward; // Reward that should be split on next TIME_RESOLUTION round event StartStaking( address staker, uint256 amount, uint256 time ); event WithdrawRequest( address staker, uint256 alignedTime, uint256 stakedAmount ); event WithdrawStake( address staker, uint256 amount, uint256 reward ); event Rescue(address _token, uint256 _amount); event SetAffiliatePercentage(uint256 _affiliatePercent, uint256 _noAffiliatePercent); constructor(uint256 _lockTime) { lockTime = _lockTime; noAffiliatePercent = 100; // by default 100% rewards go to users IERC223(SOY_TOKEN).approve(address(this), type(uint256).max); // allow contract to use transferFrom instead of transfer } function enableStaking(bool enable) external onlyOwner { isEnabled = enable; } function getRewardPerSecond() public view returns (uint256) { return ISimplifiedGlobalFarm(globalFarm).getRewardPerSecond(); } function getAllocationX1000() public view returns (uint256) { return ISimplifiedGlobalFarm(globalFarm).getAllocationX1000(address(this)); } function notifyRewardAmount(uint256 reward) external {} // ERC223 token transfer callback // bytes _data = abi.encode(address receiver, uint256 toChainId) function tokenReceived( address _from, uint256 _value, bytes calldata _data ) external { if (msg.sender == bonusToken && _value != 0) { uint256 bonus; require(_data.length == 32, "Wrong bonus percentage"); bonus = abi.decode(_data, (uint256)); // _data should contain ABI encoded UINT = bonus percentage _buyBonus(_from, _value, bonus); return; } require(msg.sender == SOY_TOKEN, "Only SOY staking is supported"); if (_from == globalFarm || _from == owner()) return; // if globalFarm or admin transfer tokens, they will be added to reward pool address _affiliate; if (_data.length == 32) _affiliate = abi.decode(_data, (address)); // _data should contain ABI encoded affiliate address // No donations accepted to fallback! // Consider value deposit is an attempt to become staker. // May not accept deposit from other contracts due GAS limit. startStaking(_from, _value, _affiliate); } // Add tokens to the unlocked staking. Reward is transferred to user function startStaking(address user, uint256 amount, address affiliate) internal { require(isEnabled, "staking disabled"); if (staker[user].endTime != 0) { if (staker[user].endTime < block.timestamp) { _withdraw(user); // withdraw if lock expired return; } else { require(amount == 0, "Account locked for staking"); } } update(0); if (affiliate != address(0) && staker[user].affiliate == address(0)) { // if affiliate was not set before // add affiliate staker[user].affiliate = affiliate; staker[user].affiliatePercent = uint32(affiliatePercent); } if (staker[user].amount == 0) staker[user].noAffiliatePercent = uint32(noAffiliatePercent); // first deposit totalStaked += amount; totalShares += (amount * (100 + staker[user].bonus) / 100); // multiply staked amount by bonus multiplier (uint256 userReward, uint256 affiliateRewardOrRest) = _pendingReward(user, accumulatedRewardPerShare); staker[user].amount += amount; staker[user].rewardPerSharePaid = accumulatedRewardPerShare; // transfer affiliate reward or split the rest _safeSplitRest(affiliateRewardOrRest, user); IERC223(SOY_TOKEN).transfer(user, userReward); // transfer rewards to user emit StartStaking(user, amount, block.timestamp); } // View function to see pending Reward on frontend. function pendingReward(address user) public view returns (uint256 userReward) { uint256 _alignedTime = (block.timestamp / TIME_RESOLUTION) * TIME_RESOLUTION; // aligned by 1 hour uint256 _lastRewardTimestamp = lastRewardTimestamp; uint256 _accumulatedRewardPerShare = accumulatedRewardPerShare; if (_alignedTime <= _lastRewardTimestamp) { (userReward,) = _pendingReward(user, _accumulatedRewardPerShare); return userReward; } uint256 _totalShares = totalShares; { uint256 _unsplitReward = unsplitReward; if (_unsplitReward > 1) { _accumulatedRewardPerShare += ((_unsplitReward-1) * 1e18 / _totalShares); // split the unsplitReward among shareholders } } uint256 _reward = getRewardPerSecond() * getAllocationX1000() * 1e15; // 1e15 = 1e18 / 1000; uint256 timePassed; uint256 i = startIndex; // start from uint256 maxRecords = balances.length; for (; i < maxRecords; i++) { if (balances[i].atTime > _alignedTime) break; // future record timePassed = balances[i].atTime - _lastRewardTimestamp; _lastRewardTimestamp = balances[i].atTime; _accumulatedRewardPerShare = _accumulatedRewardPerShare + ((timePassed * _reward) / _totalShares); _totalShares = _totalShares - balances[i].balanceReduceOrRewardPerShare; if (staker[user].endTime != 0 && staker[user].index == i) { // found block where user's stake end (userReward,) = _pendingReward(user, _accumulatedRewardPerShare); return userReward; } } timePassed = _alignedTime - _lastRewardTimestamp; if (_totalShares != 0) { _accumulatedRewardPerShare = _accumulatedRewardPerShare + ((timePassed * _reward) / _totalShares); } (userReward,) = _pendingReward(user, _accumulatedRewardPerShare); return userReward; } // Calculate pending reward of user function _pendingReward(address user, uint256 _accumulatedRewardPerShare) internal view returns (uint256 userReward, uint256 affiliateRewardOrRest) { uint256 shares = staker[user].amount * (100 + staker[user].bonus) / 100; if (staker[user].endTime != 0 && startIndex > staker[user].index) { // use accumulatedRewardPerShare stored on the moment when staking ends _accumulatedRewardPerShare = balances[uint256(staker[user].index)] .balanceReduceOrRewardPerShare; } uint256 reward = (shares * (_accumulatedRewardPerShare - staker[user].rewardPerSharePaid)) / 1e18; // total reward if (staker[user].affiliate == address(0)) { // no affiliate uint256 _noAffiliatePercent = staker[user].noAffiliatePercent; if (_noAffiliatePercent < noAffiliatePercent) _noAffiliatePercent = noAffiliatePercent; // use better noAffiliatePercent for user userReward = reward * _noAffiliatePercent / 100; affiliateRewardOrRest = reward - userReward; // rest of rewards that should be added to rewards pool. } else { affiliateRewardOrRest = reward * staker[user].affiliatePercent / 100; // affiliate reward userReward = reward - affiliateRewardOrRest; } } // update total balance and accumulatedRewardPerShare regarding ended staking // process "maxRecords" at a time. If maxRecords == 0, process all pending records function update(uint256 maxRecords) public { uint256 _alignedTime = (block.timestamp / TIME_RESOLUTION) * TIME_RESOLUTION; // aligned by 1 hour uint256 _lastRewardTimestamp = lastRewardTimestamp; if (_alignedTime <= _lastRewardTimestamp) { return; } uint256 _totalShares = totalShares; if (_totalShares == 0) { lastRewardTimestamp = _alignedTime; return; } ISimplifiedGlobalFarm(globalFarm).mintFarmingReward(address(this)); uint256 _reward = getRewardPerSecond() * getAllocationX1000() * 1e15; // 1e15 = 1e18 / 1000; uint256 _accumulatedRewardPerShare = accumulatedRewardPerShare; { uint256 _unsplitReward = unsplitReward; if (_unsplitReward > 1) { _accumulatedRewardPerShare += ((_unsplitReward-1) * 1e18 / _totalShares); // split the unsplitReward among shareholders unsplitReward = 1; // use 1 instead of 0 to save gas } } uint256 timePassed; uint256 i = startIndex; // start from maxRecords = maxRecords + i; // last record if (maxRecords == i || balances.length < maxRecords) maxRecords = balances.length; for (; i < maxRecords; i++) { if (balances[i].atTime > _alignedTime) break; // future record timePassed = balances[i].atTime - _lastRewardTimestamp; _lastRewardTimestamp = balances[i].atTime; _accumulatedRewardPerShare = _accumulatedRewardPerShare + ((timePassed * _reward) / _totalShares); _totalShares = _totalShares - balances[i].balanceReduceOrRewardPerShare; balances[i] .balanceReduceOrRewardPerShare = _accumulatedRewardPerShare; // using the same variable reduce gas usage by 15K } startIndex = i; totalShares = _totalShares; timePassed = _alignedTime - _lastRewardTimestamp; lastRewardTimestamp = _alignedTime; if (_totalShares != 0) { accumulatedRewardPerShare = _accumulatedRewardPerShare + ((timePassed * _reward) / _totalShares); } else { accumulatedRewardPerShare = _accumulatedRewardPerShare; } } // Withdraw request lock staking for lockTime. // User can't add more tokens to locked staking function withdrawRequest() external { uint256 stakedAmount = staker[msg.sender].amount; require( staker[msg.sender].endTime == 0 && stakedAmount != 0, "withdraw request already made" ); update(0); uint256 endTime = ((block.timestamp + lockTime) / TIME_RESOLUTION) * TIME_RESOLUTION; // staking end time aligned by 1 hour staker[msg.sender].endTime = uint64(endTime); emit WithdrawRequest(msg.sender, endTime, stakedAmount); uint256 bonus = staker[msg.sender].bonus * stakedAmount / 100; stakedAmount = stakedAmount + bonus; // effective share = staked amount + bonus if (balances.length != 0 && balances[balances.length - 1].atTime == endTime) { // we have records for current hour balances[balances.length - 1] .balanceReduceOrRewardPerShare += stakedAmount; } else { balances.push(Balance(endTime, stakedAmount)); } staker[msg.sender].index = uint64(balances.length - 1); } //withdraw tokens from staking function withdraw() external { _withdraw(msg.sender); } // withdraw tokens from staking on user behalf function withdraw(address user) external { _withdraw(user); } function _withdraw(address user) internal { require( staker[user].endTime < block.timestamp && staker[user].endTime != 0, "withdrawal locked" ); update(0); uint256 amount = staker[user].amount; (uint256 userReward, uint256 affiliateRewardOrRest) = _pendingReward(user, accumulatedRewardPerShare); totalStaked -= amount; delete staker[user]; // transfer affiliate reward or split the rest _safeSplitRest(affiliateRewardOrRest, user); IERC223(SOY_TOKEN).transfer(user, amount + userReward); emit WithdrawStake(user, amount, userReward); } // buy bonus percent using bonusTokens (using approve - transferFrom pattern) function buyBonus(uint256 bonus) external { _buyBonus(msg.sender, 0, bonus); } // buy bonus percent using ERC223 bonusTokens function _buyBonus(address user, uint256 value, uint256 bonus) internal { require(staker[user].endTime == 0, "Account locked for staking"); update(0); (uint256 userReward, uint256 affiliateRewardOrRest) = _pendingReward(user, accumulatedRewardPerShare); staker[user].rewardPerSharePaid = accumulatedRewardPerShare; // user can buy bonus multiplier uint256 amount = getBonusPrice(bonus, user); // get difference in price between current and wanted bonuses require(amount != 0, "user already has this bonus"); if (value == 0) { // if was not sent ERC223 then use transferFrom IERC223(bonusToken).transferFrom(user, address(this), amount); value = amount; } require(amount == value, "user transferred wrong amount"); _safeBurn(amount); // burn bonus token // apply bonus uint256 bonusShares = (bonus - staker[user].bonus) * staker[user].amount / 100; // just bought bonus * staking amount totalShares += bonusShares; staker[user].bonus = uint64(bonus); // transfer affiliate reward or split the rest _safeSplitRest(affiliateRewardOrRest, user); IERC223(SOY_TOKEN).transfer(user, userReward); // transfer rewards to user } function _safeBurn(uint256 amount) internal { try IERC223(bonusToken).burn(amount) returns (bool) // try to burn bonus token { return; } catch { // if burn function is not implemented then transfer to DEAD address IERC223(bonusToken).transfer(address(0xdEad000000000000000000000000000000000000), amount); } } // transfer affiliate reward or split the rest. function _safeSplitRest(uint256 affiliateRewardOrRest, address user) internal { if (affiliateRewardOrRest != 0) { address affiliate = staker[user].affiliate; if (affiliate != address(0)) { // transfer affiliate reward to affiliate address // we are using transferFrom to protect user from affiliate that can't accept ERC223 IERC223(SOY_TOKEN).transferFrom(address(this), affiliate, affiliateRewardOrRest); // transfer rewards to user } else { unsplitReward += affiliateRewardOrRest; // split rest reward on next update round } } } // return amount that user has to pay to buy bonus percentage (from 1 to BONUS_LIMIT) function getBonusPrice(uint256 bonus, address user) public view returns(uint256 amount) { require(bonus !=0 && bonus <= bonusPrice.length, "incorrect bonus"); uint256 alreadyPaid; uint256 userBonus = staker[user].bonus; if(bonus <= userBonus) return 0; // user already has this or better bonus if (userBonus != 0) alreadyPaid = bonusPrice[userBonus-1]; // 1% = index 0, 2% = index 1, ... amount = bonusPrice[bonus-1] - alreadyPaid; } // return array of prices. Index + 1 = percent of bonus. // I.e. [0] = price of 1% bonus, [1] - price of 2% bonus, ..., [9] - price of 10% bonus function getBonusPrices() external view returns(uint256[] memory) { return bonusPrice; } // bonusPrices is array of prices. Index + 1 = percent of bonus. // I.e. [0] = price of 1% bonus, [1] - price of 2% bonus, ..., [9] - price of 10% bonus function setBonusPrices(uint256[] memory bonusPrices) external onlyOwner { delete bonusPrice; require(bonusPrices.length <= BONUS_LIMIT, "Too big bonus"); bonusPrice = bonusPrices; } // set contract address of token that accept to buy bonus function setBonusToken(address _bonusToken) external onlyOwner { bonusToken = _bonusToken; } // set affiliate percent and no affiliate percent // allowed affiliatePercent [0% - 50%] // allowed no affiliate percent [50% - 100%] function setAffiliatePercentage(uint256 _affiliatePercent, uint256 _noAffiliatePercent) external onlyOwner { require(_affiliatePercent <= 50 && _noAffiliatePercent >= 50 && _noAffiliatePercent <= 100, "Wrong percentage"); affiliatePercent = _affiliatePercent; noAffiliatePercent = _noAffiliatePercent; emit SetAffiliatePercentage(_affiliatePercent, _noAffiliatePercent); } // rescue other token if it was transferred to contract function rescueTokens(address _token) onlyOwner external { if (_token == SOY_TOKEN && totalStaked != 0) return; // allow rescue SOY tokens when no stake uint256 amount = IERC223(_token).balanceOf(address(this)); IERC223(_token).transfer(msg.sender, amount); emit Rescue(_token, amount); } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"uint256","name":"_lockTime","internalType":"uint256"}]},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Rescue","inputs":[{"type":"address","name":"_token","internalType":"address","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetAffiliatePercentage","inputs":[{"type":"uint256","name":"_affiliatePercent","internalType":"uint256","indexed":false},{"type":"uint256","name":"_noAffiliatePercent","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"StartStaking","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"time","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"WithdrawRequest","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":false},{"type":"uint256","name":"alignedTime","internalType":"uint256","indexed":false},{"type":"uint256","name":"stakedAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"WithdrawStake","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"BONUS_LIMIT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"SOY_TOKEN","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"TIME_RESOLUTION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"accumulatedRewardPerShare","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"affiliatePercent","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"atTime","internalType":"uint256"},{"type":"uint256","name":"balanceReduceOrRewardPerShare","internalType":"uint256"}],"name":"balances","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bonusToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"buyBonus","inputs":[{"type":"uint256","name":"bonus","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableStaking","inputs":[{"type":"bool","name":"enable","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAllocationX1000","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"}],"name":"getBonusPrice","inputs":[{"type":"uint256","name":"bonus","internalType":"uint256"},{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getBonusPrices","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewardPerSecond","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"globalFarm","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastRewardTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lockTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"noAffiliatePercent","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"notifyRewardAmount","inputs":[{"type":"uint256","name":"reward","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"userReward","internalType":"uint256"}],"name":"pendingReward","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueTokens","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAffiliatePercentage","inputs":[{"type":"uint256","name":"_affiliatePercent","internalType":"uint256"},{"type":"uint256","name":"_noAffiliatePercent","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBonusPrices","inputs":[{"type":"uint256[]","name":"bonusPrices","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBonusToken","inputs":[{"type":"address","name":"_bonusToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"rewardPerSharePaid","internalType":"uint256"},{"type":"uint64","name":"endTime","internalType":"uint64"},{"type":"uint64","name":"index","internalType":"uint64"},{"type":"uint64","name":"bonus","internalType":"uint64"},{"type":"uint32","name":"affiliatePercent","internalType":"uint32"},{"type":"uint32","name":"noAffiliatePercent","internalType":"uint32"},{"type":"address","name":"affiliate","internalType":"address"}],"name":"staker","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"startIndex","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"tokenReceived","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalShares","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalStaked","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update","inputs":[{"type":"uint256","name":"maxRecords","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawRequest","inputs":[]}]
Contract Creation Code
0x60806040523480156200001157600080fd5b506040516200291138038062002911833981016040819052620000349162000140565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600b8190556064600d5560405163095ea7b360e01b81523060048201526000196024820152739fae2529863bd691b4a7171bdfcf33c7ebb10a659063095ea7b390604401602060405180830381600087803b158015620000d257600080fd5b505af1158015620000e7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010d919062000115565b50506200015a565b6000602082840312156200012857600080fd5b815180151581146200013957600080fd5b9392505050565b6000602082840312156200015357600080fd5b5051919050565b6127a7806200016a6000396000f3fe608060405234801561001057600080fd5b50600436106102105760003560e01c80636aa633b611610125578063a30946ee116100ad578063f3b2caf31161007c578063f3b2caf3146104e8578063f3c7c9d7146104fb578063f40f0f5214610510578063f4239eec14610523578063f8077fae1461052c57600080fd5b8063a30946ee146104a7578063b2eaeaaa146104ba578063da5b4ee7146104cd578063f2fde38b146104d557600080fd5b806382ab890a116100f457806382ab890a1461038c57806382e4eda41461039f5780638943ec02146104705780638da5cb5b146104835780639cefc1da1461049457600080fd5b80636aa633b61461035557806378d0410e146103725780637e9ea4281461037b578063817b1cd21461038357600080fd5b80633bb190c1116101a857806341d4a1ab1161017757806341d4a1ab146102b95780634903b0d1146102e45780634f3a1ff81461030c57806351cff8d9146103275780635b17f5061461033a57600080fd5b80633bb190c1146102845780633c6b16ab146102975780633ccfd60b146102a85780633e0e828b146102b057600080fd5b806325ed3229116101e457806325ed32291461025757806336d421951461026a578063380e687a146102735780633a98ef391461027b57600080fd5b8062ae3bf8146102155780630d6680871461022a5780631868b20b146102465780631e29653c1461024f575b600080fd5b6102286102233660046123af565b610535565b005b610233600b5481565b6040519081526020015b60405180910390f35b610233600d5481565b6102336106f1565b61023361026536600461258b565b61077b565b61023360095481565b610228610879565b61023360045481565b610228610292366004612559565b610b3e565b6102286102a5366004612559565b50565b610228610b4a565b61023360085481565b6001546102cc906001600160a01b031681565b6040516001600160a01b03909116815260200161023d565b6102f76102f2366004612559565b610b55565b6040805192835260208301919091520161023d565b6102cc73d91531bde4a60ebeaaa4a04c32f29c9f19ec77d881565b6102286103353660046123af565b610b83565b6102cc739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b6003546103629060ff1681565b604051901515815260200161023d565b610233610e1081565b610233600a81565b61023360055481565b61022861039a366004612559565b610b8c565b6104166103ad3660046123af565b6006602052600090815260409020805460018201546002830154600390930154919290916001600160401b0380831692600160401b8104821692600160801b82049092169163ffffffff600160c01b8304811692600160e01b900416906001600160a01b031688565b6040805198895260208901979097526001600160401b039586169688019690965292841660608701529216608085015263ffffffff91821660a08501521660c08301526001600160a01b031660e08201526101000161023d565b61022861047e3660046123d3565b610e48565b6000546001600160a01b03166102cc565b6102286104a236600461251f565b610fa2565b6102286104b536600461245b565b610fee565b6102286104c83660046123af565b61108c565b6102336110e7565b6102286104e33660046123af565b611136565b6102286104f63660046125bb565b61122f565b610503611306565b60405161023d91906125dd565b61023361051e3660046123af565b61135e565b610233600c5481565b610233600a5481565b336105486000546001600160a01b031690565b6001600160a01b0316146105775760405162461bcd60e51b815260040161056e90612621565b60405180910390fd5b6001600160a01b038116739fae2529863bd691b4a7171bdfcf33c7ebb10a651480156105a4575060055415155b156105ac5750565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b1580156105ee57600080fd5b505afa158015610602573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106269190612572565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb90604401602060405180830381600087803b15801561067157600080fd5b505af1158015610685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a9919061253c565b50604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af291015b60405180910390a15050565b60405163389bbbfd60e21b815230600482015260009073d91531bde4a60ebeaaa4a04c32f29c9f19ec77d89063e26eeff49060240160206040518083038186803b15801561073e57600080fd5b505afa158015610752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107769190612572565b905090565b6000821580159061078e57506002548311155b6107cc5760405162461bcd60e51b815260206004820152600f60248201526e696e636f727265637420626f6e757360881b604482015260640161056e565b6001600160a01b038216600090815260066020526040812060020154600160801b90046001600160401b031680851161080a57600092505050610873565b801561083b57600261081d6001836126da565b8154811061082d5761082d612722565b906000526020600020015491505b8160026108496001886126da565b8154811061085957610859612722565b906000526020600020015461086e91906126da565b925050505b92915050565b33600090815260066020526040902080546002909101546001600160401b03161580156108a557508015155b6108f15760405162461bcd60e51b815260206004820152601d60248201527f7769746864726177207265717565737420616c7265616479206d616465000000604482015260640161056e565b6108fb6000610b8c565b6000610e1080600b544261090f9190612656565b6109199190612699565b61092391906126bb565b33600081815260066020908152604091829020600201805467ffffffffffffffff19166001600160401b0386161790558151928352820183905281018490529091507fcbc7c7858f9ab8ce22517d4b910042540172c3d579222cf6716e222f341ca3719060600160405180910390a1336000908152600660205260408120600201546064906109c3908590600160801b90046001600160401b03166126bb565b6109cd9190612699565b90506109d98184612656565b60075490935015801590610a1f5750600780548391906109fb906001906126da565b81548110610a0b57610a0b612722565b906000526020600020906002020160000154145b15610a725760078054849190610a37906001906126da565b81548110610a4757610a47612722565b90600052602060002090600202016001016000828254610a679190612656565b90915550610ae99050565b60408051808201909152828152602081018481526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600290930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689909101555b600754610af8906001906126da565b33600090815260066020526040902060020180546001600160401b0392909216600160401b026fffffffffffffffff000000000000000019909216919091179055505050565b6102a5336000836115cc565b610b533361190c565b565b60078181548110610b6557600080fd5b60009182526020909120600290910201805460019091015490915082565b6102a58161190c565b6000610e10610b9b8142612699565b610ba591906126bb565b600a54909150808211610bb757505050565b60045480610bc7575050600a5550565b60405163032453f160e51b815230600482015273d91531bde4a60ebeaaa4a04c32f29c9f19ec77d89063648a7e2090602401600060405180830381600087803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b505050506000610c356106f1565b610c3d6110e7565b610c4791906126bb565b610c589066038d7ea4c680006126bb565b600954600e54919250906001811115610ca55783610c776001836126da565b610c8990670de0b6b3a76400006126bb565b610c939190612699565b610c9d9083612656565b6001600e5591505b50600854600090610cb68189612656565b975080881480610cc7575060075488115b15610cd25760075497505b87811015610df0578660078281548110610cee57610cee612722565b9060005260206000209060020201600001541115610d0b57610df0565b8560078281548110610d1f57610d1f612722565b906000526020600020906002020160000154610d3b91906126da565b915060078181548110610d5057610d50612722565b6000918252602090912060029091020154955084610d6e85846126bb565b610d789190612699565b610d829084612656565b925060078181548110610d9757610d97612722565b90600052602060002090600202016001015485610db491906126da565b94508260078281548110610dca57610dca612722565b600091825260209091206001600290920201015580610de8816126f1565b915050610cd2565b60088190556004859055610e0486886126da565b600a88905591508415610e385784610e1c85846126bb565b610e269190612699565b610e309084612656565b600955610e3e565b60098390555b5050505050505050565b6001546001600160a01b031633148015610e6157508215155b15610ed057600060208214610eb15760405162461bcd60e51b815260206004820152601660248201527557726f6e6720626f6e75732070657263656e7461676560501b604482015260640161056e565b610ebd82840184612559565b9050610eca8585836115cc565b50610f9c565b33739fae2529863bd691b4a7171bdfcf33c7ebb10a6514610f335760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920534f59207374616b696e6720697320737570706f72746564000000604482015260640161056e565b6001600160a01b03841673d91531bde4a60ebeaaa4a04c32f29c9f19ec77d81480610f6b57506000546001600160a01b038581169116145b15610f7557610f9c565b60006020821415610f8f57610f8c828401846123af565b90505b610f9a858583611b2e565b505b50505050565b33610fb56000546001600160a01b031690565b6001600160a01b031614610fdb5760405162461bcd60e51b815260040161056e90612621565b6003805460ff1916911515919091179055565b336110016000546001600160a01b031690565b6001600160a01b0316146110275760405162461bcd60e51b815260040161056e90612621565b61103360026000612331565b600a815111156110755760405162461bcd60e51b815260206004820152600d60248201526c546f6f2062696720626f6e757360981b604482015260640161056e565b805161108890600290602084019061234f565b5050565b3361109f6000546001600160a01b031690565b6001600160a01b0316146110c55760405162461bcd60e51b815260040161056e90612621565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600073d91531bde4a60ebeaaa4a04c32f29c9f19ec77d86001600160a01b031663da5b4ee76040518163ffffffff1660e01b815260040160206040518083038186803b15801561073e57600080fd5b336111496000546001600160a01b031690565b6001600160a01b03161461116f5760405162461bcd60e51b815260040161056e90612621565b6001600160a01b0381166111d45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161056e565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b336112426000546001600160a01b031690565b6001600160a01b0316146112685760405162461bcd60e51b815260040161056e90612621565b6032821115801561127a575060328110155b8015611287575060648111155b6112c65760405162461bcd60e51b815260206004820152601060248201526f57726f6e672070657263656e7461676560801b604482015260640161056e565b600c829055600d81905560408051838152602081018390527f8115ca955ade2fd4083142596a343f291ae6e5506f64a19d166942e56c05115c91016106e5565b6060600280548060200260200160405190810160405280929190818152602001828054801561135457602002820191906000526020600020905b815481526020019060010190808311611340575b5050505050905090565b600080610e1061136e8142612699565b61137891906126bb565b600a546009549192509081831161139d576113938582611ef8565b5095945050505050565b600454600e5460018111156113e157816113b86001836126da565b6113ca90670de0b6b3a76400006126bb565b6113d49190612699565b6113de9084612656565b92505b5060006113ec6106f1565b6113f46110e7565b6113fe91906126bb565b61140f9066038d7ea4c680006126bb565b6008546007549192506000915b8082101561158e57876007838154811061143857611438612722565b90600052602060002090600202016000015411156114555761158e565b866007838154811061146957611469612722565b90600052602060002090600202016000015461148591906126da565b92506007828154811061149a5761149a612722565b60009182526020909120600290910201549650846114b885856126bb565b6114c29190612699565b6114cc9087612656565b9550600782815481106114e1576114e1612722565b906000526020600020906002020160010154856114fe91906126da565b6001600160a01b038b166000908152600660205260409020600201549095506001600160401b03161580159061155e57506001600160a01b038a16600090815260066020526040902060020154600160401b90046001600160401b031682145b1561157c5761156d8a87611ef8565b509a9950505050505050505050565b81611586816126f1565b92505061141c565b61159887896126da565b925084156115c257846115ab85856126bb565b6115b59190612699565b6115bf9087612656565b95505b61156d8a87611ef8565b6001600160a01b0383166000908152600660205260409020600201546001600160401b03161561163e5760405162461bcd60e51b815260206004820152601a60248201527f4163636f756e74206c6f636b656420666f72207374616b696e67000000000000604482015260640161056e565b6116486000610b8c565b60008061165785600954611ef8565b6009546001600160a01b0388166000908152600660205260408120600101919091559193509150611688848761077b565b9050806116d75760405162461bcd60e51b815260206004820152601b60248201527f7573657220616c726561647920686173207468697320626f6e75730000000000604482015260640161056e565b8461176d576001546040516323b872dd60e01b81526001600160a01b03888116600483015230602483015260448201849052909116906323b872dd90606401602060405180830381600087803b15801561173057600080fd5b505af1158015611744573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611768919061253c565b508094505b8481146117bc5760405162461bcd60e51b815260206004820152601d60248201527f75736572207472616e736665727265642077726f6e6720616d6f756e74000000604482015260640161056e565b6117c58161214e565b6001600160a01b038616600090815260066020526040812080546002909101546064919061180390600160801b90046001600160401b0316886126da565b61180d91906126bb565b6118179190612699565b9050806004600082825461182b9190612656565b90915550506001600160a01b0387166000908152600660205260409020600201805467ffffffffffffffff60801b1916600160801b6001600160401b038816021790556118788388612251565b60405163a9059cbb60e01b81526001600160a01b038816600482015260248101859052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b1580156118d457600080fd5b505af11580156118e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3e919061253c565b6001600160a01b038116600090815260066020526040902060020154426001600160401b0390911610801561196457506001600160a01b0381166000908152600660205260409020600201546001600160401b031615155b6119a45760405162461bcd60e51b81526020600482015260116024820152701dda5d1a191c985dd85b081b1bd8dad959607a1b604482015260640161056e565b6119ae6000610b8c565b6001600160a01b03811660009081526006602052604081205460095490919081906119da908590611ef8565b9150915082600560008282546119f091906126da565b90915550506001600160a01b038416600090815260066020526040812081815560018101829055600281019190915560030180546001600160a01b0319169055611a3a8185612251565b739fae2529863bd691b4a7171bdfcf33c7ebb10a6563a9059cbb85611a5f8587612656565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611aa557600080fd5b505af1158015611ab9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611add919061253c565b50604080516001600160a01b0386168152602081018590529081018390527f5f808ed47938c2c6ffcf1784b8a3171a0e8cb25d277b291b26475b303473bbb09060600160405180910390a150505050565b60035460ff16611b735760405162461bcd60e51b815260206004820152601060248201526f1cdd185ada5b99c8191a5cd8589b195960821b604482015260640161056e565b6001600160a01b0383166000908152600660205260409020600201546001600160401b031615611c27576001600160a01b038316600090815260066020526040902060020154426001600160401b039091161015611bd957611bd48361190c565b505050565b8115611c275760405162461bcd60e51b815260206004820152601a60248201527f4163636f756e74206c6f636b656420666f72207374616b696e67000000000000604482015260640161056e565b611c316000610b8c565b6001600160a01b03811615801590611c6457506001600160a01b0383811660009081526006602052604090206003015416155b15611cc8576001600160a01b0383811660009081526006602052604090206003810180546001600160a01b03191692841692909217909155600c546002909101805463ffffffff60c01b1916600160c01b63ffffffff909316929092029190911790555b6001600160a01b038316600090815260066020526040902054611d2557600d546001600160a01b0384166000908152600660205260409020600201805463ffffffff909216600160e01b026001600160e01b039092169190911790555b8160056000828254611d379190612656565b90915550506001600160a01b038316600090815260066020526040902060020154606490611d7590600160801b90046001600160401b03168261266e565b611d88906001600160401b0316846126bb565b611d929190612699565b60046000828254611da39190612656565b92505081905550600080611db985600954611ef8565b6001600160a01b038716600090815260066020526040812080549395509193508692611de6908490612656565b90915550506009546001600160a01b038616600090815260066020526040902060010155611e148186612251565b60405163a9059cbb60e01b81526001600160a01b038616600482015260248101839052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b158015611e7057600080fd5b505af1158015611e84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea8919061253c565b50604080516001600160a01b038716815260208101869052428183015290517f770220af1c9e120c1375b3c3785dd5bdb8371fa98c7e83537933bb116fee490e9181900360600190a15050505050565b6001600160a01b03821660009081526006602052604081206002015481908190606490611f3590600160801b90046001600160401b03168261266e565b6001600160a01b038716600090815260066020526040902054611f61916001600160401b0316906126bb565b611f6b9190612699565b6001600160a01b0386166000908152600660205260409020600201549091506001600160401b031615801590611fce57506001600160a01b038516600090815260066020526040902060020154600854600160401b9091046001600160401b0316105b15612029576001600160a01b038516600090815260066020526040902060020154600780549091600160401b90046001600160401b031690811061201457612014612722565b90600052602060002090600202016001015493505b6001600160a01b038516600090815260066020526040812060010154670de0b6b3a76400009061205990876126da565b61206390846126bb565b61206d9190612699565b6001600160a01b03878116600090815260066020526040902060030154919250166120f6576001600160a01b038616600090815260066020526040902060020154600d54600160e01b90910463ffffffff16908110156120cc5750600d545b60646120d882846126bb565b6120e29190612699565b94506120ee85836126da565b935050612145565b6001600160a01b03861660009081526006602052604090206002015460649061212c90600160c01b900463ffffffff16836126bb565b6121369190612699565b925061214283826126da565b93505b50509250929050565b600154604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401602060405180830381600087803b15801561219457600080fd5b505af19250505080156121c4575060408051601f3d908101601f191682019092526121c19181019061253c565b60015b6110885760015460405163a9059cbb60e01b815261dead60901b6004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561221957600080fd5b505af115801561222d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611088919061253c565b8115611088576001600160a01b03808216600090815260066020526040902060030154168015612315576040516323b872dd60e01b81523060048201526001600160a01b038216602482015260448101849052739fae2529863bd691b4a7171bdfcf33c7ebb10a65906323b872dd90606401602060405180830381600087803b1580156122dd57600080fd5b505af11580156122f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9c919061253c565b82600e60008282546123279190612656565b9091555050505050565b50805460008255906000526020600020908101906102a5919061239a565b82805482825590600052602060002090810192821561238a579160200282015b8281111561238a57825182559160200191906001019061236f565b5061239692915061239a565b5090565b5b80821115612396576000815560010161239b565b6000602082840312156123c157600080fd5b81356123cc8161274e565b9392505050565b600080600080606085870312156123e957600080fd5b84356123f48161274e565b93506020850135925060408501356001600160401b038082111561241757600080fd5b818701915087601f83011261242b57600080fd5b81358181111561243a57600080fd5b88602082850101111561244c57600080fd5b95989497505060200194505050565b6000602080838503121561246e57600080fd5b82356001600160401b038082111561248557600080fd5b818501915085601f83011261249957600080fd5b8135818111156124ab576124ab612738565b8060051b604051601f19603f830116810181811085821117156124d0576124d0612738565b604052828152858101935084860182860187018a10156124ef57600080fd5b600095505b838610156125125780358552600195909501949386019386016124f4565b5098975050505050505050565b60006020828403121561253157600080fd5b81356123cc81612763565b60006020828403121561254e57600080fd5b81516123cc81612763565b60006020828403121561256b57600080fd5b5035919050565b60006020828403121561258457600080fd5b5051919050565b6000806040838503121561259e57600080fd5b8235915060208301356125b08161274e565b809150509250929050565b600080604083850312156125ce57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015612615578351835292840192918401916001016125f9565b50909695505050505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082198211156126695761266961270c565b500190565b60006001600160401b038083168185168083038211156126905761269061270c565b01949350505050565b6000826126b657634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156126d5576126d561270c565b500290565b6000828210156126ec576126ec61270c565b500390565b60006000198214156127055761270561270c565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146102a557600080fd5b80151581146102a557600080fdfea26469706673582212208d83fd1368443e135c1c59f7b86801e6d4931c7638d1f42b77e7e26fb5c9484564736f6c634300080700330000000000000000000000000000000000000000000000000000000000093a80
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102105760003560e01c80636aa633b611610125578063a30946ee116100ad578063f3b2caf31161007c578063f3b2caf3146104e8578063f3c7c9d7146104fb578063f40f0f5214610510578063f4239eec14610523578063f8077fae1461052c57600080fd5b8063a30946ee146104a7578063b2eaeaaa146104ba578063da5b4ee7146104cd578063f2fde38b146104d557600080fd5b806382ab890a116100f457806382ab890a1461038c57806382e4eda41461039f5780638943ec02146104705780638da5cb5b146104835780639cefc1da1461049457600080fd5b80636aa633b61461035557806378d0410e146103725780637e9ea4281461037b578063817b1cd21461038357600080fd5b80633bb190c1116101a857806341d4a1ab1161017757806341d4a1ab146102b95780634903b0d1146102e45780634f3a1ff81461030c57806351cff8d9146103275780635b17f5061461033a57600080fd5b80633bb190c1146102845780633c6b16ab146102975780633ccfd60b146102a85780633e0e828b146102b057600080fd5b806325ed3229116101e457806325ed32291461025757806336d421951461026a578063380e687a146102735780633a98ef391461027b57600080fd5b8062ae3bf8146102155780630d6680871461022a5780631868b20b146102465780631e29653c1461024f575b600080fd5b6102286102233660046123af565b610535565b005b610233600b5481565b6040519081526020015b60405180910390f35b610233600d5481565b6102336106f1565b61023361026536600461258b565b61077b565b61023360095481565b610228610879565b61023360045481565b610228610292366004612559565b610b3e565b6102286102a5366004612559565b50565b610228610b4a565b61023360085481565b6001546102cc906001600160a01b031681565b6040516001600160a01b03909116815260200161023d565b6102f76102f2366004612559565b610b55565b6040805192835260208301919091520161023d565b6102cc73d91531bde4a60ebeaaa4a04c32f29c9f19ec77d881565b6102286103353660046123af565b610b83565b6102cc739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b6003546103629060ff1681565b604051901515815260200161023d565b610233610e1081565b610233600a81565b61023360055481565b61022861039a366004612559565b610b8c565b6104166103ad3660046123af565b6006602052600090815260409020805460018201546002830154600390930154919290916001600160401b0380831692600160401b8104821692600160801b82049092169163ffffffff600160c01b8304811692600160e01b900416906001600160a01b031688565b6040805198895260208901979097526001600160401b039586169688019690965292841660608701529216608085015263ffffffff91821660a08501521660c08301526001600160a01b031660e08201526101000161023d565b61022861047e3660046123d3565b610e48565b6000546001600160a01b03166102cc565b6102286104a236600461251f565b610fa2565b6102286104b536600461245b565b610fee565b6102286104c83660046123af565b61108c565b6102336110e7565b6102286104e33660046123af565b611136565b6102286104f63660046125bb565b61122f565b610503611306565b60405161023d91906125dd565b61023361051e3660046123af565b61135e565b610233600c5481565b610233600a5481565b336105486000546001600160a01b031690565b6001600160a01b0316146105775760405162461bcd60e51b815260040161056e90612621565b60405180910390fd5b6001600160a01b038116739fae2529863bd691b4a7171bdfcf33c7ebb10a651480156105a4575060055415155b156105ac5750565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b1580156105ee57600080fd5b505afa158015610602573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106269190612572565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb90604401602060405180830381600087803b15801561067157600080fd5b505af1158015610685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a9919061253c565b50604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af291015b60405180910390a15050565b60405163389bbbfd60e21b815230600482015260009073d91531bde4a60ebeaaa4a04c32f29c9f19ec77d89063e26eeff49060240160206040518083038186803b15801561073e57600080fd5b505afa158015610752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107769190612572565b905090565b6000821580159061078e57506002548311155b6107cc5760405162461bcd60e51b815260206004820152600f60248201526e696e636f727265637420626f6e757360881b604482015260640161056e565b6001600160a01b038216600090815260066020526040812060020154600160801b90046001600160401b031680851161080a57600092505050610873565b801561083b57600261081d6001836126da565b8154811061082d5761082d612722565b906000526020600020015491505b8160026108496001886126da565b8154811061085957610859612722565b906000526020600020015461086e91906126da565b925050505b92915050565b33600090815260066020526040902080546002909101546001600160401b03161580156108a557508015155b6108f15760405162461bcd60e51b815260206004820152601d60248201527f7769746864726177207265717565737420616c7265616479206d616465000000604482015260640161056e565b6108fb6000610b8c565b6000610e1080600b544261090f9190612656565b6109199190612699565b61092391906126bb565b33600081815260066020908152604091829020600201805467ffffffffffffffff19166001600160401b0386161790558151928352820183905281018490529091507fcbc7c7858f9ab8ce22517d4b910042540172c3d579222cf6716e222f341ca3719060600160405180910390a1336000908152600660205260408120600201546064906109c3908590600160801b90046001600160401b03166126bb565b6109cd9190612699565b90506109d98184612656565b60075490935015801590610a1f5750600780548391906109fb906001906126da565b81548110610a0b57610a0b612722565b906000526020600020906002020160000154145b15610a725760078054849190610a37906001906126da565b81548110610a4757610a47612722565b90600052602060002090600202016001016000828254610a679190612656565b90915550610ae99050565b60408051808201909152828152602081018481526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600290930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689909101555b600754610af8906001906126da565b33600090815260066020526040902060020180546001600160401b0392909216600160401b026fffffffffffffffff000000000000000019909216919091179055505050565b6102a5336000836115cc565b610b533361190c565b565b60078181548110610b6557600080fd5b60009182526020909120600290910201805460019091015490915082565b6102a58161190c565b6000610e10610b9b8142612699565b610ba591906126bb565b600a54909150808211610bb757505050565b60045480610bc7575050600a5550565b60405163032453f160e51b815230600482015273d91531bde4a60ebeaaa4a04c32f29c9f19ec77d89063648a7e2090602401600060405180830381600087803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b505050506000610c356106f1565b610c3d6110e7565b610c4791906126bb565b610c589066038d7ea4c680006126bb565b600954600e54919250906001811115610ca55783610c776001836126da565b610c8990670de0b6b3a76400006126bb565b610c939190612699565b610c9d9083612656565b6001600e5591505b50600854600090610cb68189612656565b975080881480610cc7575060075488115b15610cd25760075497505b87811015610df0578660078281548110610cee57610cee612722565b9060005260206000209060020201600001541115610d0b57610df0565b8560078281548110610d1f57610d1f612722565b906000526020600020906002020160000154610d3b91906126da565b915060078181548110610d5057610d50612722565b6000918252602090912060029091020154955084610d6e85846126bb565b610d789190612699565b610d829084612656565b925060078181548110610d9757610d97612722565b90600052602060002090600202016001015485610db491906126da565b94508260078281548110610dca57610dca612722565b600091825260209091206001600290920201015580610de8816126f1565b915050610cd2565b60088190556004859055610e0486886126da565b600a88905591508415610e385784610e1c85846126bb565b610e269190612699565b610e309084612656565b600955610e3e565b60098390555b5050505050505050565b6001546001600160a01b031633148015610e6157508215155b15610ed057600060208214610eb15760405162461bcd60e51b815260206004820152601660248201527557726f6e6720626f6e75732070657263656e7461676560501b604482015260640161056e565b610ebd82840184612559565b9050610eca8585836115cc565b50610f9c565b33739fae2529863bd691b4a7171bdfcf33c7ebb10a6514610f335760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920534f59207374616b696e6720697320737570706f72746564000000604482015260640161056e565b6001600160a01b03841673d91531bde4a60ebeaaa4a04c32f29c9f19ec77d81480610f6b57506000546001600160a01b038581169116145b15610f7557610f9c565b60006020821415610f8f57610f8c828401846123af565b90505b610f9a858583611b2e565b505b50505050565b33610fb56000546001600160a01b031690565b6001600160a01b031614610fdb5760405162461bcd60e51b815260040161056e90612621565b6003805460ff1916911515919091179055565b336110016000546001600160a01b031690565b6001600160a01b0316146110275760405162461bcd60e51b815260040161056e90612621565b61103360026000612331565b600a815111156110755760405162461bcd60e51b815260206004820152600d60248201526c546f6f2062696720626f6e757360981b604482015260640161056e565b805161108890600290602084019061234f565b5050565b3361109f6000546001600160a01b031690565b6001600160a01b0316146110c55760405162461bcd60e51b815260040161056e90612621565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600073d91531bde4a60ebeaaa4a04c32f29c9f19ec77d86001600160a01b031663da5b4ee76040518163ffffffff1660e01b815260040160206040518083038186803b15801561073e57600080fd5b336111496000546001600160a01b031690565b6001600160a01b03161461116f5760405162461bcd60e51b815260040161056e90612621565b6001600160a01b0381166111d45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161056e565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b336112426000546001600160a01b031690565b6001600160a01b0316146112685760405162461bcd60e51b815260040161056e90612621565b6032821115801561127a575060328110155b8015611287575060648111155b6112c65760405162461bcd60e51b815260206004820152601060248201526f57726f6e672070657263656e7461676560801b604482015260640161056e565b600c829055600d81905560408051838152602081018390527f8115ca955ade2fd4083142596a343f291ae6e5506f64a19d166942e56c05115c91016106e5565b6060600280548060200260200160405190810160405280929190818152602001828054801561135457602002820191906000526020600020905b815481526020019060010190808311611340575b5050505050905090565b600080610e1061136e8142612699565b61137891906126bb565b600a546009549192509081831161139d576113938582611ef8565b5095945050505050565b600454600e5460018111156113e157816113b86001836126da565b6113ca90670de0b6b3a76400006126bb565b6113d49190612699565b6113de9084612656565b92505b5060006113ec6106f1565b6113f46110e7565b6113fe91906126bb565b61140f9066038d7ea4c680006126bb565b6008546007549192506000915b8082101561158e57876007838154811061143857611438612722565b90600052602060002090600202016000015411156114555761158e565b866007838154811061146957611469612722565b90600052602060002090600202016000015461148591906126da565b92506007828154811061149a5761149a612722565b60009182526020909120600290910201549650846114b885856126bb565b6114c29190612699565b6114cc9087612656565b9550600782815481106114e1576114e1612722565b906000526020600020906002020160010154856114fe91906126da565b6001600160a01b038b166000908152600660205260409020600201549095506001600160401b03161580159061155e57506001600160a01b038a16600090815260066020526040902060020154600160401b90046001600160401b031682145b1561157c5761156d8a87611ef8565b509a9950505050505050505050565b81611586816126f1565b92505061141c565b61159887896126da565b925084156115c257846115ab85856126bb565b6115b59190612699565b6115bf9087612656565b95505b61156d8a87611ef8565b6001600160a01b0383166000908152600660205260409020600201546001600160401b03161561163e5760405162461bcd60e51b815260206004820152601a60248201527f4163636f756e74206c6f636b656420666f72207374616b696e67000000000000604482015260640161056e565b6116486000610b8c565b60008061165785600954611ef8565b6009546001600160a01b0388166000908152600660205260408120600101919091559193509150611688848761077b565b9050806116d75760405162461bcd60e51b815260206004820152601b60248201527f7573657220616c726561647920686173207468697320626f6e75730000000000604482015260640161056e565b8461176d576001546040516323b872dd60e01b81526001600160a01b03888116600483015230602483015260448201849052909116906323b872dd90606401602060405180830381600087803b15801561173057600080fd5b505af1158015611744573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611768919061253c565b508094505b8481146117bc5760405162461bcd60e51b815260206004820152601d60248201527f75736572207472616e736665727265642077726f6e6720616d6f756e74000000604482015260640161056e565b6117c58161214e565b6001600160a01b038616600090815260066020526040812080546002909101546064919061180390600160801b90046001600160401b0316886126da565b61180d91906126bb565b6118179190612699565b9050806004600082825461182b9190612656565b90915550506001600160a01b0387166000908152600660205260409020600201805467ffffffffffffffff60801b1916600160801b6001600160401b038816021790556118788388612251565b60405163a9059cbb60e01b81526001600160a01b038816600482015260248101859052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b1580156118d457600080fd5b505af11580156118e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3e919061253c565b6001600160a01b038116600090815260066020526040902060020154426001600160401b0390911610801561196457506001600160a01b0381166000908152600660205260409020600201546001600160401b031615155b6119a45760405162461bcd60e51b81526020600482015260116024820152701dda5d1a191c985dd85b081b1bd8dad959607a1b604482015260640161056e565b6119ae6000610b8c565b6001600160a01b03811660009081526006602052604081205460095490919081906119da908590611ef8565b9150915082600560008282546119f091906126da565b90915550506001600160a01b038416600090815260066020526040812081815560018101829055600281019190915560030180546001600160a01b0319169055611a3a8185612251565b739fae2529863bd691b4a7171bdfcf33c7ebb10a6563a9059cbb85611a5f8587612656565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611aa557600080fd5b505af1158015611ab9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611add919061253c565b50604080516001600160a01b0386168152602081018590529081018390527f5f808ed47938c2c6ffcf1784b8a3171a0e8cb25d277b291b26475b303473bbb09060600160405180910390a150505050565b60035460ff16611b735760405162461bcd60e51b815260206004820152601060248201526f1cdd185ada5b99c8191a5cd8589b195960821b604482015260640161056e565b6001600160a01b0383166000908152600660205260409020600201546001600160401b031615611c27576001600160a01b038316600090815260066020526040902060020154426001600160401b039091161015611bd957611bd48361190c565b505050565b8115611c275760405162461bcd60e51b815260206004820152601a60248201527f4163636f756e74206c6f636b656420666f72207374616b696e67000000000000604482015260640161056e565b611c316000610b8c565b6001600160a01b03811615801590611c6457506001600160a01b0383811660009081526006602052604090206003015416155b15611cc8576001600160a01b0383811660009081526006602052604090206003810180546001600160a01b03191692841692909217909155600c546002909101805463ffffffff60c01b1916600160c01b63ffffffff909316929092029190911790555b6001600160a01b038316600090815260066020526040902054611d2557600d546001600160a01b0384166000908152600660205260409020600201805463ffffffff909216600160e01b026001600160e01b039092169190911790555b8160056000828254611d379190612656565b90915550506001600160a01b038316600090815260066020526040902060020154606490611d7590600160801b90046001600160401b03168261266e565b611d88906001600160401b0316846126bb565b611d929190612699565b60046000828254611da39190612656565b92505081905550600080611db985600954611ef8565b6001600160a01b038716600090815260066020526040812080549395509193508692611de6908490612656565b90915550506009546001600160a01b038616600090815260066020526040902060010155611e148186612251565b60405163a9059cbb60e01b81526001600160a01b038616600482015260248101839052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b158015611e7057600080fd5b505af1158015611e84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea8919061253c565b50604080516001600160a01b038716815260208101869052428183015290517f770220af1c9e120c1375b3c3785dd5bdb8371fa98c7e83537933bb116fee490e9181900360600190a15050505050565b6001600160a01b03821660009081526006602052604081206002015481908190606490611f3590600160801b90046001600160401b03168261266e565b6001600160a01b038716600090815260066020526040902054611f61916001600160401b0316906126bb565b611f6b9190612699565b6001600160a01b0386166000908152600660205260409020600201549091506001600160401b031615801590611fce57506001600160a01b038516600090815260066020526040902060020154600854600160401b9091046001600160401b0316105b15612029576001600160a01b038516600090815260066020526040902060020154600780549091600160401b90046001600160401b031690811061201457612014612722565b90600052602060002090600202016001015493505b6001600160a01b038516600090815260066020526040812060010154670de0b6b3a76400009061205990876126da565b61206390846126bb565b61206d9190612699565b6001600160a01b03878116600090815260066020526040902060030154919250166120f6576001600160a01b038616600090815260066020526040902060020154600d54600160e01b90910463ffffffff16908110156120cc5750600d545b60646120d882846126bb565b6120e29190612699565b94506120ee85836126da565b935050612145565b6001600160a01b03861660009081526006602052604090206002015460649061212c90600160c01b900463ffffffff16836126bb565b6121369190612699565b925061214283826126da565b93505b50509250929050565b600154604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401602060405180830381600087803b15801561219457600080fd5b505af19250505080156121c4575060408051601f3d908101601f191682019092526121c19181019061253c565b60015b6110885760015460405163a9059cbb60e01b815261dead60901b6004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561221957600080fd5b505af115801561222d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611088919061253c565b8115611088576001600160a01b03808216600090815260066020526040902060030154168015612315576040516323b872dd60e01b81523060048201526001600160a01b038216602482015260448101849052739fae2529863bd691b4a7171bdfcf33c7ebb10a65906323b872dd90606401602060405180830381600087803b1580156122dd57600080fd5b505af11580156122f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9c919061253c565b82600e60008282546123279190612656565b9091555050505050565b50805460008255906000526020600020908101906102a5919061239a565b82805482825590600052602060002090810192821561238a579160200282015b8281111561238a57825182559160200191906001019061236f565b5061239692915061239a565b5090565b5b80821115612396576000815560010161239b565b6000602082840312156123c157600080fd5b81356123cc8161274e565b9392505050565b600080600080606085870312156123e957600080fd5b84356123f48161274e565b93506020850135925060408501356001600160401b038082111561241757600080fd5b818701915087601f83011261242b57600080fd5b81358181111561243a57600080fd5b88602082850101111561244c57600080fd5b95989497505060200194505050565b6000602080838503121561246e57600080fd5b82356001600160401b038082111561248557600080fd5b818501915085601f83011261249957600080fd5b8135818111156124ab576124ab612738565b8060051b604051601f19603f830116810181811085821117156124d0576124d0612738565b604052828152858101935084860182860187018a10156124ef57600080fd5b600095505b838610156125125780358552600195909501949386019386016124f4565b5098975050505050505050565b60006020828403121561253157600080fd5b81356123cc81612763565b60006020828403121561254e57600080fd5b81516123cc81612763565b60006020828403121561256b57600080fd5b5035919050565b60006020828403121561258457600080fd5b5051919050565b6000806040838503121561259e57600080fd5b8235915060208301356125b08161274e565b809150509250929050565b600080604083850312156125ce57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015612615578351835292840192918401916001016125f9565b50909695505050505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082198211156126695761266961270c565b500190565b60006001600160401b038083168185168083038211156126905761269061270c565b01949350505050565b6000826126b657634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156126d5576126d561270c565b500290565b6000828210156126ec576126ec61270c565b500390565b60006000198214156127055761270561270c565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146102a557600080fd5b80151581146102a557600080fdfea26469706673582212208d83fd1368443e135c1c59f7b86801e6d4931c7638d1f42b77e7e26fb5c9484564736f6c63430008070033