More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 693 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 20391739 | 34 days ago | IN | 0.00089 ETH | 0.00171528 | ||||
Withdraw | 20253523 | 53 days ago | IN | 0.00089 ETH | 0.00053537 | ||||
Withdraw | 20187733 | 62 days ago | IN | 0.00089 ETH | 0.00114403 | ||||
Withdraw | 20153749 | 67 days ago | IN | 0.00089 ETH | 0.00212909 | ||||
Withdraw | 19844702 | 110 days ago | IN | 0.00089 ETH | 0.00089566 | ||||
Withdraw | 19842711 | 110 days ago | IN | 0.00089 ETH | 0.00195883 | ||||
Claim Reward | 19826973 | 113 days ago | IN | 0.00089 ETH | 0.00118036 | ||||
Withdraw | 19731692 | 126 days ago | IN | 0.00089 ETH | 0.00422584 | ||||
Withdraw | 19699981 | 130 days ago | IN | 0.00089 ETH | 0.00072633 | ||||
Withdraw | 19644551 | 138 days ago | IN | 0.00089 ETH | 0.00236936 | ||||
Transfer | 19421203 | 170 days ago | IN | 0.0111 ETH | 0.00140978 | ||||
Claim Reward | 19395330 | 173 days ago | IN | 0.00089 ETH | 0.0108884 | ||||
Withdraw | 19231536 | 196 days ago | IN | 0.00089 ETH | 0.00381042 | ||||
Claim Reward | 19231510 | 196 days ago | IN | 0.00089 ETH | 0.0039429 | ||||
Claim Reward | 19151059 | 207 days ago | IN | 0.00089 ETH | 0.00314053 | ||||
Withdraw | 19103389 | 214 days ago | IN | 0.00089 ETH | 0.00339069 | ||||
Claim Reward | 19075081 | 218 days ago | IN | 0.00089 ETH | 0.00195057 | ||||
Claim Reward | 19057100 | 221 days ago | IN | 0.00089 ETH | 0.0030429 | ||||
Claim Reward | 18987682 | 230 days ago | IN | 0.00089 ETH | 0.0038754 | ||||
Claim Reward | 18985205 | 231 days ago | IN | 0.00089 ETH | 0.00699669 | ||||
Claim Reward | 18937220 | 237 days ago | IN | 0.00089 ETH | 0.00345612 | ||||
Withdraw | 18863630 | 248 days ago | IN | 0.00089 ETH | 0.00800157 | ||||
Withdraw | 18861946 | 248 days ago | IN | 0.00089 ETH | 0.00668286 | ||||
Withdraw | 18859218 | 248 days ago | IN | 0.00089 ETH | 0.00536995 | ||||
Claim Reward | 18858799 | 248 days ago | IN | 0.00089 ETH | 0.0040831 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
20391739 | 34 days ago | 0.00089 ETH | ||||
20253523 | 53 days ago | 0.00089 ETH | ||||
20187733 | 62 days ago | 0.00089 ETH | ||||
20153749 | 67 days ago | 0.00089 ETH | ||||
19844702 | 110 days ago | 0.00089 ETH | ||||
19842711 | 110 days ago | 0.00089 ETH | ||||
19826973 | 113 days ago | 0.00089 ETH | ||||
19731692 | 126 days ago | 0.00089 ETH | ||||
19699981 | 130 days ago | 0.00089 ETH | ||||
19644551 | 138 days ago | 0.00089 ETH | ||||
19395330 | 173 days ago | 0.00089 ETH | ||||
19231536 | 196 days ago | 0.00089 ETH | ||||
19231510 | 196 days ago | 0.00089 ETH | ||||
19151059 | 207 days ago | 0.00089 ETH | ||||
19103389 | 214 days ago | 0.00089 ETH | ||||
19075081 | 218 days ago | 0.00089 ETH | ||||
19057100 | 221 days ago | 0.00089 ETH | ||||
18987682 | 230 days ago | 0.00089 ETH | ||||
18985205 | 231 days ago | 0.00089 ETH | ||||
18937220 | 237 days ago | 0.00089 ETH | ||||
18863630 | 248 days ago | 0.00089 ETH | ||||
18861946 | 248 days ago | 0.00089 ETH | ||||
18859218 | 248 days ago | 0.00089 ETH | ||||
18858799 | 248 days ago | 0.00089 ETH | ||||
18692495 | 272 days ago | 0.00089 ETH |
Loading...
Loading
Contract Name:
LuckyRooNftStaking
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @author Brewlabs * This contract has been developed by brewlabs.info */ import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract LuckyRooNftStaking is Ownable, IERC721Receiver, ReentrancyGuard { using SafeERC20 for IERC20; bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; uint256 private constant BLOCKS_PER_DAY = 6426; uint256 private PRECISION_FACTOR; // Whether it is initialized bool public isInitialized; uint256 public duration = 365; // 365 days // The block number when staking starts. uint256 public startBlock; // The block number when staking ends. uint256 public bonusEndBlock; // tokens created per block. uint256 public rewardPerBlock; // The block number of the last pool update uint256 public lastRewardBlock; address public treasury = 0xf91AfC2c104d040c5FCcDA625d038b09AE407019; uint256 public performanceFee = 0.00089 ether; // The staked token IERC721 public stakingNft; // The earned token IERC20 public earnedToken; // Accrued token per share uint256 public accTokenPerShare; uint256 public oneTimeLimit = 40; uint256 public totalStaked; uint256 private totalEarned; uint256 private paidRewards; uint256 private shouldTotalPaid; struct UserInfo { uint256 amount; // number of staked NFTs uint256[] tokenIds; // staked tokenIds uint256 rewardDebt; // Reward debt } // Info of each user that stakes tokenIds mapping(address => UserInfo) public userInfo; event Deposit(address indexed user, uint256[] tokenIds); event Withdraw(address indexed user, uint256[] tokenIds); event Claim(address indexed user, uint256 amount); event EmergencyWithdraw(address indexed user, uint256[] tokenIds); event AdminTokenRecovered(address tokenRecovered, uint256 amount); event NewStartAndEndBlocks(uint256 startBlock, uint256 endBlock); event NewRewardPerBlock(uint256 rewardPerBlock); event RewardsStop(uint256 blockNumber); event EndBlockUpdated(uint256 blockNumber); event ServiceInfoUpadted(address _addr, uint256 _fee); event DurationUpdated(uint256 _duration); constructor() {} /* * @notice Initialize the contract * @param _stakingNft: nft address to stake * @param _earnedToken: earned token address * @param _rewardPerBlock: reward per block (in earnedToken) */ function initialize( IERC721 _stakingNft, IERC20 _earnedToken, uint256 _rewardPerBlock ) external onlyOwner { require(!isInitialized, "Already initialized"); // Make this contract initialized isInitialized = true; stakingNft = _stakingNft; earnedToken = _earnedToken; rewardPerBlock = _rewardPerBlock; uint256 decimalsRewardToken = uint256(IERC20Metadata(address(earnedToken)).decimals()); require(decimalsRewardToken < 30, "Must be inferior to 30"); PRECISION_FACTOR = uint256(10**(40 - decimalsRewardToken)); } /* * @notice Deposit staked tokens and collect reward tokens (if any) * @param _amount: amount to withdraw (in earnedToken) */ function deposit(uint256[] memory _tokenIds) external payable nonReentrant { require(startBlock > 0 && startBlock < block.number, "Staking hasn't started yet"); require(_tokenIds.length > 0, "must add at least one tokenId"); require(_tokenIds.length <= oneTimeLimit, "cannot exceed one-time limit"); _transferPerformanceFee(); _updatePool(); UserInfo storage user = userInfo[msg.sender]; if (user.amount > 0) { uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; if (pending > 0) { require(availableRewardTokens() >= pending, "Insufficient reward tokens"); earnedToken.safeTransfer(address(msg.sender), pending); paidRewards += pending; emit Claim(msg.sender, pending); } } for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 tokenId = _tokenIds[i]; stakingNft.safeTransferFrom(msg.sender, address(this), tokenId); user.tokenIds.push(tokenId); } user.amount = user.amount + _tokenIds.length; user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; totalStaked = totalStaked + _tokenIds.length; emit Deposit(msg.sender, _tokenIds); } /* * @notice Withdraw staked tokenIds and collect reward tokens * @param _amount: number of tokenIds to unstake */ function withdraw(uint256 _amount) external payable nonReentrant { require(_amount > 0, "Amount should be greator than 0"); require(_amount <= oneTimeLimit, "cannot exceed one-time limit"); UserInfo storage user = userInfo[msg.sender]; require(user.amount >= _amount, "Amount to withdraw too high"); _transferPerformanceFee(); _updatePool(); if (user.amount > 0) { uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; if (pending > 0) { require(availableRewardTokens() >= pending, "Insufficient reward tokens"); earnedToken.safeTransfer(address(msg.sender), pending); paidRewards += pending; emit Claim(msg.sender, pending); } } uint256[] memory _tokenIds = new uint256[](_amount); for (uint256 i = 0; i < _amount; i++) { uint256 tokenId = user.tokenIds[user.tokenIds.length - 1]; user.tokenIds.pop(); _tokenIds[i] = tokenId; stakingNft.safeTransferFrom(address(this), msg.sender, tokenId); } user.amount = user.amount - _amount; user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; totalStaked = totalStaked - _amount; emit Withdraw(msg.sender, _tokenIds); } function claimReward() external payable nonReentrant { UserInfo storage user = userInfo[msg.sender]; _transferPerformanceFee(); _updatePool(); if (user.amount == 0) return; uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; if (pending > 0) { require(availableRewardTokens() >= pending, "Insufficient reward tokens"); earnedToken.safeTransfer(address(msg.sender), pending); paidRewards += pending; } user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; emit Claim(msg.sender, pending); } /* * @notice Withdraw staked NFTs without caring about rewards * @dev Needs to be for emergency. */ function emergencyWithdraw() external nonReentrant { UserInfo storage user = userInfo[msg.sender]; uint256 _amount = user.amount; if (_amount > oneTimeLimit) _amount = oneTimeLimit; uint256[] memory _tokenIds = new uint256[](_amount); for (uint256 i = 0; i < _amount; i++) { uint256 tokenId = user.tokenIds[user.tokenIds.length - 1]; user.tokenIds.pop(); _tokenIds[i] = tokenId; stakingNft.safeTransferFrom(address(this), msg.sender, tokenId); } user.amount = user.amount - _amount; user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; totalStaked = totalStaked - _amount; emit EmergencyWithdraw(msg.sender, _tokenIds); } function stakedInfo(address _user) external view returns (uint256, uint256[] memory) { return (userInfo[_user].amount, userInfo[_user].tokenIds); } /** * @notice Available amount of reward token */ function availableRewardTokens() public view returns (uint256) { return earnedToken.balanceOf(address(this)); } function insufficientRewards() external view returns (uint256) { uint256 adjustedShouldTotalPaid = shouldTotalPaid; uint256 remainRewards = availableRewardTokens() + paidRewards; if (startBlock == 0) { adjustedShouldTotalPaid += rewardPerBlock * duration * BLOCKS_PER_DAY; } else { uint256 remainBlocks = _getMultiplier(lastRewardBlock, bonusEndBlock); adjustedShouldTotalPaid += rewardPerBlock * remainBlocks; } if (remainRewards >= adjustedShouldTotalPaid) return 0; return adjustedShouldTotalPaid - remainRewards; } /* * @notice View function to see pending reward on frontend. * @param _user: user address * @return Pending reward for a given user */ function pendingReward(address _user) external view returns (uint256) { UserInfo storage user = userInfo[_user]; uint256 adjustedTokenPerShare = accTokenPerShare; if (block.number > lastRewardBlock && totalStaked != 0 && lastRewardBlock > 0) { uint256 multiplier = _getMultiplier(lastRewardBlock, block.number); uint256 rewards = multiplier * rewardPerBlock; adjustedTokenPerShare += (rewards * PRECISION_FACTOR) / totalStaked; } return (user.amount * adjustedTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; } /************************ ** Admin Methods *************************/ function increaseEmissionRate(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(); earnedToken.safeTransferFrom(msg.sender, address(this), _amount); uint256 remainRewards = availableRewardTokens() + paidRewards; if (remainRewards > shouldTotalPaid) { remainRewards = remainRewards - shouldTotalPaid; uint256 remainBlocks = bonusEndBlock - block.number; rewardPerBlock = remainRewards / remainBlocks; emit NewRewardPerBlock(rewardPerBlock); } } /* * @notice Withdraw reward token * @dev Only callable by owner. Needs to be for emergency. */ function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { require(block.number > bonusEndBlock, "Pool is running"); require(availableRewardTokens() >= _amount, "Insufficient reward tokens"); if (_amount == 0) _amount = availableRewardTokens(); earnedToken.safeTransfer(address(msg.sender), _amount); } function startReward() external onlyOwner { require(startBlock == 0, "Pool was already started"); startBlock = block.number + 100; bonusEndBlock = startBlock + duration * BLOCKS_PER_DAY; lastRewardBlock = startBlock; emit NewStartAndEndBlocks(startBlock, bonusEndBlock); } function stopReward() external onlyOwner { _updatePool(); uint256 remainRewards = availableRewardTokens() + paidRewards; if (remainRewards > shouldTotalPaid) { remainRewards = remainRewards - shouldTotalPaid; earnedToken.transfer(msg.sender, 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); } /* * @notice Update reward per block * @dev Only callable by owner. * @param _rewardPerBlock: the reward per block */ function updateRewardPerBlock(uint256 _rewardPerBlock) external onlyOwner { rewardPerBlock = _rewardPerBlock; emit NewRewardPerBlock(_rewardPerBlock); } function setDuration(uint256 _duration) external onlyOwner { require(_duration >= 30, "lower limit reached"); duration = _duration; if (startBlock > 0) { bonusEndBlock = startBlock + duration * BLOCKS_PER_DAY; require(bonusEndBlock > block.number, "invalid duration"); } emit DurationUpdated(_duration); } function setServiceInfo(address _treasury, uint256 _fee) external { require(msg.sender == treasury, "setServiceInfo: FORBIDDEN"); require(_treasury != address(0x0), "Invalid address"); treasury = _treasury; performanceFee = _fee; emit ServiceInfoUpadted(_treasury, _fee); } /** * @notice It allows the admin to recover wrong tokens sent to the contract * @param _token: the address of the token to withdraw * @dev This function is only callable by admin. */ function rescueTokens(address _token) external onlyOwner { require(_token != address(earnedToken), "Cannot be reward token"); uint256 amount = address(this).balance; if (_token == address(0x0)) { payable(msg.sender).transfer(amount); } else { amount = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransfer(address(msg.sender), amount); } emit AdminTokenRecovered(_token, amount); } /************************ ** Internal Methods *************************/ /* * @notice Update reward variables of the given pool to be up-to-date. */ function _updatePool() internal { if (block.number <= lastRewardBlock || lastRewardBlock == 0) return; if (totalStaked == 0) { lastRewardBlock = block.number; return; } uint256 multiplier = _getMultiplier(lastRewardBlock, block.number); uint256 _reward = multiplier * rewardPerBlock; accTokenPerShare += (_reward * PRECISION_FACTOR) / totalStaked; lastRewardBlock = block.number; shouldTotalPaid += _reward; } /* * @notice Return reward multiplier over the given _from to _to block. * @param _from: block to start * @param _to: block to finish */ 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 _transferPerformanceFee() internal { require(msg.value >= performanceFee, "should pay small gas to compound or harvest"); payable(treasury).transfer(performanceFee); if (msg.value > performanceFee) { payable(msg.sender).transfer(msg.value - performanceFee); } } /** * onERC721Received(address operator, address from, uint256 tokenId, bytes data) → bytes4 * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. */ function onERC721Received( address, address, uint256, bytes calldata ) external view override returns (bytes4) { require(msg.sender == address(stakingNft), "not enabled NFT"); return _ERC721_RECEIVED; } receive() external payable {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) 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() { _transferOwnership(_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 { _transferOwnership(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"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) 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 making 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 // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) 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' 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 require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) 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) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) 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 // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) 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; 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"); (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"); (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"); (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"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "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":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","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":"tokenIds","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":"uint256","name":"rewardPerBlock","type":"uint256"}],"name":"NewRewardPerBlock","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":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"accTokenPerShare","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":"claimReward","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"increaseEmissionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"_stakingNft","type":"address"},{"internalType":"contract IERC20","name":"_earnedToken","type":"address"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"}],"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":[],"name":"lastRewardBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oneTimeLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"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":"_treasury","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setServiceInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"stakedInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingNft","outputs":[{"internalType":"contract IERC721","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":"treasury","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":"uint256","name":"_rewardPerBlock","type":"uint256"}],"name":"updateRewardPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405261016d600455600980546001600160a01b03191673f91afc2c104d040c5fccda625d038b09ae4070191790556603297345d9a000600a556028600e5534801561004c57600080fd5b506100563361005f565b600180556100af565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612ab9806100be6000396000f3fe6080604052600436106101d15760003560e01c806380dc0672116100f8578063a9f8d18111610090578063a9f8d1811461050a578063b493877714610520578063b88a802f1461054e578063db2e21bc14610556578063f2fde38b1461056b578063f3aeb31d1461058b578063f40f0f52146105a0578063f4ef5ed5146105c0578063f6be71d1146105e057600080fd5b806380dc06721461043d578063817b1cd21461045257806381b619481461046857806387788782146104885780638ae39cac1461049e5780638da5cb5b146104b45780638f662915146104c95780639f94e272146104df578063a2cd12d2146104f457600080fd5b80633279beab1161016b5780633279beab14610333578063392e53cd1461035357806348cd4cb11461037d578063598b8e711461039357806361d027b3146103a65780636982d815146103d35780636e707b73146103f3578063715018a614610413578063746c8ae11461042857600080fd5b80626f0231146101dd578062ae3bf8146101ff57806301f8a9761461021f5780630fb5a6b41461023f578063150b7a02146102685780631794bb3c146102a15780631959a002146102c15780631aed65531461030a5780632e1a7d4d1461032057600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612651565b610600565b005b34801561020b57600080fd5b506101fd61021a366004612450565b610759565b34801561022b57600080fd5b506101fd61023a366004612651565b6108f0565b34801561024b57600080fd5b5061025560045481565b6040519081526020015b60405180910390f35b34801561027457600080fd5b5061028861028336600461246c565b610954565b6040516001600160e01b0319909116815260200161025f565b3480156102ad57600080fd5b506101fd6102bc366004612611565b6109b5565b3480156102cd57600080fd5b506102f56102dc366004612450565b6013602052600090815260409020805460029091015482565b6040805192835260208301919091520161025f565b34801561031657600080fd5b5061025560065481565b6101fd61032e366004612651565b610b4b565b34801561033f57600080fd5b506101fd61034e366004612651565b610f0d565b34801561035f57600080fd5b5060035461036d9060ff1681565b604051901515815260200161025f565b34801561038957600080fd5b5061025560055481565b6101fd6103a1366004612531565b610fd0565b3480156103b257600080fd5b506009546103c6906001600160a01b031681565b60405161025f91906126f8565b3480156103df57600080fd5b50600b546103c6906001600160a01b031681565b3480156103ff57600080fd5b50600c546103c6906001600160a01b031681565b34801561041f57600080fd5b506101fd6112f3565b34801561043457600080fd5b506101fd61132e565b34801561044957600080fd5b506101fd611420565b34801561045e57600080fd5b50610255600f5481565b34801561047457600080fd5b506101fd610483366004612506565b611544565b34801561049457600080fd5b50610255600a5481565b3480156104aa57600080fd5b5061025560075481565b3480156104c057600080fd5b506103c6611634565b3480156104d557600080fd5b50610255600d5481565b3480156104eb57600080fd5b50610255611643565b34801561050057600080fd5b50610255600e5481565b34801561051657600080fd5b5061025560085481565b34801561052c57600080fd5b5061054061053b366004612450565b6116c9565b60405161025f929190612869565b6101fd611745565b34801561056257600080fd5b506101fd61186d565b34801561057757600080fd5b506101fd610586366004612450565b611aa5565b34801561059757600080fd5b50610255611b42565b3480156105ac57600080fd5b506102556105bb366004612450565b611beb565b3480156105cc57600080fd5b506101fd6105db366004612651565b611ca8565b3480156105ec57600080fd5b506101fd6105fb366004612651565b611e59565b33610609611634565b6001600160a01b0316146106385760405162461bcd60e51b815260040161062f9061278f565b60405180910390fd5b6000600554116106805760405162461bcd60e51b8152602060048201526013602482015272141bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b604482015260640161062f565b43600654116106cd5760405162461bcd60e51b8152602060048201526019602482015278141bdbdb081dd85cc8185b1c9958591e48199a5b9a5cda1959603a1b604482015260640161062f565b43811180156106dd575060055481115b61071d5760405162461bcd60e51b8152602060048201526011602482015270496e76616c696420656e6420626c6f636b60781b604482015260640161062f565b60068190556040518181527f0972575658363b3e7c472ab3a6a918726742c853b732f6a4a2763e2e3a94c977906020015b60405180910390a150565b33610762611634565b6001600160a01b0316146107885760405162461bcd60e51b815260040161062f9061278f565b600c546001600160a01b03828116911614156107df5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103132903932bbb0b932103a37b5b2b760511b604482015260640161062f565b476001600160a01b03821661082157604051339082156108fc029083906000818181858888f1935050505015801561081b573d6000803e3d6000fd5b506108b3565b6040516370a0823160e01b81526001600160a01b038316906370a082319061084d9030906004016126f8565b60206040518083038186803b15801561086557600080fd5b505afa158015610879573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089d9190612669565b90506108b36001600160a01b0383163383611f6f565b7f74f5dcd55c394cb1c6d3b9da22c2464bcc46c38cc3865bd629ed75823249b40b82826040516108e4929190612730565b60405180910390a15050565b336108f9611634565b6001600160a01b03161461091f5760405162461bcd60e51b815260040161062f9061278f565b60078190556040518181527f0c4d677eef92893ac7ec52faf8140fc6c851ab4736302b4f3a89dfb20696a0df9060200161074e565b600b546000906001600160a01b031633146109a35760405162461bcd60e51b815260206004820152600f60248201526e1b9bdd08195b98589b195908139195608a1b604482015260640161062f565b50630a85bd0160e11b95945050505050565b336109be611634565b6001600160a01b0316146109e45760405162461bcd60e51b815260040161062f9061278f565b60035460ff1615610a2d5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015260640161062f565b6003805460ff19166001179055600b80546001600160a01b038086166001600160a01b031992831617909255600c8054928516929091168217905560078290556040805163313ce56760e01b815290516000929163313ce567916004828101926020929190829003018186803b158015610aa657600080fd5b505afa158015610aba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade9190612681565b60ff169050601e8110610b2c5760405162461bcd60e51b815260206004820152601660248201527504d75737420626520696e666572696f7220746f2033360541b604482015260640161062f565b610b378160286129c4565b610b4290600a6128fd565b60025550505050565b60026001541415610b6e5760405162461bcd60e51b815260040161062f906127fb565b600260015580610bc05760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e742073686f756c642062652067726561746f72207468616e203000604482015260640161062f565b600e54811115610be25760405162461bcd60e51b815260040161062f906127c4565b3360009081526013602052604090208054821115610c425760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e7420746f20776974686472617720746f6f20686967680000000000604482015260640161062f565b610c4a611fca565b610c526120b2565b805415610d0c5760008160020154600254600d548460000154610c7591906129a5565b610c7f919061289a565b610c8991906129c4565b90508015610d0a5780610c9a611643565b1015610cb85760405162461bcd60e51b815260040161062f90612832565b600c54610ccf906001600160a01b03163383611f6f565b8060116000828254610ce19190612882565b90915550506040518181523390600080516020612a648339815191529060200160405180910390a25b505b60008267ffffffffffffffff811115610d3557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d5e578160200160208202803683370190505b50905060005b83811015610e875760018084018054600092610d7f916129c4565b81548110610d9d57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905083600101805480610dcb57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905580838381518110610e0257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600b54604051632142170760e11b81526001600160a01b03909116906342842e0e90610e419030903390869060040161270c565b600060405180830381600087803b158015610e5b57600080fd5b505af1158015610e6f573d6000803e3d6000fd5b50505050508080610e7f90612a07565b915050610d64565b508154610e959084906129c4565b808355600254600d549091610eaa91906129a5565b610eb4919061289a565b6002830155600f54610ec79084906129c4565b600f5560405133907f67e9df8b3c7743c9f1b625ba4f2b4e601206dbd46ed5c33c85a1242e4d23a2d190610efc908490612749565b60405180910390a250506001805550565b33610f16611634565b6001600160a01b031614610f3c5760405162461bcd60e51b815260040161062f9061278f565b6006544311610f7f5760405162461bcd60e51b815260206004820152600f60248201526e506f6f6c2069732072756e6e696e6760881b604482015260640161062f565b80610f88611643565b1015610fa65760405162461bcd60e51b815260040161062f90612832565b80610fb657610fb3611643565b90505b600c54610fcd906001600160a01b03163383611f6f565b50565b60026001541415610ff35760405162461bcd60e51b815260040161062f906127fb565b60026001556005541580159061100a575043600554105b6110565760405162461bcd60e51b815260206004820152601a60248201527f5374616b696e67206861736e2774207374617274656420796574000000000000604482015260640161062f565b60008151116110a75760405162461bcd60e51b815260206004820152601d60248201527f6d75737420616464206174206c65617374206f6e6520746f6b656e4964000000604482015260640161062f565b600e54815111156110ca5760405162461bcd60e51b815260040161062f906127c4565b6110d2611fca565b6110da6120b2565b3360009081526013602052604090208054156111a35760008160020154600254600d54846000015461110c91906129a5565b611116919061289a565b61112091906129c4565b905080156111a15780611131611643565b101561114f5760405162461bcd60e51b815260040161062f90612832565b600c54611166906001600160a01b03163383611f6f565b80601160008282546111789190612882565b90915550506040518181523390600080516020612a648339815191529060200160405180910390a25b505b60005b825181101561126c5760008382815181106111d157634e487b7160e01b600052603260045260246000fd5b6020908102919091010151600b54604051632142170760e11b81529192506001600160a01b0316906342842e0e906112119033903090869060040161270c565b600060405180830381600087803b15801561122b57600080fd5b505af115801561123f573d6000803e3d6000fd5b5050505060018381018054918201815560009081526020902001558061126481612a07565b9150506111a6565b508151815461127b9190612882565b808255600254600d54909161129091906129a5565b61129a919061289a565b60028201558151600f546112ae9190612882565b600f5560405133907fff409334d2645d660e7cfa41a637aa21f45a79ecb9660a6931aa923bf75577c7906112e3908590612749565b60405180910390a2505060018055565b336112fc611634565b6001600160a01b0316146113225760405162461bcd60e51b815260040161062f9061278f565b61132c600061214c565b565b33611337611634565b6001600160a01b03161461135d5760405162461bcd60e51b815260040161062f9061278f565b600554156113a85760405162461bcd60e51b8152602060048201526018602482015277141bdbdb081dd85cc8185b1c9958591e481cdd185c9d195960421b604482015260640161062f565b6113b3436064612882565b6005556004546113c69061191a906129a5565b6005546113d39190612882565b600681905560055460088190556040517f7cd0ab87d19036f3dfadadb232c78aa4879dda3f0c994a9d637532410ee2ce0692611416928252602082015260400190565b60405180910390a1565b33611429611634565b6001600160a01b03161461144f5760405162461bcd60e51b815260040161062f9061278f565b6114576120b2565b6000601154611464611643565b61146e9190612882565b905060125481111561150e5760125461148790826129c4565b600c5460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb906114ba9033908590600401612730565b602060405180830381600087803b1580156114d457600080fd5b505af11580156114e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150c91906125f1565b505b4360068190556040519081527ffed9fcb0ca3d1e761a4b929792bb24082fba92dca81252646ad306d3068065669060200161074e565b6009546001600160a01b0316331461159a5760405162461bcd60e51b815260206004820152601960248201527839b2ba29b2b93b34b1b2a4b733379d102327a92124a22222a760391b604482015260640161062f565b6001600160a01b0382166115e25760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161062f565b600980546001600160a01b0319166001600160a01b038416179055600a8190556040517f232f2e6280d2064b1e439bf40ecdada042d84eefbb55039e4c49e8dc4f4c90c9906108e49084908490612730565b6000546001600160a01b031690565b600c546040516370a0823160e01b81526000916001600160a01b0316906370a08231906116749030906004016126f8565b60206040518083038186803b15801561168c57600080fd5b505afa1580156116a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c49190612669565b905090565b6001600160a01b03811660009081526013602090815260408083208054600190910180548351818602810186019094528084526060949293919283919083018282801561173557602002820191906000526020600020905b815481526020019060010190808311611721575b5050505050905091509150915091565b600260015414156117685760405162461bcd60e51b815260040161062f906127fb565b6002600155336000908152601360205260409020611784611fca565b61178c6120b2565b80546117985750611867565b60008160020154600254600d5484600001546117b491906129a5565b6117be919061289a565b6117c891906129c4565b9050801561182657806117d9611643565b10156117f75760405162461bcd60e51b815260040161062f90612832565b600c5461180e906001600160a01b03163383611f6f565b80601160008282546118209190612882565b90915550505b600254600d54835461183891906129a5565b611842919061289a565b60028301556040518181523390600080516020612a64833981519152906020016112e3565b60018055565b600260015414156118905760405162461bcd60e51b815260040161062f906127fb565b60026001553360009081526013602052604090208054600e548111156118b55750600e545b60008167ffffffffffffffff8111156118de57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611907578160200160208202803683370190505b50905060005b82811015611a305760018085018054600092611928916129c4565b8154811061194657634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508460010180548061197457634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055808383815181106119ab57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600b54604051632142170760e11b81526001600160a01b03909116906342842e0e906119ea9030903390869060040161270c565b600060405180830381600087803b158015611a0457600080fd5b505af1158015611a18573d6000803e3d6000fd5b50505050508080611a2890612a07565b91505061190d565b508254611a3e9083906129c4565b808455600254600d549091611a5391906129a5565b611a5d919061289a565b6002840155600f54611a709083906129c4565b600f5560405133907f1ad6082f7aa3e32095e38fd4c0bf76fa2bb7584e81474cf3519d2dea4081181c90610efc908490612749565b33611aae611634565b6001600160a01b031614611ad45760405162461bcd60e51b815260040161062f9061278f565b6001600160a01b038116611b395760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161062f565b610fcd8161214c565b60008060125490506000601154611b57611643565b611b619190612882565b905060055460001415611b9c5761191a600454600754611b8191906129a5565b611b8b91906129a5565b611b959083612882565b9150611bca565b6000611bac60085460065461219c565b905080600754611bbc91906129a5565b611bc69084612882565b9250505b818110611bda5760009250505090565b611be481836129c4565b9250505090565b6001600160a01b0381166000908152601360205260408120600d5460085443118015611c185750600f5415155b8015611c2657506000600854115b15611c77576000611c396008544361219c565b9050600060075482611c4b91906129a5565b9050600f5460025482611c5e91906129a5565b611c68919061289a565b611c729084612882565b925050505b60028083015490548354611c8c9084906129a5565b611c96919061289a565b611ca091906129c4565b949350505050565b33611cb1611634565b6001600160a01b031614611cd75760405162461bcd60e51b815260040161062f9061278f565b600060055411611d1f5760405162461bcd60e51b81526020600482015260136024820152721c1bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b604482015260640161062f565b4360065411611d6c5760405162461bcd60e51b81526020600482015260196024820152781c1bdbdb081dd85cc8185b1c9958591e48199a5b9a5cda1959603a1b604482015260640161062f565b60008111611dad5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015260640161062f565b611db56120b2565b600c54611dcd906001600160a01b03163330846121dd565b6000601154611dda611643565b611de49190612882565b9050601254811115611e5557601254611dfd90826129c4565b9050600043600654611e0f91906129c4565b9050611e1b818361289a565b60078190556040519081527f0c4d677eef92893ac7ec52faf8140fc6c851ab4736302b4f3a89dfb20696a0df9060200160405180910390a1505b5050565b33611e62611634565b6001600160a01b031614611e885760405162461bcd60e51b815260040161062f9061278f565b601e811015611ecf5760405162461bcd60e51b81526020600482015260136024820152721b1bddd95c881b1a5b5a5d081c995858da1959606a1b604482015260640161062f565b600481905560055415611f3f5761191a600454611eec91906129a5565b600554611ef99190612882565b60068190554310611f3f5760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210323ab930ba34b7b760811b604482015260640161062f565b6040518181527f91abcc2d6823e3a3f11d31b208dd3065d2c6a791f1c7c9fe96a42ce12897eac59060200161074e565b611fc58363a9059cbb60e01b8484604051602401611f8e929190612730565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612204565b505050565b600a543410156120305760405162461bcd60e51b815260206004820152602b60248201527f73686f756c642070617920736d616c6c2067617320746f20636f6d706f756e6460448201526a081bdc881a185c9d995cdd60aa1b606482015260840161062f565b600954600a546040516001600160a01b039092169181156108fc0291906000818181858888f1935050505015801561206c573d6000803e3d6000fd5b50600a5434111561132c57600a5433906108fc9061208a90346129c4565b6040518115909202916000818181858888f19350505050158015610fcd573d6000803e3d6000fd5b600854431115806120c35750600854155b156120ca57565b600f546120d75743600855565b60006120e56008544361219c565b90506000600754826120f791906129a5565b9050600f546002548261210a91906129a5565b612114919061289a565b600d60008282546121259190612882565b90915550504360085560128054829190600090612143908490612882565b90915550505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060065482116121b8576121b183836129c4565b90506121d7565b60065483106121c9575060006121d7565b826006546121b191906129c4565b92915050565b6121fe846323b872dd60e01b858585604051602401611f8e9392919061270c565b50505050565b6000612259826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122d69092919063ffffffff16565b805190915015611fc5578080602001905181019061227791906125f1565b611fc55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161062f565b60606122e584846000856122ef565b90505b9392505050565b6060824710156123505760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161062f565b843b61239e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161062f565b600080866001600160a01b031685876040516123ba91906126dc565b60006040518083038185875af1925050503d80600081146123f7576040519150601f19603f3d011682016040523d82523d6000602084013e6123fc565b606091505b509150915061240c828286612417565b979650505050505050565b606083156124265750816122e8565b8251156124365782518084602001fd5b8160405162461bcd60e51b815260040161062f919061275c565b600060208284031215612461578081fd5b81356122e881612a4e565b600080600080600060808688031215612483578081fd5b853561248e81612a4e565b9450602086013561249e81612a4e565b935060408601359250606086013567ffffffffffffffff808211156124c1578283fd5b818801915088601f8301126124d4578283fd5b8135818111156124e2578384fd5b8960208285010111156124f3578384fd5b9699959850939650602001949392505050565b60008060408385031215612518578182fd5b823561252381612a4e565b946020939093013593505050565b60006020808385031215612543578182fd5b823567ffffffffffffffff8082111561255a578384fd5b818501915085601f83011261256d578384fd5b81358181111561257f5761257f612a38565b8060051b604051601f19603f830116810181811085821117156125a4576125a4612a38565b604052828152858101935084860182860187018a10156125c2578788fd5b8795505b838610156125e45780358552600195909501949386019386016125c6565b5098975050505050505050565b600060208284031215612602578081fd5b815180151581146122e8578182fd5b600080600060608486031215612625578283fd5b833561263081612a4e565b9250602084013561264081612a4e565b929592945050506040919091013590565b600060208284031215612662578081fd5b5035919050565b60006020828403121561267a578081fd5b5051919050565b600060208284031215612692578081fd5b815160ff811681146122e8578182fd5b6000815180845260208085019450808401835b838110156126d1578151875295820195908201906001016126b5565b509495945050505050565b600082516126ee8184602087016129db565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020815260006122e860208301846126a2565b602081526000825180602084015261277b8160408501602087016129db565b601f01601f19169190910160400192915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601c908201527f63616e6e6f7420657863656564206f6e652d74696d65206c696d697400000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601a908201527f496e73756666696369656e742072657761726420746f6b656e73000000000000604082015260600190565b8281526040602082015260006122e560408301846126a2565b6000821982111561289557612895612a22565b500190565b6000826128b557634e487b7160e01b81526012600452602481fd5b500490565b600181815b808511156128f55781600019048211156128db576128db612a22565b808516156128e857918102915b93841c93908002906128bf565b509250929050565b60006122e88383600082612913575060016121d7565b81612920575060006121d7565b816001811461293657600281146129405761295c565b60019150506121d7565b60ff84111561295157612951612a22565b50506001821b6121d7565b5060208310610133831016604e8410600b841016171561297f575081810a6121d7565b61298983836128ba565b806000190482111561299d5761299d612a22565b029392505050565b60008160001904831182151516156129bf576129bf612a22565b500290565b6000828210156129d6576129d6612a22565b500390565b60005b838110156129f65781810151838201526020016129de565b838111156121fe5750506000910152565b6000600019821415612a1b57612a1b612a22565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610fcd57600080fdfe47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4a2646970667358221220c763573931201d3ae31e69400944abfc28d39955e41e12c5f4f42a851efe176c64736f6c63430008040033
Deployed Bytecode
0x6080604052600436106101d15760003560e01c806380dc0672116100f8578063a9f8d18111610090578063a9f8d1811461050a578063b493877714610520578063b88a802f1461054e578063db2e21bc14610556578063f2fde38b1461056b578063f3aeb31d1461058b578063f40f0f52146105a0578063f4ef5ed5146105c0578063f6be71d1146105e057600080fd5b806380dc06721461043d578063817b1cd21461045257806381b619481461046857806387788782146104885780638ae39cac1461049e5780638da5cb5b146104b45780638f662915146104c95780639f94e272146104df578063a2cd12d2146104f457600080fd5b80633279beab1161016b5780633279beab14610333578063392e53cd1461035357806348cd4cb11461037d578063598b8e711461039357806361d027b3146103a65780636982d815146103d35780636e707b73146103f3578063715018a614610413578063746c8ae11461042857600080fd5b80626f0231146101dd578062ae3bf8146101ff57806301f8a9761461021f5780630fb5a6b41461023f578063150b7a02146102685780631794bb3c146102a15780631959a002146102c15780631aed65531461030a5780632e1a7d4d1461032057600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612651565b610600565b005b34801561020b57600080fd5b506101fd61021a366004612450565b610759565b34801561022b57600080fd5b506101fd61023a366004612651565b6108f0565b34801561024b57600080fd5b5061025560045481565b6040519081526020015b60405180910390f35b34801561027457600080fd5b5061028861028336600461246c565b610954565b6040516001600160e01b0319909116815260200161025f565b3480156102ad57600080fd5b506101fd6102bc366004612611565b6109b5565b3480156102cd57600080fd5b506102f56102dc366004612450565b6013602052600090815260409020805460029091015482565b6040805192835260208301919091520161025f565b34801561031657600080fd5b5061025560065481565b6101fd61032e366004612651565b610b4b565b34801561033f57600080fd5b506101fd61034e366004612651565b610f0d565b34801561035f57600080fd5b5060035461036d9060ff1681565b604051901515815260200161025f565b34801561038957600080fd5b5061025560055481565b6101fd6103a1366004612531565b610fd0565b3480156103b257600080fd5b506009546103c6906001600160a01b031681565b60405161025f91906126f8565b3480156103df57600080fd5b50600b546103c6906001600160a01b031681565b3480156103ff57600080fd5b50600c546103c6906001600160a01b031681565b34801561041f57600080fd5b506101fd6112f3565b34801561043457600080fd5b506101fd61132e565b34801561044957600080fd5b506101fd611420565b34801561045e57600080fd5b50610255600f5481565b34801561047457600080fd5b506101fd610483366004612506565b611544565b34801561049457600080fd5b50610255600a5481565b3480156104aa57600080fd5b5061025560075481565b3480156104c057600080fd5b506103c6611634565b3480156104d557600080fd5b50610255600d5481565b3480156104eb57600080fd5b50610255611643565b34801561050057600080fd5b50610255600e5481565b34801561051657600080fd5b5061025560085481565b34801561052c57600080fd5b5061054061053b366004612450565b6116c9565b60405161025f929190612869565b6101fd611745565b34801561056257600080fd5b506101fd61186d565b34801561057757600080fd5b506101fd610586366004612450565b611aa5565b34801561059757600080fd5b50610255611b42565b3480156105ac57600080fd5b506102556105bb366004612450565b611beb565b3480156105cc57600080fd5b506101fd6105db366004612651565b611ca8565b3480156105ec57600080fd5b506101fd6105fb366004612651565b611e59565b33610609611634565b6001600160a01b0316146106385760405162461bcd60e51b815260040161062f9061278f565b60405180910390fd5b6000600554116106805760405162461bcd60e51b8152602060048201526013602482015272141bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b604482015260640161062f565b43600654116106cd5760405162461bcd60e51b8152602060048201526019602482015278141bdbdb081dd85cc8185b1c9958591e48199a5b9a5cda1959603a1b604482015260640161062f565b43811180156106dd575060055481115b61071d5760405162461bcd60e51b8152602060048201526011602482015270496e76616c696420656e6420626c6f636b60781b604482015260640161062f565b60068190556040518181527f0972575658363b3e7c472ab3a6a918726742c853b732f6a4a2763e2e3a94c977906020015b60405180910390a150565b33610762611634565b6001600160a01b0316146107885760405162461bcd60e51b815260040161062f9061278f565b600c546001600160a01b03828116911614156107df5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103132903932bbb0b932103a37b5b2b760511b604482015260640161062f565b476001600160a01b03821661082157604051339082156108fc029083906000818181858888f1935050505015801561081b573d6000803e3d6000fd5b506108b3565b6040516370a0823160e01b81526001600160a01b038316906370a082319061084d9030906004016126f8565b60206040518083038186803b15801561086557600080fd5b505afa158015610879573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089d9190612669565b90506108b36001600160a01b0383163383611f6f565b7f74f5dcd55c394cb1c6d3b9da22c2464bcc46c38cc3865bd629ed75823249b40b82826040516108e4929190612730565b60405180910390a15050565b336108f9611634565b6001600160a01b03161461091f5760405162461bcd60e51b815260040161062f9061278f565b60078190556040518181527f0c4d677eef92893ac7ec52faf8140fc6c851ab4736302b4f3a89dfb20696a0df9060200161074e565b600b546000906001600160a01b031633146109a35760405162461bcd60e51b815260206004820152600f60248201526e1b9bdd08195b98589b195908139195608a1b604482015260640161062f565b50630a85bd0160e11b95945050505050565b336109be611634565b6001600160a01b0316146109e45760405162461bcd60e51b815260040161062f9061278f565b60035460ff1615610a2d5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015260640161062f565b6003805460ff19166001179055600b80546001600160a01b038086166001600160a01b031992831617909255600c8054928516929091168217905560078290556040805163313ce56760e01b815290516000929163313ce567916004828101926020929190829003018186803b158015610aa657600080fd5b505afa158015610aba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade9190612681565b60ff169050601e8110610b2c5760405162461bcd60e51b815260206004820152601660248201527504d75737420626520696e666572696f7220746f2033360541b604482015260640161062f565b610b378160286129c4565b610b4290600a6128fd565b60025550505050565b60026001541415610b6e5760405162461bcd60e51b815260040161062f906127fb565b600260015580610bc05760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e742073686f756c642062652067726561746f72207468616e203000604482015260640161062f565b600e54811115610be25760405162461bcd60e51b815260040161062f906127c4565b3360009081526013602052604090208054821115610c425760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e7420746f20776974686472617720746f6f20686967680000000000604482015260640161062f565b610c4a611fca565b610c526120b2565b805415610d0c5760008160020154600254600d548460000154610c7591906129a5565b610c7f919061289a565b610c8991906129c4565b90508015610d0a5780610c9a611643565b1015610cb85760405162461bcd60e51b815260040161062f90612832565b600c54610ccf906001600160a01b03163383611f6f565b8060116000828254610ce19190612882565b90915550506040518181523390600080516020612a648339815191529060200160405180910390a25b505b60008267ffffffffffffffff811115610d3557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d5e578160200160208202803683370190505b50905060005b83811015610e875760018084018054600092610d7f916129c4565b81548110610d9d57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905083600101805480610dcb57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905580838381518110610e0257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600b54604051632142170760e11b81526001600160a01b03909116906342842e0e90610e419030903390869060040161270c565b600060405180830381600087803b158015610e5b57600080fd5b505af1158015610e6f573d6000803e3d6000fd5b50505050508080610e7f90612a07565b915050610d64565b508154610e959084906129c4565b808355600254600d549091610eaa91906129a5565b610eb4919061289a565b6002830155600f54610ec79084906129c4565b600f5560405133907f67e9df8b3c7743c9f1b625ba4f2b4e601206dbd46ed5c33c85a1242e4d23a2d190610efc908490612749565b60405180910390a250506001805550565b33610f16611634565b6001600160a01b031614610f3c5760405162461bcd60e51b815260040161062f9061278f565b6006544311610f7f5760405162461bcd60e51b815260206004820152600f60248201526e506f6f6c2069732072756e6e696e6760881b604482015260640161062f565b80610f88611643565b1015610fa65760405162461bcd60e51b815260040161062f90612832565b80610fb657610fb3611643565b90505b600c54610fcd906001600160a01b03163383611f6f565b50565b60026001541415610ff35760405162461bcd60e51b815260040161062f906127fb565b60026001556005541580159061100a575043600554105b6110565760405162461bcd60e51b815260206004820152601a60248201527f5374616b696e67206861736e2774207374617274656420796574000000000000604482015260640161062f565b60008151116110a75760405162461bcd60e51b815260206004820152601d60248201527f6d75737420616464206174206c65617374206f6e6520746f6b656e4964000000604482015260640161062f565b600e54815111156110ca5760405162461bcd60e51b815260040161062f906127c4565b6110d2611fca565b6110da6120b2565b3360009081526013602052604090208054156111a35760008160020154600254600d54846000015461110c91906129a5565b611116919061289a565b61112091906129c4565b905080156111a15780611131611643565b101561114f5760405162461bcd60e51b815260040161062f90612832565b600c54611166906001600160a01b03163383611f6f565b80601160008282546111789190612882565b90915550506040518181523390600080516020612a648339815191529060200160405180910390a25b505b60005b825181101561126c5760008382815181106111d157634e487b7160e01b600052603260045260246000fd5b6020908102919091010151600b54604051632142170760e11b81529192506001600160a01b0316906342842e0e906112119033903090869060040161270c565b600060405180830381600087803b15801561122b57600080fd5b505af115801561123f573d6000803e3d6000fd5b5050505060018381018054918201815560009081526020902001558061126481612a07565b9150506111a6565b508151815461127b9190612882565b808255600254600d54909161129091906129a5565b61129a919061289a565b60028201558151600f546112ae9190612882565b600f5560405133907fff409334d2645d660e7cfa41a637aa21f45a79ecb9660a6931aa923bf75577c7906112e3908590612749565b60405180910390a2505060018055565b336112fc611634565b6001600160a01b0316146113225760405162461bcd60e51b815260040161062f9061278f565b61132c600061214c565b565b33611337611634565b6001600160a01b03161461135d5760405162461bcd60e51b815260040161062f9061278f565b600554156113a85760405162461bcd60e51b8152602060048201526018602482015277141bdbdb081dd85cc8185b1c9958591e481cdd185c9d195960421b604482015260640161062f565b6113b3436064612882565b6005556004546113c69061191a906129a5565b6005546113d39190612882565b600681905560055460088190556040517f7cd0ab87d19036f3dfadadb232c78aa4879dda3f0c994a9d637532410ee2ce0692611416928252602082015260400190565b60405180910390a1565b33611429611634565b6001600160a01b03161461144f5760405162461bcd60e51b815260040161062f9061278f565b6114576120b2565b6000601154611464611643565b61146e9190612882565b905060125481111561150e5760125461148790826129c4565b600c5460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb906114ba9033908590600401612730565b602060405180830381600087803b1580156114d457600080fd5b505af11580156114e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150c91906125f1565b505b4360068190556040519081527ffed9fcb0ca3d1e761a4b929792bb24082fba92dca81252646ad306d3068065669060200161074e565b6009546001600160a01b0316331461159a5760405162461bcd60e51b815260206004820152601960248201527839b2ba29b2b93b34b1b2a4b733379d102327a92124a22222a760391b604482015260640161062f565b6001600160a01b0382166115e25760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161062f565b600980546001600160a01b0319166001600160a01b038416179055600a8190556040517f232f2e6280d2064b1e439bf40ecdada042d84eefbb55039e4c49e8dc4f4c90c9906108e49084908490612730565b6000546001600160a01b031690565b600c546040516370a0823160e01b81526000916001600160a01b0316906370a08231906116749030906004016126f8565b60206040518083038186803b15801561168c57600080fd5b505afa1580156116a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c49190612669565b905090565b6001600160a01b03811660009081526013602090815260408083208054600190910180548351818602810186019094528084526060949293919283919083018282801561173557602002820191906000526020600020905b815481526020019060010190808311611721575b5050505050905091509150915091565b600260015414156117685760405162461bcd60e51b815260040161062f906127fb565b6002600155336000908152601360205260409020611784611fca565b61178c6120b2565b80546117985750611867565b60008160020154600254600d5484600001546117b491906129a5565b6117be919061289a565b6117c891906129c4565b9050801561182657806117d9611643565b10156117f75760405162461bcd60e51b815260040161062f90612832565b600c5461180e906001600160a01b03163383611f6f565b80601160008282546118209190612882565b90915550505b600254600d54835461183891906129a5565b611842919061289a565b60028301556040518181523390600080516020612a64833981519152906020016112e3565b60018055565b600260015414156118905760405162461bcd60e51b815260040161062f906127fb565b60026001553360009081526013602052604090208054600e548111156118b55750600e545b60008167ffffffffffffffff8111156118de57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611907578160200160208202803683370190505b50905060005b82811015611a305760018085018054600092611928916129c4565b8154811061194657634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508460010180548061197457634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055808383815181106119ab57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600b54604051632142170760e11b81526001600160a01b03909116906342842e0e906119ea9030903390869060040161270c565b600060405180830381600087803b158015611a0457600080fd5b505af1158015611a18573d6000803e3d6000fd5b50505050508080611a2890612a07565b91505061190d565b508254611a3e9083906129c4565b808455600254600d549091611a5391906129a5565b611a5d919061289a565b6002840155600f54611a709083906129c4565b600f5560405133907f1ad6082f7aa3e32095e38fd4c0bf76fa2bb7584e81474cf3519d2dea4081181c90610efc908490612749565b33611aae611634565b6001600160a01b031614611ad45760405162461bcd60e51b815260040161062f9061278f565b6001600160a01b038116611b395760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161062f565b610fcd8161214c565b60008060125490506000601154611b57611643565b611b619190612882565b905060055460001415611b9c5761191a600454600754611b8191906129a5565b611b8b91906129a5565b611b959083612882565b9150611bca565b6000611bac60085460065461219c565b905080600754611bbc91906129a5565b611bc69084612882565b9250505b818110611bda5760009250505090565b611be481836129c4565b9250505090565b6001600160a01b0381166000908152601360205260408120600d5460085443118015611c185750600f5415155b8015611c2657506000600854115b15611c77576000611c396008544361219c565b9050600060075482611c4b91906129a5565b9050600f5460025482611c5e91906129a5565b611c68919061289a565b611c729084612882565b925050505b60028083015490548354611c8c9084906129a5565b611c96919061289a565b611ca091906129c4565b949350505050565b33611cb1611634565b6001600160a01b031614611cd75760405162461bcd60e51b815260040161062f9061278f565b600060055411611d1f5760405162461bcd60e51b81526020600482015260136024820152721c1bdbdb081a5cc81b9bdd081cdd185c9d1959606a1b604482015260640161062f565b4360065411611d6c5760405162461bcd60e51b81526020600482015260196024820152781c1bdbdb081dd85cc8185b1c9958591e48199a5b9a5cda1959603a1b604482015260640161062f565b60008111611dad5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015260640161062f565b611db56120b2565b600c54611dcd906001600160a01b03163330846121dd565b6000601154611dda611643565b611de49190612882565b9050601254811115611e5557601254611dfd90826129c4565b9050600043600654611e0f91906129c4565b9050611e1b818361289a565b60078190556040519081527f0c4d677eef92893ac7ec52faf8140fc6c851ab4736302b4f3a89dfb20696a0df9060200160405180910390a1505b5050565b33611e62611634565b6001600160a01b031614611e885760405162461bcd60e51b815260040161062f9061278f565b601e811015611ecf5760405162461bcd60e51b81526020600482015260136024820152721b1bddd95c881b1a5b5a5d081c995858da1959606a1b604482015260640161062f565b600481905560055415611f3f5761191a600454611eec91906129a5565b600554611ef99190612882565b60068190554310611f3f5760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210323ab930ba34b7b760811b604482015260640161062f565b6040518181527f91abcc2d6823e3a3f11d31b208dd3065d2c6a791f1c7c9fe96a42ce12897eac59060200161074e565b611fc58363a9059cbb60e01b8484604051602401611f8e929190612730565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612204565b505050565b600a543410156120305760405162461bcd60e51b815260206004820152602b60248201527f73686f756c642070617920736d616c6c2067617320746f20636f6d706f756e6460448201526a081bdc881a185c9d995cdd60aa1b606482015260840161062f565b600954600a546040516001600160a01b039092169181156108fc0291906000818181858888f1935050505015801561206c573d6000803e3d6000fd5b50600a5434111561132c57600a5433906108fc9061208a90346129c4565b6040518115909202916000818181858888f19350505050158015610fcd573d6000803e3d6000fd5b600854431115806120c35750600854155b156120ca57565b600f546120d75743600855565b60006120e56008544361219c565b90506000600754826120f791906129a5565b9050600f546002548261210a91906129a5565b612114919061289a565b600d60008282546121259190612882565b90915550504360085560128054829190600090612143908490612882565b90915550505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060065482116121b8576121b183836129c4565b90506121d7565b60065483106121c9575060006121d7565b826006546121b191906129c4565b92915050565b6121fe846323b872dd60e01b858585604051602401611f8e9392919061270c565b50505050565b6000612259826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122d69092919063ffffffff16565b805190915015611fc5578080602001905181019061227791906125f1565b611fc55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161062f565b60606122e584846000856122ef565b90505b9392505050565b6060824710156123505760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161062f565b843b61239e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161062f565b600080866001600160a01b031685876040516123ba91906126dc565b60006040518083038185875af1925050503d80600081146123f7576040519150601f19603f3d011682016040523d82523d6000602084013e6123fc565b606091505b509150915061240c828286612417565b979650505050505050565b606083156124265750816122e8565b8251156124365782518084602001fd5b8160405162461bcd60e51b815260040161062f919061275c565b600060208284031215612461578081fd5b81356122e881612a4e565b600080600080600060808688031215612483578081fd5b853561248e81612a4e565b9450602086013561249e81612a4e565b935060408601359250606086013567ffffffffffffffff808211156124c1578283fd5b818801915088601f8301126124d4578283fd5b8135818111156124e2578384fd5b8960208285010111156124f3578384fd5b9699959850939650602001949392505050565b60008060408385031215612518578182fd5b823561252381612a4e565b946020939093013593505050565b60006020808385031215612543578182fd5b823567ffffffffffffffff8082111561255a578384fd5b818501915085601f83011261256d578384fd5b81358181111561257f5761257f612a38565b8060051b604051601f19603f830116810181811085821117156125a4576125a4612a38565b604052828152858101935084860182860187018a10156125c2578788fd5b8795505b838610156125e45780358552600195909501949386019386016125c6565b5098975050505050505050565b600060208284031215612602578081fd5b815180151581146122e8578182fd5b600080600060608486031215612625578283fd5b833561263081612a4e565b9250602084013561264081612a4e565b929592945050506040919091013590565b600060208284031215612662578081fd5b5035919050565b60006020828403121561267a578081fd5b5051919050565b600060208284031215612692578081fd5b815160ff811681146122e8578182fd5b6000815180845260208085019450808401835b838110156126d1578151875295820195908201906001016126b5565b509495945050505050565b600082516126ee8184602087016129db565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020815260006122e860208301846126a2565b602081526000825180602084015261277b8160408501602087016129db565b601f01601f19169190910160400192915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601c908201527f63616e6e6f7420657863656564206f6e652d74696d65206c696d697400000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601a908201527f496e73756666696369656e742072657761726420746f6b656e73000000000000604082015260600190565b8281526040602082015260006122e560408301846126a2565b6000821982111561289557612895612a22565b500190565b6000826128b557634e487b7160e01b81526012600452602481fd5b500490565b600181815b808511156128f55781600019048211156128db576128db612a22565b808516156128e857918102915b93841c93908002906128bf565b509250929050565b60006122e88383600082612913575060016121d7565b81612920575060006121d7565b816001811461293657600281146129405761295c565b60019150506121d7565b60ff84111561295157612951612a22565b50506001821b6121d7565b5060208310610133831016604e8410600b841016171561297f575081810a6121d7565b61298983836128ba565b806000190482111561299d5761299d612a22565b029392505050565b60008160001904831182151516156129bf576129bf612a22565b500290565b6000828210156129d6576129d6612a22565b500390565b60005b838110156129f65781810151838201526020016129de565b838111156121fe5750506000910152565b6000600019821415612a1b57612a1b612a22565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610fcd57600080fdfe47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4a2646970667358221220c763573931201d3ae31e69400944abfc28d39955e41e12c5f4f42a851efe176c64736f6c63430008040033
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.