More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 274 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 16091911 | 849 days ago | IN | 0 ETH | 0.00720919 | ||||
Unstake | 15985434 | 864 days ago | IN | 0 ETH | 0.00503262 | ||||
Unstake Token | 15980514 | 865 days ago | IN | 0 ETH | 0.00252295 | ||||
Unstake Token | 15980485 | 865 days ago | IN | 0 ETH | 0.00282484 | ||||
Unstake Token | 15980483 | 865 days ago | IN | 0 ETH | 0.00267344 | ||||
Unstake Token | 15980481 | 865 days ago | IN | 0 ETH | 0.00290485 | ||||
Unstake Token | 15980479 | 865 days ago | IN | 0 ETH | 0.00465832 | ||||
Unstake | 15612580 | 916 days ago | IN | 0 ETH | 0.00128758 | ||||
Claim | 15595304 | 919 days ago | IN | 0 ETH | 0.00142115 | ||||
Unstake | 15489923 | 935 days ago | IN | 0 ETH | 0.00210758 | ||||
Claim | 15489920 | 935 days ago | IN | 0 ETH | 0.00163517 | ||||
Safe Transfer Fr... | 15488762 | 935 days ago | IN | 0 ETH | 0.00103081 | ||||
Set Document | 15485321 | 935 days ago | IN | 0 ETH | 0.004672 | ||||
Set Document | 15485320 | 935 days ago | IN | 0 ETH | 0.00334412 | ||||
Set Document | 15485317 | 935 days ago | IN | 0 ETH | 0.00452661 | ||||
Unstake | 15402178 | 949 days ago | IN | 0 ETH | 0.00375468 | ||||
Stake | 15289532 | 967 days ago | IN | 0 ETH | 0.00150478 | ||||
Claim | 15289497 | 967 days ago | IN | 0 ETH | 0.00270301 | ||||
Claim | 15183026 | 983 days ago | IN | 0 ETH | 0.00357948 | ||||
Unstake | 15142073 | 989 days ago | IN | 0 ETH | 0.01180694 | ||||
Claim | 15142072 | 989 days ago | IN | 0 ETH | 0.0125738 | ||||
Unstake | 15039694 | 1006 days ago | IN | 0 ETH | 0.01215095 | ||||
Unstake | 14970781 | 1018 days ago | IN | 0 ETH | 0.00649447 | ||||
Unstake | 14970501 | 1018 days ago | IN | 0 ETH | 0.00747059 | ||||
Unstake | 14943935 | 1023 days ago | IN | 0 ETH | 0.00809031 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
JellyPool
Compiler Version
v0.8.6+commit.11564f7e
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.8.6; /** * @title Jelly Pool V1.3: * * ,,,, * g@@@@@@K * l@@@@@@@@P * $@@@@@@@" l@@@ l@@@ * "*NNM" l@@@ l@@@ * l@@@ l@@@ * ,g@@@g ,,gg@gg, l@@@ l@@@ ,ggg ,ggg * @@@@@@@@p g@@@EEEEE@@W l@@@ l@@@ $@@g ,@@@Y * l@@@@@@@@@ @@@P ]@@@ l@@@ l@@@ $@@g ,@@@Y * l@@@@@@@@@ $@@D,,,,,,,,]@@@ l@@@ l@@@ '@@@p @@@Y * l@@@@@@@@@ @@@@EEEEEEEEEEEE l@@@ l@@@ "@@@p @@@Y * l@@@@@@@@@ l@@K l@@@ l@@@ '@@@, @@@Y * @@@@@@@@@ %@@@, ,g@@@ l@@@ l@@@ ^@@@@@@Y * "@@@@@@@@ "N@@@@@@@@E' l@@@ l@@@ "*@@@Y * "J@@@@@@ "**"" ''' ''' @@@Y * ,gg@@g "J@@@P @@@Y * @@@@@@@@p J@@' @@@Y * @@@@@@@@P J@h RNNY * 'B@@@@@@ $P * "JE@@@p"' * * */ /** * @author ProfWobble * @dev * - Pool Contract with Staking NFTs: * - Mints NFTs on stake() which represent staked tokens * and claimable rewards in the pool. * - Supports Merkle proofs using the JellyList interface. * - External rewarder logic for multiple pools. * - NFT attributes onchain via the descriptor. * */ import "IJellyAccessControls.sol"; import "IJellyRewarder.sol"; import "IJellyPool.sol"; import "IJellyContract.sol"; import "IMerkleList.sol"; import "IDescriptor.sol"; import "SafeERC20.sol"; import "Documents.sol"; import "BoringMath.sol"; import "JellyPoolNFT.sol"; contract JellyPool is IJellyPool, IJellyContract, JellyPoolNFT, Documents { using SafeERC20 for OZIERC20; /// @notice Jelly template id for the pool factory. /// @dev For different pool types, this must be incremented. uint256 public override constant TEMPLATE_TYPE = 2; bytes32 public override constant TEMPLATE_ID = keccak256("JELLY_POOL"); uint256 public constant pointMultiplier = 10e12; IJellyAccessControls public accessControls; IJellyRewarder public rewardsContract; IDescriptor public descriptor; /// @notice Token to stake. address public override poolToken; address public owner; struct PoolSettings { bool tokensClaimable; bool useList; bool useListAmounts; bool initialised; uint256 transferTimeout; /// @notice Address that manages approvals. address list; } PoolSettings public poolSettings; /// @notice Total tokens staked. uint256 public override stakedTokenTotal; struct RewardInfo { uint48 lastUpdateTime; uint208 rewardsPerTokenPoints; } /// @notice reward token address => rewardsPerTokenPoints mapping(address => RewardInfo) public poolRewards; address[] public rewardTokens; struct TokenRewards { uint128 rewardsEarned; uint128 rewardsReleased; uint48 lastUpdateTime; uint208 lastRewardPoints; } /// @notice Mapping from tokenId => rewards token => reward info. mapping (uint256 => mapping(address => TokenRewards)) public tokenRewards; struct TokenInfo { uint128 staked; uint48 lastUpdateTime; } /// @notice Mapping from tokenId => token info. mapping (uint256 => TokenInfo) public tokenInfo; struct UserPool { uint128 stakeLimit; } /// @notice user address => pool details mapping(address => UserPool) public userPool; /** * @notice Event emitted when claimable status is updated. * @param status True or False. */ event TokensClaimable(bool status); /** * @notice Event emitted when rewards contract has been updated. * @param oldRewardsToken Address of the old reward token contract. * @param newRewardsToken Address of the new reward token contract. */ event RewardsContractSet(address indexed oldRewardsToken, address newRewardsToken); /** * @notice Event emmited when a user has staked LPs. * @param owner Address of the staker. * @param amount Amount staked in LP tokens. */ event Staked(address indexed owner, uint256 amount); /** * @notice Event emitted when a user claims rewards. * @param user Address of the user. * @param reward Reward amount. */ event RewardsClaimed(address indexed user, uint256 reward); /** * @notice Event emitted when a user has unstaked LPs. * @param owner Address of the unstaker. * @param amount Amount unstaked in LP tokens. */ event Unstaked(address indexed owner, uint256 amount); /** * @notice Event emitted when user unstaked in emergency mode. * @param user Address of the user. * @param tokenId unstaked tokenId. */ event EmergencyUnstake(address indexed user, uint256 tokenId); constructor() { } //-------------------------------------------------------- // Pool Config //-------------------------------------------------------- /** * @notice Admin can change rewards contract through this function. * @param _addr Address of the new rewards contract. */ function setRewardsContract(address _addr) external override { require(accessControls.hasAdminRole(msg.sender)); require(_addr != address(0)); emit RewardsContractSet(address(rewardsContract), _addr); rewardsContract = IJellyRewarder(_addr); rewardTokens = rewardsContract.rewardTokens(address(this)); } /** * @notice Admin can set reward tokens claimable through this function. * @param _enabled True or False. */ function setTokensClaimable(bool _enabled) external override { require(accessControls.hasAdminRole(msg.sender)); emit TokensClaimable(_enabled); poolSettings.tokensClaimable = _enabled; } /** * @notice Getter function for tokens claimable. */ function tokensClaimable() external override view returns(bool) { return poolSettings.tokensClaimable; } //-------------------------------------------------------- // Jelly Pool NFTs //-------------------------------------------------------- /** * @notice Set the token URI descriptor. * @dev Only callable by the admin. */ function setDescriptor(address _descriptor) external { require(accessControls.hasAdminRole(msg.sender)); descriptor = IDescriptor(_descriptor); } /** * @notice Set admin details of the NFT including owner, token name and symbol. * @dev Only callable by the admin. */ function setTokenDetails(string memory _name, string memory _symbol, address _owner) external { require(accessControls.hasAdminRole(msg.sender)); tokenName = _name; tokenSymbol = _symbol; owner = _owner; } /** * @notice Add a delay between updating staked position and a token transfer. * @dev Only callable by the admin. */ function setTransferTimeout(uint256 _timeout) external { require(accessControls.hasAdminRole(msg.sender)); require(_timeout < block.timestamp); poolSettings.transferTimeout = _timeout; } function getOwnerTokens(address _owner) public view returns (uint256[] memory) { uint256 count = balanceOf(_owner); uint256[] memory tokenIds = new uint256[](count); for(uint i = 0; i < count; i++) { tokenIds[i] = _ownedTokens[_owner][i]; } return tokenIds; } /** * @notice A distinct Uniform Resource Identifier (URI) for a given asset. * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId), 'Non-existent token'); return descriptor.tokenURI(_tokenId); } /** * @notice Includes a configurable delay between updating staked position and a token transfer. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { for(uint i = 0; i < rewardTokens.length; i++) { require(tokenRewards[tokenId][rewardTokens[i]].lastUpdateTime <= block.timestamp - uint256(poolSettings.transferTimeout), "Staked value recently updated"); } super._beforeTokenTransfer(from, to, tokenId); } //-------------------------------------------------------- // Verify //-------------------------------------------------------- /** * @notice Whitelisted staking * @param _merkleRoot List identifier. * @param _index User index. * @param _user User address. * @param _stakeLimit Max amount of tokens stakable by user, set in proof. * @param _data Bytes array to send to the list contract. */ function verify(bytes32 _merkleRoot, uint256 _index, address _user, uint256 _stakeLimit, bytes32[] calldata _data ) public { UserPool storage _userPool = userPool[_user]; require(_stakeLimit > 0, "Limit must be > 0"); if (_stakeLimit > uint256(_userPool.stakeLimit)) { uint256 merkleAmount = IMerkleList(poolSettings.list).tokensClaimable(_merkleRoot, _index, _user, _stakeLimit, _data ); require(merkleAmount > 0, "Incorrect merkle proof"); _userPool.stakeLimit = BoringMath.to128(merkleAmount); } } /** * @notice Function for verifying whitelist, staking and minting a Staking NFT * @param _amount Number of tokens in merkle proof. * @param _merkleRoot Merkle root. * @param _index Merkle index. * @param _stakeLimit Max amount of tokens stakable by user, set in proof. * @param _data Bytes array to send to the list contract. */ function verifyAndStake(uint256 _amount, bytes32 _merkleRoot, uint256 _index, uint256 _stakeLimit, bytes32[] calldata _data ) external { verify(_merkleRoot, _index, msg.sender, _stakeLimit, _data ); _stake(msg.sender, _amount); } //-------------------------------------------------------- // Stake //-------------------------------------------------------- /** * @notice Deposits tokens into the JellyPool and mints a Staking NFT * @param _amount Number of tokens deposited into the pool. */ function stake(uint256 _amount) external { _stake(msg.sender, _amount); } /** * @notice Internal staking function called by both verifyAndStake() and stake(). * @param _user Stakers address. * @param _amount Number of tokens to deposit. */ function _stake( address _user, uint256 _amount ) internal { require( _amount > 0, "Amount must be > 0" ); /// @dev If a whitelist is set, this checks user balance. if (poolSettings.useList) { if (poolSettings.useListAmounts) { require(_amount < userPool[_user].stakeLimit); } else { require(userPool[_user].stakeLimit > 0); } } /// @dev Mints a Staking NFT if the user doesnt already have one. if (balanceOf(_user) == 0) { // Mints new Staking NFT uint256 _tokenId = _safeMint(_user); // Sets initial rewards points for(uint i = 0; i < rewardTokens.length; i++) { address rewardToken = rewardTokens[i]; if(tokenRewards[_tokenId][rewardToken].lastRewardPoints == 0) { tokenRewards[_tokenId][rewardToken].lastRewardPoints = poolRewards[rewardToken].rewardsPerTokenPoints; } } } /// We always add balance to the users first token. uint256 tokenId = _ownedTokens[_user][0]; /// Updates internal accounting and stakes tokens snapshot(tokenId); tokenInfo[tokenId] = TokenInfo(tokenInfo[tokenId].staked + BoringMath.to128(_amount) , BoringMath.to48(block.timestamp) ); stakedTokenTotal += BoringMath.to128(_amount); OZIERC20(poolToken).safeTransferFrom( address(_user), address(this), _amount ); emit Staked(_user, _amount); } /** * @notice Returns the number of tokens staked for a tokenID. * @param _tokenId TokenID to be checked. */ function stakedBalance(uint256 _tokenId) external view override returns(uint256){ return tokenInfo[_tokenId].staked; } //-------------------------------------------------------- // Rewards //-------------------------------------------------------- /// @dev Updates the rewards accounting onchain for a specific tokenID. function snapshot( uint256 _tokenId ) public { require(_exists(_tokenId), 'Non-existent token'); IJellyRewarder rewarder = rewardsContract; rewarder.updateRewards(); uint256 sTotal = stakedTokenTotal; for(uint i = 0; i < rewardTokens.length; i++) { address rewardToken = rewardTokens[i]; RewardInfo storage rInfo = poolRewards[rewardTokens[i]]; /// Get total pool rewards from rewarder uint208 currentRewardPoints; if (sTotal == 0) { currentRewardPoints = rInfo.rewardsPerTokenPoints; } else { uint256 currentRewards = rewarder.poolRewards(address(this), rewardToken, uint256(rInfo.lastUpdateTime), block.timestamp); /// Convert to reward points currentRewardPoints = rInfo.rewardsPerTokenPoints + BoringMath.to208(currentRewards * 1e18 * pointMultiplier / sTotal); } /// Update reward info rInfo.rewardsPerTokenPoints = currentRewardPoints; rInfo.lastUpdateTime = BoringMath.to48(block.timestamp) ; _updateTokenRewards(_tokenId, rewardToken, currentRewardPoints); } } function _updateTokenRewards(uint256 _tokenId, address _rewardToken, uint208 currentRewardPoints) internal { TokenRewards storage _tokenRewards = tokenRewards[_tokenId][_rewardToken]; // update token rewards _tokenRewards.rewardsEarned += BoringMath.to128(tokenInfo[_tokenId].staked * uint256(currentRewardPoints -_tokenRewards.lastRewardPoints) / 1e18 / pointMultiplier); // Update token details _tokenRewards.lastUpdateTime = BoringMath.to48(block.timestamp); _tokenRewards.lastRewardPoints = currentRewardPoints; } //-------------------------------------------------------- // Claim //-------------------------------------------------------- /** * @notice Claim rewards for all Staking NFTS owned by the sender. */ function claim() external { require( poolSettings.tokensClaimable == true, "Not yet claimable" ); uint256[] memory tokenIds = getOwnerTokens(msg.sender); if (tokenIds.length > 0) { for(uint i = 0; i < tokenIds.length; i++) { snapshot(tokenIds[i]); } for(uint j = 0; j < rewardTokens.length; j++) { _claimRewards(tokenIds, rewardTokens[j], msg.sender); } } } /** * @notice Claiming rewards on behalf of a token ID. * @param _tokenId Token ID. */ function fancyClaim(uint256 _tokenId) public { claimRewards(_tokenId, rewardTokens); } /** * @notice Claiming rewards for user for specific rewards. * @param _tokenId Token ID. */ function claimRewards(uint256 _tokenId, address[] memory _rewardTokens) public { require( poolSettings.tokensClaimable == true, "Not yet claimable" ); snapshot(_tokenId); uint256[] memory tokenIds = new uint256[](1); tokenIds[0] = _tokenId; address recipient = ownerOf(_tokenId); for(uint i = 0; i < _rewardTokens.length; i++) { _claimRewards(tokenIds, _rewardTokens[i], recipient); } } /** * @notice Claiming rewards for user. * @param _tokenIds Array of Token IDs. */ function _claimRewards(uint256[] memory _tokenIds, address _rewardToken, address _recipient) internal { uint256 payableAmount; uint128 rewards; for(uint i = 0; i < _tokenIds.length; i++) { TokenRewards storage _tokenRewards = tokenRewards[_tokenIds[i]][_rewardToken]; rewards = _tokenRewards.rewardsEarned - _tokenRewards.rewardsReleased; payableAmount += uint256(rewards); _tokenRewards.rewardsReleased += rewards; } OZIERC20(_rewardToken).safeTransfer(_recipient, payableAmount); emit RewardsClaimed(_recipient, payableAmount); } //-------------------------------------------------------- // Unstake //-------------------------------------------------------- /** * @notice Function for unstaking exact amount of tokens, claims all rewards. * @param _amount amount of tokens to unstake. */ function unstake(uint256 _amount) external { uint256[] memory tokenIds = getOwnerTokens(msg.sender); uint256 unstakeAmount; require(tokenIds.length > 0, "Nothing to unstake"); for(uint i = 0; i < tokenIds.length; i++) { if (_amount > 0) { unstakeAmount = tokenInfo[tokenIds[i]].staked; if (unstakeAmount > _amount) { unstakeAmount = _amount; } _amount = _amount - unstakeAmount; fancyClaim(tokenIds[i]); _unstake(msg.sender, tokenIds[i], unstakeAmount); } } } /** * @notice Function for unstaking exact amount of tokens, for a specific NFT token id. * @param _tokenId TokenID to be unstaked * @param _amount amount of tokens to unstake. */ function unstakeToken(uint256 _tokenId, uint256 _amount) external { require( ownerOf(_tokenId) == msg.sender, "Must own tokenId" ); fancyClaim(_tokenId); _unstake(msg.sender, _tokenId, _amount); } /** * @notice Function that executes the unstaking. * @param _user Stakers address. * @param _tokenId Number of tokens to unstake. * @param _amount amount of tokens to unstake. */ function _unstake(address _user, uint256 _tokenId, uint256 _amount) internal { tokenInfo[_tokenId] = TokenInfo(tokenInfo[_tokenId].staked - BoringMath.to128(_amount) , BoringMath.to48(block.timestamp) ); stakedTokenTotal -= BoringMath.to128(_amount); if (tokenInfo[_tokenId].staked == 0) { delete tokenInfo[_tokenId]; _burn(_tokenId); } uint256 tokenBal = OZIERC20(poolToken).balanceOf(address(this)); if (_amount > tokenBal) { _amount = tokenBal; } OZIERC20(poolToken).safeTransfer(address(_user), _amount); emit Unstaked(_user, _amount); } /** * @notice Unstake without rewards. EMERGENCY ONLY. */ function emergencyUnstake(uint256 _tokenId) external { require( ownerOf(_tokenId) == msg.sender, "Must own tokenId" ); _unstake(msg.sender, _tokenId, tokenInfo[_tokenId].staked); emit EmergencyUnstake(msg.sender, _tokenId); } //-------------------------------------------------------- // List //-------------------------------------------------------- /** * @notice Address used for whitelist if activated */ function list() external view returns (address) { return poolSettings.list; } function setList(address _list) external { require(accessControls.hasAdminRole(msg.sender)); if (_list != address(0)) { poolSettings.list = _list; } } function enableList(bool _useList, bool _useListAmounts) public { require(accessControls.hasAdminRole(msg.sender)); poolSettings.useList = _useList; poolSettings.useListAmounts = _useListAmounts; } //-------------------------------------------------------- // Documents //-------------------------------------------------------- function setDocument(string calldata _name, string calldata _data) external { require(accessControls.hasAdminRole(msg.sender) ); if (bytes(_data).length > 0) { _setDocument( _name, _data); } else { _removeDocument(_name); } } //-------------------------------------------------------- // Factory //-------------------------------------------------------- /** * @notice Initializes main contract variables. * @dev Init function. * @param _poolToken Address of the pool token. * @param _accessControls Access controls interface. */ function initJellyPool( address _poolToken, address _accessControls ) public { require(!poolSettings.initialised); poolToken = _poolToken; accessControls = IJellyAccessControls(_accessControls); poolSettings.initialised = true; } function init(bytes calldata _data) external override payable {} function initContract( bytes calldata _data ) external override { ( address _poolToken, address _accessControls ) = abi.decode(_data, (address, address)); initJellyPool( _poolToken, _accessControls ); } }
pragma solidity 0.8.6; interface IJellyAccessControls { function hasAdminRole(address _address) external view returns (bool); function addAdminRole(address _address) external; function removeAdminRole(address _address) external; function hasMinterRole(address _address) external view returns (bool); function addMinterRole(address _address) external; function removeMinterRole(address _address) external; function hasOperatorRole(address _address) external view returns (bool); function addOperatorRole(address _address) external; function removeOperatorRole(address _address) external; function initAccessControls(address _admin) external ; }
pragma solidity 0.8.6; interface IJellyRewarder { // function setRewards( // uint256[] memory rewardPeriods, // uint256[] memory amounts // ) external; // function setBonus( // uint256 poolId, // uint256[] memory rewardPeriods, // uint256[] memory amounts // ) external; function updateRewards() external returns(bool); // function updateRewards(address _pool) external returns(bool); function totalRewards(address _poolAddress) external view returns (uint256 rewards); function totalRewards() external view returns (address[] memory, uint256[] memory); // function poolRewards(uint256 _pool, uint256 _from, uint256 _to) external view returns (uint256 rewards); function poolRewards(address _pool, address _rewardToken, uint256 _from, uint256 _to) external view returns (uint256 rewards); function rewardTokens() external view returns (address[] memory rewards); function rewardTokens(address _pool) external view returns (address[] memory rewards); function poolCount() external view returns (uint256); function setPoolPoints(address _poolAddress, uint256 _poolPoints) external; function setVault(address _addr) external; function addRewardsToPool( address _poolAddress, address _rewardAddress, uint256 _startTime, uint256 _duration, uint256 _amount ) external ; }
pragma solidity 0.8.6; interface IJellyPool { function setRewardsContract(address _addr) external; function setTokensClaimable(bool _enabled) external; function stakedTokenTotal() external view returns(uint256); function stakedBalance(uint256 _tokenId) external view returns(uint256); function tokensClaimable() external view returns(bool); function poolToken() external view returns(address); }
pragma solidity 0.8.6; import "IMasterContract.sol"; interface IJellyContract is IMasterContract { /// @notice Init function that gets called from `BoringFactory.deploy`. /// Also kown as the constructor for cloned contracts. function TEMPLATE_ID() external view returns(bytes32); function TEMPLATE_TYPE() external view returns(uint256); function initContract( bytes calldata data ) external; }
pragma solidity 0.8.6; interface IMasterContract { /// @notice Init function that gets called from `BoringFactory.deploy`. /// Also kown as the constructor for cloned contracts. /// Any ETH send to `BoringFactory.deploy` ends up here. /// @param data Can be abi encoded arguments or anything else. function init(bytes calldata data) external payable; }
pragma solidity 0.8.6; interface IMerkleList { function tokensClaimable(uint256 _index, address _account, uint256 _amount, bytes32[] calldata _merkleProof ) external view returns (bool); function tokensClaimable(bytes32 _merkleRoot, uint256 _index, address _account, uint256 _amount, bytes32[] calldata _merkleProof ) external view returns (uint256); function currentMerkleURI() external view returns (string memory); function initMerkleList(address accessControl) external ; function addProof(bytes32 _merkleRoot, string memory _merkleURI) external; }
pragma solidity 0.8.6; interface IDescriptor { function tokenURI( uint256 tokenId ) external view returns (string memory); }
pragma solidity ^0.8.0; import "OZIERC20.sol"; import "Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( OZIERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( OZIERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( OZIERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( OZIERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( OZIERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(OZIERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface OZIERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "insufficient balance for call"); require(isContract(target), "call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
pragma solidity 0.8.6; // pragma experimental ABIEncoderV2; /** * @title Standard implementation of ERC1643 Document management */ contract Documents { struct Document { uint32 docIndex; // Store the document name indexes uint64 lastModified; // Timestamp at which document details was last modified string data; // data of the document that exist off-chain } // mapping to store the documents details in the document mapping(string => Document) internal _documents; // mapping to store the document name indexes mapping(string => uint32) internal _docIndexes; // Array use to store all the document name present in the contracts string[] _docNames; // Document Events event DocumentRemoved(string indexed _name, string _data); event DocumentUpdated(string indexed _name, string _data); /** * @notice Used to attach a new document to the contract, or update the data or hash of an existing attached document * @dev Can only be executed by the owner of the contract. * @param _name Name of the document. It should be unique always * @param _data Off-chain data of the document from where it is accessible to investors/advisors to read. */ function _setDocument(string calldata _name, string calldata _data) internal { require(bytes(_name).length > 0); // dev: Zero name is not allowed require(bytes(_data).length > 0); // dev: Zero data is not allowed // Document storage document = _documents[_name]; if (_documents[_name].lastModified == uint64(0)) { _docNames.push(_name); _documents[_name].docIndex = uint32(_docNames.length); } _documents[_name] = Document(_documents[_name].docIndex, uint64(block.timestamp), _data); emit DocumentUpdated(_name, _data); } /** * @notice Used to remove an existing document from the contract by giving the name of the document. * @dev Can only be executed by the owner of the contract. * @param _name Name of the document. It should be unique always */ function _removeDocument(string calldata _name) internal { require(_documents[_name].lastModified != uint64(0)); // dev: Document should exist uint32 index = _documents[_name].docIndex - 1; if (index != _docNames.length - 1) { _docNames[index] = _docNames[_docNames.length - 1]; _documents[_docNames[index]].docIndex = index + 1; } _docNames.pop(); emit DocumentRemoved(_name, _documents[_name].data); delete _documents[_name]; } /** * @notice Used to return the details of a document with a known name (`string`). * @param _name Name of the document * @return string The data associated with the document. * @return uint256 the timestamp at which the document was last modified. */ function getDocument(string calldata _name) external view returns (string memory, uint256) { return ( _documents[_name].data, uint256(_documents[_name].lastModified) ); } /** * @notice Used to retrieve a full list of documents attached to the smart contract. * @return string List of all documents names present in the contract. */ function getAllDocuments() external view returns (string[] memory) { return _docNames; } /** * @notice Used to retrieve the total documents in the smart contract. * @return uint256 Count of the document names present in the contract. */ function getDocumentCount() external view returns (uint256) { return _docNames.length; } /** * @notice Used to retrieve the document name from index in the smart contract. * @return string Name of the document name. */ function getDocumentName(uint256 _index) external view returns (string memory) { require(_index < _docNames.length); // dev: Index out of bounds return _docNames[_index]; } }
pragma solidity 0.8.6; /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). library BoringMath { function add(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint256 a, uint256 b) internal pure returns (uint256 c) { require(b > 0, "BoringMath: Div zero"); c = a / b; } function to224(uint256 a) internal pure returns (uint224 c) { require(a <= type(uint224).max, "BoringMath: uint224 Overflow"); c = uint224(a); } function to208(uint256 a) internal pure returns (uint208 c) { require(a <= type(uint208).max, "BoringMath: uint128 Overflow"); c = uint208(a); } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= type(uint128).max, "BoringMath: uint128 Overflow"); c = uint128(a); } function to64(uint256 a) internal pure returns (uint64 c) { require(a <= type(uint64).max, "BoringMath: uint64 Overflow"); c = uint64(a); } function to48(uint256 a) internal pure returns (uint48 c) { require(a <= type(uint48).max); c = uint48(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= type(uint32).max); c = uint32(a); } function to16(uint256 a) internal pure returns (uint16 c) { require(a <= type(uint16).max); c = uint16(a); } function to8(uint256 a) internal pure returns (uint8 c) { require(a <= type(uint8).max); c = uint8(a); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint224. library BoringMath224 { function add(uint224 a, uint224 b) internal pure returns (uint224 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint224 a, uint224 b) internal pure returns (uint224 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint224. library BoringMath208 { function add(uint208 a, uint208 b) internal pure returns (uint224 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint208 a, uint208 b) internal pure returns (uint224 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint128. library BoringMath128 { function add(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint64. library BoringMath64 { function add(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint48. library BoringMath48 { function add(uint48 a, uint48 b) internal pure returns (uint48 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint48 a, uint48 b) internal pure returns (uint48 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. library BoringMath32 { function add(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. library BoringMath16 { function add(uint16 a, uint16 b) internal pure returns (uint16 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint16 a, uint16 b) internal pure returns (uint16 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint8. library BoringMath8 { function add(uint8 a, uint8 b) internal pure returns (uint8 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint8 a, uint8 b) internal pure returns (uint8 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } }
pragma solidity 0.8.6; import "ERC721SemiNumerable.sol"; import "Counters.sol"; contract JellyPoolNFT is ERC721SemiNumerable { using Counters for Counters.Counter; Counters.Counter internal _tokenIdTracker; constructor() ERC721("JellyPool NFT","JPOOL") { } function _safeMint(address _user) internal returns (uint256){ uint256 _tokenId = _tokenIdTracker.current(); _safeMint(_user, _tokenId); _tokenIdTracker.increment(); return _tokenId; } }
pragma solidity ^0.8.0; import "ERC721.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721SemiNumerable is ERC721 { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) internal _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) { require(index < ERC721.balanceOf(owner), "Index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } }
pragma solidity ^0.8.0; import "IERC721.sol"; import "IERC721Receiver.sol"; import "IERC721Metadata.sol"; import "Address.sol"; import "Context.sol"; import "Strings.sol"; import "ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string internal tokenName; // Token symbol string internal tokenSymbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { tokenName = name_; tokenSymbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0)); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0)); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return tokenName; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return tokenSymbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "Non-existent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "Approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "Not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "Non-existent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId)); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "Not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @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. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "Non ERC721Receiver"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "Non-existent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "Non ERC721Receiver" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0)); require(!_exists(tokenId)); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "Not owner of token"); require(to != address(0)); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
pragma solidity ^0.8.0; import "IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
pragma solidity ^0.8.0; import "IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0); return string(buffer); } }
pragma solidity ^0.8.0; import "IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
{ "evmVersion": "istanbul", "optimizer": { "enabled": true, "runs": 99999 }, "libraries": { "JellyPool.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"_name","type":"string"},{"indexed":false,"internalType":"string","name":"_data","type":"string"}],"name":"DocumentRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"_name","type":"string"},{"indexed":false,"internalType":"string","name":"_data","type":"string"}],"name":"DocumentUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EmergencyUnstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRewardsToken","type":"address"},{"indexed":false,"internalType":"address","name":"newRewardsToken","type":"address"}],"name":"RewardsContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"TokensClaimable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"TEMPLATE_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TEMPLATE_TYPE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accessControls","outputs":[{"internalType":"contract IJellyAccessControls","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address[]","name":"_rewardTokens","type":"address[]"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"descriptor","outputs":[{"internalType":"contract IDescriptor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"emergencyUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_useList","type":"bool"},{"internalType":"bool","name":"_useListAmounts","type":"bool"}],"name":"enableList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"fancyClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllDocuments","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"getDocument","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDocumentCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getDocumentName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getOwnerTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"init","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_poolToken","type":"address"},{"internalType":"address","name":"_accessControls","type":"address"}],"name":"initJellyPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"list","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pointMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolRewards","outputs":[{"internalType":"uint48","name":"lastUpdateTime","type":"uint48"},{"internalType":"uint208","name":"rewardsPerTokenPoints","type":"uint208"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolSettings","outputs":[{"internalType":"bool","name":"tokensClaimable","type":"bool"},{"internalType":"bool","name":"useList","type":"bool"},{"internalType":"bool","name":"useListAmounts","type":"bool"},{"internalType":"bool","name":"initialised","type":"bool"},{"internalType":"uint256","name":"transferTimeout","type":"uint256"},{"internalType":"address","name":"list","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsContract","outputs":[{"internalType":"contract IJellyRewarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_descriptor","type":"address"}],"name":"setDescriptor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_data","type":"string"}],"name":"setDocument","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_list","type":"address"}],"name":"setList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"setRewardsContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_owner","type":"address"}],"name":"setTokenDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setTokensClaimable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timeout","type":"uint256"}],"name":"setTransferTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"snapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"stakedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakedTokenTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenInfo","outputs":[{"internalType":"uint128","name":"staked","type":"uint128"},{"internalType":"uint48","name":"lastUpdateTime","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"tokenRewards","outputs":[{"internalType":"uint128","name":"rewardsEarned","type":"uint128"},{"internalType":"uint128","name":"rewardsReleased","type":"uint128"},{"internalType":"uint48","name":"lastUpdateTime","type":"uint48"},{"internalType":"uint208","name":"lastRewardPoints","type":"uint208"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensClaimable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstakeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userPool","outputs":[{"internalType":"uint128","name":"stakeLimit","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_stakeLimit","type":"uint256"},{"internalType":"bytes32[]","name":"_data","type":"bytes32[]"}],"name":"verify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_stakeLimit","type":"uint256"},{"internalType":"bytes32[]","name":"_data","type":"bytes32[]"}],"name":"verifyAndStake","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604080518082018252600d81526c12995b1b1e541bdbdb08139195609a1b602080830191825283518085019094526005845264129413d3d360da1b908401528151919291620000649160009162000083565b5080516200007a90600190602084019062000083565b50505062000166565b828054620000919062000129565b90600052602060002090601f016020900481019282620000b5576000855562000100565b82601f10620000d057805160ff191683800117855562000100565b8280016001018555821562000100579182015b8281111562000100578251825591602001919060010190620000e3565b506200010e92915062000112565b5090565b5b808211156200010e576000815560010162000113565b600181811c908216806200013e57607f821691505b602082108114156200016057634e487b7160e01b600052602260045260246000fd5b50919050565b615ebd80620001766000396000f3fe6080604052600436106103815760003560e01c80638bb7352c116101d1578063c6b547e611610102578063db92feca116100a0578063e985e9c51161006f578063e985e9c514610d38578063f256cad514610d8e578063f8f40e2914610dcd578063ffa7a4a314610ded57600080fd5b8063db92feca14610bc0578063dd5aba4b14610c62578063dfa0dfa514610cf8578063e719ca9c14610d1857600080fd5b8063cc33c875116100dc578063cc33c87514610ac7578063d63d4af014610b53578063d69d3e6214610b80578063db2de3ff14610ba057600080fd5b8063c6b547e614610a5a578063c87b56dd14610a7a578063cbdf382c14610a9a57600080fd5b80639dc7cddc1161016f578063a694fc3a11610149578063a694fc3a146109da578063b88d4fde146109fa578063bcad0d6014610a1a578063c059a24314610a3a57600080fd5b80639dc7cddc146109825780639fa5f50b14610998578063a22cb465146109ba57600080fd5b80638f1dd809116101ab5780638f1dd809146108cd57806395d89b41146108ed57806397434ce7146109025780639c64d0ae1461096257600080fd5b80638bb7352c146107895780638c7542e9146108805780638da5cb5b146108a057600080fd5b8063351dfba0116102b65780636352211e116102545780637a7b3508116102235780637a7b3508146106e75780637bb7bed1146107075780637ccb6a641461072757806387eb502e1461075557600080fd5b80636352211e14610660578063658b98a91461068057806370a082311461069a578063748365ef146106ba57600080fd5b80634d806abd116102905780634d806abd146105f95780634ddf47d4146106195780634e71d92d1461062b578063542360fd1461064057600080fd5b8063351dfba0146105a45780633d1c2273146105c457806342842e0e146105d957600080fd5b80630f560cd7116103235780632e17de78116102fd5780632e17de781461051f5780632f745c591461053f578063303e74df1461055f57806331f684c01461058c57600080fd5b80630f560cd7146104a7578063220cce97146104d257806323b872dd146104ff57600080fd5b806306fdde031161035f57806306fdde03146103fd578063081812fc1461041f578063095ea7b3146104645780630b24dbda1461048457600080fd5b8063012ce5011461038657806301b9a397146103a857806301ffc9a7146103c8575b600080fd5b34801561039257600080fd5b506103a66103a136600461551a565b610e0d565b005b3480156103b457600080fd5b506103a66103c3366004615066565b610eff565b3480156103d457600080fd5b506103e86103e3366004615343565b610ff0565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b506104126110d5565b6040516103f49190615973565b34801561042b57600080fd5b5061043f61043a36600461551a565b611167565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103f4565b34801561047057600080fd5b506103a661047f3660046151ab565b61121b565b34801561049057600080fd5b50610499600281565b6040519081526020016103f4565b3480156104b357600080fd5b5060135473ffffffffffffffffffffffffffffffffffffffff1661043f565b3480156104de57600080fd5b50600d5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050b57600080fd5b506103a661051a3660046150bc565b61135c565b34801561052b57600080fd5b506103a661053a36600461551a565b61137a565b34801561054b57600080fd5b5061049961055a3660046151ab565b6114c0565b34801561056b57600080fd5b50600e5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561059857600080fd5b5060115460ff166103e8565b3480156105b057600080fd5b506103a66105bf3660046152b2565b611569565b3480156105d057600080fd5b50600b54610499565b3480156105e557600080fd5b506103a66105f43660046150bc565b611679565b34801561060557600080fd5b506103a661061436600461537d565b611694565b6103a661062736600461537d565b5050565b34801561063757600080fd5b506103a66116b1565b34801561064c57600080fd5b506103a661065b366004615278565b6117d9565b34801561066c57600080fd5b5061043f61067b36600461551a565b6118e9565b34801561068c57600080fd5b506104996509184e72a00081565b3480156106a657600080fd5b506104996106b5366004615066565b611918565b3480156106c657600080fd5b50600c5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156106f357600080fd5b506103a6610702366004615083565b611963565b34801561071357600080fd5b5061043f61072236600461551a565b6119fb565b34801561073357600080fd5b5061074761074236600461537d565b611a32565b6040516103f4929190615986565b34801561076157600080fd5b506104997fbe99a7819011738128e6033b2899e7050b9a3a4971747a96ac5121fae159ba4a81565b34801561079557600080fd5b506108236107a436600461554c565b6017602090815260009283526040808420909152908252902080546001909101546fffffffffffffffffffffffffffffffff808316927001000000000000000000000000000000009004169065ffffffffffff8116906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1684565b604080516fffffffffffffffffffffffffffffffff958616815294909316602085015265ffffffffffff9091169183019190915279ffffffffffffffffffffffffffffffffffffffffffffffffffff1660608201526080016103f4565b34801561088c57600080fd5b506103a661089b366004615571565b611b2b565b3480156108ac57600080fd5b5060105461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156108d957600080fd5b506103a66108e836600461551a565b611c3d565b3480156108f957600080fd5b50610412611ff5565b34801561090e57600080fd5b5061094161091d366004615066565b6019602052600090815260409020546fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff90911681526020016103f4565b34801561096e57600080fd5b506103a661097d3660046153bf565b612004565b34801561098e57600080fd5b5061049960145481565b3480156109a457600080fd5b506109ad6120cf565b6040516103f491906157db565b3480156109c657600080fd5b506103a66109d536600461517d565b6121a8565b3480156109e657600080fd5b506103a66109f536600461551a565b6122bf565b348015610a0657600080fd5b506103a6610a153660046150fd565b6122c9565b348015610a2657600080fd5b506103a6610a3536600461551a565b612345565b348015610a4657600080fd5b506103a6610a553660046154a2565b612400565b348015610a6657600080fd5b50610412610a7536600461551a565b61251b565b348015610a8657600080fd5b50610412610a9536600461551a565b6125d9565b348015610aa657600080fd5b50600f5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610ad357600080fd5b50610b24610ae236600461551a565b6018602052600090815260409020546fffffffffffffffffffffffffffffffff811690700100000000000000000000000000000000900465ffffffffffff1682565b604080516fffffffffffffffffffffffffffffffff909316835265ffffffffffff9091166020830152016103f4565b348015610b5f57600080fd5b50610b73610b6e366004615066565b61272b565b6040516103f4919061585b565b348015610b8c57600080fd5b506103a6610b9b366004615066565b6127f6565b348015610bac57600080fd5b506103a6610bbb36600461561e565b612901565b348015610bcc57600080fd5b50601154601254601354610c159260ff808216936101008304821693620100008404831693630100000090049092169173ffffffffffffffffffffffffffffffffffffffff1686565b60408051961515875294151560208701529215159385019390935215156060840152608083019190915273ffffffffffffffffffffffffffffffffffffffff1660a082015260c0016103f4565b348015610c6e57600080fd5b50610cbf610c7d366004615066565b60156020526000908152604090205465ffffffffffff8116906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1682565b6040805165ffffffffffff909316835279ffffffffffffffffffffffffffffffffffffffffffffffffffff9091166020830152016103f4565b348015610d0457600080fd5b506103a6610d13366004615066565b612921565b348015610d2457600080fd5b506103a6610d333660046152d0565b612b3a565b348015610d4457600080fd5b506103e8610d53366004615083565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610d9a57600080fd5b50610499610da936600461551a565b6000908152601860205260409020546fffffffffffffffffffffffffffffffff1690565b348015610dd957600080fd5b506103a6610de836600461551a565b612d4e565b348015610df957600080fd5b506103a6610e0836600461566a565b612dbf565b33610e17826118e9565b73ffffffffffffffffffffffffffffffffffffffff1614610e99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d757374206f776e20746f6b656e49640000000000000000000000000000000060448201526064015b60405180910390fd5b600081815260186020526040902054610ec790339083906fffffffffffffffffffffffffffffffff16612e56565b60405181815233907f571394674ec9d9e81517060110f8f894ce912af2b2febc091bee0cdea68adf009060200160405180910390a250565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa09190615295565b610fa957600080fd5b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061108357507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806110cf57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6060600080546110e490615ce0565b80601f016020809104026020016040519081016040528092919081815260200182805461111090615ce0565b801561115d5780601f106111325761010080835404028352916020019161115d565b820191906000526020600020905b81548152906001019060200180831161114057829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166111f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000611226826118e9565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156112be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f417070726f76616c20746f2063757272656e74206f776e6572000000000000006044820152606401610e90565b3373ffffffffffffffffffffffffffffffffffffffff821614806112e757506112e78133610d53565b61134d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c00006044820152606401610e90565b61135783836130ee565b505050565b611366338261318e565b61136f57600080fd5b6113578383836132d8565b60006113853361272b565b90506000808251116113f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f7468696e6720746f20756e7374616b6500000000000000000000000000006044820152606401610e90565b60005b82518110156114ba5783156114a8576018600084838151811061141b5761141b615dcb565b6020908102919091018101518252810191909152604001600020546fffffffffffffffffffffffffffffffff16915083821115611456578391505b6114608285615c80565b935061148483828151811061147757611477615dcb565b6020026020010151612d4e565b6114a83384838151811061149a5761149a615dcb565b602002602001015184612e56565b806114b281615d34565b9150506113f6565b50505050565b60006114cb83611918565b8210611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401610e90565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b1580156115d257600080fd5b505afa1580156115e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160a9190615295565b61161357600080fd5b601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff16610100931515939093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff16929092176201000091151591909102179055565b611357838383604051806020016040528060008152506122c9565b6000806116a383850185615083565b915091506114ba8282611963565b60115460ff161515600114611722576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f742079657420636c61696d61626c650000000000000000000000000000006044820152606401610e90565b600061172d3361272b565b8051909150156117d65760005b81518110156117775761176582828151811061175857611758615dcb565b6020026020010151611c3d565b8061176f81615d34565b91505061173a565b5060005b601654811015610627576117c4826016838154811061179c5761179c615dcb565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16336134a2565b806117ce81615d34565b91505061177b565b50565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561184257600080fd5b505afa158015611856573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187a9190615295565b61188357600080fd5b60405181151581527fb6088c1c0a66042d23ce101cb07e7080b262a8a6525dba7b56e994f99d9bb5549060200160405180910390a1601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806110cf57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff821661193a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b6011546301000000900460ff161561197a57600080fd5b600f805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600c8054929093169116179055601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff166301000000179055565b60168181548110611a0b57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6060600060098484604051611a489291906156f2565b908152602001604051809103902060010160098585604051611a6b9291906156f2565b90815260405190819003602001902054815467ffffffffffffffff64010000000090920491909116908290611a9f90615ce0565b80601f0160208091040260200160405190810160405280929190818152602001828054611acb90615ce0565b8015611b185780601f10611aed57610100808354040283529160200191611b18565b820191906000526020600020905b815481529060010190602001808311611afb57829003601f168201915b50505050509150915091505b9250929050565b60115460ff161515600114611b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f742079657420636c61696d61626c650000000000000000000000000000006044820152606401610e90565b611ba582611c3d565b604080516001808252818301909252600091602080830190803683370190505090508281600081518110611bdb57611bdb615dcb565b6020026020010181815250506000611bf2846118e9565b905060005b8351811015611c3657611c2483858381518110611c1657611c16615dcb565b6020026020010151846134a2565b80611c2e81615d34565b915050611bf7565b5050505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b600d54604080517f3e158b0c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216918291633e158b0c9160048083019260209291908290030181600087803b158015611d3657600080fd5b505af1158015611d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6e9190615295565b5060145460005b6016548110156114ba57600060168281548110611d9457611d94615dcb565b60009182526020822001546016805473ffffffffffffffffffffffffffffffffffffffff909216935060159183919086908110611dd357611dd3615dcb565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040018120915084611e39575080546601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16611f66565b81546040517f4f4cd33e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff858116602483015265ffffffffffff9092166044820152426064820152600091881690634f4cd33e9060840160206040518083038186803b158015611ec057600080fd5b505afa158015611ed4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef89190615533565b9050611f30866509184e72a000611f1784670de0b6b3a7640000615bdf565b611f219190615bdf565b611f2b9190615ba4565b61365b565b8354611f6291906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16615b38565b9150505b815465ffffffffffff16660100000000000079ffffffffffffffffffffffffffffffffffffffffffffffffffff831602178255611fa2426136e5565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000001665ffffffffffff91909116178255611fdf8784836136fa565b5050508080611fed90615d34565b915050611d75565b6060600180546110e490615ce0565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561206d57600080fd5b505afa158015612081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a59190615295565b6120ae57600080fd5b80156120c5576120c084848484613877565b6114ba565b6114ba8484613abd565b6060600b805480602002602001604051908101604052809291908181526020016000905b8282101561219f57838290600052602060002001805461211290615ce0565b80601f016020809104026020016040519081016040528092919081815260200182805461213e90615ce0565b801561218b5780601f106121605761010080835404028352916020019161218b565b820191906000526020600020905b81548152906001019060200180831161216e57829003601f168201915b5050505050815260200190600101906120f3565b50505050905090565b73ffffffffffffffffffffffffffffffffffffffff8216331415612228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f617070726f766520746f2063616c6c65720000000000000000000000000000006044820152606401610e90565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6117d63382613d3a565b6122d3338361318e565b612339576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610e90565b6114ba84848484614148565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b1580156123ae57600080fd5b505afa1580156123c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e69190615295565b6123ef57600080fd5b4281106123fb57600080fd5b601255565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561246957600080fd5b505afa15801561247d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a19190615295565b6124aa57600080fd5b82516124bd906000906020860190614d2f565b5081516124d1906001906020850190614d2f565b50601080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b600b54606090821061252c57600080fd5b600b828154811061253f5761253f615dcb565b90600052602060002001805461255490615ce0565b80601f016020809104026020016040519081016040528092919081815260200182805461258090615ce0565b80156125cd5780601f106125a2576101008083540402835291602001916125cd565b820191906000526020600020905b8154815290600101906020018083116125b057829003601f168201915b50505050509050919050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16612667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b600e546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c87b56dd9060240160006040518083038186803b1580156126d157600080fd5b505afa1580156126e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110cf919081019061542b565b6060600061273883611918565b905060008167ffffffffffffffff81111561275557612755615dfa565b60405190808252806020026020018201604052801561277e578160200160208202803683370190505b50905060005b828110156127ee5773ffffffffffffffffffffffffffffffffffffffff8516600090815260066020908152604080832084845290915290205482518390839081106127d1576127d1615dcb565b6020908102919091010152806127e681615d34565b915050612784565b509392505050565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561285f57600080fd5b505afa158015612873573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128979190615295565b6128a057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116156117d6576013805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905550565b61290f858533868686612b3a565b6129193387613d3a565b505050505050565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561298a57600080fd5b505afa15801561299e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c29190615295565b6129cb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81166129eb57600080fd5b600d5460405173ffffffffffffffffffffffffffffffffffffffff8381168252909116907f2e1b1ec770eb46a856f99429bd4157515f465cb04c90951962aabbb1b301333f9060200160405180910390a2600d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517ff5ab16cc00000000000000000000000000000000000000000000000000000000815230600482015263f5ab16cc9060240160006040518083038186803b158015612acc57600080fd5b505afa158015612ae0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612b2691908101906151d7565b805161062791601691602090910190614daf565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260196020526040902083612bc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4c696d6974206d757374206265203e20300000000000000000000000000000006044820152606401610e90565b80546fffffffffffffffffffffffffffffffff16841115612d45576013546040517fb7d6a23100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff169063b7d6a23190612c42908b908b908b908b908b908b9060040161589f565b60206040518083038186803b158015612c5a57600080fd5b505afa158015612c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c929190615533565b905060008111612cfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e636f7272656374206d65726b6c652070726f6f66000000000000000000006044820152606401610e90565b612d07816141c5565b82547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91909116178255505b50505050505050565b6117d6816016805480602002602001604051908101604052809291908181526020018280548015612db557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612d8a575b5050505050611b2b565b33612dc9836118e9565b73ffffffffffffffffffffffffffffffffffffffff1614612e46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d757374206f776e20746f6b656e4964000000000000000000000000000000006044820152606401610e90565b612e4f82612d4e565b6106273383835b6040518060400160405280612e6a836141c5565b600085815260186020526040902054612e9591906fffffffffffffffffffffffffffffffff16615c1c565b6fffffffffffffffffffffffffffffffff168152602001612eb5426136e5565b65ffffffffffff9081169091526000848152601860209081526040909120835181549490920151909216700100000000000000000000000000000000027fffffffffffffffffffff000000000000000000000000000000000000000000009093166fffffffffffffffffffffffffffffffff90911617919091179055612f3a816141c5565b6fffffffffffffffffffffffffffffffff1660146000828254612f5d9190615c80565b90915550506000828152601860205260409020546fffffffffffffffffffffffffffffffff16612fc457600082815260186020526040902080547fffffffffffffffffffff00000000000000000000000000000000000000000000169055612fc482614241565b600f546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b15801561302e57600080fd5b505afa158015613042573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130669190615533565b905080821115613074578091505b600f546130989073ffffffffffffffffffffffffffffffffffffffff16858461431a565b8373ffffffffffffffffffffffffffffffffffffffff167f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75836040516130e091815260200190565b60405180910390a250505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190613148826118e9565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16613219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b6000613224836118e9565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061329357508373ffffffffffffffffffffffffffffffffffffffff1661327b84611167565b73ffffffffffffffffffffffffffffffffffffffff16145b806132d0575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff166132f8826118e9565b73ffffffffffffffffffffffffffffffffffffffff1614613375576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f74206f776e6572206f6620746f6b656e00000000000000000000000000006044820152606401610e90565b73ffffffffffffffffffffffffffffffffffffffff821661339557600080fd5b6133a08383836143ee565b6133ab6000826130ee565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906133e1908490615c80565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061341c908490615b6d565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60008060005b85518110156135e2576000601760008884815181106134c9576134c9615dcb565b6020908102919091018101518252818101929092526040908101600090812073ffffffffffffffffffffffffffffffffffffffff8a1682529092529020805490915061353d906fffffffffffffffffffffffffffffffff700100000000000000000000000000000000820481169116615c1c565b925061355b6fffffffffffffffffffffffffffffffff841685615b6d565b81549094508390829060109061359890849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16615b04565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505080806135da90615d34565b9150506134a8565b5061360473ffffffffffffffffffffffffffffffffffffffff8516848461431a565b8273ffffffffffffffffffffffffffffffffffffffff167ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe8360405161364c91815260200190565b60405180910390a25050505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff8211156136e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006044820152606401610e90565b5090565b600065ffffffffffff8211156136e157600080fd5b600083815260176020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902060018101546137d4906509184e72a00090670de0b6b3a764000090613774906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1686615c4d565b6000888152601860205260409020546137bb9179ffffffffffffffffffffffffffffffffffffffffffffffffffff16906fffffffffffffffffffffffffffffffff16615bdf565b6137c59190615ba4565b6137cf9190615ba4565b6141c5565b815482906000906137f89084906fffffffffffffffffffffffffffffffff16615b04565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550613837426136e5565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff90921666010000000000000265ffffffffffff92909216919091176001909101555050565b8261388157600080fd5b8061388b57600080fd5b600067ffffffffffffffff16600985856040516138a99291906156f2565b9081526040519081900360200190205467ffffffffffffffff64010000000090910416141561396b57600b805460018101825560009190915261390f907f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9018585614e29565b50600b5460405160099061392690879087906156f2565b908152604051908190036020019020805463ffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009092169190911790555b6040518060600160405280600986866040516139889291906156f2565b90815260408051602092819003830190205463ffffffff1683524267ffffffffffffffff16838301528051601f8601839004830281018301825285815292019190859085908190840183828082843760009201919091525050509152506040516009906139f890879087906156f2565b90815260408051918290036020908101909220835181548585015167ffffffffffffffff16640100000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911663ffffffff909216919091171781559083015180519192613a7192600185019290910190614d2f565b5050604051613a849150859085906156f2565b60405180910390207fbaa206e5ea800eb88bce099f453fee53295b793b9d5d1cfc4ce4b6db06a34f5383836040516130e0929190615926565b600067ffffffffffffffff1660098383604051613adb9291906156f2565b9081526040519081900360200190205467ffffffffffffffff640100000000909104161415613b0957600080fd5b6000600160098484604051613b1f9291906156f2565b90815260405190819003602001902054613b3f919063ffffffff16615c97565b600b54909150613b5190600190615c80565b8163ffffffff1614613c4457600b8054613b6d90600190615c80565b81548110613b7d57613b7d615dcb565b90600052602060002001600b8263ffffffff1681548110613ba057613ba0615dcb565b90600052602060002001908054613bb690615ce0565b613bc1929190614ebb565b50613bcd816001615b85565b6009600b8363ffffffff1681548110613be857613be8615dcb565b90600052602060002001604051613bff9190615702565b908152604051908190036020019020805463ffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009092169190911790555b600b805480613c5557613c55615d9c565b600190038181906000526020600020016000613c719190614f36565b90558282604051613c839291906156f2565b60405180910390207f4b5338540b4d1c0f6dd0308a25f633b7ff60472f894d711cff9dd64e35c613b260098585604051613cbe9291906156f2565b9081526020016040518091039020600101604051613cdc91906159a8565b60405180910390a260098383604051613cf69291906156f2565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681556000611c366001830182614f36565b60008111613da4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f416d6f756e74206d757374206265203e203000000000000000000000000000006044820152606401610e90565b601154610100900460ff1615613e4e5760115462010000900460ff1615613e0d5773ffffffffffffffffffffffffffffffffffffffff82166000908152601960205260409020546fffffffffffffffffffffffffffffffff168110613e0857600080fd5b613e4e565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601960205260409020546fffffffffffffffffffffffffffffffff16613e4e57600080fd5b613e5782611918565b613f88576000613e66836144f0565b905060005b601654811015613f8557600060168281548110613e8a57613e8a615dcb565b600091825260208083209091015485835260178252604080842073ffffffffffffffffffffffffffffffffffffffff9092168085529190925291206001015490915079ffffffffffffffffffffffffffffffffffffffffffffffffffff660100000000000090910416613f725773ffffffffffffffffffffffffffffffffffffffff811660008181526015602090815260408083205487845260178352818420948452939091529020600101805465ffffffffffff1666010000000000009283900479ffffffffffffffffffffffffffffffffffffffffffffffffffff169092029190911790555b5080613f7d81615d34565b915050613e6b565b50505b73ffffffffffffffffffffffffffffffffffffffff82166000908152600660209081526040808320838052909152902054613fc281611c3d565b6040518060400160405280613fd6846141c5565b60008481526018602052604090205461400191906fffffffffffffffffffffffffffffffff16615b04565b6fffffffffffffffffffffffffffffffff168152602001614021426136e5565b65ffffffffffff9081169091526000838152601860209081526040909120835181549490920151909216700100000000000000000000000000000000027fffffffffffffffffffff000000000000000000000000000000000000000000009093166fffffffffffffffffffffffffffffffff909116179190911790556140a6826141c5565b6fffffffffffffffffffffffffffffffff16601460008282546140c99190615b6d565b9091555050600f546140f39073ffffffffffffffffffffffffffffffffffffffff16843085614516565b8273ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d8360405161413b91815260200190565b60405180910390a2505050565b6141538484846132d8565b61415f84848484614574565b6114ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e20455243373231526563656976657200000000000000000000000000006044820152606401610e90565b60006fffffffffffffffffffffffffffffffff8211156136e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006044820152606401610e90565b600061424c826118e9565b905061425a816000846143ee565b6142656000836130ee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080546001929061429b908490615c80565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113579084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526146f0565b60005b6016548110156144e4576012546144089042615c80565b6000838152601760205260408120601680549192918590811061442d5761442d615dcb565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190206001015465ffffffffffff1611156144d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f5374616b65642076616c756520726563656e746c7920757064617465640000006044820152606401610e90565b806144dc81615d34565b9150506143f1565b506113578383836147fc565b6000806144fc60085490565b905061450883826148b6565b6110cf600880546001019055565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526114ba9085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161436c565b600073ffffffffffffffffffffffffffffffffffffffff84163b156146e5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a02906145eb903390899088908890600401615792565b602060405180830381600087803b15801561460557600080fd5b505af1925050508015614653575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261465091810190615360565b60015b61469a573d808015614681576040519150601f19603f3d011682016040523d82523d6000602084013e614686565b606091505b50805161469257600080fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506132d0565b506001949350505050565b6000614752826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166148d09092919063ffffffff16565b80519091501561135757808060200190518101906147709190615295565b611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610e90565b73ffffffffffffffffffffffffffffffffffffffff831661481c57614859565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146148595761485983826148e9565b73ffffffffffffffffffffffffffffffffffffffff821661487957505050565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113575761135782826149a0565b6106278282604051806020016040528060008152506149f1565b60606148df8484600085614a6e565b90505b9392505050565b600060016148f684611918565b6149009190615c80565b6000838152600760205260409020549091508082146149605773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b60006149ab83611918565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6149fb8383614bc8565b614a086000848484614574565b611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e20455243373231526563656976657200000000000000000000000000006044820152606401610e90565b606082471015614ada576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f696e73756666696369656e742062616c616e636520666f722063616c6c0000006044820152606401610e90565b843b614b42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f63616c6c20746f206e6f6e2d636f6e74726163740000000000000000000000006044820152606401610e90565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051614b6b91906156d6565b60006040518083038185875af1925050503d8060008114614ba8576040519150601f19603f3d011682016040523d82523d6000602084013e614bad565b606091505b5091509150614bbd828286614cdc565b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216614be857600080fd5b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615614c1757600080fd5b614c23600083836143ee565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290614c59908490615b6d565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608315614ceb5750816148e2565b825115614cfb5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e909190615973565b828054614d3b90615ce0565b90600052602060002090601f016020900481019282614d5d5760008555614da3565b82601f10614d7657805160ff1916838001178555614da3565b82800160010185558215614da3579182015b82811115614da3578251825591602001919060010190614d88565b506136e1929150614f6c565b828054828255906000526020600020908101928215614da3579160200282015b82811115614da357825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614dcf565b828054614e3590615ce0565b90600052602060002090601f016020900481019282614e575760008555614da3565b82601f10614e8e578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555614da3565b82800160010185558215614da3579182015b82811115614da3578235825591602001919060010190614ea0565b828054614ec790615ce0565b90600052602060002090601f016020900481019282614ee95760008555614da3565b82601f10614efa5780548555614da3565b82800160010185558215614da357600052602060002091601f016020900482015b82811115614da3578254825591600101919060010190614f1b565b508054614f4290615ce0565b6000825580601f10614f52575050565b601f0160209004906000526020600020908101906117d691905b5b808211156136e15760008155600101614f6d565b6000614f94614f8f84615abe565b615a4b565b9050828152838383011115614fa857600080fd5b828260208301376000602084830101529392505050565b60008083601f840112614fd157600080fd5b50813567ffffffffffffffff811115614fe957600080fd5b6020830191508360208260051b8501011115611b2457600080fd5b60008083601f84011261501657600080fd5b50813567ffffffffffffffff81111561502e57600080fd5b602083019150836020828501011115611b2457600080fd5b600082601f83011261505757600080fd5b6148e283833560208501614f81565b60006020828403121561507857600080fd5b81356148e281615e29565b6000806040838503121561509657600080fd5b82356150a181615e29565b915060208301356150b181615e29565b809150509250929050565b6000806000606084860312156150d157600080fd5b83356150dc81615e29565b925060208401356150ec81615e29565b929592945050506040919091013590565b6000806000806080858703121561511357600080fd5b843561511e81615e29565b9350602085013561512e81615e29565b925060408501359150606085013567ffffffffffffffff81111561515157600080fd5b8501601f8101871361516257600080fd5b61517187823560208401614f81565b91505092959194509250565b6000806040838503121561519057600080fd5b823561519b81615e29565b915060208301356150b181615e4b565b600080604083850312156151be57600080fd5b82356151c981615e29565b946020939093013593505050565b600060208083850312156151ea57600080fd5b825167ffffffffffffffff81111561520157600080fd5b8301601f8101851361521257600080fd5b8051615220614f8f82615a9a565b80828252848201915084840188868560051b870101111561524057600080fd5b600094505b8385101561526c57805161525881615e29565b835260019490940193918501918501615245565b50979650505050505050565b60006020828403121561528a57600080fd5b81356148e281615e4b565b6000602082840312156152a757600080fd5b81516148e281615e4b565b600080604083850312156152c557600080fd5b823561519b81615e4b565b60008060008060008060a087890312156152e957600080fd5b8635955060208701359450604087013561530281615e29565b935060608701359250608087013567ffffffffffffffff81111561532557600080fd5b61533189828a01614fbf565b979a9699509497509295939492505050565b60006020828403121561535557600080fd5b81356148e281615e59565b60006020828403121561537257600080fd5b81516148e281615e59565b6000806020838503121561539057600080fd5b823567ffffffffffffffff8111156153a757600080fd5b6153b385828601615004565b90969095509350505050565b600080600080604085870312156153d557600080fd5b843567ffffffffffffffff808211156153ed57600080fd5b6153f988838901615004565b9096509450602087013591508082111561541257600080fd5b5061541f87828801615004565b95989497509550505050565b60006020828403121561543d57600080fd5b815167ffffffffffffffff81111561545457600080fd5b8201601f8101841361546557600080fd5b8051615473614f8f82615abe565b81815285602083850101111561548857600080fd5b615499826020830160208601615cb4565b95945050505050565b6000806000606084860312156154b757600080fd5b833567ffffffffffffffff808211156154cf57600080fd5b6154db87838801615046565b945060208601359150808211156154f157600080fd5b506154fe86828701615046565b925050604084013561550f81615e29565b809150509250925092565b60006020828403121561552c57600080fd5b5035919050565b60006020828403121561554557600080fd5b5051919050565b6000806040838503121561555f57600080fd5b8235915060208301356150b181615e29565b6000806040838503121561558457600080fd5b8235915060208084013567ffffffffffffffff8111156155a357600080fd5b8401601f810186136155b457600080fd5b80356155c2614f8f82615a9a565b80828252848201915084840189868560051b87010111156155e257600080fd5b600094505b8385101561560e5780356155fa81615e29565b8352600194909401939185019185016155e7565b5080955050505050509250929050565b60008060008060008060a0878903121561563757600080fd5b86359550602087013594506040870135935060608701359250608087013567ffffffffffffffff81111561532557600080fd5b6000806040838503121561567d57600080fd5b50508035926020909101359150565b600081518084526156a4816020860160208601615cb4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516156e8818460208701615cb4565b9190910192915050565b8183823760009101908152919050565b600080835461571081615ce0565b60018281168015615728576001811461575757615786565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841687528287019450615786565b8760005260208060002060005b8581101561577d5781548a820152908401908201615764565b50505082870194505b50929695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526157d1608083018461568c565b9695505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561584e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261583c85835161568c565b94509285019290850190600101615802565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561589357835183529284019291840191600101615877565b50909695505050505050565b86815285602082015273ffffffffffffffffffffffffffffffffffffffff8516604082015283606082015260a060808201528160a082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561590657600080fd5b8260051b808560c08501376000920160c001918252509695505050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6020815260006148e2602083018461568c565b604081526000615999604083018561568c565b90508260208301529392505050565b60006020808352600084546159bc81615ce0565b808487015260406001808416600081146159dd5760018114615a0f57615a3d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a0152606089019550615a3d565b896000528660002060005b85811015615a355781548b8201860152908301908801615a1a565b8a0184019650505b509398975050505050505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715615a9257615a92615dfa565b604052919050565b600067ffffffffffffffff821115615ab457615ab4615dfa565b5060051b60200190565b600067ffffffffffffffff821115615ad857615ad8615dfa565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615b2f57615b2f615d6d565b01949350505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff808316818516808303821115615b2f57615b2f615d6d565b60008219821115615b8057615b80615d6d565b500190565b600063ffffffff808316818516808303821115615b2f57615b2f615d6d565b600082615bda577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c1757615c17615d6d565b500290565b60006fffffffffffffffffffffffffffffffff83811690831681811015615c4557615c45615d6d565b039392505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff83811690831681811015615c4557615c45615d6d565b600082821015615c9257615c92615d6d565b500390565b600063ffffffff83811690831681811015615c4557615c45615d6d565b60005b83811015615ccf578181015183820152602001615cb7565b838111156114ba5750506000910152565b600181811c90821680615cf457607f821691505b60208210811415615d2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615d6657615d66615d6d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146117d657600080fd5b80151581146117d657600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000811681146117d657600080fdfea2646970667358221220c0066b2da066f889a6d374c8d05bd42e5fb49cbe00d4db104c32c059feadcd8f64736f6c63430008060033
Deployed Bytecode
0x6080604052600436106103815760003560e01c80638bb7352c116101d1578063c6b547e611610102578063db92feca116100a0578063e985e9c51161006f578063e985e9c514610d38578063f256cad514610d8e578063f8f40e2914610dcd578063ffa7a4a314610ded57600080fd5b8063db92feca14610bc0578063dd5aba4b14610c62578063dfa0dfa514610cf8578063e719ca9c14610d1857600080fd5b8063cc33c875116100dc578063cc33c87514610ac7578063d63d4af014610b53578063d69d3e6214610b80578063db2de3ff14610ba057600080fd5b8063c6b547e614610a5a578063c87b56dd14610a7a578063cbdf382c14610a9a57600080fd5b80639dc7cddc1161016f578063a694fc3a11610149578063a694fc3a146109da578063b88d4fde146109fa578063bcad0d6014610a1a578063c059a24314610a3a57600080fd5b80639dc7cddc146109825780639fa5f50b14610998578063a22cb465146109ba57600080fd5b80638f1dd809116101ab5780638f1dd809146108cd57806395d89b41146108ed57806397434ce7146109025780639c64d0ae1461096257600080fd5b80638bb7352c146107895780638c7542e9146108805780638da5cb5b146108a057600080fd5b8063351dfba0116102b65780636352211e116102545780637a7b3508116102235780637a7b3508146106e75780637bb7bed1146107075780637ccb6a641461072757806387eb502e1461075557600080fd5b80636352211e14610660578063658b98a91461068057806370a082311461069a578063748365ef146106ba57600080fd5b80634d806abd116102905780634d806abd146105f95780634ddf47d4146106195780634e71d92d1461062b578063542360fd1461064057600080fd5b8063351dfba0146105a45780633d1c2273146105c457806342842e0e146105d957600080fd5b80630f560cd7116103235780632e17de78116102fd5780632e17de781461051f5780632f745c591461053f578063303e74df1461055f57806331f684c01461058c57600080fd5b80630f560cd7146104a7578063220cce97146104d257806323b872dd146104ff57600080fd5b806306fdde031161035f57806306fdde03146103fd578063081812fc1461041f578063095ea7b3146104645780630b24dbda1461048457600080fd5b8063012ce5011461038657806301b9a397146103a857806301ffc9a7146103c8575b600080fd5b34801561039257600080fd5b506103a66103a136600461551a565b610e0d565b005b3480156103b457600080fd5b506103a66103c3366004615066565b610eff565b3480156103d457600080fd5b506103e86103e3366004615343565b610ff0565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b506104126110d5565b6040516103f49190615973565b34801561042b57600080fd5b5061043f61043a36600461551a565b611167565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103f4565b34801561047057600080fd5b506103a661047f3660046151ab565b61121b565b34801561049057600080fd5b50610499600281565b6040519081526020016103f4565b3480156104b357600080fd5b5060135473ffffffffffffffffffffffffffffffffffffffff1661043f565b3480156104de57600080fd5b50600d5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050b57600080fd5b506103a661051a3660046150bc565b61135c565b34801561052b57600080fd5b506103a661053a36600461551a565b61137a565b34801561054b57600080fd5b5061049961055a3660046151ab565b6114c0565b34801561056b57600080fd5b50600e5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561059857600080fd5b5060115460ff166103e8565b3480156105b057600080fd5b506103a66105bf3660046152b2565b611569565b3480156105d057600080fd5b50600b54610499565b3480156105e557600080fd5b506103a66105f43660046150bc565b611679565b34801561060557600080fd5b506103a661061436600461537d565b611694565b6103a661062736600461537d565b5050565b34801561063757600080fd5b506103a66116b1565b34801561064c57600080fd5b506103a661065b366004615278565b6117d9565b34801561066c57600080fd5b5061043f61067b36600461551a565b6118e9565b34801561068c57600080fd5b506104996509184e72a00081565b3480156106a657600080fd5b506104996106b5366004615066565b611918565b3480156106c657600080fd5b50600c5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156106f357600080fd5b506103a6610702366004615083565b611963565b34801561071357600080fd5b5061043f61072236600461551a565b6119fb565b34801561073357600080fd5b5061074761074236600461537d565b611a32565b6040516103f4929190615986565b34801561076157600080fd5b506104997fbe99a7819011738128e6033b2899e7050b9a3a4971747a96ac5121fae159ba4a81565b34801561079557600080fd5b506108236107a436600461554c565b6017602090815260009283526040808420909152908252902080546001909101546fffffffffffffffffffffffffffffffff808316927001000000000000000000000000000000009004169065ffffffffffff8116906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1684565b604080516fffffffffffffffffffffffffffffffff958616815294909316602085015265ffffffffffff9091169183019190915279ffffffffffffffffffffffffffffffffffffffffffffffffffff1660608201526080016103f4565b34801561088c57600080fd5b506103a661089b366004615571565b611b2b565b3480156108ac57600080fd5b5060105461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156108d957600080fd5b506103a66108e836600461551a565b611c3d565b3480156108f957600080fd5b50610412611ff5565b34801561090e57600080fd5b5061094161091d366004615066565b6019602052600090815260409020546fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff90911681526020016103f4565b34801561096e57600080fd5b506103a661097d3660046153bf565b612004565b34801561098e57600080fd5b5061049960145481565b3480156109a457600080fd5b506109ad6120cf565b6040516103f491906157db565b3480156109c657600080fd5b506103a66109d536600461517d565b6121a8565b3480156109e657600080fd5b506103a66109f536600461551a565b6122bf565b348015610a0657600080fd5b506103a6610a153660046150fd565b6122c9565b348015610a2657600080fd5b506103a6610a3536600461551a565b612345565b348015610a4657600080fd5b506103a6610a553660046154a2565b612400565b348015610a6657600080fd5b50610412610a7536600461551a565b61251b565b348015610a8657600080fd5b50610412610a9536600461551a565b6125d9565b348015610aa657600080fd5b50600f5461043f9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610ad357600080fd5b50610b24610ae236600461551a565b6018602052600090815260409020546fffffffffffffffffffffffffffffffff811690700100000000000000000000000000000000900465ffffffffffff1682565b604080516fffffffffffffffffffffffffffffffff909316835265ffffffffffff9091166020830152016103f4565b348015610b5f57600080fd5b50610b73610b6e366004615066565b61272b565b6040516103f4919061585b565b348015610b8c57600080fd5b506103a6610b9b366004615066565b6127f6565b348015610bac57600080fd5b506103a6610bbb36600461561e565b612901565b348015610bcc57600080fd5b50601154601254601354610c159260ff808216936101008304821693620100008404831693630100000090049092169173ffffffffffffffffffffffffffffffffffffffff1686565b60408051961515875294151560208701529215159385019390935215156060840152608083019190915273ffffffffffffffffffffffffffffffffffffffff1660a082015260c0016103f4565b348015610c6e57600080fd5b50610cbf610c7d366004615066565b60156020526000908152604090205465ffffffffffff8116906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1682565b6040805165ffffffffffff909316835279ffffffffffffffffffffffffffffffffffffffffffffffffffff9091166020830152016103f4565b348015610d0457600080fd5b506103a6610d13366004615066565b612921565b348015610d2457600080fd5b506103a6610d333660046152d0565b612b3a565b348015610d4457600080fd5b506103e8610d53366004615083565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610d9a57600080fd5b50610499610da936600461551a565b6000908152601860205260409020546fffffffffffffffffffffffffffffffff1690565b348015610dd957600080fd5b506103a6610de836600461551a565b612d4e565b348015610df957600080fd5b506103a6610e0836600461566a565b612dbf565b33610e17826118e9565b73ffffffffffffffffffffffffffffffffffffffff1614610e99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d757374206f776e20746f6b656e49640000000000000000000000000000000060448201526064015b60405180910390fd5b600081815260186020526040902054610ec790339083906fffffffffffffffffffffffffffffffff16612e56565b60405181815233907f571394674ec9d9e81517060110f8f894ce912af2b2febc091bee0cdea68adf009060200160405180910390a250565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa09190615295565b610fa957600080fd5b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061108357507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806110cf57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6060600080546110e490615ce0565b80601f016020809104026020016040519081016040528092919081815260200182805461111090615ce0565b801561115d5780601f106111325761010080835404028352916020019161115d565b820191906000526020600020905b81548152906001019060200180831161114057829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166111f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000611226826118e9565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156112be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f417070726f76616c20746f2063757272656e74206f776e6572000000000000006044820152606401610e90565b3373ffffffffffffffffffffffffffffffffffffffff821614806112e757506112e78133610d53565b61134d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c00006044820152606401610e90565b61135783836130ee565b505050565b611366338261318e565b61136f57600080fd5b6113578383836132d8565b60006113853361272b565b90506000808251116113f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f7468696e6720746f20756e7374616b6500000000000000000000000000006044820152606401610e90565b60005b82518110156114ba5783156114a8576018600084838151811061141b5761141b615dcb565b6020908102919091018101518252810191909152604001600020546fffffffffffffffffffffffffffffffff16915083821115611456578391505b6114608285615c80565b935061148483828151811061147757611477615dcb565b6020026020010151612d4e565b6114a83384838151811061149a5761149a615dcb565b602002602001015184612e56565b806114b281615d34565b9150506113f6565b50505050565b60006114cb83611918565b8210611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401610e90565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b1580156115d257600080fd5b505afa1580156115e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160a9190615295565b61161357600080fd5b601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff16610100931515939093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff16929092176201000091151591909102179055565b611357838383604051806020016040528060008152506122c9565b6000806116a383850185615083565b915091506114ba8282611963565b60115460ff161515600114611722576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f742079657420636c61696d61626c650000000000000000000000000000006044820152606401610e90565b600061172d3361272b565b8051909150156117d65760005b81518110156117775761176582828151811061175857611758615dcb565b6020026020010151611c3d565b8061176f81615d34565b91505061173a565b5060005b601654811015610627576117c4826016838154811061179c5761179c615dcb565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16336134a2565b806117ce81615d34565b91505061177b565b50565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561184257600080fd5b505afa158015611856573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187a9190615295565b61188357600080fd5b60405181151581527fb6088c1c0a66042d23ce101cb07e7080b262a8a6525dba7b56e994f99d9bb5549060200160405180910390a1601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806110cf57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff821661193a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b6011546301000000900460ff161561197a57600080fd5b600f805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600c8054929093169116179055601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff166301000000179055565b60168181548110611a0b57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6060600060098484604051611a489291906156f2565b908152602001604051809103902060010160098585604051611a6b9291906156f2565b90815260405190819003602001902054815467ffffffffffffffff64010000000090920491909116908290611a9f90615ce0565b80601f0160208091040260200160405190810160405280929190818152602001828054611acb90615ce0565b8015611b185780601f10611aed57610100808354040283529160200191611b18565b820191906000526020600020905b815481529060010190602001808311611afb57829003601f168201915b50505050509150915091505b9250929050565b60115460ff161515600114611b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f742079657420636c61696d61626c650000000000000000000000000000006044820152606401610e90565b611ba582611c3d565b604080516001808252818301909252600091602080830190803683370190505090508281600081518110611bdb57611bdb615dcb565b6020026020010181815250506000611bf2846118e9565b905060005b8351811015611c3657611c2483858381518110611c1657611c16615dcb565b6020026020010151846134a2565b80611c2e81615d34565b915050611bf7565b5050505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b600d54604080517f3e158b0c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216918291633e158b0c9160048083019260209291908290030181600087803b158015611d3657600080fd5b505af1158015611d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6e9190615295565b5060145460005b6016548110156114ba57600060168281548110611d9457611d94615dcb565b60009182526020822001546016805473ffffffffffffffffffffffffffffffffffffffff909216935060159183919086908110611dd357611dd3615dcb565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040018120915084611e39575080546601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16611f66565b81546040517f4f4cd33e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff858116602483015265ffffffffffff9092166044820152426064820152600091881690634f4cd33e9060840160206040518083038186803b158015611ec057600080fd5b505afa158015611ed4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef89190615533565b9050611f30866509184e72a000611f1784670de0b6b3a7640000615bdf565b611f219190615bdf565b611f2b9190615ba4565b61365b565b8354611f6291906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff16615b38565b9150505b815465ffffffffffff16660100000000000079ffffffffffffffffffffffffffffffffffffffffffffffffffff831602178255611fa2426136e5565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000001665ffffffffffff91909116178255611fdf8784836136fa565b5050508080611fed90615d34565b915050611d75565b6060600180546110e490615ce0565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561206d57600080fd5b505afa158015612081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a59190615295565b6120ae57600080fd5b80156120c5576120c084848484613877565b6114ba565b6114ba8484613abd565b6060600b805480602002602001604051908101604052809291908181526020016000905b8282101561219f57838290600052602060002001805461211290615ce0565b80601f016020809104026020016040519081016040528092919081815260200182805461213e90615ce0565b801561218b5780601f106121605761010080835404028352916020019161218b565b820191906000526020600020905b81548152906001019060200180831161216e57829003601f168201915b5050505050815260200190600101906120f3565b50505050905090565b73ffffffffffffffffffffffffffffffffffffffff8216331415612228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f617070726f766520746f2063616c6c65720000000000000000000000000000006044820152606401610e90565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6117d63382613d3a565b6122d3338361318e565b612339576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610e90565b6114ba84848484614148565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b1580156123ae57600080fd5b505afa1580156123c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e69190615295565b6123ef57600080fd5b4281106123fb57600080fd5b601255565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561246957600080fd5b505afa15801561247d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a19190615295565b6124aa57600080fd5b82516124bd906000906020860190614d2f565b5081516124d1906001906020850190614d2f565b50601080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b600b54606090821061252c57600080fd5b600b828154811061253f5761253f615dcb565b90600052602060002001805461255490615ce0565b80601f016020809104026020016040519081016040528092919081815260200182805461258090615ce0565b80156125cd5780601f106125a2576101008083540402835291602001916125cd565b820191906000526020600020905b8154815290600101906020018083116125b057829003601f168201915b50505050509050919050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16612667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b600e546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c87b56dd9060240160006040518083038186803b1580156126d157600080fd5b505afa1580156126e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110cf919081019061542b565b6060600061273883611918565b905060008167ffffffffffffffff81111561275557612755615dfa565b60405190808252806020026020018201604052801561277e578160200160208202803683370190505b50905060005b828110156127ee5773ffffffffffffffffffffffffffffffffffffffff8516600090815260066020908152604080832084845290915290205482518390839081106127d1576127d1615dcb565b6020908102919091010152806127e681615d34565b915050612784565b509392505050565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561285f57600080fd5b505afa158015612873573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128979190615295565b6128a057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116156117d6576013805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905550565b61290f858533868686612b3a565b6129193387613d3a565b505050505050565b600c546040517fc395fcb300000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063c395fcb39060240160206040518083038186803b15801561298a57600080fd5b505afa15801561299e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c29190615295565b6129cb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81166129eb57600080fd5b600d5460405173ffffffffffffffffffffffffffffffffffffffff8381168252909116907f2e1b1ec770eb46a856f99429bd4157515f465cb04c90951962aabbb1b301333f9060200160405180910390a2600d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517ff5ab16cc00000000000000000000000000000000000000000000000000000000815230600482015263f5ab16cc9060240160006040518083038186803b158015612acc57600080fd5b505afa158015612ae0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612b2691908101906151d7565b805161062791601691602090910190614daf565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260196020526040902083612bc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4c696d6974206d757374206265203e20300000000000000000000000000000006044820152606401610e90565b80546fffffffffffffffffffffffffffffffff16841115612d45576013546040517fb7d6a23100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff169063b7d6a23190612c42908b908b908b908b908b908b9060040161589f565b60206040518083038186803b158015612c5a57600080fd5b505afa158015612c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c929190615533565b905060008111612cfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e636f7272656374206d65726b6c652070726f6f66000000000000000000006044820152606401610e90565b612d07816141c5565b82547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff91909116178255505b50505050505050565b6117d6816016805480602002602001604051908101604052809291908181526020018280548015612db557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612d8a575b5050505050611b2b565b33612dc9836118e9565b73ffffffffffffffffffffffffffffffffffffffff1614612e46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d757374206f776e20746f6b656e4964000000000000000000000000000000006044820152606401610e90565b612e4f82612d4e565b6106273383835b6040518060400160405280612e6a836141c5565b600085815260186020526040902054612e9591906fffffffffffffffffffffffffffffffff16615c1c565b6fffffffffffffffffffffffffffffffff168152602001612eb5426136e5565b65ffffffffffff9081169091526000848152601860209081526040909120835181549490920151909216700100000000000000000000000000000000027fffffffffffffffffffff000000000000000000000000000000000000000000009093166fffffffffffffffffffffffffffffffff90911617919091179055612f3a816141c5565b6fffffffffffffffffffffffffffffffff1660146000828254612f5d9190615c80565b90915550506000828152601860205260409020546fffffffffffffffffffffffffffffffff16612fc457600082815260186020526040902080547fffffffffffffffffffff00000000000000000000000000000000000000000000169055612fc482614241565b600f546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b15801561302e57600080fd5b505afa158015613042573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130669190615533565b905080821115613074578091505b600f546130989073ffffffffffffffffffffffffffffffffffffffff16858461431a565b8373ffffffffffffffffffffffffffffffffffffffff167f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75836040516130e091815260200190565b60405180910390a250505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190613148826118e9565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16613219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e2d6578697374656e7420746f6b656e00000000000000000000000000006044820152606401610e90565b6000613224836118e9565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061329357508373ffffffffffffffffffffffffffffffffffffffff1661327b84611167565b73ffffffffffffffffffffffffffffffffffffffff16145b806132d0575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff166132f8826118e9565b73ffffffffffffffffffffffffffffffffffffffff1614613375576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f74206f776e6572206f6620746f6b656e00000000000000000000000000006044820152606401610e90565b73ffffffffffffffffffffffffffffffffffffffff821661339557600080fd5b6133a08383836143ee565b6133ab6000826130ee565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906133e1908490615c80565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061341c908490615b6d565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60008060005b85518110156135e2576000601760008884815181106134c9576134c9615dcb565b6020908102919091018101518252818101929092526040908101600090812073ffffffffffffffffffffffffffffffffffffffff8a1682529092529020805490915061353d906fffffffffffffffffffffffffffffffff700100000000000000000000000000000000820481169116615c1c565b925061355b6fffffffffffffffffffffffffffffffff841685615b6d565b81549094508390829060109061359890849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16615b04565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505080806135da90615d34565b9150506134a8565b5061360473ffffffffffffffffffffffffffffffffffffffff8516848461431a565b8273ffffffffffffffffffffffffffffffffffffffff167ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe8360405161364c91815260200190565b60405180910390a25050505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff8211156136e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006044820152606401610e90565b5090565b600065ffffffffffff8211156136e157600080fd5b600083815260176020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902060018101546137d4906509184e72a00090670de0b6b3a764000090613774906601000000000000900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1686615c4d565b6000888152601860205260409020546137bb9179ffffffffffffffffffffffffffffffffffffffffffffffffffff16906fffffffffffffffffffffffffffffffff16615bdf565b6137c59190615ba4565b6137cf9190615ba4565b6141c5565b815482906000906137f89084906fffffffffffffffffffffffffffffffff16615b04565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550613837426136e5565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff90921666010000000000000265ffffffffffff92909216919091176001909101555050565b8261388157600080fd5b8061388b57600080fd5b600067ffffffffffffffff16600985856040516138a99291906156f2565b9081526040519081900360200190205467ffffffffffffffff64010000000090910416141561396b57600b805460018101825560009190915261390f907f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9018585614e29565b50600b5460405160099061392690879087906156f2565b908152604051908190036020019020805463ffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009092169190911790555b6040518060600160405280600986866040516139889291906156f2565b90815260408051602092819003830190205463ffffffff1683524267ffffffffffffffff16838301528051601f8601839004830281018301825285815292019190859085908190840183828082843760009201919091525050509152506040516009906139f890879087906156f2565b90815260408051918290036020908101909220835181548585015167ffffffffffffffff16640100000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911663ffffffff909216919091171781559083015180519192613a7192600185019290910190614d2f565b5050604051613a849150859085906156f2565b60405180910390207fbaa206e5ea800eb88bce099f453fee53295b793b9d5d1cfc4ce4b6db06a34f5383836040516130e0929190615926565b600067ffffffffffffffff1660098383604051613adb9291906156f2565b9081526040519081900360200190205467ffffffffffffffff640100000000909104161415613b0957600080fd5b6000600160098484604051613b1f9291906156f2565b90815260405190819003602001902054613b3f919063ffffffff16615c97565b600b54909150613b5190600190615c80565b8163ffffffff1614613c4457600b8054613b6d90600190615c80565b81548110613b7d57613b7d615dcb565b90600052602060002001600b8263ffffffff1681548110613ba057613ba0615dcb565b90600052602060002001908054613bb690615ce0565b613bc1929190614ebb565b50613bcd816001615b85565b6009600b8363ffffffff1681548110613be857613be8615dcb565b90600052602060002001604051613bff9190615702565b908152604051908190036020019020805463ffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009092169190911790555b600b805480613c5557613c55615d9c565b600190038181906000526020600020016000613c719190614f36565b90558282604051613c839291906156f2565b60405180910390207f4b5338540b4d1c0f6dd0308a25f633b7ff60472f894d711cff9dd64e35c613b260098585604051613cbe9291906156f2565b9081526020016040518091039020600101604051613cdc91906159a8565b60405180910390a260098383604051613cf69291906156f2565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681556000611c366001830182614f36565b60008111613da4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f416d6f756e74206d757374206265203e203000000000000000000000000000006044820152606401610e90565b601154610100900460ff1615613e4e5760115462010000900460ff1615613e0d5773ffffffffffffffffffffffffffffffffffffffff82166000908152601960205260409020546fffffffffffffffffffffffffffffffff168110613e0857600080fd5b613e4e565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601960205260409020546fffffffffffffffffffffffffffffffff16613e4e57600080fd5b613e5782611918565b613f88576000613e66836144f0565b905060005b601654811015613f8557600060168281548110613e8a57613e8a615dcb565b600091825260208083209091015485835260178252604080842073ffffffffffffffffffffffffffffffffffffffff9092168085529190925291206001015490915079ffffffffffffffffffffffffffffffffffffffffffffffffffff660100000000000090910416613f725773ffffffffffffffffffffffffffffffffffffffff811660008181526015602090815260408083205487845260178352818420948452939091529020600101805465ffffffffffff1666010000000000009283900479ffffffffffffffffffffffffffffffffffffffffffffffffffff169092029190911790555b5080613f7d81615d34565b915050613e6b565b50505b73ffffffffffffffffffffffffffffffffffffffff82166000908152600660209081526040808320838052909152902054613fc281611c3d565b6040518060400160405280613fd6846141c5565b60008481526018602052604090205461400191906fffffffffffffffffffffffffffffffff16615b04565b6fffffffffffffffffffffffffffffffff168152602001614021426136e5565b65ffffffffffff9081169091526000838152601860209081526040909120835181549490920151909216700100000000000000000000000000000000027fffffffffffffffffffff000000000000000000000000000000000000000000009093166fffffffffffffffffffffffffffffffff909116179190911790556140a6826141c5565b6fffffffffffffffffffffffffffffffff16601460008282546140c99190615b6d565b9091555050600f546140f39073ffffffffffffffffffffffffffffffffffffffff16843085614516565b8273ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d8360405161413b91815260200190565b60405180910390a2505050565b6141538484846132d8565b61415f84848484614574565b6114ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e20455243373231526563656976657200000000000000000000000000006044820152606401610e90565b60006fffffffffffffffffffffffffffffffff8211156136e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006044820152606401610e90565b600061424c826118e9565b905061425a816000846143ee565b6142656000836130ee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080546001929061429b908490615c80565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113579084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526146f0565b60005b6016548110156144e4576012546144089042615c80565b6000838152601760205260408120601680549192918590811061442d5761442d615dcb565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190206001015465ffffffffffff1611156144d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f5374616b65642076616c756520726563656e746c7920757064617465640000006044820152606401610e90565b806144dc81615d34565b9150506143f1565b506113578383836147fc565b6000806144fc60085490565b905061450883826148b6565b6110cf600880546001019055565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526114ba9085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161436c565b600073ffffffffffffffffffffffffffffffffffffffff84163b156146e5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a02906145eb903390899088908890600401615792565b602060405180830381600087803b15801561460557600080fd5b505af1925050508015614653575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261465091810190615360565b60015b61469a573d808015614681576040519150601f19603f3d011682016040523d82523d6000602084013e614686565b606091505b50805161469257600080fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506132d0565b506001949350505050565b6000614752826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166148d09092919063ffffffff16565b80519091501561135757808060200190518101906147709190615295565b611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610e90565b73ffffffffffffffffffffffffffffffffffffffff831661481c57614859565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146148595761485983826148e9565b73ffffffffffffffffffffffffffffffffffffffff821661487957505050565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113575761135782826149a0565b6106278282604051806020016040528060008152506149f1565b60606148df8484600085614a6e565b90505b9392505050565b600060016148f684611918565b6149009190615c80565b6000838152600760205260409020549091508082146149605773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b60006149ab83611918565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6149fb8383614bc8565b614a086000848484614574565b611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4e6f6e20455243373231526563656976657200000000000000000000000000006044820152606401610e90565b606082471015614ada576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f696e73756666696369656e742062616c616e636520666f722063616c6c0000006044820152606401610e90565b843b614b42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f63616c6c20746f206e6f6e2d636f6e74726163740000000000000000000000006044820152606401610e90565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051614b6b91906156d6565b60006040518083038185875af1925050503d8060008114614ba8576040519150601f19603f3d011682016040523d82523d6000602084013e614bad565b606091505b5091509150614bbd828286614cdc565b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216614be857600080fd5b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615614c1757600080fd5b614c23600083836143ee565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290614c59908490615b6d565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608315614ceb5750816148e2565b825115614cfb5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e909190615973565b828054614d3b90615ce0565b90600052602060002090601f016020900481019282614d5d5760008555614da3565b82601f10614d7657805160ff1916838001178555614da3565b82800160010185558215614da3579182015b82811115614da3578251825591602001919060010190614d88565b506136e1929150614f6c565b828054828255906000526020600020908101928215614da3579160200282015b82811115614da357825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614dcf565b828054614e3590615ce0565b90600052602060002090601f016020900481019282614e575760008555614da3565b82601f10614e8e578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555614da3565b82800160010185558215614da3579182015b82811115614da3578235825591602001919060010190614ea0565b828054614ec790615ce0565b90600052602060002090601f016020900481019282614ee95760008555614da3565b82601f10614efa5780548555614da3565b82800160010185558215614da357600052602060002091601f016020900482015b82811115614da3578254825591600101919060010190614f1b565b508054614f4290615ce0565b6000825580601f10614f52575050565b601f0160209004906000526020600020908101906117d691905b5b808211156136e15760008155600101614f6d565b6000614f94614f8f84615abe565b615a4b565b9050828152838383011115614fa857600080fd5b828260208301376000602084830101529392505050565b60008083601f840112614fd157600080fd5b50813567ffffffffffffffff811115614fe957600080fd5b6020830191508360208260051b8501011115611b2457600080fd5b60008083601f84011261501657600080fd5b50813567ffffffffffffffff81111561502e57600080fd5b602083019150836020828501011115611b2457600080fd5b600082601f83011261505757600080fd5b6148e283833560208501614f81565b60006020828403121561507857600080fd5b81356148e281615e29565b6000806040838503121561509657600080fd5b82356150a181615e29565b915060208301356150b181615e29565b809150509250929050565b6000806000606084860312156150d157600080fd5b83356150dc81615e29565b925060208401356150ec81615e29565b929592945050506040919091013590565b6000806000806080858703121561511357600080fd5b843561511e81615e29565b9350602085013561512e81615e29565b925060408501359150606085013567ffffffffffffffff81111561515157600080fd5b8501601f8101871361516257600080fd5b61517187823560208401614f81565b91505092959194509250565b6000806040838503121561519057600080fd5b823561519b81615e29565b915060208301356150b181615e4b565b600080604083850312156151be57600080fd5b82356151c981615e29565b946020939093013593505050565b600060208083850312156151ea57600080fd5b825167ffffffffffffffff81111561520157600080fd5b8301601f8101851361521257600080fd5b8051615220614f8f82615a9a565b80828252848201915084840188868560051b870101111561524057600080fd5b600094505b8385101561526c57805161525881615e29565b835260019490940193918501918501615245565b50979650505050505050565b60006020828403121561528a57600080fd5b81356148e281615e4b565b6000602082840312156152a757600080fd5b81516148e281615e4b565b600080604083850312156152c557600080fd5b823561519b81615e4b565b60008060008060008060a087890312156152e957600080fd5b8635955060208701359450604087013561530281615e29565b935060608701359250608087013567ffffffffffffffff81111561532557600080fd5b61533189828a01614fbf565b979a9699509497509295939492505050565b60006020828403121561535557600080fd5b81356148e281615e59565b60006020828403121561537257600080fd5b81516148e281615e59565b6000806020838503121561539057600080fd5b823567ffffffffffffffff8111156153a757600080fd5b6153b385828601615004565b90969095509350505050565b600080600080604085870312156153d557600080fd5b843567ffffffffffffffff808211156153ed57600080fd5b6153f988838901615004565b9096509450602087013591508082111561541257600080fd5b5061541f87828801615004565b95989497509550505050565b60006020828403121561543d57600080fd5b815167ffffffffffffffff81111561545457600080fd5b8201601f8101841361546557600080fd5b8051615473614f8f82615abe565b81815285602083850101111561548857600080fd5b615499826020830160208601615cb4565b95945050505050565b6000806000606084860312156154b757600080fd5b833567ffffffffffffffff808211156154cf57600080fd5b6154db87838801615046565b945060208601359150808211156154f157600080fd5b506154fe86828701615046565b925050604084013561550f81615e29565b809150509250925092565b60006020828403121561552c57600080fd5b5035919050565b60006020828403121561554557600080fd5b5051919050565b6000806040838503121561555f57600080fd5b8235915060208301356150b181615e29565b6000806040838503121561558457600080fd5b8235915060208084013567ffffffffffffffff8111156155a357600080fd5b8401601f810186136155b457600080fd5b80356155c2614f8f82615a9a565b80828252848201915084840189868560051b87010111156155e257600080fd5b600094505b8385101561560e5780356155fa81615e29565b8352600194909401939185019185016155e7565b5080955050505050509250929050565b60008060008060008060a0878903121561563757600080fd5b86359550602087013594506040870135935060608701359250608087013567ffffffffffffffff81111561532557600080fd5b6000806040838503121561567d57600080fd5b50508035926020909101359150565b600081518084526156a4816020860160208601615cb4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516156e8818460208701615cb4565b9190910192915050565b8183823760009101908152919050565b600080835461571081615ce0565b60018281168015615728576001811461575757615786565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841687528287019450615786565b8760005260208060002060005b8581101561577d5781548a820152908401908201615764565b50505082870194505b50929695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526157d1608083018461568c565b9695505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561584e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261583c85835161568c565b94509285019290850190600101615802565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561589357835183529284019291840191600101615877565b50909695505050505050565b86815285602082015273ffffffffffffffffffffffffffffffffffffffff8516604082015283606082015260a060808201528160a082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561590657600080fd5b8260051b808560c08501376000920160c001918252509695505050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6020815260006148e2602083018461568c565b604081526000615999604083018561568c565b90508260208301529392505050565b60006020808352600084546159bc81615ce0565b808487015260406001808416600081146159dd5760018114615a0f57615a3d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a0152606089019550615a3d565b896000528660002060005b85811015615a355781548b8201860152908301908801615a1a565b8a0184019650505b509398975050505050505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715615a9257615a92615dfa565b604052919050565b600067ffffffffffffffff821115615ab457615ab4615dfa565b5060051b60200190565b600067ffffffffffffffff821115615ad857615ad8615dfa565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615b2f57615b2f615d6d565b01949350505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff808316818516808303821115615b2f57615b2f615d6d565b60008219821115615b8057615b80615d6d565b500190565b600063ffffffff808316818516808303821115615b2f57615b2f615d6d565b600082615bda577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c1757615c17615d6d565b500290565b60006fffffffffffffffffffffffffffffffff83811690831681811015615c4557615c45615d6d565b039392505050565b600079ffffffffffffffffffffffffffffffffffffffffffffffffffff83811690831681811015615c4557615c45615d6d565b600082821015615c9257615c92615d6d565b500390565b600063ffffffff83811690831681811015615c4557615c45615d6d565b60005b83811015615ccf578181015183820152602001615cb7565b838111156114ba5750506000910152565b600181811c90821680615cf457607f821691505b60208210811415615d2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615d6657615d66615d6d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146117d657600080fd5b80151581146117d657600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000811681146117d657600080fdfea2646970667358221220c0066b2da066f889a6d374c8d05bd42e5fb49cbe00d4db104c32c059feadcd8f64736f6c63430008060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.