More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 387 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Stake Batch | 7928383 | 1 sec ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928378 | 6 secs ago | IN | 0 APE | 0.00774273 | ||||
Stake Batch | 7928374 | 11 secs ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928369 | 16 secs ago | IN | 0 APE | 0.00774273 | ||||
Stake Batch | 7928361 | 27 secs ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928356 | 34 secs ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928348 | 44 secs ago | IN | 0 APE | 0.00774273 | ||||
Stake Batch | 7928337 | 52 secs ago | IN | 0 APE | 0.00774268 | ||||
Stake Batch | 7928279 | 1 min ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928269 | 2 mins ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928258 | 2 mins ago | IN | 0 APE | 0.00774273 | ||||
Stake Batch | 7928251 | 2 mins ago | IN | 0 APE | 0.00774276 | ||||
Stake Batch | 7928241 | 2 mins ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928235 | 2 mins ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7928223 | 3 mins ago | IN | 0 APE | 0.00767155 | ||||
Stake Batch | 7927936 | 9 mins ago | IN | 0 APE | 0.00774273 | ||||
Stake Batch | 7927925 | 9 mins ago | IN | 0 APE | 0.00774237 | ||||
Stake Batch | 7927884 | 10 mins ago | IN | 0 APE | 0.00665925 | ||||
Stake Batch | 7927049 | 29 mins ago | IN | 0 APE | 0.00653721 | ||||
Stake Batch | 7926594 | 37 mins ago | IN | 0 APE | 0.0067304 | ||||
Stake Batch | 7926581 | 37 mins ago | IN | 0 APE | 0.00673043 | ||||
Stake Batch | 7926539 | 37 mins ago | IN | 0 APE | 0.0067304 | ||||
Stake Batch | 7926498 | 38 mins ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7926452 | 39 mins ago | IN | 0 APE | 0.00774271 | ||||
Stake Batch | 7926422 | 39 mins ago | IN | 0 APE | 0.00754951 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
OOGIESstaking
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity)
/** *Submitted for verification at apescan.io on 2025-01-10 */ // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @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); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; /** * @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`. * * 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; /** * @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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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 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 address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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); } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.9.0) (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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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); } } // File: contracts/OOGIESstaking.sol pragma solidity ^0.8.17; /** * @title NFTStaking * @notice Stake ERC721 tokens to earn ERC20 rewards (AFTR) from this contract's balance, * with optional locks of 30/60/90 days at higher multipliers (1.5x, 2x, 2.5x). */ contract OOGIESstaking is ReentrancyGuard, Ownable { // ---------------------------------------- // State Variables // ---------------------------------------- /// @notice The ERC721 contract whose NFTs we are staking. IERC721 public nftContract = IERC721(0x214cAE51c3BAE88515aAEfd8e1867E64502B0342); /// @notice The ERC20 token used as the reward (must be deposited into this contract). IERC20 public rewardToken = IERC20(0xA0a3b1Fdb070B4b99E76E23D983F3000F093A102); /// @notice Number of seconds in 1 day (used for integer division). uint256 public dayInSeconds = 1 days; /** * @notice Base daily reward rate (in wei). * e.g. 1 ether = 1 token/day if token has 18 decimals. */ uint256 public rewardRateNormal = 5 ether; /** * @notice Lock durations and multipliers (all editable by admin). * Example multipliers: 150 = 1.5x, 200 = 2x, 250 = 2.5x. */ uint256 public lockDuration30 = 30 days; uint256 public lockMultiplier30 = 150; // 1.5x uint256 public lockDuration60 = 60 days; uint256 public lockMultiplier60 = 200; // 2.0x uint256 public lockDuration90 = 90 days; uint256 public lockMultiplier90 = 250; // 2.5x /** * @notice NFT-specific multipliers: e.g., 150 = 1.5x, 200 = 2x. * If 0, treat it as 100 (1x). */ mapping(uint256 => uint256) public nftMultiplier; /// @notice Lock option choices enum LockOption { None, // no lock (normal staking) Lock30, // 30-day lock at lockMultiplier30 Lock60, // 60-day lock at lockMultiplier60 Lock90 // 90-day lock at lockMultiplier90 } /// @notice Info about each staked NFT. struct StakedNFT { address owner; // who staked it uint256 tokenId; // which token uint256 stakedAt; // when it was staked uint256 lastClaimedAt; // last time rewards were claimed LockOption lockOption; // which lock type uint256 lockStartedAt; // when current lock was set } /// @notice tokenId => staking info mapping(uint256 => StakedNFT) public stakedNFTs; /// @notice Keep track of all currently staked tokenIds (for enumerations). uint256[] private allStakedTokenIds; /// @notice tokenId => index in allStakedTokenIds mapping(uint256 => uint256) private allStakedTokenIndex; /// @notice For easy lookup of which tokenIds a user has staked. mapping(address => uint256[]) private userStakedTokens; /// @notice tokenId => index in userStakedTokens[user] mapping(uint256 => uint256) private userStakedTokensIndex; // ---------------------------------------- // Events // ---------------------------------------- event Staked(address indexed user, uint256 tokenId, LockOption lockOption); event Unstaked(address indexed user, uint256 tokenId); event RewardClaimed(address indexed user, uint256 tokenId, uint256 amount); event LockOptionChanged(address indexed user, uint256 tokenId, LockOption newLockOption); event TokensDeposited(address indexed from, uint256 amount); // ---------------------------------------- // Constructor // ---------------------------------------- constructor(address _initialOwner) Ownable(_initialOwner) {} // ---------------------------------------- // Owner-Only Functions // ---------------------------------------- function setNftContract(IERC721 _nftContract) external onlyOwner { nftContract = _nftContract; } function setRewardToken(IERC20 _rewardToken) external onlyOwner { rewardToken = _rewardToken; } function setDayInSeconds(uint256 _seconds) external onlyOwner { dayInSeconds = _seconds; } function setRewardRateNormal(uint256 _normal) external onlyOwner { rewardRateNormal = _normal; } /** * @notice Update lock durations and/or multipliers for 30, 60, and 90 days. * Example multipliers: 150 => 1.5x, 200 => 2x, 250 => 2.5x. */ function setLockParams( uint256 _lockDuration30, uint256 _lockMultiplier30, uint256 _lockDuration60, uint256 _lockMultiplier60, uint256 _lockDuration90, uint256 _lockMultiplier90 ) external onlyOwner { lockDuration30 = _lockDuration30; lockMultiplier30 = _lockMultiplier30; lockDuration60 = _lockDuration60; lockMultiplier60 = _lockMultiplier60; lockDuration90 = _lockDuration90; lockMultiplier90 = _lockMultiplier90; } /** * @notice Set multipliers for multiple NFTs at once. * @param _tokenIds array of token IDs * @param _multipliers array of multipliers (e.g. 150 = 1.5x), must match length of _tokenIds */ function setNFTMultiplierBatch(uint256[] calldata _tokenIds, uint256[] calldata _multipliers) external onlyOwner { require(_tokenIds.length == _multipliers.length, "Array length mismatch"); for (uint256 i = 0; i < _tokenIds.length; i++) { nftMultiplier[_tokenIds[i]] = _multipliers[i]; } } // ---------------------------------- // Rescue functions // ---------------------------------- function rescueNative(uint256 _amount) external onlyOwner { require(address(this).balance >= _amount, "Not enough native balance"); payable(msg.sender).transfer(_amount); } function rescueERC20(address _token, uint256 _amount) external onlyOwner { IERC20(_token).transfer(msg.sender, _amount); } // ---------------------------------------- // Deposit Rewards (ERC20) // ---------------------------------------- function depositTokens(uint256 amount) external nonReentrant { require(amount > 0, "Cannot deposit 0"); bool success = rewardToken.transferFrom(msg.sender, address(this), amount); require(success, "transferFrom failed"); emit TokensDeposited(msg.sender, amount); } function getContractBalance() external view returns (uint256) { return rewardToken.balanceOf(address(this)); } // ---------------------------------------- // Batch Operations // ---------------------------------------- /** * @notice Stake multiple NFTs at once with a chosen lock option (None, Lock30, Lock60, Lock90). * @param _tokenIds array of token IDs * @param _lockOptions array of lock options */ function stakeBatch(uint256[] calldata _tokenIds, LockOption[] calldata _lockOptions) external nonReentrant { require(_tokenIds.length == _lockOptions.length, "Array length mismatch"); for (uint256 i = 0; i < _tokenIds.length; i++) { _stakeInternal(_tokenIds[i], _lockOptions[i]); } } /** * @notice Unstake multiple NFTs at once. * Reverts if the lock period has not ended yet. */ function unstakeBatch(uint256[] calldata _tokenIds) external nonReentrant { for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 tokenId = _tokenIds[i]; require(stakedNFTs[tokenId].owner == msg.sender, "Not staker"); _unstakeInternal(tokenId); } } /** * @notice Claim rewards for multiple NFTs at once. */ function claimRewardsBatch(uint256[] calldata _tokenIds) external nonReentrant { for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 tokenId = _tokenIds[i]; require(stakedNFTs[tokenId].owner == msg.sender, "Not staker"); _claimRewards(tokenId); } } /** * @notice Lock multiple NFTs that are currently staked but unlocked (None). * Or if they were locked and the lock is finished, this also acts as “re-lock.” * @dev If the lock is still active and not finished, this will revert. */ function lockStakedNFTBatch(uint256[] calldata _tokenIds, LockOption[] calldata _lockOptions) external nonReentrant { require(_tokenIds.length == _lockOptions.length, "Array length mismatch"); for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 tokenId = _tokenIds[i]; require(stakedNFTs[tokenId].owner == msg.sender, "Not staker"); _lockStakedNFTInternal(tokenId, _lockOptions[i]); } } /** * @notice Re-lock multiple NFTs (choose any lock option) once your previous lock ended. * @dev If lock not ended, will revert; if not locked at all, will revert. */ function reLockBatch(uint256[] calldata _tokenIds, LockOption[] calldata _newLockOptions) external nonReentrant { require(_tokenIds.length == _newLockOptions.length, "Array length mismatch"); for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 tokenId = _tokenIds[i]; require(stakedNFTs[tokenId].owner == msg.sender, "Not staker"); _reLockInternal(tokenId, _newLockOptions[i]); } } // ---------------------------------------- // Batch Views (Claimable Rewards, etc.) // ---------------------------------------- /** * @notice Returns an array of claimable rewards for the given NFT IDs, in the same order. */ function claimableRewardsBatch(uint256[] calldata _tokenIds) external view returns (uint256[] memory) { uint256[] memory amounts = new uint256[](_tokenIds.length); for (uint256 i = 0; i < _tokenIds.length; i++) { amounts[i] = _claimableRewardsView(_tokenIds[i]); } return amounts; } /** * @notice Returns how many tokens (AFTR) this user generates per full day * across all staked NFTs, factoring in lock options and NFT multipliers. */ function generatingPerDay(address _user) external view returns (uint256) { uint256 totalDailyRate = 0; uint256[] memory tokenIds = userStakedTokens[_user]; for (uint256 i = 0; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; StakedNFT storage info = stakedNFTs[tokenId]; // sanity check if (info.owner != _user) continue; // figure out if still in lock period (uint256 chosenLockMult, bool inLock) = _getLockMultiplierAndStatus(info); uint256 baseDaily; if (inLock) { // still in lock => base rate * chosenLockMult baseDaily = (rewardRateNormal * chosenLockMult) / 100; } else { // not locked or lock ended => normal rate baseDaily = rewardRateNormal; } // apply NFT-specific multiplier uint256 nftMult = nftMultiplier[tokenId]; if (nftMult == 0) nftMult = 100; uint256 finalRate = (baseDaily * nftMult) / 100; totalDailyRate += finalRate; } return totalDailyRate; } // ---------------------------------------- // Internal (Single-Token) Logic // ---------------------------------------- // Called by the batch functions above. function _stakeInternal(uint256 _tokenId, LockOption _lockOption) internal { // Transfer NFT from user to this contract nftContract.transferFrom(msg.sender, address(this), _tokenId); // Record staking info StakedNFT storage info = stakedNFTs[_tokenId]; info.owner = msg.sender; info.tokenId = _tokenId; info.stakedAt = block.timestamp; info.lastClaimedAt = block.timestamp; info.lockOption = _lockOption; info.lockStartedAt = (_lockOption == LockOption.None) ? 0 : block.timestamp; // Add to global and user tracking _addToAllStakedTokenIds(_tokenId); _addToUserStakedTokens(msg.sender, _tokenId); emit Staked(msg.sender, _tokenId, _lockOption); } function _unstakeInternal(uint256 _tokenId) internal { StakedNFT storage info = stakedNFTs[_tokenId]; // if locked, ensure lock period ended if (info.lockOption != LockOption.None) { uint256 lockEnd = info.lockStartedAt + _getLockDuration(info.lockOption); require(block.timestamp >= lockEnd, "Lock period not over. Cannot unstake yet."); } // claim all rewards up to now _claimRewards(_tokenId); // transfer NFT back nftContract.transferFrom(address(this), info.owner, _tokenId); // cleanup _removeFromAllStakedTokenIds(_tokenId); _removeFromUserStakedTokens(info.owner, _tokenId); delete stakedNFTs[_tokenId]; emit Unstaked(info.owner, _tokenId); } /** * @dev Lock an NFT that is currently staked but: * - either has never been locked (lockOption == None), or * - was locked and its lock period is finished (so effectively “re-lock”). * If it's still locked and not finished, this reverts. */ function _lockStakedNFTInternal(uint256 _tokenId, LockOption _newLockOption) internal { StakedNFT storage info = stakedNFTs[_tokenId]; // Must be staked require(info.owner != address(0), "Not staked"); // If it's currently locked, check if the lock ended if (info.lockOption != LockOption.None) { uint256 lockEnd = info.lockStartedAt + _getLockDuration(info.lockOption); require(block.timestamp >= lockEnd, "Current lock not finished"); } // First claim everything earned so far (including any unlocked days) _claimRewards(_tokenId); // Set new lock info.lockOption = _newLockOption; info.lockStartedAt = block.timestamp; info.lastClaimedAt = block.timestamp; // so we start fresh emit LockOptionChanged(info.owner, _tokenId, _newLockOption); } /** * @dev Re-lock an NFT that was already locked, picking a new lock option * after the old lock has ended. Reverts if lock not over or was never locked. */ function _reLockInternal(uint256 _tokenId, LockOption _newLockOption) internal { StakedNFT storage info = stakedNFTs[_tokenId]; // Must already be locked with some option require(info.lockOption != LockOption.None, "NFT not currently locked"); // Ensure old lock ended uint256 lockEnd = info.lockStartedAt + _getLockDuration(info.lockOption); require(block.timestamp >= lockEnd, "Current lock not finished"); // Claim all rewards up to now _claimRewards(_tokenId); // Re-lock with the new option info.lockOption = _newLockOption; info.lockStartedAt = block.timestamp; info.lastClaimedAt = block.timestamp; emit LockOptionChanged(info.owner, _tokenId, _newLockOption); } // ---------------------------------------- // Reward Logic // ---------------------------------------- /** * @dev Internal function to calculate and transfer rewards from the contract’s balance. */ function _claimRewards(uint256 _tokenId) internal returns (uint256) { StakedNFT storage info = stakedNFTs[_tokenId]; uint256 currentTime = block.timestamp; uint256 lastClaimed = info.lastClaimedAt; // no time passed => no rewards if (currentTime <= lastClaimed) { return 0; } uint256 timeDiff = currentTime - lastClaimed; uint256 totalReward = 0; // figure out lock end uint256 lockEnd = (info.lockOption == LockOption.None) ? 0 : (info.lockStartedAt + _getLockDuration(info.lockOption)); // break the time into possible segments: locked vs. unlocked if (info.lockOption != LockOption.None) { // some lock option if (lastClaimed < lockEnd) { // portion in lock uint256 lockedSegmentEnd = (currentTime < lockEnd) ? currentTime : lockEnd; uint256 lockedTime = (lockedSegmentEnd > lastClaimed) ? lockedSegmentEnd - lastClaimed : 0; uint256 lockedDays = lockedTime / dayInSeconds; uint256 lockedMult = _getLockMultiplier(info.lockOption); // locked portion daily rate = rewardRateNormal * lockedMult/100 // we apply the NFT multiplier below uint256 lockedDailyRate = (rewardRateNormal * lockedMult) / 100; // NFT-specific multiplier uint256 nftMult = nftMultiplier[_tokenId]; if (nftMult == 0) nftMult = 100; // final locked portion = lockedDays * lockedDailyRate * (nftMult/100) uint256 lockedReward = lockedDays * ((lockedDailyRate * nftMult) / 100); totalReward += lockedReward; // portion after lock (if currentTime > lockEnd) if (currentTime > lockEnd) { uint256 postLockTime = currentTime - lockEnd; uint256 postLockDays = postLockTime / dayInSeconds; // post-lock daily rate => normal rate * NFT multiplier uint256 postLockDailyRate = (rewardRateNormal * nftMult) / 100; totalReward += postLockDays * postLockDailyRate; } } else { // entire interval is after lock ended uint256 daysCount = timeDiff / dayInSeconds; uint256 nftMult = nftMultiplier[_tokenId]; if (nftMult == 0) nftMult = 100; uint256 postLockDaily = (rewardRateNormal * nftMult) / 100; totalReward += daysCount * postLockDaily; } } else { // no lock => purely normal uint256 daysCount = timeDiff / dayInSeconds; uint256 nftMult = nftMultiplier[_tokenId]; if (nftMult == 0) nftMult = 100; uint256 daily = (rewardRateNormal * nftMult) / 100; totalReward += daysCount * daily; } // update lastClaimed info.lastClaimedAt = currentTime; // transfer from contract to staker if (totalReward > 0) { uint256 contractBal = rewardToken.balanceOf(address(this)); require(contractBal >= totalReward, "Not enough reward tokens in contract"); rewardToken.transfer(info.owner, totalReward); emit RewardClaimed(info.owner, _tokenId, totalReward); } return totalReward; } /** * @dev View-only version of claiming logic (no state changes). */ function _claimableRewardsView(uint256 _tokenId) internal view returns (uint256) { StakedNFT storage info = stakedNFTs[_tokenId]; if (info.owner == address(0)) return 0; // not staked uint256 currentTime = block.timestamp; uint256 lastClaimed = info.lastClaimedAt; if (currentTime <= lastClaimed) return 0; uint256 timeDiff = currentTime - lastClaimed; uint256 totalReward = 0; uint256 lockEnd = (info.lockOption == LockOption.None) ? 0 : (info.lockStartedAt + _getLockDuration(info.lockOption)); if (info.lockOption != LockOption.None) { if (lastClaimed < lockEnd) { uint256 lockedSegmentEnd = (currentTime < lockEnd) ? currentTime : lockEnd; uint256 lockedTime = (lockedSegmentEnd > lastClaimed) ? lockedSegmentEnd - lastClaimed : 0; uint256 lockedDays = lockedTime / dayInSeconds; uint256 lockedMult = _getLockMultiplier(info.lockOption); uint256 lockedDailyRate = (rewardRateNormal * lockedMult) / 100; uint256 nftMult = nftMultiplier[_tokenId]; if (nftMult == 0) nftMult = 100; uint256 lockedReward = lockedDays * ((lockedDailyRate * nftMult) / 100); totalReward += lockedReward; if (currentTime > lockEnd) { uint256 postLockTime = currentTime - lockEnd; uint256 postLockDays = postLockTime / dayInSeconds; uint256 postLockDaily = (rewardRateNormal * nftMult) / 100; totalReward += postLockDays * postLockDaily; } } else { // entire interval after lock uint256 daysCount = timeDiff / dayInSeconds; uint256 nftMult = nftMultiplier[_tokenId]; if (nftMult == 0) nftMult = 100; uint256 postLockDaily = (rewardRateNormal * nftMult) / 100; totalReward += daysCount * postLockDaily; } } else { // no lock uint256 daysCount = timeDiff / dayInSeconds; uint256 nftMult = nftMultiplier[_tokenId]; if (nftMult == 0) nftMult = 100; uint256 daily = (rewardRateNormal * nftMult) / 100; totalReward += daysCount * daily; } return totalReward; } // ---------------------------------------- // View Functions (Enumeration, etc.) // ---------------------------------------- function totalStaked() external view returns (uint256) { return allStakedTokenIds.length; } function getAllStakedNFTs() external view returns (StakedNFT[] memory) { uint256 length = allStakedTokenIds.length; StakedNFT[] memory result = new StakedNFT[](length); for (uint256 i = 0; i < length; i++) { uint256 tokenId = allStakedTokenIds[i]; result[i] = stakedNFTs[tokenId]; } return result; } function getStakedNFTsOf(address _wallet) external view returns (StakedNFT[] memory) { uint256[] storage tokenIds = userStakedTokens[_wallet]; uint256 length = tokenIds.length; StakedNFT[] memory result = new StakedNFT[](length); for (uint256 i = 0; i < length; i++) { uint256 tokenId = tokenIds[i]; result[i] = stakedNFTs[tokenId]; } return result; } // ---------------------------------------- // Internal Helpers // ---------------------------------------- function _addToAllStakedTokenIds(uint256 _tokenId) internal { allStakedTokenIndex[_tokenId] = allStakedTokenIds.length; allStakedTokenIds.push(_tokenId); } function _removeFromAllStakedTokenIds(uint256 _tokenId) internal { uint256 idx = allStakedTokenIndex[_tokenId]; uint256 lastIndex = allStakedTokenIds.length - 1; if (idx != lastIndex) { uint256 lastTokenId = allStakedTokenIds[lastIndex]; allStakedTokenIds[idx] = lastTokenId; allStakedTokenIndex[lastTokenId] = idx; } allStakedTokenIds.pop(); delete allStakedTokenIndex[_tokenId]; } function _addToUserStakedTokens(address _user, uint256 _tokenId) internal { userStakedTokensIndex[_tokenId] = userStakedTokens[_user].length; userStakedTokens[_user].push(_tokenId); } function _removeFromUserStakedTokens(address _user, uint256 _tokenId) internal { uint256 idx = userStakedTokensIndex[_tokenId]; uint256 lastIndex = userStakedTokens[_user].length - 1; if (idx != lastIndex) { uint256 lastTokenId = userStakedTokens[_user][lastIndex]; userStakedTokens[_user][idx] = lastTokenId; userStakedTokensIndex[lastTokenId] = idx; } userStakedTokens[_user].pop(); delete userStakedTokensIndex[_tokenId]; } /** * @dev Returns the configured lock duration (in seconds) for the chosen option. */ function _getLockDuration(LockOption option) internal view returns (uint256) { if (option == LockOption.Lock30) { return lockDuration30; } else if (option == LockOption.Lock60) { return lockDuration60; } else if (option == LockOption.Lock90) { return lockDuration90; } return 0; } /** * @dev Returns the lock multiplier (e.g. 150 => 1.5×) for the chosen lock option. */ function _getLockMultiplier(LockOption option) internal view returns (uint256) { if (option == LockOption.Lock30) { return lockMultiplier30; } else if (option == LockOption.Lock60) { return lockMultiplier60; } else if (option == LockOption.Lock90) { return lockMultiplier90; } return 100; // None => normal } /** * @dev Helper to see if a given staked NFT is still within its lock period, * plus the chosen lock multiplier. */ function _getLockMultiplierAndStatus( StakedNFT storage info ) internal view returns (uint256 chosenMultiplier, bool stillInLock) { if (info.lockOption == LockOption.None) { return (100, false); } uint256 duration = _getLockDuration(info.lockOption); uint256 endTime = info.lockStartedAt + duration; bool inLockPeriod = (block.timestamp < endTime); uint256 lockMult = _getLockMultiplier(info.lockOption); return (lockMult, inLockPeriod); } /** * @notice Forcibly return an array of staked NFTs to their respective owners. * No rewards are claimed or paid. Resets all internal tracking. * @param _tokenIds Array of token IDs to be returned. */ function emergencyReturnBatch(uint256[] calldata _tokenIds) external onlyOwner nonReentrant { for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 tokenId = _tokenIds[i]; StakedNFT storage info = stakedNFTs[tokenId]; // If it's actually staked (owner != address(0)) if (info.owner != address(0)) { // Transfer NFT back to staker nftContract.transferFrom(address(this), info.owner, tokenId); // Remove from global array _removeFromAllStakedTokenIds(tokenId); // Remove from user array _removeFromUserStakedTokens(info.owner, tokenId); // Clear staking info (no rewards) delete stakedNFTs[tokenId]; } } } /** * @notice Forcibly return ALL currently staked NFTs to their respective owners. * No rewards are claimed or paid. Resets all internal tracking for each NFT. */ function emergencyReturnAllStaked() external onlyOwner nonReentrant { // Keep removing from the end of allStakedTokenIds until empty while (allStakedTokenIds.length > 0) { uint256 lastIndex = allStakedTokenIds.length - 1; uint256 tokenId = allStakedTokenIds[lastIndex]; StakedNFT storage info = stakedNFTs[tokenId]; if (info.owner != address(0)) { // Transfer NFT back to staker nftContract.transferFrom(address(this), info.owner, tokenId); // Remove from user array _removeFromUserStakedTokens(info.owner, tokenId); // Clear staking info delete stakedNFTs[tokenId]; } // Finally remove it from the global array allStakedTokenIds.pop(); } } /** * @notice Allow contract owner to withdraw any NFT directly to their own wallet, * ignoring normal staking rules. Use with care! * @param _tokenId Token ID to withdraw to the owner's wallet. */ function emergencyWithdrawNFT(uint256 _tokenId) external onlyOwner nonReentrant { nftContract.transferFrom(address(this), owner(), _tokenId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"enum OOGIESstaking.LockOption","name":"newLockOption","type":"uint8"}],"name":"LockOptionChanged","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":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"claimRewardsBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"claimableRewardsBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dayInSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyReturnAllStaked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"emergencyReturnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"emergencyWithdrawNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"generatingPerDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllStakedNFTs","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"stakedAt","type":"uint256"},{"internalType":"uint256","name":"lastClaimedAt","type":"uint256"},{"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"},{"internalType":"uint256","name":"lockStartedAt","type":"uint256"}],"internalType":"struct OOGIESstaking.StakedNFT[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getStakedNFTsOf","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"stakedAt","type":"uint256"},{"internalType":"uint256","name":"lastClaimedAt","type":"uint256"},{"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"},{"internalType":"uint256","name":"lockStartedAt","type":"uint256"}],"internalType":"struct OOGIESstaking.StakedNFT[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDuration30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDuration60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDuration90","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMultiplier30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMultiplier60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMultiplier90","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum OOGIESstaking.LockOption[]","name":"_lockOptions","type":"uint8[]"}],"name":"lockStakedNFTBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nftContract","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftMultiplier","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":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum OOGIESstaking.LockOption[]","name":"_newLockOptions","type":"uint8[]"}],"name":"reLockBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rescueNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardRateNormal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_seconds","type":"uint256"}],"name":"setDayInSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockDuration30","type":"uint256"},{"internalType":"uint256","name":"_lockMultiplier30","type":"uint256"},{"internalType":"uint256","name":"_lockDuration60","type":"uint256"},{"internalType":"uint256","name":"_lockMultiplier60","type":"uint256"},{"internalType":"uint256","name":"_lockDuration90","type":"uint256"},{"internalType":"uint256","name":"_lockMultiplier90","type":"uint256"}],"name":"setLockParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_multipliers","type":"uint256[]"}],"name":"setNFTMultiplierBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"_nftContract","type":"address"}],"name":"setNftContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_normal","type":"uint256"}],"name":"setRewardRateNormal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_rewardToken","type":"address"}],"name":"setRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum OOGIESstaking.LockOption[]","name":"_lockOptions","type":"uint8[]"}],"name":"stakeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakedNFTs","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"stakedAt","type":"uint256"},{"internalType":"uint256","name":"lastClaimedAt","type":"uint256"},{"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"},{"internalType":"uint256","name":"lockStartedAt","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"unstakeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600280546001600160a01b031990811673214cae51c3bae88515aaefd8e1867e64502b0342179091556003805490911673a0a3b1fdb070b4b99e76e23d983f3000f093a10217905562015180600455674563918244f4000060055562278d006006556096600755624f1a0060085560c86009556276a700600a5560fa600b553480156200008f575f80fd5b5060405162002b5238038062002b52833981016040819052620000b29162000149565b60015f55806001600160a01b038116620000e557604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b620000f081620000f8565b505062000178565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f602082840312156200015a575f80fd5b81516001600160a01b038116811462000171575f80fd5b9392505050565b6129cc80620001865f395ff3fe608060405234801561000f575f80fd5b5060043610610229575f3560e01c80638da5cb5b1161012a578063dbb7a621116100b4578063f7c618c111610079578063f7c618c1146104c9578063f7e455d7146104dc578063fae40fa0146104fc578063fb64455b14610505578063ffd2d8291461050d575f80fd5b8063dbb7a62114610475578063dd49756e1461047d578063e64a21f314610490578063efdd78e1146104a3578063f2fde38b146104b6575f80fd5b8063b2040612116100fa578063b2040612146103cf578063b865749d146103d8578063bf4bac391461043c578063d3abfe121461044f578063d56d229d14610462575f80fd5b80638da5cb5b1461038f57806399ba918d146103b45780639ce98f0e146103bd578063ae63586c146103c6575f80fd5b806370becf5d116101b6578063817b1cd21161017b578063817b1cd21461032e578063888ce4af1461033657806388c0771b146103565780638aee8127146103695780638cd4426d1461037c575f80fd5b806370becf5d146102d8578063715018a6146102e1578063760edace146102e95780637dc3db8f146102fc5780637f4ca1d71461030f575f80fd5b8063454aa669116101fc578063454aa6691461028457806352f5ad7714610297578063646e6f8b146102aa57806366e4664a146102bd5780636f9fb98a146102d0575f80fd5b80630dfa1e961461022d578063224eb12914610249578063398612b81461025e5780633af7a79514610271575b5f80fd5b61023660085481565b6040519081526020015b60405180910390f35b61025c610257366004612523565b610516565b005b61025c61026c366004612582565b610523565b61025c61027f366004612582565b6105fd565b61025c610292366004612523565b610684565b61025c6102a53660046125fd565b61070a565b61025c6102b836600461261f565b610734565b61025c6102cb366004612582565b6107ba565b61023661083b565b610236600a5481565b61025c6108aa565b6102366102f73660046125fd565b6108bd565b61025c61030a366004612523565b610a0e565b61023661031d366004612523565b600c6020525f908152604090205481565b600e54610236565b6103496103443660046125fd565b610a1b565b6040516102409190612692565b61025c610364366004612523565b610b6c565b61025c6103773660046125fd565b610bf8565b61025c61038a36600461271c565b610c22565b6001546001600160a01b03165b6040516001600160a01b039091168152602001610240565b61023660055481565b61023660065481565b61023660045481565b610236600b5481565b61042a6103e6366004612523565b600d6020525f90815260409020805460018201546002830154600384015460048501546005909501546001600160a01b039094169492939192909160ff9091169086565b60405161024096959493929190612746565b61025c61044a366004612582565b610c9d565b61025c61045d36600461261f565b610d5e565b60025461039c906001600160a01b031681565b61025c610e87565b61025c61048b366004612523565b610fe5565b61025c61049e36600461261f565b611127565b61025c6104b1366004612789565b6111a2565b61025c6104c43660046125fd565b6111c7565b60035461039c906001600160a01b031681565b6104ef6104ea36600461261f565b611201565b60405161024091906127c8565b61023660095481565b6103496112a3565b61023660075481565b61051e6113de565b600455565b61052b61140b565b8281146105535760405162461bcd60e51b815260040161054a9061280b565b60405180910390fd5b5f5b838110156105ed575f8585838181106105705761057061283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146105b45760405162461bcd60e51b815260040161054a9061284e565b6105e4818585858181106105ca576105ca61283a565b90506020020160208101906105df9190612872565b611462565b50600101610555565b506105f760015f55565b50505050565b6106056113de565b8281146106245760405162461bcd60e51b815260040161054a9061280b565b5f5b8381101561067d578282828181106106405761064061283a565b90506020020135600c5f87878581811061065c5761065c61283a565b602090810292909201358352508101919091526040015f2055600101610626565b5050505050565b61068c6113de565b804710156106dc5760405162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f756768206e61746976652062616c616e636500000000000000604482015260640161054a565b604051339082156108fc029083905f818181858888f19350505050158015610706573d5f803e3d5ffd5b5050565b6107126113de565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b61073c61140b565b5f5b818110156107b0575f8383838181106107595761075961283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b0316331461079d5760405162461bcd60e51b815260040161054a9061284e565b6107a6816115ce565b505060010161073e565b5061070660015f55565b6107c261140b565b8281146107e15760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed576108338585838181106108005761080061283a565b905060200201358484848181106108195761081961283a565b905060200201602081019061082e9190612872565b6119fa565b6001016107e3565b6003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610881573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a59190612890565b905090565b6108b26113de565b6108bb5f611b87565b565b6001600160a01b0381165f90815260106020908152604080832080548251818502810185019093528083528493849392919083018282801561091c57602002820191905f5260205f20905b815481526020019060010190808311610908575b505050505090505f5b8151811015610a05575f8282815181106109415761094161283a565b6020908102919091018101515f818152600d90925260409091208054919250906001600160a01b0388811691161461097a5750506109fd565b5f8061098583611bd8565b915091505f81156109b1576064836005546109a091906128bb565b6109aa91906128d2565b90506109b6565b506005545b5f858152600c6020526040812054908190036109d0575060645b5f60646109dd83856128bb565b6109e791906128d2565b90506109f3818b6128f1565b9950505050505050505b600101610925565b50909392505050565b610a166113de565b600555565b6001600160a01b0381165f90815260106020526040812080546060928167ffffffffffffffff811115610a5057610a50612904565b604051908082528060200260200182016040528015610a8957816020015b610a766124d9565b815260200190600190039081610a6e5790505b5090505f5b82811015610b63575f848281548110610aa957610aa961283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff1690811115610b1e57610b1e61265e565b6003811115610b2f57610b2f61265e565b8152602001600582015481525050838381518110610b4f57610b4f61283a565b602090810291909101015250600101610a8e565b50949350505050565b610b746113de565b610b7c61140b565b6002546001600160a01b03166323b872dd30610ba06001546001600160a01b031690565b846040518463ffffffff1660e01b8152600401610bbf93929190612918565b5f604051808303815f87803b158015610bd6575f80fd5b505af1158015610be8573d5f803e3d5ffd5b50505050610bf560015f55565b50565b610c006113de565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b610c2a6113de565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303815f875af1158015610c74573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c98919061293c565b505050565b610ca561140b565b828114610cc45760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed575f858583818110610ce157610ce161283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b03163314610d255760405162461bcd60e51b815260040161054a9061284e565b610d5581858585818110610d3b57610d3b61283a565b9050602002016020810190610d509190612872565b611c51565b50600101610cc6565b610d666113de565b610d6e61140b565b5f5b818110156107b0575f838383818110610d8b57610d8b61283a565b602090810292909201355f818152600d90935260409092208054929350916001600160a01b0316159050610e7d5760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610df1923092909116908790600401612918565b5f604051808303815f87803b158015610e08575f80fd5b505af1158015610e1a573d5f803e3d5ffd5b50505050610e2782611dc0565b8054610e3c906001600160a01b031683611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b5050600101610d70565b610e8f6113de565b610e9761140b565b600e5415610fdc57600e545f90610eb09060019061295b565b90505f600e8281548110610ec657610ec661283a565b5f918252602080832090910154808352600d90915260409091208054919250906001600160a01b031615610fb05760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610f2c923092909116908790600401612918565b5f604051808303815f87803b158015610f43575f80fd5b505af1158015610f55573d5f803e3d5ffd5b50508254610f6f92506001600160a01b0316905083611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b600e805480610fc157610fc161296e565b600190038181905f5260205f20015f90559055505050610e97565b6108bb60015f55565b610fed61140b565b5f811161102f5760405162461bcd60e51b815260206004820152601060248201526f043616e6e6f74206465706f73697420360841b604482015260640161054a565b6003546040516323b872dd60e01b81525f916001600160a01b0316906323b872dd9061106390339030908790600401612918565b6020604051808303815f875af115801561107f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a3919061293c565b9050806110e85760405162461bcd60e51b81526020600482015260136024820152721d1c985b9cd9995c919c9bdb4819985a5b1959606a1b604482015260640161054a565b60405182815233907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e9060200160405180910390a250610bf560015f55565b61112f61140b565b5f5b818110156107b0575f83838381811061114c5761114c61283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146111905760405162461bcd60e51b815260040161054a9061284e565b61119981611f8c565b50600101611131565b6111aa6113de565b600695909555600793909355600891909155600955600a55600b55565b6111cf6113de565b6001600160a01b0381166111f857604051631e4fbdf760e01b81525f600482015260240161054a565b610bf581611b87565b60605f8267ffffffffffffffff81111561121d5761121d612904565b604051908082528060200260200182016040528015611246578160200160208202803683370190505b5090505f5b83811015611299576112748585838181106112685761126861283a565b90506020020135612155565b8282815181106112865761128661283a565b602090810291909101015260010161124b565b5090505b92915050565b600e546060905f8167ffffffffffffffff8111156112c3576112c3612904565b6040519080825280602002602001820160405280156112fc57816020015b6112e96124d9565b8152602001906001900390816112e15790505b5090505f5b828110156113d7575f600e828154811061131d5761131d61283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff16908111156113925761139261265e565b60038111156113a3576113a361265e565b81526020016005820154815250508383815181106113c3576113c361283a565b602090810291909101015250600101611301565b5092915050565b6001546001600160a01b031633146108bb5760405163118cdaa760e01b815233600482015260240161054a565b60025f540361145c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161054a565b60025f55565b5f828152600d6020526040902080546001600160a01b03166114b35760405162461bcd60e51b815260206004820152600a602482015269139bdd081cdd185ad95960b21b604482015260640161054a565b5f600482015460ff1660038111156114cd576114cd61265e565b146115445760048101545f906114e59060ff16612402565b82600501546114f491906128f1565b9050804210156115425760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b505b61154d836115ce565b5060048101805483919060ff1916600183600381111561156f5761156f61265e565b02179055504260058201819055600382015580546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f3906115c19086908690612982565b60405180910390a2505050565b5f818152600d60205260408120600381015442908082116115f357505f949350505050565b5f6115fe828461295b565b90505f8080600487015460ff16600381111561161c5761161c61265e565b146116465760048601546116329060ff16612402565b866005015461164191906128f1565b611648565b5f5b90505f600487015460ff1660038111156116645761166461265e565b146117f95780841015611793575f81861061167f5781611681565b855b90505f858211611691575f61169b565b61169b868361295b565b90505f600454826116ac91906128d2565b60048a01549091505f906116c29060ff1661246d565b90505f6064826005546116d591906128bb565b6116df91906128d2565b5f8e8152600c60205260408120549192508190036116fb575060645b5f606461170883856128bb565b61171291906128d2565b61171c90866128bb565b9050611728818a6128f1565b9850878c1115611787575f61173d898e61295b565b90505f6004548261174e91906128d2565b90505f60648560055461176191906128bb565b61176b91906128d2565b905061177781836128bb565b611781908d6128f1565b9b505050505b5050505050505061185b565b5f600454846117a291906128d2565b5f8a8152600c60205260408120549192508190036117be575060645b5f6064826005546117cf91906128bb565b6117d991906128d2565b90506117e581846128bb565b6117ef90866128f1565b945050505061185b565b5f6004548461180891906128d2565b5f8a8152600c6020526040812054919250819003611824575060645b5f60648260055461183591906128bb565b61183f91906128d2565b905061184b81846128bb565b61185590866128f1565b94505050505b6003860185905581156119ef576003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa1580156118ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118d29190612890565b9050828110156119305760405162461bcd60e51b8152602060048201526024808201527f4e6f7420656e6f7567682072657761726420746f6b656e7320696e20636f6e746044820152631c9858dd60e21b606482015260840161054a565b600354875460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905291169063a9059cbb906044016020604051808303815f875af1158015611981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119a5919061293c565b508654604080518b8152602081018690526001600160a01b03909216917ff01da32686223933d8a18a391060918c7f11a3648639edd87ae013e2e2731743910160405180910390a2505b509695505050505050565b6002546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611a2e90339030908790600401612918565b5f604051808303815f87803b158015611a45575f80fd5b505af1158015611a57573d5f803e3d5ffd5b5050505f838152600d6020526040902080546001600160a01b03191633178155600180820185905542600283018190556003808401919091556004830180549394508593909260ff19909116918490811115611ab557611ab561265e565b02179055505f826003811115611acd57611acd61265e565b14611ad85742611ada565b5f5b6005820155611b2683600e80545f838152600f60205260408120829055600182018355919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0155565b335f8181526010602081815260408084208054898652601184528286208190559383526001840181558452922001859055517f8acf475137e0cd74ca7f611d16b1e6383ec9a9c71a8e5b85967781b9c7214d11906115c19086908690612982565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8080600484015460ff166003811115611bf457611bf461265e565b03611c0457506064925f92509050565b60048301545f90611c179060ff16612402565b90505f818560050154611c2a91906128f1565b6004860154909150428211905f90611c449060ff1661246d565b9791965090945050505050565b5f828152600d6020526040812090600482015460ff166003811115611c7857611c7861265e565b03611cc55760405162461bcd60e51b815260206004820152601860248201527f4e4654206e6f742063757272656e746c79206c6f636b65640000000000000000604482015260640161054a565b60048101545f90611cd89060ff16612402565b8260050154611ce791906128f1565b905080421015611d355760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b611d3e846115ce565b5060048201805484919060ff19166001836003811115611d6057611d6061265e565b02179055504260058301819055600383015581546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f390611db29087908790612982565b60405180910390a250505050565b5f818152600f6020526040812054600e54909190611de09060019061295b565b9050808214611e3b575f600e8281548110611dfd57611dfd61283a565b905f5260205f200154905080600e8481548110611e1c57611e1c61283a565b5f918252602080832090910192909255918252600f9052604090208290555b600e805480611e4c57611e4c61296e565b5f828152602080822083015f19908101839055909201909255938152600f90935250506040812055565b5f818152601160209081526040808320546001600160a01b03861684526010909252822054909190611eaa9060019061295b565b9050808214611f3b576001600160a01b0384165f908152601060205260408120805483908110611edc57611edc61283a565b905f5260205f20015490508060105f876001600160a01b03166001600160a01b031681526020019081526020015f208481548110611f1c57611f1c61283a565b5f91825260208083209091019290925591825260119052604090208290555b6001600160a01b0384165f908152601060205260409020805480611f6157611f6161296e565b5f828152602080822083015f1990810183905590920190925593815260119093525050604081205550565b5f818152600d6020526040812090600482015460ff166003811115611fb357611fb361265e565b146120405760048101545f90611fcb9060ff16612402565b8260050154611fda91906128f1565b90508042101561203e5760405162461bcd60e51b815260206004820152602960248201527f4c6f636b20706572696f64206e6f74206f7665722e2043616e6e6f7420756e736044820152683a30b5b2903cb2ba1760b91b606482015260840161054a565b505b612049826115ce565b5060025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92612082923092909116908790600401612918565b5f604051808303815f87803b158015612099575f80fd5b505af11580156120ab573d5f803e3d5ffd5b505050506120b882611dc0565b80546120cd906001600160a01b031683611e76565b5f828152600d6020908152604080832080546001600160a01b031916815560018101849055600281018490556003810184905560048101805460ff1916905560050192909255825491518481526001600160a01b03909216917f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75910160405180910390a25050565b5f818152600d6020526040812080546001600160a01b031661217957505f92915050565b6003810154429080821161219157505f949350505050565b5f61219c828461295b565b90505f8080600487015460ff1660038111156121ba576121ba61265e565b146121e45760048601546121d09060ff16612402565b86600501546121df91906128f1565b6121e6565b5f5b90505f600487015460ff1660038111156122025761220261265e565b146123975780841015612331575f81861061221d578161221f565b855b90505f85821161222f575f612239565b612239868361295b565b90505f6004548261224a91906128d2565b60048a01549091505f906122609060ff1661246d565b90505f60648260055461227391906128bb565b61227d91906128d2565b5f8e8152600c6020526040812054919250819003612299575060645b5f60646122a683856128bb565b6122b091906128d2565b6122ba90866128bb565b90506122c6818a6128f1565b9850878c1115612325575f6122db898e61295b565b90505f600454826122ec91906128d2565b90505f6064856005546122ff91906128bb565b61230991906128d2565b905061231581836128bb565b61231f908d6128f1565b9b505050505b505050505050506119ef565b5f6004548461234091906128d2565b5f8a8152600c602052604081205491925081900361235c575060645b5f60648260055461236d91906128bb565b61237791906128d2565b905061238381846128bb565b61238d90866128f1565b94505050506119ef565b5f600454846123a691906128d2565b5f8a8152600c60205260408120549192508190036123c2575060645b5f6064826005546123d391906128bb565b6123dd91906128d2565b90506123e981846128bb565b6123f390866128f1565b9b9a5050505050505050505050565b5f60018260038111156124175761241761265e565b0361242457505060065490565b60028260038111156124385761243861265e565b0361244557505060085490565b60038260038111156124595761245961265e565b03612466575050600a5490565b505f919050565b5f60018260038111156124825761248261265e565b0361248f57505060075490565b60028260038111156124a3576124a361265e565b036124b057505060095490565b60038260038111156124c4576124c461265e565b036124d1575050600b5490565b506064919050565b6040518060c001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f60038111156125175761251761265e565b81526020015f81525090565b5f60208284031215612533575f80fd5b5035919050565b5f8083601f84011261254a575f80fd5b50813567ffffffffffffffff811115612561575f80fd5b6020830191508360208260051b850101111561257b575f80fd5b9250929050565b5f805f8060408587031215612595575f80fd5b843567ffffffffffffffff808211156125ac575f80fd5b6125b88883890161253a565b909650945060208701359150808211156125d0575f80fd5b506125dd8782880161253a565b95989497509550505050565b6001600160a01b0381168114610bf5575f80fd5b5f6020828403121561260d575f80fd5b8135612618816125e9565b9392505050565b5f8060208385031215612630575f80fd5b823567ffffffffffffffff811115612646575f80fd5b6126528582860161253a565b90969095509350505050565b634e487b7160e01b5f52602160045260245ffd5b6004811061268e57634e487b7160e01b5f52602160045260245ffd5b9052565b602080825282518282018190525f919060409081850190868401855b8281101561270f57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201516126f182880182612672565b505060a0908101519085015260c090930192908501906001016126ae565b5091979650505050505050565b5f806040838503121561272d575f80fd5b8235612738816125e9565b946020939093013593505050565b6001600160a01b038716815260208101869052604081018590526060810184905260c081016127786080830185612672565b8260a0830152979650505050505050565b5f805f805f8060c0878903121561279e575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b602080825282518282018190525f9190848201906040850190845b818110156127ff578351835292840192918401916001016127e3565b50909695505050505050565b602080825260159082015274082e4e4c2f240d8cadccee8d040dad2e6dac2e8c6d605b1b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b6020808252600a90820152692737ba1039ba30b5b2b960b11b604082015260600190565b5f60208284031215612882575f80fd5b813560048110612618575f80fd5b5f602082840312156128a0575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761129d5761129d6128a7565b5f826128ec57634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561129d5761129d6128a7565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f6020828403121561294c575f80fd5b81518015158114612618575f80fd5b8181038181111561129d5761129d6128a7565b634e487b7160e01b5f52603160045260245ffd5b82815260408101612618602083018461267256fea2646970667358221220d6512025beb4d0383dcc5a6a0d4bae55bc44f6a8ca78f3af309df7f9a9bf123b64736f6c634300081800330000000000000000000000003303c4350259c2b8f3c560b2ec70ad3ed87a5e72
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610229575f3560e01c80638da5cb5b1161012a578063dbb7a621116100b4578063f7c618c111610079578063f7c618c1146104c9578063f7e455d7146104dc578063fae40fa0146104fc578063fb64455b14610505578063ffd2d8291461050d575f80fd5b8063dbb7a62114610475578063dd49756e1461047d578063e64a21f314610490578063efdd78e1146104a3578063f2fde38b146104b6575f80fd5b8063b2040612116100fa578063b2040612146103cf578063b865749d146103d8578063bf4bac391461043c578063d3abfe121461044f578063d56d229d14610462575f80fd5b80638da5cb5b1461038f57806399ba918d146103b45780639ce98f0e146103bd578063ae63586c146103c6575f80fd5b806370becf5d116101b6578063817b1cd21161017b578063817b1cd21461032e578063888ce4af1461033657806388c0771b146103565780638aee8127146103695780638cd4426d1461037c575f80fd5b806370becf5d146102d8578063715018a6146102e1578063760edace146102e95780637dc3db8f146102fc5780637f4ca1d71461030f575f80fd5b8063454aa669116101fc578063454aa6691461028457806352f5ad7714610297578063646e6f8b146102aa57806366e4664a146102bd5780636f9fb98a146102d0575f80fd5b80630dfa1e961461022d578063224eb12914610249578063398612b81461025e5780633af7a79514610271575b5f80fd5b61023660085481565b6040519081526020015b60405180910390f35b61025c610257366004612523565b610516565b005b61025c61026c366004612582565b610523565b61025c61027f366004612582565b6105fd565b61025c610292366004612523565b610684565b61025c6102a53660046125fd565b61070a565b61025c6102b836600461261f565b610734565b61025c6102cb366004612582565b6107ba565b61023661083b565b610236600a5481565b61025c6108aa565b6102366102f73660046125fd565b6108bd565b61025c61030a366004612523565b610a0e565b61023661031d366004612523565b600c6020525f908152604090205481565b600e54610236565b6103496103443660046125fd565b610a1b565b6040516102409190612692565b61025c610364366004612523565b610b6c565b61025c6103773660046125fd565b610bf8565b61025c61038a36600461271c565b610c22565b6001546001600160a01b03165b6040516001600160a01b039091168152602001610240565b61023660055481565b61023660065481565b61023660045481565b610236600b5481565b61042a6103e6366004612523565b600d6020525f90815260409020805460018201546002830154600384015460048501546005909501546001600160a01b039094169492939192909160ff9091169086565b60405161024096959493929190612746565b61025c61044a366004612582565b610c9d565b61025c61045d36600461261f565b610d5e565b60025461039c906001600160a01b031681565b61025c610e87565b61025c61048b366004612523565b610fe5565b61025c61049e36600461261f565b611127565b61025c6104b1366004612789565b6111a2565b61025c6104c43660046125fd565b6111c7565b60035461039c906001600160a01b031681565b6104ef6104ea36600461261f565b611201565b60405161024091906127c8565b61023660095481565b6103496112a3565b61023660075481565b61051e6113de565b600455565b61052b61140b565b8281146105535760405162461bcd60e51b815260040161054a9061280b565b60405180910390fd5b5f5b838110156105ed575f8585838181106105705761057061283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146105b45760405162461bcd60e51b815260040161054a9061284e565b6105e4818585858181106105ca576105ca61283a565b90506020020160208101906105df9190612872565b611462565b50600101610555565b506105f760015f55565b50505050565b6106056113de565b8281146106245760405162461bcd60e51b815260040161054a9061280b565b5f5b8381101561067d578282828181106106405761064061283a565b90506020020135600c5f87878581811061065c5761065c61283a565b602090810292909201358352508101919091526040015f2055600101610626565b5050505050565b61068c6113de565b804710156106dc5760405162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f756768206e61746976652062616c616e636500000000000000604482015260640161054a565b604051339082156108fc029083905f818181858888f19350505050158015610706573d5f803e3d5ffd5b5050565b6107126113de565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b61073c61140b565b5f5b818110156107b0575f8383838181106107595761075961283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b0316331461079d5760405162461bcd60e51b815260040161054a9061284e565b6107a6816115ce565b505060010161073e565b5061070660015f55565b6107c261140b565b8281146107e15760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed576108338585838181106108005761080061283a565b905060200201358484848181106108195761081961283a565b905060200201602081019061082e9190612872565b6119fa565b6001016107e3565b6003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610881573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a59190612890565b905090565b6108b26113de565b6108bb5f611b87565b565b6001600160a01b0381165f90815260106020908152604080832080548251818502810185019093528083528493849392919083018282801561091c57602002820191905f5260205f20905b815481526020019060010190808311610908575b505050505090505f5b8151811015610a05575f8282815181106109415761094161283a565b6020908102919091018101515f818152600d90925260409091208054919250906001600160a01b0388811691161461097a5750506109fd565b5f8061098583611bd8565b915091505f81156109b1576064836005546109a091906128bb565b6109aa91906128d2565b90506109b6565b506005545b5f858152600c6020526040812054908190036109d0575060645b5f60646109dd83856128bb565b6109e791906128d2565b90506109f3818b6128f1565b9950505050505050505b600101610925565b50909392505050565b610a166113de565b600555565b6001600160a01b0381165f90815260106020526040812080546060928167ffffffffffffffff811115610a5057610a50612904565b604051908082528060200260200182016040528015610a8957816020015b610a766124d9565b815260200190600190039081610a6e5790505b5090505f5b82811015610b63575f848281548110610aa957610aa961283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff1690811115610b1e57610b1e61265e565b6003811115610b2f57610b2f61265e565b8152602001600582015481525050838381518110610b4f57610b4f61283a565b602090810291909101015250600101610a8e565b50949350505050565b610b746113de565b610b7c61140b565b6002546001600160a01b03166323b872dd30610ba06001546001600160a01b031690565b846040518463ffffffff1660e01b8152600401610bbf93929190612918565b5f604051808303815f87803b158015610bd6575f80fd5b505af1158015610be8573d5f803e3d5ffd5b50505050610bf560015f55565b50565b610c006113de565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b610c2a6113de565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303815f875af1158015610c74573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c98919061293c565b505050565b610ca561140b565b828114610cc45760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed575f858583818110610ce157610ce161283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b03163314610d255760405162461bcd60e51b815260040161054a9061284e565b610d5581858585818110610d3b57610d3b61283a565b9050602002016020810190610d509190612872565b611c51565b50600101610cc6565b610d666113de565b610d6e61140b565b5f5b818110156107b0575f838383818110610d8b57610d8b61283a565b602090810292909201355f818152600d90935260409092208054929350916001600160a01b0316159050610e7d5760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610df1923092909116908790600401612918565b5f604051808303815f87803b158015610e08575f80fd5b505af1158015610e1a573d5f803e3d5ffd5b50505050610e2782611dc0565b8054610e3c906001600160a01b031683611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b5050600101610d70565b610e8f6113de565b610e9761140b565b600e5415610fdc57600e545f90610eb09060019061295b565b90505f600e8281548110610ec657610ec661283a565b5f918252602080832090910154808352600d90915260409091208054919250906001600160a01b031615610fb05760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610f2c923092909116908790600401612918565b5f604051808303815f87803b158015610f43575f80fd5b505af1158015610f55573d5f803e3d5ffd5b50508254610f6f92506001600160a01b0316905083611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b600e805480610fc157610fc161296e565b600190038181905f5260205f20015f90559055505050610e97565b6108bb60015f55565b610fed61140b565b5f811161102f5760405162461bcd60e51b815260206004820152601060248201526f043616e6e6f74206465706f73697420360841b604482015260640161054a565b6003546040516323b872dd60e01b81525f916001600160a01b0316906323b872dd9061106390339030908790600401612918565b6020604051808303815f875af115801561107f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a3919061293c565b9050806110e85760405162461bcd60e51b81526020600482015260136024820152721d1c985b9cd9995c919c9bdb4819985a5b1959606a1b604482015260640161054a565b60405182815233907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e9060200160405180910390a250610bf560015f55565b61112f61140b565b5f5b818110156107b0575f83838381811061114c5761114c61283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146111905760405162461bcd60e51b815260040161054a9061284e565b61119981611f8c565b50600101611131565b6111aa6113de565b600695909555600793909355600891909155600955600a55600b55565b6111cf6113de565b6001600160a01b0381166111f857604051631e4fbdf760e01b81525f600482015260240161054a565b610bf581611b87565b60605f8267ffffffffffffffff81111561121d5761121d612904565b604051908082528060200260200182016040528015611246578160200160208202803683370190505b5090505f5b83811015611299576112748585838181106112685761126861283a565b90506020020135612155565b8282815181106112865761128661283a565b602090810291909101015260010161124b565b5090505b92915050565b600e546060905f8167ffffffffffffffff8111156112c3576112c3612904565b6040519080825280602002602001820160405280156112fc57816020015b6112e96124d9565b8152602001906001900390816112e15790505b5090505f5b828110156113d7575f600e828154811061131d5761131d61283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff16908111156113925761139261265e565b60038111156113a3576113a361265e565b81526020016005820154815250508383815181106113c3576113c361283a565b602090810291909101015250600101611301565b5092915050565b6001546001600160a01b031633146108bb5760405163118cdaa760e01b815233600482015260240161054a565b60025f540361145c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161054a565b60025f55565b5f828152600d6020526040902080546001600160a01b03166114b35760405162461bcd60e51b815260206004820152600a602482015269139bdd081cdd185ad95960b21b604482015260640161054a565b5f600482015460ff1660038111156114cd576114cd61265e565b146115445760048101545f906114e59060ff16612402565b82600501546114f491906128f1565b9050804210156115425760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b505b61154d836115ce565b5060048101805483919060ff1916600183600381111561156f5761156f61265e565b02179055504260058201819055600382015580546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f3906115c19086908690612982565b60405180910390a2505050565b5f818152600d60205260408120600381015442908082116115f357505f949350505050565b5f6115fe828461295b565b90505f8080600487015460ff16600381111561161c5761161c61265e565b146116465760048601546116329060ff16612402565b866005015461164191906128f1565b611648565b5f5b90505f600487015460ff1660038111156116645761166461265e565b146117f95780841015611793575f81861061167f5781611681565b855b90505f858211611691575f61169b565b61169b868361295b565b90505f600454826116ac91906128d2565b60048a01549091505f906116c29060ff1661246d565b90505f6064826005546116d591906128bb565b6116df91906128d2565b5f8e8152600c60205260408120549192508190036116fb575060645b5f606461170883856128bb565b61171291906128d2565b61171c90866128bb565b9050611728818a6128f1565b9850878c1115611787575f61173d898e61295b565b90505f6004548261174e91906128d2565b90505f60648560055461176191906128bb565b61176b91906128d2565b905061177781836128bb565b611781908d6128f1565b9b505050505b5050505050505061185b565b5f600454846117a291906128d2565b5f8a8152600c60205260408120549192508190036117be575060645b5f6064826005546117cf91906128bb565b6117d991906128d2565b90506117e581846128bb565b6117ef90866128f1565b945050505061185b565b5f6004548461180891906128d2565b5f8a8152600c6020526040812054919250819003611824575060645b5f60648260055461183591906128bb565b61183f91906128d2565b905061184b81846128bb565b61185590866128f1565b94505050505b6003860185905581156119ef576003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa1580156118ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118d29190612890565b9050828110156119305760405162461bcd60e51b8152602060048201526024808201527f4e6f7420656e6f7567682072657761726420746f6b656e7320696e20636f6e746044820152631c9858dd60e21b606482015260840161054a565b600354875460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905291169063a9059cbb906044016020604051808303815f875af1158015611981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119a5919061293c565b508654604080518b8152602081018690526001600160a01b03909216917ff01da32686223933d8a18a391060918c7f11a3648639edd87ae013e2e2731743910160405180910390a2505b509695505050505050565b6002546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611a2e90339030908790600401612918565b5f604051808303815f87803b158015611a45575f80fd5b505af1158015611a57573d5f803e3d5ffd5b5050505f838152600d6020526040902080546001600160a01b03191633178155600180820185905542600283018190556003808401919091556004830180549394508593909260ff19909116918490811115611ab557611ab561265e565b02179055505f826003811115611acd57611acd61265e565b14611ad85742611ada565b5f5b6005820155611b2683600e80545f838152600f60205260408120829055600182018355919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0155565b335f8181526010602081815260408084208054898652601184528286208190559383526001840181558452922001859055517f8acf475137e0cd74ca7f611d16b1e6383ec9a9c71a8e5b85967781b9c7214d11906115c19086908690612982565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8080600484015460ff166003811115611bf457611bf461265e565b03611c0457506064925f92509050565b60048301545f90611c179060ff16612402565b90505f818560050154611c2a91906128f1565b6004860154909150428211905f90611c449060ff1661246d565b9791965090945050505050565b5f828152600d6020526040812090600482015460ff166003811115611c7857611c7861265e565b03611cc55760405162461bcd60e51b815260206004820152601860248201527f4e4654206e6f742063757272656e746c79206c6f636b65640000000000000000604482015260640161054a565b60048101545f90611cd89060ff16612402565b8260050154611ce791906128f1565b905080421015611d355760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b611d3e846115ce565b5060048201805484919060ff19166001836003811115611d6057611d6061265e565b02179055504260058301819055600383015581546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f390611db29087908790612982565b60405180910390a250505050565b5f818152600f6020526040812054600e54909190611de09060019061295b565b9050808214611e3b575f600e8281548110611dfd57611dfd61283a565b905f5260205f200154905080600e8481548110611e1c57611e1c61283a565b5f918252602080832090910192909255918252600f9052604090208290555b600e805480611e4c57611e4c61296e565b5f828152602080822083015f19908101839055909201909255938152600f90935250506040812055565b5f818152601160209081526040808320546001600160a01b03861684526010909252822054909190611eaa9060019061295b565b9050808214611f3b576001600160a01b0384165f908152601060205260408120805483908110611edc57611edc61283a565b905f5260205f20015490508060105f876001600160a01b03166001600160a01b031681526020019081526020015f208481548110611f1c57611f1c61283a565b5f91825260208083209091019290925591825260119052604090208290555b6001600160a01b0384165f908152601060205260409020805480611f6157611f6161296e565b5f828152602080822083015f1990810183905590920190925593815260119093525050604081205550565b5f818152600d6020526040812090600482015460ff166003811115611fb357611fb361265e565b146120405760048101545f90611fcb9060ff16612402565b8260050154611fda91906128f1565b90508042101561203e5760405162461bcd60e51b815260206004820152602960248201527f4c6f636b20706572696f64206e6f74206f7665722e2043616e6e6f7420756e736044820152683a30b5b2903cb2ba1760b91b606482015260840161054a565b505b612049826115ce565b5060025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92612082923092909116908790600401612918565b5f604051808303815f87803b158015612099575f80fd5b505af11580156120ab573d5f803e3d5ffd5b505050506120b882611dc0565b80546120cd906001600160a01b031683611e76565b5f828152600d6020908152604080832080546001600160a01b031916815560018101849055600281018490556003810184905560048101805460ff1916905560050192909255825491518481526001600160a01b03909216917f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75910160405180910390a25050565b5f818152600d6020526040812080546001600160a01b031661217957505f92915050565b6003810154429080821161219157505f949350505050565b5f61219c828461295b565b90505f8080600487015460ff1660038111156121ba576121ba61265e565b146121e45760048601546121d09060ff16612402565b86600501546121df91906128f1565b6121e6565b5f5b90505f600487015460ff1660038111156122025761220261265e565b146123975780841015612331575f81861061221d578161221f565b855b90505f85821161222f575f612239565b612239868361295b565b90505f6004548261224a91906128d2565b60048a01549091505f906122609060ff1661246d565b90505f60648260055461227391906128bb565b61227d91906128d2565b5f8e8152600c6020526040812054919250819003612299575060645b5f60646122a683856128bb565b6122b091906128d2565b6122ba90866128bb565b90506122c6818a6128f1565b9850878c1115612325575f6122db898e61295b565b90505f600454826122ec91906128d2565b90505f6064856005546122ff91906128bb565b61230991906128d2565b905061231581836128bb565b61231f908d6128f1565b9b505050505b505050505050506119ef565b5f6004548461234091906128d2565b5f8a8152600c602052604081205491925081900361235c575060645b5f60648260055461236d91906128bb565b61237791906128d2565b905061238381846128bb565b61238d90866128f1565b94505050506119ef565b5f600454846123a691906128d2565b5f8a8152600c60205260408120549192508190036123c2575060645b5f6064826005546123d391906128bb565b6123dd91906128d2565b90506123e981846128bb565b6123f390866128f1565b9b9a5050505050505050505050565b5f60018260038111156124175761241761265e565b0361242457505060065490565b60028260038111156124385761243861265e565b0361244557505060085490565b60038260038111156124595761245961265e565b03612466575050600a5490565b505f919050565b5f60018260038111156124825761248261265e565b0361248f57505060075490565b60028260038111156124a3576124a361265e565b036124b057505060095490565b60038260038111156124c4576124c461265e565b036124d1575050600b5490565b506064919050565b6040518060c001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f60038111156125175761251761265e565b81526020015f81525090565b5f60208284031215612533575f80fd5b5035919050565b5f8083601f84011261254a575f80fd5b50813567ffffffffffffffff811115612561575f80fd5b6020830191508360208260051b850101111561257b575f80fd5b9250929050565b5f805f8060408587031215612595575f80fd5b843567ffffffffffffffff808211156125ac575f80fd5b6125b88883890161253a565b909650945060208701359150808211156125d0575f80fd5b506125dd8782880161253a565b95989497509550505050565b6001600160a01b0381168114610bf5575f80fd5b5f6020828403121561260d575f80fd5b8135612618816125e9565b9392505050565b5f8060208385031215612630575f80fd5b823567ffffffffffffffff811115612646575f80fd5b6126528582860161253a565b90969095509350505050565b634e487b7160e01b5f52602160045260245ffd5b6004811061268e57634e487b7160e01b5f52602160045260245ffd5b9052565b602080825282518282018190525f919060409081850190868401855b8281101561270f57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201516126f182880182612672565b505060a0908101519085015260c090930192908501906001016126ae565b5091979650505050505050565b5f806040838503121561272d575f80fd5b8235612738816125e9565b946020939093013593505050565b6001600160a01b038716815260208101869052604081018590526060810184905260c081016127786080830185612672565b8260a0830152979650505050505050565b5f805f805f8060c0878903121561279e575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b602080825282518282018190525f9190848201906040850190845b818110156127ff578351835292840192918401916001016127e3565b50909695505050505050565b602080825260159082015274082e4e4c2f240d8cadccee8d040dad2e6dac2e8c6d605b1b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b6020808252600a90820152692737ba1039ba30b5b2b960b11b604082015260600190565b5f60208284031215612882575f80fd5b813560048110612618575f80fd5b5f602082840312156128a0575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761129d5761129d6128a7565b5f826128ec57634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561129d5761129d6128a7565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f6020828403121561294c575f80fd5b81518015158114612618575f80fd5b8181038181111561129d5761129d6128a7565b634e487b7160e01b5f52603160045260245ffd5b82815260408101612618602083018461267256fea2646970667358221220d6512025beb4d0383dcc5a6a0d4bae55bc44f6a8ca78f3af309df7f9a9bf123b64736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003303c4350259c2b8f3c560b2ec70ad3ed87a5e72
-----Decoded View---------------
Arg [0] : _initialOwner (address): 0x3303C4350259C2B8F3C560B2ec70aD3ed87A5E72
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000003303c4350259c2b8f3c560b2ec70ad3ed87a5e72
Deployed Bytecode Sourcemap
16470:28667:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17549:39;;;;;;;;;160:25:1;;;148:2;133:18;17549:39:0;;;;;;;;20265:104;;;;;;:::i;:::-;;:::i;:::-;;24617:488;;;;;;:::i;:::-;;:::i;21438:334::-;;;;;;:::i;:::-;;:::i;21893:195::-;;;;;;:::i;:::-;;:::i;20030:110::-;;;;;;:::i;:::-;;:::i;24019:315::-;;;;;;:::i;:::-;;:::i;23159:329::-;;;;;;:::i;:::-;;:::i;22685:124::-;;;:::i;17649:39::-;;;;;;15344:103;;;:::i;26564:1203::-;;;;;;:::i;:::-;;:::i;20377:110::-;;;;;;:::i;:::-;;:::i;17882:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;38381:105;38454:17;:24;38381:105;;38877:436;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;44975:157::-;;;;;;:::i;:::-;;:::i;20148:109::-;;;;;;:::i;:::-;;:::i;22096:136::-;;;;;;:::i;:::-;;:::i;14669:87::-;14742:6;;-1:-1:-1;;;;;14742:6:0;14669:87;;;-1:-1:-1;;;;;5771:32:1;;;5753:51;;5741:2;5726:18;14669:87:0;5607:203:1;17238:41:0;;;;;;17449:39;;;;;;17057:36;;;;;;17695:37;;;;;;18662:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18662:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;25305:457::-;;;;;;:::i;:::-;;:::i;42824:834::-;;;;;;:::i;:::-;;:::i;16716:80::-;;;;;-1:-1:-1;;;;;16716:80:0;;;43861:871;;;:::i;22372:305::-;;;;;;:::i;:::-;;:::i;23623:313::-;;;;;;:::i;:::-;;:::i;20669:541::-;;;;;;:::i;:::-;;:::i;15602:220::-;;;;;;:::i;:::-;;:::i;16897:78::-;;;;;-1:-1:-1;;;;;16897:78:0;;;26034:336;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;17595:37::-;;;;;;38494:375;;;:::i;17495:37::-;;;;;;20265:104;14555:13;:11;:13::i;:::-;20338:12:::1;:23:::0;20265:104::o;24617:488::-;11195:21;:19;:21::i;:::-;24778:39;;::::1;24770:73;;;;-1:-1:-1::0;;;24770:73:0::1;;;;;;;:::i;:::-;;;;;;;;;24859:9;24854:244;24874:20:::0;;::::1;24854:244;;;24916:15;24934:9;;24944:1;24934:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;24969:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;24934:12;;-1:-1:-1;;;;;;;24969:25:0::1;24998:10;24969:39;24961:62;;;;-1:-1:-1::0;;;24961:62:0::1;;;;;;;:::i;:::-;25038:48;25061:7;25070:12;;25083:1;25070:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;25038:22;:48::i;:::-;-1:-1:-1::0;24896:3:0::1;;24854:244;;;;11239:20:::0;10633:1;11759:7;:22;11576:213;11239:20;24617:488;;;;:::o;21438:334::-;14555:13;:11;:13::i;:::-;21570:39;;::::1;21562:73;;;;-1:-1:-1::0;;;21562:73:0::1;;;;;;;:::i;:::-;21651:9;21646:119;21666:20:::0;;::::1;21646:119;;;21738:12;;21751:1;21738:15;;;;;;;:::i;:::-;;;;;;;21708:13;:27;21722:9;;21732:1;21722:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;21708:27:::0;;-1:-1:-1;21708:27:0;::::1;::::0;;;;;;-1:-1:-1;21708:27:0;:45;21688:3:::1;;21646:119;;;;21438:334:::0;;;;:::o;21893:195::-;14555:13;:11;:13::i;:::-;21995:7:::1;21970:21;:32;;21962:70;;;::::0;-1:-1:-1;;;21962:70:0;;9321:2:1;21962:70:0::1;::::0;::::1;9303:21:1::0;9360:2;9340:18;;;9333:30;9399:27;9379:18;;;9372:55;9444:18;;21962:70:0::1;9119:349:1::0;21962:70:0::1;22043:37;::::0;22051:10:::1;::::0;22043:37;::::1;;;::::0;22072:7;;22043:37:::1;::::0;;;22072:7;22051:10;22043:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;21893:195:::0;:::o;20030:110::-;14555:13;:11;:13::i;:::-;20106:11:::1;:26:::0;;-1:-1:-1;;;;;;20106:26:0::1;-1:-1:-1::0;;;;;20106:26:0;;;::::1;::::0;;;::::1;::::0;;20030:110::o;24019:315::-;11195:21;:19;:21::i;:::-;24114:9:::1;24109:218;24129:20:::0;;::::1;24109:218;;;24171:15;24189:9;;24199:1;24189:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;24224:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;24189:12;;-1:-1:-1;;;;;;;24224:25:0::1;24253:10;24224:39;24216:62;;;;-1:-1:-1::0;;;24216:62:0::1;;;;;;;:::i;:::-;24293:22;24307:7;24293:13;:22::i;:::-;-1:-1:-1::0;;24151:3:0::1;;24109:218;;;;11239:20:::0;10633:1;11759:7;:22;11576:213;23159:329;11195:21;:19;:21::i;:::-;23286:39;;::::1;23278:73;;;;-1:-1:-1::0;;;23278:73:0::1;;;;;;;:::i;:::-;23367:9;23362:119;23382:20:::0;;::::1;23362:119;;;23424:45;23439:9;;23449:1;23439:12;;;;;;;:::i;:::-;;;;;;;23453;;23466:1;23453:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;23424:14;:45::i;:::-;23404:3;;23362:119;;22685:124:::0;22765:11;;:36;;-1:-1:-1;;;22765:36:0;;22795:4;22765:36;;;5753:51:1;22738:7:0;;-1:-1:-1;;;;;22765:11:0;;:21;;5726:18:1;;22765:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22758:43;;22685:124;:::o;15344:103::-;14555:13;:11;:13::i;:::-;15409:30:::1;15436:1;15409:18;:30::i;:::-;15344:103::o:0;26564:1203::-;-1:-1:-1;;;;;26713:23:0;;26628:7;26713:23;;;:16;:23;;;;;;;;26685:51;;;;;;;;;;;;;;;;;26628:7;;;;26685:51;26713:23;26685:51;;;26713:23;26685:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26754:9;26749:977;26773:8;:15;26769:1;:19;26749:977;;;26810:15;26828:8;26837:1;26828:11;;;;;;;;:::i;:::-;;;;;;;;;;;;26854:22;26879:19;;;:10;:19;;;;;;;26948:10;;26828:11;;-1:-1:-1;26879:19:0;-1:-1:-1;;;;;26948:19:0;;;:10;;:19;26944:33;;26969:8;;;;26944:33;27046:22;27070:11;27085:33;27113:4;27085:27;:33::i;:::-;27045:73;;;;27133:17;27171:6;27167:293;;;27312:3;27294:14;27275:16;;:33;;;;:::i;:::-;27274:41;;;;:::i;:::-;27262:53;;27167:293;;;-1:-1:-1;27428:16:0;;27167:293;27522:15;27540:22;;;:13;:22;;;;;;;27581:12;;;27577:31;;-1:-1:-1;27605:3:0;27577:31;27625:17;27669:3;27646:19;27658:7;27646:9;:19;:::i;:::-;27645:27;;;;:::i;:::-;27625:47;-1:-1:-1;27687:27:0;27625:47;27687:27;;:::i;:::-;;;26795:931;;;;;;;26749:977;26790:3;;26749:977;;;-1:-1:-1;27745:14:0;;26564:1203;-1:-1:-1;;;26564:1203:0:o;20377:110::-;14555:13;:11;:13::i;:::-;20453:16:::1;:26:::0;20377:110::o;38877:436::-;-1:-1:-1;;;;;39002:25:0;;38973:26;39002:25;;;:16;:25;;;;;39055:15;;38942:18;;39055:15;39109:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;39081:51;;39148:9;39143:139;39167:6;39163:1;:10;39143:139;;;39195:15;39213:8;39222:1;39213:11;;;;;;;;:::i;:::-;;;;;;;;;;;;;39251:19;;;:10;:19;;;;;;;39239:31;;;;;;;;;-1:-1:-1;;;;;39239:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39213:11;;-1:-1:-1;39239:31:0;;39251:19;39239:31;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:6;39246:1;39239:9;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;39175:3:0;;39143:139;;;-1:-1:-1;39299:6:0;38877:436;-1:-1:-1;;;;38877:436:0:o;44975:157::-;14555:13;:11;:13::i;:::-;11195:21:::1;:19;:21::i;:::-;45066:11:::2;::::0;-1:-1:-1;;;;;45066:11:0::2;:24;45099:4;45106:7;14742:6:::0;;-1:-1:-1;;;;;14742:6:0;;14669:87;45106:7:::2;45115:8;45066:58;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;11239:20:::1;10633:1:::0;11759:7;:22;11576:213;11239:20:::1;44975:157:::0;:::o;20148:109::-;14555:13;:11;:13::i;:::-;20223:11:::1;:26:::0;;-1:-1:-1;;;;;;20223:26:0::1;-1:-1:-1::0;;;;;20223:26:0;;;::::1;::::0;;;::::1;::::0;;20148:109::o;22096:136::-;14555:13;:11;:13::i;:::-;22180:44:::1;::::0;-1:-1:-1;;;22180:44:0;;22204:10:::1;22180:44;::::0;::::1;11005:51:1::0;11072:18;;;11065:34;;;-1:-1:-1;;;;;22180:23:0;::::1;::::0;::::1;::::0;10978:18:1;;22180:44:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;22096:136:::0;;:::o;25305:457::-;11195:21;:19;:21::i;:::-;25436:42;;::::1;25428:76;;;;-1:-1:-1::0;;;25428:76:0::1;;;;;;;:::i;:::-;25520:9;25515:240;25535:20:::0;;::::1;25515:240;;;25577:15;25595:9;;25605:1;25595:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;25630:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;25595:12;;-1:-1:-1;;;;;;;25630:25:0::1;25659:10;25630:39;25622:62;;;;-1:-1:-1::0;;;25622:62:0::1;;;;;;;:::i;:::-;25699:44;25715:7;25724:15;;25740:1;25724:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;25699:15;:44::i;:::-;-1:-1:-1::0;25557:3:0::1;;25515:240;;42824:834:::0;14555:13;:11;:13::i;:::-;11195:21:::1;:19;:21::i;:::-;42932:9:::2;42927:724;42947:20:::0;;::::2;42927:724;;;42989:15;43007:9;;43017:1;43007:12;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;::::2;;43034:22;43059:19:::0;;;:10:::2;:19:::0;;;;;;;43161:10;;43007:12;;-1:-1:-1;43059:19:0;-1:-1:-1;;;;;43161:10:0::2;:24:::0;;-1:-1:-1;43157:483:0::2;;43254:11;::::0;43294:10;;43254:60:::2;::::0;-1:-1:-1;;;43254:60:0;;-1:-1:-1;;;;;43254:11:0;;::::2;::::0;:24:::2;::::0;:60:::2;::::0;43287:4:::2;::::0;43294:10;;::::2;::::0;43306:7;;43254:60:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;43380:37;43409:7;43380:28;:37::i;:::-;43507:10:::0;;43479:48:::2;::::0;-1:-1:-1;;;;;43507:10:0::2;43519:7:::0;43479:27:::2;:48::i;:::-;43605:19;::::0;;;:10:::2;:19;::::0;;;;43598:26;;-1:-1:-1;;;;;;43598:26:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;-1:-1:-1;;43598:26:0::2;::::0;;::::2;;::::0;43157:483:::2;-1:-1:-1::0;;42969:3:0::2;;42927:724;;43861:871:::0;14555:13;:11;:13::i;:::-;11195:21:::1;:19;:21::i;:::-;44019:17:::2;:24:::0;:28;44012:713:::2;;44084:17;:24:::0;44064:17:::2;::::0;44084:28:::2;::::0;44111:1:::2;::::0;44084:28:::2;:::i;:::-;44064:48;;44127:15;44145:17;44163:9;44145:28;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;;;::::2;::::0;44213:19;;;:10:::2;:19:::0;;;;;;;44253:10;;44145:28;;-1:-1:-1;44213:19:0;-1:-1:-1;;;;;44253:10:0::2;:24:::0;44249:369:::2;;44346:11;::::0;44386:10;;44346:60:::2;::::0;-1:-1:-1;;;44346:60:0;;-1:-1:-1;;;;;44346:11:0;;::::2;::::0;:24:::2;::::0;:60:::2;::::0;44379:4:::2;::::0;44386:10;;::::2;::::0;44398:7;;44346:60:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;44498:10:0;;44470:48:::2;::::0;-1:-1:-1;;;;;;44498:10:0::2;::::0;-1:-1:-1;44510:7:0;44470:27:::2;:48::i;:::-;44583:19;::::0;;;:10:::2;:19;::::0;;;;44576:26;;-1:-1:-1;;;;;;44576:26:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;-1:-1:-1;;44576:26:0::2;::::0;;::::2;;::::0;44249:369:::2;44690:17;:23;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;44049:676;;;44012:713;;;11239:20:::1;10633:1:::0;11759:7;:22;11576:213;22372:305;11195:21;:19;:21::i;:::-;22461:1:::1;22452:6;:10;22444:39;;;::::0;-1:-1:-1;;;22444:39:0;;11859:2:1;22444:39:0::1;::::0;::::1;11841:21:1::0;11898:2;11878:18;;;11871:30;-1:-1:-1;;;11917:18:1;;;11910:46;11973:18;;22444:39:0::1;11657:340:1::0;22444:39:0::1;22509:11;::::0;:59:::1;::::0;-1:-1:-1;;;22509:59:0;;22494:12:::1;::::0;-1:-1:-1;;;;;22509:11:0::1;::::0;:24:::1;::::0;:59:::1;::::0;22534:10:::1;::::0;22554:4:::1;::::0;22561:6;;22509:59:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22494:74;;22587:7;22579:39;;;::::0;-1:-1:-1;;;22579:39:0;;12204:2:1;22579:39:0::1;::::0;::::1;12186:21:1::0;12243:2;12223:18;;;12216:30;-1:-1:-1;;;12262:18:1;;;12255:49;12321:18;;22579:39:0::1;12002:343:1::0;22579:39:0::1;22634:35;::::0;160:25:1;;;22650:10:0::1;::::0;22634:35:::1;::::0;148:2:1;133:18;22634:35:0::1;;;;;;;22433:244;11239:20:::0;10633:1;11759:7;:22;11576:213;23623:313;11195:21;:19;:21::i;:::-;23713:9:::1;23708:221;23728:20:::0;;::::1;23708:221;;;23770:15;23788:9;;23798:1;23788:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;23823:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;23788:12;;-1:-1:-1;;;;;;;23823:25:0::1;23852:10;23823:39;23815:62;;;;-1:-1:-1::0;;;23815:62:0::1;;;;;;;:::i;:::-;23892:25;23909:7;23892:16;:25::i;:::-;-1:-1:-1::0;23750:3:0::1;;23708:221;;20669:541:::0;14555:13;:11;:13::i;:::-;20939:14:::1;:32:::0;;;;20982:16:::1;:36:::0;;;;21031:14:::1;:32:::0;;;;21074:16:::1;:36:::0;21123:14:::1;:32:::0;21166:16:::1;:36:::0;20669:541::o;15602:220::-;14555:13;:11;:13::i;:::-;-1:-1:-1;;;;;15687:22:0;::::1;15683:93;;15733:31;::::0;-1:-1:-1;;;15733:31:0;;15761:1:::1;15733:31;::::0;::::1;5753:51:1::0;5726:18;;15733:31:0::1;5607:203:1::0;15683:93:0::1;15786:28;15805:8;15786:18;:28::i;26034:336::-:0;26118:16;26147:24;26188:9;26174:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26174:31:0;;26147:58;;26221:9;26216:122;26236:20;;;26216:122;;;26291:35;26313:9;;26323:1;26313:12;;;;;;;:::i;:::-;;;;;;;26291:21;:35::i;:::-;26278:7;26286:1;26278:10;;;;;;;;:::i;:::-;;;;;;;;;;:48;26258:3;;26216:122;;;-1:-1:-1;26355:7:0;-1:-1:-1;26034:336:0;;;;;:::o;38494:375::-;38593:17;:24;38545:18;;38576:14;38593:24;38656:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;38628:51;;38695:9;38690:148;38714:6;38710:1;:10;38690:148;;;38742:15;38760:17;38778:1;38760:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;38807:19;;;:10;:19;;;;;;;38795:31;;;;;;;;;-1:-1:-1;;;;;38795:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38760:20;;-1:-1:-1;38795:31:0;;38807:19;38795:31;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:6;38802:1;38795:9;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;38722:3:0;;38690:148;;;-1:-1:-1;38855:6:0;38494:375;-1:-1:-1;;38494:375:0:o;14834:166::-;14742:6;;-1:-1:-1;;;;;14742:6:0;12865:10;14894:23;14890:103;;14941:40;;-1:-1:-1;;;14941:40:0;;12865:10;14941:40;;;5753:51:1;5726:18;;14941:40:0;5607:203:1;11275:293:0;10677:1;11409:7;;:19;11401:63;;;;-1:-1:-1;;;11401:63:0;;12552:2:1;11401:63:0;;;12534:21:1;12591:2;12571:18;;;12564:30;12630:33;12610:18;;;12603:61;12681:18;;11401:63:0;12350:355:1;11401:63:0;10677:1;11542:7;:18;11275:293::o;29864:902::-;29961:22;29986:20;;;:10;:20;;;;;30054:10;;-1:-1:-1;;;;;30054:10:0;30046:47;;;;-1:-1:-1;;;30046:47:0;;12912:2:1;30046:47:0;;;12894:21:1;12951:2;12931:18;;;12924:30;-1:-1:-1;;;12970:18:1;;;12963:40;13020:18;;30046:47:0;12710:334:1;30046:47:0;30191:15;30172;;;;;;:34;;;;;;;;:::i;:::-;;30168:218;;30279:15;;;;30223;;30262:33;;30279:15;;30262:16;:33::i;:::-;30241:4;:18;;;:54;;;;:::i;:::-;30223:72;;30337:7;30318:15;:26;;30310:64;;;;-1:-1:-1;;;30310:64:0;;13251:2:1;30310:64:0;;;13233:21:1;13290:2;13270:18;;;13263:30;-1:-1:-1;;;13309:18:1;;;13302:55;13374:18;;30310:64:0;13049:349:1;30310:64:0;30208:178;30168:218;30477:23;30491:8;30477:13;:23::i;:::-;-1:-1:-1;30538:15:0;;;:32;;30556:14;;30538:15;-1:-1:-1;;30538:32:0;;30556:14;30538:32;;;;;;;;:::i;:::-;;;;;-1:-1:-1;30602:15:0;30581:18;;;:36;;;30628:18;;;:36;30721:10;;30703:55;;-1:-1:-1;;;;;30721:10:0;;;;30703:55;;;;30733:8;;30743:14;;30703:55;:::i;:::-;;;;;;;;29950:816;29864:902;;:::o;32008:3599::-;32067:7;32112:20;;;:10;:20;;;;;32215:18;;;;32167:15;;32291:26;;;32287:67;;-1:-1:-1;32341:1:0;;32008:3599;-1:-1:-1;;;;32008:3599:0:o;32287:67::-;32366:16;32385:25;32399:11;32385;:25;:::i;:::-;32366:44;-1:-1:-1;32421:19:0;;;32508:15;;;;;;:34;;;;;;;;:::i;:::-;;32507:125;;32615:15;;;;32598:33;;32615:15;;32598:16;:33::i;:::-;32577:4;:18;;;:54;;;;:::i;:::-;32507:125;;;32559:1;32507:125;32489:143;-1:-1:-1;32739:15:0;32720;;;;;;:34;;;;;;;;:::i;:::-;;32716:2394;;32822:7;32808:11;:21;32804:1962;;;32886:24;32928:7;32914:11;:21;32913:47;;32953:7;32913:47;;;32939:11;32913:47;32886:74;;32979:18;33020:11;33001:16;:30;33000:111;;33110:1;33000:111;;;33056:30;33075:11;33056:16;:30;:::i;:::-;32979:132;;33132:18;33166:12;;33153:10;:25;;;;:::i;:::-;33237:15;;;;33132:46;;-1:-1:-1;33197:18:0;;33218:35;;33237:15;;33218:18;:35::i;:::-;33197:56;;33410:23;33470:3;33456:10;33437:16;;:29;;;;:::i;:::-;33436:37;;;;:::i;:::-;33538:15;33556:23;;;:13;:23;;;;;;33410:63;;-1:-1:-1;33602:12:0;;;33598:31;;-1:-1:-1;33626:3:0;33598:31;33738:20;33805:3;33776:25;33794:7;33776:15;:25;:::i;:::-;33775:33;;;;:::i;:::-;33761:48;;:10;:48;:::i;:::-;33738:71;-1:-1:-1;33828:27:0;33738:71;33828:27;;:::i;:::-;;;33960:7;33946:11;:21;33942:421;;;33992:20;34015:21;34029:7;34015:11;:21;:::i;:::-;33992:44;;34059:20;34097:12;;34082;:27;;;;:::i;:::-;34059:50;;34211:25;34270:3;34259:7;34240:16;;:26;;;;:::i;:::-;34239:34;;;;:::i;:::-;34211:62;-1:-1:-1;34311:32:0;34211:62;34311:12;:32;:::i;:::-;34296:47;;;;:::i;:::-;;;33969:394;;;33942:421;32831:1547;;;;;;;32716:2394;;32804:1962;34459:17;34490:12;;34479:8;:23;;;;:::i;:::-;34521:15;34539:23;;;:13;:23;;;;;;34459:43;;-1:-1:-1;34585:12:0;;;34581:31;;-1:-1:-1;34609:3:0;34581:31;34633:21;34688:3;34677:7;34658:16;;:26;;;;:::i;:::-;34657:34;;;;:::i;:::-;34633:58;-1:-1:-1;34725:25:0;34633:58;34725:9;:25;:::i;:::-;34710:40;;;;:::i;:::-;;;34384:382;;;32716:2394;;;34839:17;34870:12;;34859:8;:23;;;;:::i;:::-;34897:15;34915:23;;;:13;:23;;;;;;34839:43;;-1:-1:-1;34957:12:0;;;34953:31;;-1:-1:-1;34981:3:0;34953:31;35001:13;35048:3;35037:7;35018:16;;:26;;;;:::i;:::-;35017:34;;;;:::i;:::-;35001:50;-1:-1:-1;35081:17:0;35001:50;35081:9;:17;:::i;:::-;35066:32;;;;:::i;:::-;;;34783:327;;;32716:2394;35153:18;;;:32;;;35247:15;;35243:326;;35301:11;;:36;;-1:-1:-1;;;35301:36:0;;35331:4;35301:36;;;5753:51:1;35279:19:0;;-1:-1:-1;;;;;35301:11:0;;:21;;5726:18:1;;35301:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35279:58;;35375:11;35360;:26;;35352:75;;;;-1:-1:-1;;;35352:75:0;;13890:2:1;35352:75:0;;;13872:21:1;13929:2;13909:18;;;13902:30;13968:34;13948:18;;;13941:62;-1:-1:-1;;;14019:18:1;;;14012:34;14063:19;;35352:75:0;13688:400:1;35352:75:0;35442:11;;35463:10;;35442:45;;-1:-1:-1;;;35442:45:0;;-1:-1:-1;;;;;35463:10:0;;;35442:45;;;11005:51:1;11072:18;;;11065:34;;;35442:11:0;;;:20;;10978:18:1;;35442:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;35523:10:0;;35509:48;;;14267:25:1;;;14323:2;14308:18;;14301:34;;;-1:-1:-1;;;;;35523:10:0;;;;35509:48;;14240:18:1;35509:48:0;;;;;;;35264:305;35243:326;-1:-1:-1;35588:11:0;32008:3599;-1:-1:-1;;;;;;32008:3599:0:o;27958:784::-;28096:11;;:61;;-1:-1:-1;;;28096:61:0;;-1:-1:-1;;;;;28096:11:0;;;;:24;;:61;;28121:10;;28141:4;;28148:8;;28096:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;28202:22:0;28227:20;;;:10;:20;;;;;28258:23;;-1:-1:-1;;;;;;28258:23:0;28271:10;28258:23;;;;28292:12;;;:23;;;28342:15;28326:13;;;:31;;;28368:18;;;;:36;;;;28415:15;;;:29;;28227:20;;-1:-1:-1;28433:11:0;;28415:15;;-1:-1:-1;;28415:29:0;;;;28433:11;;28415:29;;;;;;;:::i;:::-;;;;;-1:-1:-1;28492:15:0;28477:11;:30;;;;;;;;:::i;:::-;;28476:54;;28515:15;28476:54;;;28511:1;28476:54;28455:18;;;:75;28587:33;28611:8;39549:17;:24;;39517:29;;;;:19;:29;;;;;:56;;;39584:32;;;;;;;;;;;;39446:178;28587:33;28654:10;40239:23;;;;:16;:23;;;;;;;;:30;;40205:31;;;:21;:31;;;;;:64;;;40280:23;;;:38;;;;;;;;;;;;;28693:41;;;;;40205:31;;28722:11;;28693:41;:::i;15982:191::-;16075:6;;;-1:-1:-1;;;;;16092:17:0;;;-1:-1:-1;;;;;;16092:17:0;;;;;;;16125:40;;16075:6;;;16092:17;16075:6;;16125:40;;16056:16;;16125:40;16045:128;15982:191;:::o;42008:570::-;42138:24;;;42203:15;;;;;;:34;;;;;;;;:::i;:::-;;42199:86;;-1:-1:-1;42262:3:0;;42267:5;;-1:-1:-1;42008:570:0;-1:-1:-1;42008:570:0:o;42199:86::-;42331:15;;;;42295:16;;42314:33;;42331:15;;42314:16;:33::i;:::-;42295:52;;42358:15;42397:8;42376:4;:18;;;:29;;;;:::i;:::-;42512:15;;;;42358:47;;-1:-1:-1;42437:15:0;:25;-1:-1:-1;42437:25:0;42416:17;;42493:35;;42512:15;;42493:18;:35::i;:::-;42474:54;42557:12;;-1:-1:-1;42008:570:0;;-1:-1:-1;;;;;42008:570:0:o;30960:801::-;31050:22;31075:20;;;:10;:20;;;;;;31168:15;;;;;;:34;;;;;;;;:::i;:::-;;31160:71;;;;-1:-1:-1;;;31160:71:0;;14548:2:1;31160:71:0;;;14530:21:1;14587:2;14567:18;;;14560:30;14626:26;14606:18;;;14599:54;14670:18;;31160:71:0;14346:348:1;31160:71:0;31334:15;;;;31278;;31317:33;;31334:15;;31317:16;:33::i;:::-;31296:4;:18;;;:54;;;;:::i;:::-;31278:72;;31388:7;31369:15;:26;;31361:64;;;;-1:-1:-1;;;31361:64:0;;13251:2:1;31361:64:0;;;13233:21:1;13290:2;13270:18;;;13263:30;-1:-1:-1;;;13309:18:1;;;13302:55;13374:18;;31361:64:0;13049:349:1;31361:64:0;31478:23;31492:8;31478:13;:23::i;:::-;-1:-1:-1;31554:15:0;;;:32;;31572:14;;31554:15;-1:-1:-1;;31554:32:0;;31572:14;31554:32;;;;;;;;:::i;:::-;;;;;-1:-1:-1;31618:15:0;31597:18;;;:36;;;31644:18;;;:36;31716:10;;31698:55;;-1:-1:-1;;;;;31716:10:0;;;;31698:55;;;;31728:8;;31738:14;;31698:55;:::i;:::-;;;;;;;;31039:722;;30960:801;;:::o;39632:480::-;39708:11;39722:29;;;:19;:29;;;;;;39782:17;:24;39722:29;;39708:11;39782:28;;39809:1;;39782:28;:::i;:::-;39762:48;;39832:9;39825:3;:16;39821:203;;39858:19;39880:17;39898:9;39880:28;;;;;;;;:::i;:::-;;;;;;;;;39858:50;;39948:11;39923:17;39941:3;39923:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;39974:32;;;:19;:32;;;;;:38;;;39821:203;40034:17;:23;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;40034:23:0;;;;;;;;;;;;40075:29;;;:19;:29;;;-1:-1:-1;;40075:29:0;;;40068:36;39632:480::o;40334:526::-;40424:11;40438:31;;;:21;:31;;;;;;;;;-1:-1:-1;;;;;40500:23:0;;;;:16;:23;;;;;:30;40438:31;;40424:11;40500:34;;40533:1;;40500:34;:::i;:::-;40480:54;;40558:9;40551:3;:16;40547:217;;-1:-1:-1;;;;;40606:23:0;;40584:19;40606:23;;;:16;:23;;;;;:34;;40630:9;;40606:34;;;;;;:::i;:::-;;;;;;;;;40584:56;;40686:11;40655:16;:23;40672:5;-1:-1:-1;;;;;40655:23:0;-1:-1:-1;;;;;40655:23:0;;;;;;;;;;;;40679:3;40655:28;;;;;;;;:::i;:::-;;;;;;;;;;;;:42;;;;40712:34;;;:21;:34;;;;;:40;;;40547:217;-1:-1:-1;;;;;40774:23:0;;;;;;:16;:23;;;;;:29;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;40774:29:0;;;;;;;;;;;;40821:31;;;:21;:31;;;-1:-1:-1;;40821:31:0;;;40814:38;-1:-1:-1;40334:526:0:o;28750:808::-;28814:22;28839:20;;;:10;:20;;;;;;28924:15;;;;;;:34;;;;;;;;:::i;:::-;;28920:234;;29031:15;;;;28975;;29014:33;;29031:15;;29014:16;:33::i;:::-;28993:4;:18;;;:54;;;;:::i;:::-;28975:72;;29089:7;29070:15;:26;;29062:80;;;;-1:-1:-1;;;29062:80:0;;14901:2:1;29062:80:0;;;14883:21:1;14940:2;14920:18;;;14913:30;14979:34;14959:18;;;14952:62;-1:-1:-1;;;15030:18:1;;;15023:39;15079:19;;29062:80:0;14699:405:1;29062:80:0;28960:194;28920:234;29206:23;29220:8;29206:13;:23::i;:::-;-1:-1:-1;29272:11:0;;29312:10;;29272:61;;-1:-1:-1;;;29272:61:0;;-1:-1:-1;;;;;29272:11:0;;;;:24;;:61;;29305:4;;29312:10;;;;29324:8;;29272:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29366:38;29395:8;29366:28;:38::i;:::-;29443:10;;29415:49;;-1:-1:-1;;;;;29443:10:0;29455:8;29415:27;:49::i;:::-;29482:20;;;;:10;:20;;;;;;;;29475:27;;-1:-1:-1;;;;;;29475:27:0;;;-1:-1:-1;29475:27:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;29475:27:0;;;;;;;;;29529:10;;29520:30;;160:25:1;;;-1:-1:-1;;;;;29529:10:0;;;;29520:30;;133:18:1;29520:30:0;;;;;;;28803:755;28750:808;:::o;35702:2528::-;35774:7;35819:20;;;:10;:20;;;;;35854:10;;-1:-1:-1;;;;;35854:10:0;35850:38;;-1:-1:-1;35887:1:0;;35702:2528;-1:-1:-1;;35702:2528:0:o;35850:38::-;35985:18;;;;35937:15;;36018:26;;;36014:40;;-1:-1:-1;36053:1:0;;35702:2528;-1:-1:-1;;;;35702:2528:0:o;36014:40::-;36067:16;36086:25;36100:11;36086;:25;:::i;:::-;36067:44;-1:-1:-1;36122:19:0;;;36177:15;;;;;;:34;;;;;;;;:::i;:::-;;36176:125;;36284:15;;;;36267:33;;36284:15;;36267:16;:33::i;:::-;36246:4;:18;;;:54;;;;:::i;:::-;36176:125;;;36228:1;36176:125;36158:143;-1:-1:-1;36337:15:0;36318;;;;;;:34;;;;;;;;:::i;:::-;;36314:1878;;36387:7;36373:11;:21;36369:1496;;;36415:24;36457:7;36443:11;:21;36442:47;;36482:7;36442:47;;;36468:11;36442:47;36415:74;;36508:18;36549:11;36530:16;:30;36529:111;;36639:1;36529:111;;;36585:30;36604:11;36585:16;:30;:::i;:::-;36508:132;;36661:18;36695:12;;36682:10;:25;;;;:::i;:::-;36766:15;;;;36661:46;;-1:-1:-1;36726:18:0;;36747:35;;36766:15;;36747:18;:35::i;:::-;36726:56;;36803:23;36863:3;36849:10;36830:16;;:29;;;;:::i;:::-;36829:37;;;;:::i;:::-;36887:15;36905:23;;;:13;:23;;;;;;36803:63;;-1:-1:-1;36951:12:0;;;36947:31;;-1:-1:-1;36975:3:0;36947:31;36999:20;37066:3;37037:25;37055:7;37037:15;:25;:::i;:::-;37036:33;;;;:::i;:::-;37022:48;;:10;:48;:::i;:::-;36999:71;-1:-1:-1;37089:27:0;36999:71;37089:27;;:::i;:::-;;;37155:7;37141:11;:21;37137:334;;;37187:20;37210:21;37224:7;37210:11;:21;:::i;:::-;37187:44;;37254:20;37292:12;;37277;:27;;;;:::i;:::-;37254:50;;37327:21;37382:3;37371:7;37352:16;;:26;;;;:::i;:::-;37351:34;;;;:::i;:::-;37327:58;-1:-1:-1;37423:28:0;37327:58;37423:12;:28;:::i;:::-;37408:43;;;;:::i;:::-;;;37164:307;;;37137:334;36396:1090;;;;;;;36314:1878;;36369:1496;37558:17;37589:12;;37578:8;:23;;;;:::i;:::-;37620:15;37638:23;;;:13;:23;;;;;;37558:43;;-1:-1:-1;37684:12:0;;;37680:31;;-1:-1:-1;37708:3:0;37680:31;37732:21;37787:3;37776:7;37757:16;;:26;;;;:::i;:::-;37756:34;;;;:::i;:::-;37732:58;-1:-1:-1;37824:25:0;37732:58;37824:9;:25;:::i;:::-;37809:40;;;;:::i;:::-;;;37492:373;;;36314:1878;;;37921:17;37952:12;;37941:8;:23;;;;:::i;:::-;37979:15;37997:23;;;:13;:23;;;;;;37921:43;;-1:-1:-1;38039:12:0;;;38035:31;;-1:-1:-1;38063:3:0;38035:31;38083:13;38130:3;38119:7;38100:16;;:26;;;;:::i;:::-;38099:34;;;;:::i;:::-;38083:50;-1:-1:-1;38163:17:0;38083:50;38163:9;:17;:::i;:::-;38148:32;;;;:::i;:::-;;38211:11;-1:-1:-1;;;;;;;;;;;35702:2528:0:o;40972:369::-;41040:7;41074:17;41064:6;:27;;;;;;;;:::i;:::-;;41060:255;;-1:-1:-1;;41115:14:0;;;40972:369::o;41060:255::-;41161:17;41151:6;:27;;;;;;;;:::i;:::-;;41147:168;;-1:-1:-1;;41202:14:0;;;40972:369::o;41147:168::-;41248:17;41238:6;:27;;;;;;;;:::i;:::-;;41234:81;;-1:-1:-1;;41289:14:0;;;40972:369::o;41234:81::-;-1:-1:-1;41332:1:0;;40972:369;-1:-1:-1;40972:369:0:o;41456:397::-;41526:7;41560:17;41550:6;:27;;;;;;;;:::i;:::-;;41546:261;;-1:-1:-1;;41601:16:0;;;41456:397::o;41546:261::-;41649:17;41639:6;:27;;;;;;;;:::i;:::-;;41635:172;;-1:-1:-1;;41690:16:0;;;41456:397::o;41635:172::-;41738:17;41728:6;:27;;;;;;;;:::i;:::-;;41724:83;;-1:-1:-1;;41779:16:0;;;41456:397::o;41724:83::-;-1:-1:-1;41824:3:0;;41456:397;-1:-1:-1;41456:397:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;381:367::-;444:8;454:6;508:3;501:4;493:6;489:17;485:27;475:55;;526:1;523;516:12;475:55;-1:-1:-1;549:20:1;;592:18;581:30;;578:50;;;624:1;621;614:12;578:50;661:4;653:6;649:17;637:29;;721:3;714:4;704:6;701:1;697:14;689:6;685:27;681:38;678:47;675:67;;;738:1;735;728:12;675:67;381:367;;;;;:::o;753:787::-;889:6;897;905;913;966:2;954:9;945:7;941:23;937:32;934:52;;;982:1;979;972:12;934:52;1022:9;1009:23;1051:18;1092:2;1084:6;1081:14;1078:34;;;1108:1;1105;1098:12;1078:34;1147:70;1209:7;1200:6;1189:9;1185:22;1147:70;:::i;:::-;1236:8;;-1:-1:-1;1121:96:1;-1:-1:-1;1324:2:1;1309:18;;1296:32;;-1:-1:-1;1340:16:1;;;1337:36;;;1369:1;1366;1359:12;1337:36;;1408:72;1472:7;1461:8;1450:9;1446:24;1408:72;:::i;:::-;753:787;;;;-1:-1:-1;1499:8:1;-1:-1:-1;;;;753:787:1:o;2323:140::-;-1:-1:-1;;;;;2407:31:1;;2397:42;;2387:70;;2453:1;2450;2443:12;2468:271;2542:6;2595:2;2583:9;2574:7;2570:23;2566:32;2563:52;;;2611:1;2608;2601:12;2563:52;2650:9;2637:23;2669:40;2703:5;2669:40;:::i;:::-;2728:5;2468:271;-1:-1:-1;;;2468:271:1:o;2744:437::-;2830:6;2838;2891:2;2879:9;2870:7;2866:23;2862:32;2859:52;;;2907:1;2904;2897:12;2859:52;2947:9;2934:23;2980:18;2972:6;2969:30;2966:50;;;3012:1;3009;3002:12;2966:50;3051:70;3113:7;3104:6;3093:9;3089:22;3051:70;:::i;:::-;3140:8;;3025:96;;-1:-1:-1;2744:437:1;-1:-1:-1;;;;2744:437:1:o;3447:127::-;3508:10;3503:3;3499:20;3496:1;3489:31;3539:4;3536:1;3529:15;3563:4;3560:1;3553:15;3579:238;3661:1;3654:5;3651:12;3641:143;;3706:10;3701:3;3697:20;3694:1;3687:31;3741:4;3738:1;3731:15;3769:4;3766:1;3759:15;3641:143;3793:18;;3579:238::o;3822:1176::-;4045:2;4097:21;;;4167:13;;4070:18;;;4189:22;;;4016:4;;4045:2;4230;;4248:18;;;;4289:15;;;4016:4;4332:640;4346:6;4343:1;4340:13;4332:640;;;4405:13;;4447:9;;-1:-1:-1;;;;;4443:35:1;4431:48;;4519:11;;;4513:18;4499:12;;;4492:40;4572:11;;;4566:18;4552:12;;;4545:40;4608:4;4652:11;;;4646:18;4632:12;;;4625:40;4688:4;4731:11;;;4725:18;4756:54;4797:12;;;4725:18;4756:54;:::i;:::-;-1:-1:-1;;4833:4:1;4877:11;;;4871:18;4857:12;;;4850:40;4919:4;4910:14;;;;4947:15;;;;4368:1;4361:9;4332:640;;;-1:-1:-1;4989:3:1;;3822:1176;-1:-1:-1;;;;;;;3822:1176:1:o;5278:324::-;5346:6;5354;5407:2;5395:9;5386:7;5382:23;5378:32;5375:52;;;5423:1;5420;5413:12;5375:52;5462:9;5449:23;5481:40;5515:5;5481:40;:::i;:::-;5540:5;5592:2;5577:18;;;;5564:32;;-1:-1:-1;;;5278:324:1:o;5815:593::-;-1:-1:-1;;;;;6132:32:1;;6114:51;;6196:2;6181:18;;6174:34;;;6239:2;6224:18;;6217:34;;;6282:2;6267:18;;6260:34;;;6101:3;6086:19;;6303:55;6353:3;6338:19;;6330:6;6303:55;:::i;:::-;6395:6;6389:3;6378:9;6374:19;6367:35;5815:593;;;;;;;;;:::o;6636:523::-;6740:6;6748;6756;6764;6772;6780;6833:3;6821:9;6812:7;6808:23;6804:33;6801:53;;;6850:1;6847;6840:12;6801:53;-1:-1:-1;;6873:23:1;;;6943:2;6928:18;;6915:32;;-1:-1:-1;6994:2:1;6979:18;;6966:32;;7045:2;7030:18;;7017:32;;-1:-1:-1;7096:3:1;7081:19;;7068:33;;-1:-1:-1;7148:3:1;7133:19;7120:33;;-1:-1:-1;6636:523:1;-1:-1:-1;6636:523:1:o;7386:632::-;7557:2;7609:21;;;7679:13;;7582:18;;;7701:22;;;7528:4;;7557:2;7780:15;;;;7754:2;7739:18;;;7528:4;7823:169;7837:6;7834:1;7831:13;7823:169;;;7898:13;;7886:26;;7967:15;;;;7932:12;;;;7859:1;7852:9;7823:169;;;-1:-1:-1;8009:3:1;;7386:632;-1:-1:-1;;;;;;7386:632:1:o;8023:345::-;8225:2;8207:21;;;8264:2;8244:18;;;8237:30;-1:-1:-1;;;8298:2:1;8283:18;;8276:51;8359:2;8344:18;;8023:345::o;8373:127::-;8434:10;8429:3;8425:20;8422:1;8415:31;8465:4;8462:1;8455:15;8489:4;8486:1;8479:15;8505:334;8707:2;8689:21;;;8746:2;8726:18;;;8719:30;-1:-1:-1;;;8780:2:1;8765:18;;8758:40;8830:2;8815:18;;8505:334::o;8844:270::-;8917:6;8970:2;8958:9;8949:7;8945:23;8941:32;8938:52;;;8986:1;8983;8976:12;8938:52;9025:9;9012:23;9064:1;9057:5;9054:12;9044:40;;9080:1;9077;9070:12;9473:184;9543:6;9596:2;9584:9;9575:7;9571:23;9567:32;9564:52;;;9612:1;9609;9602:12;9564:52;-1:-1:-1;9635:16:1;;9473:184;-1:-1:-1;9473:184:1:o;9662:127::-;9723:10;9718:3;9714:20;9711:1;9704:31;9754:4;9751:1;9744:15;9778:4;9775:1;9768:15;9794:168;9867:9;;;9898;;9915:15;;;9909:22;;9895:37;9885:71;;9936:18;;:::i;9967:217::-;10007:1;10033;10023:132;;10077:10;10072:3;10068:20;10065:1;10058:31;10112:4;10109:1;10102:15;10140:4;10137:1;10130:15;10023:132;-1:-1:-1;10169:9:1;;9967:217::o;10189:125::-;10254:9;;;10275:10;;;10272:36;;;10288:18;;:::i;10319:127::-;10380:10;10375:3;10371:20;10368:1;10361:31;10411:4;10408:1;10401:15;10435:4;10432:1;10425:15;10451:375;-1:-1:-1;;;;;10709:15:1;;;10691:34;;10761:15;;;;10756:2;10741:18;;10734:43;10808:2;10793:18;;10786:34;;;;10641:2;10626:18;;10451:375::o;11110:277::-;11177:6;11230:2;11218:9;11209:7;11205:23;11201:32;11198:52;;;11246:1;11243;11236:12;11198:52;11278:9;11272:16;11331:5;11324:13;11317:21;11310:5;11307:32;11297:60;;11353:1;11350;11343:12;11392:128;11459:9;;;11480:11;;;11477:37;;;11494:18;;:::i;11525:127::-;11586:10;11581:3;11577:20;11574:1;11567:31;11617:4;11614:1;11607:15;11641:4;11638:1;11631:15;13403:280;13589:25;;;13577:2;13562:18;;13623:54;13673:2;13658:18;;13650:6;13623:54;:::i
Swarm Source
ipfs://d6512025beb4d0383dcc5a6a0d4bae55bc44f6a8ca78f3af309df7f9a9bf123b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.