Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a06040 | 15891638 | 750 days ago | IN | 0 ETH | 0.07110943 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ProfileAuction
Compiler Version
v0.8.6+commit.11564f7e
Optimization Enabled:
Yes with 0 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../interface/INftProfileHelper.sol"; import "../interface/IGenesisKeyStake.sol"; import "./StringUtils.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; interface INftProfile { function createProfile( address receiver, string memory _profileURI, uint256 _expiry ) external; function totalSupply() external view returns (uint256); function extendLicense( string memory _profileURI, uint256 _duration, address _licensee ) external; function purchaseExpiredProfile( string memory _profileURI, uint256 _duration, address _receiver ) external; function tokenUsed(string memory _string) external view returns (bool); function profileOwner(string memory _string) external view returns (address); } struct BatchClaimProfile { string profileUrl; uint256 tokenId; address recipient; bytes32 hash; bytes signature; } error MaxProfiles(); contract ProfileAuction is Initializable, UUPSUpgradeable, ReentrancyGuardUpgradeable { using StringUtils for *; using ECDSAUpgradeable for bytes32; address public governor; uint96 public yearlyFee; // public fee for mint price address public owner; uint96 public yearsToOwn; // number of years of license to pay to own a profile address public usdc_; bool public publicMintBool; // true to allow public mint bool public genKeyWhitelistOnly; // true to only allow merkle claims address public nftProfile; address public contract2; address public contract1; address public nftProfileHelperAddress; address public genesisKeyContract; address public signerAddress; mapping(uint256 => uint256) public genesisKeyClaimNumber; // genKey tokenId => number of profiles claimed mapping(uint256 => uint256) public lengthPremium; // premium multiple for profile length mapping(string => uint256) public ownedProfileStake; // genKey tokenId => staked token mapping(bytes32 => bool) public cancelledOrFinalized; // used hash mapping(address => uint256) public publicMinted; // record of profiles public minted per user address public emptySlot; // empty slot for now, to be used in future uint88 public maxProfilePerAddress; // max profiles that can be minted per address, set by DAO bool public publicClaimBool; event UpdatedProfileStake(string _profileUrl, uint256 _stake); event MintedProfile(address _user, string _val, uint256 tokenId, uint256 _duration, uint256 _fee); event ExtendLicense(address _receiver, string _profileUrl, uint256 _duration, uint256 _fee, bool _expired); event NewLengthPremium(uint256 _length, uint256 _premium); event NewYearlyFee(uint96 _fee); event YearsToOwn(uint96 _years); event NewMaxProfile(uint88 _max); modifier validAndUnusedURI(string memory _profileURI) { require(validURI(_profileURI)); require(!INftProfile(nftProfile).tokenUsed(_profileURI)); _; } modifier onlyGovernor() { require(msg.sender == governor); _; } modifier onlyOwner() { require(msg.sender == owner); _; } function initialize( address _nftProfile, address _governor, address _nftProfileHelperAddress, address _genesisKeyContract ) public initializer { __ReentrancyGuard_init(); __UUPSUpgradeable_init(); nftProfile = _nftProfile; nftProfileHelperAddress = _nftProfileHelperAddress; owner = msg.sender; governor = _governor; genesisKeyContract = _genesisKeyContract; genKeyWhitelistOnly = true; lengthPremium[1] = 1024; lengthPremium[2] = 512; lengthPremium[3] = 128; lengthPremium[4] = 32; yearlyFee = 100 * 10**18; yearsToOwn = 2; signerAddress = 0x9EfcD5075cDfB7f58C26e3fB3F22Bb498C6E3174; } function _authorizeUpgrade(address) internal override onlyOwner {} /** @notice helper function transfer tokens @param _user user transferring tokens @param _amount number of tokens being transferred */ function transferTokens(address _user, uint256 _amount) private returns (bool) { return IERC20Upgradeable(usdc_).transferFrom(_user, contract1, _amount); } /** @notice helper function to add permit */ function permitNFT( address _owner, address spender, uint8 v, bytes32 r, bytes32 s ) private { return IERC20PermitUpgradeable(usdc_).permit(_owner, spender, type(uint256).max, type(uint256).max, v, r, s); } function validURI(string memory _name) private view returns (bool) { return INftProfileHelper(nftProfileHelperAddress)._validURI(_name); } // GOV FUNCTIONS function setOwner(address _new) external onlyOwner { owner = _new; } function setGovernor(address _new) external onlyGovernor { governor = _new; } function setSigner(address _signer) external onlyOwner { signerAddress = _signer; } function setUsdc(address _usdc) external onlyOwner { usdc_ = _usdc; } function setContract1(address _new) external onlyOwner { contract1 = _new; } function setContract2(address _new) external onlyOwner { contract2 = _new; } function verifySignature(bytes32 hash, bytes memory signature) public view returns (bool) { return signerAddress == hash.recover(signature); } function setLengthPremium(uint256 _length, uint256 _premium) external onlyGovernor { lengthPremium[_length] = _premium; emit NewLengthPremium(_length, _premium); } function setYearlyFee(uint96 _fee) external onlyGovernor { yearlyFee = _fee; emit NewYearlyFee(_fee); } function setMaxProfilePerAddress(uint88 _max) external onlyGovernor { maxProfilePerAddress = _max; emit NewMaxProfile(_max); } function setYearsToOwn(uint96 _years) external onlyGovernor { yearsToOwn = _years; emit YearsToOwn(_years); } function setGenKeyWhitelistOnly(bool _genKeyWhitelistOnly) external onlyGovernor { genKeyWhitelistOnly = _genKeyWhitelistOnly; } function setPublicMint(bool _val) external onlyGovernor { publicMintBool = _val; } function setPublicClaim(bool _val) external onlyGovernor { publicClaimBool = _val; } function hashTransaction(address sender, string memory profileUrl) private pure returns (bytes32) { bytes32 hash = keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(abi.encodePacked(sender, profileUrl))) ); return hash; } // CLAIM FUNCTIONS /** * @dev allows gen key holder to claim a profile * @param profileUrl profileUrl to claim * @param tokenId tokenId of genesis key owned * @param recipient user who is calling the claim function */ function genesisKeyClaimProfile( string memory profileUrl, uint256 tokenId, address recipient, bytes32 hash, bytes memory signature ) external validAndUnusedURI(profileUrl) nonReentrant { // checks require(IERC721EnumerableUpgradeable(genesisKeyContract).ownerOf(tokenId) == recipient, "gkp: !owner"); require(verifySignature(hash, signature) && !cancelledOrFinalized[hash], "gkp: !sig"); require(hashTransaction(msg.sender, profileUrl) == hash, "gkp: !hash"); uint256 profilesAllowed = genKeyWhitelistOnly ? 4 : 7; require(genesisKeyClaimNumber[tokenId] != profilesAllowed); // effects genesisKeyClaimNumber[tokenId] += 1; // interactions INftProfile(nftProfile).createProfile( recipient, profileUrl, genesisKeyClaimNumber[tokenId] <= 4 ? 1000 * (365 days) : 365 days ); emit MintedProfile( recipient, profileUrl, INftProfile(nftProfile).totalSupply() - 1, genesisKeyClaimNumber[tokenId] <= 4 ? 1000 * (365 days) : 365 days, 0 ); } function genesisKeyBatchClaimProfile( BatchClaimProfile[] memory claims ) external nonReentrant { for (uint256 i = 0; i < claims.length; ) { string memory profileUrl = claims[i].profileUrl; uint256 tokenId = claims[i].tokenId; address recipient = claims[i].recipient; bytes32 hash = claims[i].hash; bytes memory signature = claims[i].signature; // checks require(IERC721EnumerableUpgradeable(genesisKeyContract).ownerOf(tokenId) == recipient, "gkp: !owner"); require(validURI(profileUrl), "gkp: !validURI"); require(!INftProfile(nftProfile).tokenUsed(profileUrl), "gkp: !unused"); require(verifySignature(hash, signature) && !cancelledOrFinalized[hash], "gkp: !sig"); require(hashTransaction(msg.sender, profileUrl) == hash, "gkp: !hash"); uint256 profilesAllowed = genKeyWhitelistOnly ? 4 : 7; require(genesisKeyClaimNumber[tokenId] != profilesAllowed); // effects genesisKeyClaimNumber[tokenId] += 1; // interactions INftProfile(nftProfile).createProfile( recipient, profileUrl, genesisKeyClaimNumber[tokenId] <= 4 ? 1000 * (365 days) : 365 days ); emit MintedProfile( recipient, profileUrl, INftProfile(nftProfile).totalSupply() - 1, genesisKeyClaimNumber[tokenId] <= 4 ? 1000 * (365 days) : 365 days, 0 ); unchecked { ++i; } } } // used for profile factory function publicClaim( string memory profileUrl, bytes32 hash, bytes memory signature ) external nonReentrant validAndUnusedURI(profileUrl) { // checks require(publicClaimBool, "pm: publicClaimBool"); require(verifySignature(hash, signature) && !cancelledOrFinalized[hash], "pm: !sig"); require(hashTransaction(msg.sender, profileUrl) == hash, "pm: !hash"); if (publicMinted[msg.sender] >= maxProfilePerAddress) revert MaxProfiles(); // effects publicMinted[msg.sender] += 1; // grace period of 1 year (unless DAO intervention) INftProfile(nftProfile).createProfile(msg.sender, profileUrl, 365 days); emit MintedProfile(msg.sender, profileUrl, INftProfile(nftProfile).totalSupply() - 1, 365 days, 0); } function publicMint( string memory profileUrl, uint256 duration, uint8 v, bytes32 r, bytes32 s, bytes32 hash, bytes memory signature ) external nonReentrant validAndUnusedURI(profileUrl) { // checks require(publicMintBool, "pm: !publicMint"); require(verifySignature(hash, signature) && !cancelledOrFinalized[hash], "pm: !sig"); require(hashTransaction(msg.sender, profileUrl) == hash, "pm: !hash"); // interactions if (IERC20Upgradeable(usdc_).allowance(msg.sender, address(this)) == 0) { permitNFT(msg.sender, address(this), v, r, s); // approve token } require(transferTokens(msg.sender, getFee(profileUrl, duration)), "pm: !funds"); INftProfile(nftProfile).createProfile(msg.sender, profileUrl, duration); emit MintedProfile( msg.sender, profileUrl, INftProfile(nftProfile).totalSupply() - 1, duration, getFee(profileUrl, duration) ); } function getFee(string memory profileUrl, uint256 duration) public view returns (uint256) { uint256 baseFee = (yearlyFee * duration) / 365 days; uint256 premium = lengthPremium[profileUrl.strlen()]; // if premium is not set, then use base fee, otherwise, multiply return premium == 0 ? baseFee : baseFee * premium; } /** * @dev allows any user to pay to extend a profile * @param profileUrl profileUrl to extend * @param duration number of seconds to extend */ function extendLicense( string memory profileUrl, uint256 duration, uint8 v, bytes32 r, bytes32 s ) external nonReentrant { require(publicMintBool, "el: public minting is disabled"); if (IERC20Upgradeable(usdc_).allowance(msg.sender, address(this)) == 0) { permitNFT(msg.sender, address(this), v, r, s); } require(transferTokens(msg.sender, getFee(profileUrl, duration)), "el: insufficient funds"); INftProfile(nftProfile).extendLicense(profileUrl, duration, msg.sender); emit ExtendLicense(msg.sender, profileUrl, duration, getFee(profileUrl, duration), false); } function purchaseExpiredProfile( string memory profileUrl, uint256 duration, uint8 v, bytes32 r, bytes32 s ) external nonReentrant { // checks require(publicMintBool, "pe: public minting is disabled"); require(ownedProfileStake[profileUrl] == 0, "pe: profile is already staked"); // effects // interactions if (IERC20Upgradeable(usdc_).allowance(msg.sender, address(this)) == 0) { permitNFT(msg.sender, address(this), v, r, s); } require(transferTokens(msg.sender, getFee(profileUrl, duration)), "pe: insufficient funds"); INftProfile(nftProfile).purchaseExpiredProfile(profileUrl, duration, msg.sender); emit ExtendLicense(msg.sender, profileUrl, duration, getFee(profileUrl, duration), true); } function ownProfile(string memory profileUrl) external nonReentrant { // checks require(publicMintBool, "op: public minting is disabled"); require(ownedProfileStake[profileUrl] == 0); // uint256 xNftKeyReq = (getFee(profileUrl, 365 days) * yearsToOwn * IGenesisKeyStake(contract2).totalSupply()) / IGenesisKeyStake(contract2).totalStakedCoin(); require(xNftKeyReq != 0, "op: !0"); // effects ownedProfileStake[profileUrl] = xNftKeyReq; // interactions require( IERC20Upgradeable(contract2).transferFrom(msg.sender, address(this), xNftKeyReq), "op: insufficient funds" ); emit UpdatedProfileStake(profileUrl, xNftKeyReq); } function redeemProfile(string memory profileUrl) public nonReentrant { // checks require(publicMintBool, "rp: public minting is disabled"); require(ownedProfileStake[profileUrl] != 0, "rp: profile is not staked"); require(INftProfile(nftProfile).profileOwner(profileUrl) == msg.sender, "rp: profile is not owned by user"); // effects ownedProfileStake[profileUrl] = 0; // interactions require(IERC20Upgradeable(contract2).transferFrom(address(this), msg.sender, ownedProfileStake[profileUrl])); emit UpdatedProfileStake(profileUrl, 0); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; library StringUtils { /** * @dev Returns the length of a given string * * @param s The string to measure the length of * @return The length of the input string */ function strlen(string memory s) internal pure returns (uint256) { uint256 len; uint256 i = 0; uint256 bytelength = bytes(s).length; for (len = 0; i < bytelength; len++) { bytes1 b = bytes(s)[i]; if (b < 0x80) { i += 1; } else if (b < 0xE0) { i += 2; } else if (b < 0xF0) { i += 3; } else if (b < 0xF8) { i += 4; } else if (b < 0xFC) { i += 5; } else { i += 6; } } return len; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IGenesisKeyStake { function stakedAddress(address _user) external view returns (uint256); function totalSupply() external view returns (uint256); function totalStakedCoin() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface INftProfileHelper { function _validURI(string memory _name) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721EnumerableUpgradeable is IERC721Upgradeable { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../StringsUpgradeable.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSAUpgradeable { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: 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 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 the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @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) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @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, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
{ "metadata": { "bytecodeHash": "none" }, "optimizer": { "enabled": true, "runs": 0 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"MaxProfiles","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_receiver","type":"address"},{"indexed":false,"internalType":"string","name":"_profileUrl","type":"string"},{"indexed":false,"internalType":"uint256","name":"_duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_expired","type":"bool"}],"name":"ExtendLicense","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"string","name":"_val","type":"string"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"MintedProfile","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_length","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_premium","type":"uint256"}],"name":"NewLengthPremium","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint88","name":"_max","type":"uint88"}],"name":"NewMaxProfile","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"_fee","type":"uint96"}],"name":"NewYearlyFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_profileUrl","type":"string"},{"indexed":false,"internalType":"uint256","name":"_stake","type":"uint256"}],"name":"UpdatedProfileStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"_years","type":"uint96"}],"name":"YearsToOwn","type":"event"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"cancelledOrFinalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contract1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contract2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emptySlot","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"extendLicense","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"genKeyWhitelistOnly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"profileUrl","type":"string"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BatchClaimProfile[]","name":"claims","type":"tuple[]"}],"name":"genesisKeyBatchClaimProfile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"genesisKeyClaimNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"genesisKeyClaimProfile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"genesisKeyContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftProfile","type":"address"},{"internalType":"address","name":"_governor","type":"address"},{"internalType":"address","name":"_nftProfileHelperAddress","type":"address"},{"internalType":"address","name":"_genesisKeyContract","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lengthPremium","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxProfilePerAddress","outputs":[{"internalType":"uint88","name":"","type":"uint88"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftProfile","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftProfileHelperAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"}],"name":"ownProfile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"ownedProfileStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"publicClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"publicClaimBool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"publicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"publicMintBool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"purchaseExpiredProfile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"profileUrl","type":"string"}],"name":"redeemProfile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setContract1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setContract2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_genKeyWhitelistOnly","type":"bool"}],"name":"setGenKeyWhitelistOnly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_length","type":"uint256"},{"internalType":"uint256","name":"_premium","type":"uint256"}],"name":"setLengthPremium","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint88","name":"_max","type":"uint88"}],"name":"setMaxProfilePerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_val","type":"bool"}],"name":"setPublicClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_val","type":"bool"}],"name":"setPublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_usdc","type":"address"}],"name":"setUsdc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_fee","type":"uint96"}],"name":"setYearlyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_years","type":"uint96"}],"name":"setYearsToOwn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"usdc_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"verifySignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yearlyFee","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yearsToOwn","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523060601b60805234801561001757600080fd5b5060805160601c6142c261005260003960008181611a9801528181611ad801528181611b9801528181611bd80152611c5401526142c26000f3fe6080604052600436106102225760003560e01c8062da7733146102275780630c340a24146102495780630e2d56cf146102865780631015805b146102a657806310d70f24146102e157806313af40351461030157806314dc648e1461032157806317ef67c6146103415780631a8999fb1461036157806329c33853146103815780632a131fe3146103a15780632ebd7c6f146103c157806330334540146103e15780633659cfe614610401578063445601c5146104215780634af6b5c2146104415780634c62d88c146104615780634f1ef2861461048157806351b20ed01461049457806352d1902d146104c85780635b7633d0146104dd5780635f9fe274146104fd5780636c19e7831461051d5780637e2337a51461053d5780638076f0051461055d57806389462c381461059d5780638da5cb5b146105bd5780639b6c0796146105dd5780639b995f5c146105fe5780639db1b5af1461061e578063b0127b6d1461063e578063b6eb4e641461065e578063ba11a7c21461068b578063bc7dbc0d146106ab578063be26cc7b146106df578063c0c93071146106ff578063c42cf5351461071f578063ca291ca81461073f578063cb1468791461075f578063daca6f781461077f578063db64f6871461079f578063dc9db853146107bf578063e1e91f8a146107f7578063eebeb9411461081e578063f8c8765e1461084b578063fc47b8d31461086b578063fdcd61d61461088b578063ff137c87146108ac575b600080fd5b34801561023357600080fd5b5061024761024236600461394a565b6108cd565b005b34801561025557600080fd5b50609754610269906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561029257600080fd5b506102476102a13660046138ae565b610c16565b3480156102b257600080fd5b506102d36102c136600461367d565b60a46020526000908152604090205481565b60405190815260200161027d565b3480156102ed57600080fd5b506102476102fc366004613b29565b610c4b565b34801561030d57600080fd5b5061024761031c36600461367d565b610fdf565b34801561032d57600080fd5b5061024761033c366004613c0e565b611018565b34801561034d57600080fd5b5061024761035c36600461367d565b61108a565b34801561036d57600080fd5b5061024761037c366004613986565b6110c3565b34801561038d57600080fd5b506102d361039c3660046139f2565b6113df565b3480156103ad57600080fd5b506102476103bc366004613be5565b611456565b3480156103cd57600080fd5b506102476103dc366004613ac1565b6114c1565b3480156103ed57600080fd5b506102476103fc366004613a36565b6116d1565b34801561040d57600080fd5b5061024761041c36600461367d565b611a8d565b34801561042d57600080fd5b5061024761043c3660046138ae565b611b56565b34801561044d57600080fd5b50609b54610269906001600160a01b031681565b34801561046d57600080fd5b50609c54610269906001600160a01b031681565b61024761048f366004613713565b611b8d565b3480156104a057600080fd5b5060a5546104bb90600160a01b90046001600160581b031681565b60405161027d919061403c565b3480156104d457600080fd5b506102d3611c47565b3480156104e957600080fd5b50609f54610269906001600160a01b031681565b34801561050957600080fd5b50609d54610269906001600160a01b031681565b34801561052957600080fd5b5061024761053836600461367d565b611cf5565b34801561054957600080fd5b50610247610558366004613ac1565b611d2e565b34801561056957600080fd5b5061058d6105783660046138e8565b60a36020526000908152604090205460ff1681565b604051901515815260200161027d565b3480156105a957600080fd5b506102476105b836600461367d565b611f98565b3480156105c957600080fd5b50609854610269906001600160a01b031681565b3480156105e957600080fd5b5060a55461058d90600160f81b900460ff1681565b34801561060a57600080fd5b50609a54610269906001600160a01b031681565b34801561062a57600080fd5b50610247610639366004613762565b611fd1565b34801561064a57600080fd5b50610247610659366004613c0e565b6124b9565b34801561066a57600080fd5b506102d36106793660046138e8565b60a16020526000908152604090205481565b34801561069757600080fd5b506102476106a636600461394a565b612520565b3480156106b757600080fd5b506097546106d290600160a01b90046001600160601b031681565b60405161027d9190614050565b3480156106eb57600080fd5b50609954610269906001600160a01b031681565b34801561070b57600080fd5b5061024761071a366004613bc3565b6127e6565b34801561072b57600080fd5b5061024761073a36600461367d565b61284c565b34801561074b57600080fd5b50609e54610269906001600160a01b031681565b34801561076b57600080fd5b5061024761077a36600461367d565b612885565b34801561078b57600080fd5b5061058d61079a36600461391a565b6128be565b3480156107ab57600080fd5b506102476107ba3660046138ae565b6128e2565b3480156107cb57600080fd5b506102d36107da36600461394a565b805160208183018101805160a28252928201919093012091525481565b34801561080357600080fd5b506098546106d290600160a01b90046001600160601b031681565b34801561082a57600080fd5b506102d36108393660046138e8565b60a06020526000908152604090205481565b34801561085757600080fd5b506102476108663660046136b7565b612917565b34801561087757600080fd5b5060a554610269906001600160a01b031681565b34801561089757600080fd5b5060995461058d90600160a01b900460ff1681565b3480156108b857600080fd5b5060995461058d90600160a81b900460ff1681565b600260655414156108f95760405162461bcd60e51b81526004016108f090613fe2565b60405180910390fd5b6002606555609954600160a01b900460ff166109575760405162461bcd60e51b815260206004820152601e60248201527f6f703a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b60a2816040516109679190613c98565b90815260200160405180910390205460001461098257600080fd5b609b54604080516312f73d0360e11b815290516000926001600160a01b0316916325ee7a06916004808301926020929190829003018186803b1580156109c757600080fd5b505afa1580156109db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ff9190613901565b609b60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a4d57600080fd5b505afa158015610a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a859190613901565b609854600160a01b90046001600160601b0316610aa6856301e133806113df565b610ab091906140f6565b610aba91906140f6565b610ac491906140d4565b905080610afc5760405162461bcd60e51b815260206004820152600660248201526506f703a2021360d41b60448201526064016108f0565b8060a283604051610b0d9190613c98565b90815260405190819003602001812091909155609b546323b872dd60e01b82526001600160a01b0316906323b872dd90610b4f90339030908690600401613cce565b602060405180830381600087803b158015610b6957600080fd5b505af1158015610b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba191906138cb565b610be65760405162461bcd60e51b81526020600482015260166024820152756f703a20696e73756666696369656e742066756e647360501b60448201526064016108f0565b60008051602061420f8339815191528282604051610c05929190613e40565b60405180910390a150506001606555565b6097546001600160a01b03163314610c2d57600080fd5b60998054911515600160a01b0260ff60a01b19909216919091179055565b60026065541415610c6e5760405162461bcd60e51b81526004016108f090613fe2565b600260655586610c7d81612b60565b610c8657600080fd5b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd9690610cb6908490600401613e2d565b60206040518083038186803b158015610cce57600080fd5b505afa158015610ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0691906138cb565b15610d1057600080fd5b609954600160a01b900460ff16610d5b5760405162461bcd60e51b815260206004820152600f60248201526e1c1b4e88085c1d589b1a58d35a5b9d608a1b60448201526064016108f0565b610d6583836128be565b8015610d805750600083815260a3602052604090205460ff16155b610d9c5760405162461bcd60e51b81526004016108f090613ede565b82610da7338a612be7565b14610dc45760405162461bcd60e51b81526004016108f090614019565b609954604051636eb1769f60e11b81526001600160a01b039091169063dd62ed3e90610df69033903090600401613cb4565b60206040518083038186803b158015610e0e57600080fd5b505afa158015610e22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e469190613901565b610e5757610e573330888888612c65565b610e6a33610e658a8a6113df565b612cf9565b610ea35760405162461bcd60e51b815260206004820152600a602482015269706d3a202166756e647360b01b60448201526064016108f0565b609a5460405163121cbf4560e21b81526001600160a01b0390911690634872fd1490610ed79033908c908c90600401613cf2565b600060405180830381600087803b158015610ef157600080fd5b505af1158015610f05573d6000803e3d6000fd5b505050506000805160206141ef83398151915233896001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f6a57600080fd5b505afa158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190613901565b610fac9190614115565b8a610fb78d8d6113df565b604051610fc8959493929190613d26565b60405180910390a150506001606555505050505050565b6098546001600160a01b03163314610ff657600080fd5b609880546001600160a01b0319166001600160a01b0392909216919091179055565b6097546001600160a01b0316331461102f57600080fd5b609880546001600160a01b0316600160a01b6001600160601b038416021790556040517fb395a37dd4eb95d1e572e09133b8d6458643a806657c23b0448725f46087dd929061107f908390614050565b60405180910390a150565b6098546001600160a01b031633146110a157600080fd5b609c80546001600160a01b0319166001600160a01b0392909216919091179055565b600260655414156110e65760405162461bcd60e51b81526004016108f090613fe2565b6002606555826110f581612b60565b6110fe57600080fd5b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd969061112e908490600401613e2d565b60206040518083038186803b15801561114657600080fd5b505afa15801561115a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117e91906138cb565b1561118857600080fd5b60a554600160f81b900460ff166111d75760405162461bcd60e51b81526020600482015260136024820152721c1b4e881c1d589b1a58d0db185a5b509bdbdb606a1b60448201526064016108f0565b6111e183836128be565b80156111fc5750600083815260a3602052604090205460ff16155b6112185760405162461bcd60e51b81526004016108f090613ede565b826112233386612be7565b146112405760405162461bcd60e51b81526004016108f090614019565b60a55433600090815260a46020526040902054600160a01b9091046001600160581b03161161128257604051639e92c61f60e01b815260040160405180910390fd5b33600090815260a4602052604081208054600192906112a29084906140bc565b9091555050609a5460405163121cbf4560e21b81526001600160a01b0390911690634872fd14906112df90339088906301e1338090600401613cf2565b600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b505050506000805160206141ef83398151915233856001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561137257600080fd5b505afa158015611386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113aa9190613901565b6113b49190614115565b6301e1338060006040516113cc959493929190613d26565b60405180910390a1505060016065555050565b60975460009081906301e1338090611408908590600160a01b90046001600160601b03166140f6565b61141291906140d4565b9050600060a1600061142387612d8c565b81526020019081526020016000205490508060001461144b5761144681836140f6565b61144d565b815b95945050505050565b6097546001600160a01b0316331461146d57600080fd5b60a58054600160a01b600160f81b031916600160a01b6001600160581b038416021790556040517f69bf8e28fdfad65f1c3889032b88ed519c37e782fedc7159de360c2bbce58cf59061107f90839061403c565b600260655414156114e45760405162461bcd60e51b81526004016108f090613fe2565b6002606555609954600160a01b900460ff166115425760405162461bcd60e51b815260206004820152601e60248201527f656c3a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b609954604051636eb1769f60e11b81526001600160a01b039091169063dd62ed3e906115749033903090600401613cb4565b60206040518083038186803b15801561158c57600080fd5b505afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c49190613901565b6115d5576115d53330858585612c65565b6115e333610e6587876113df565b6116285760405162461bcd60e51b8152602060048201526016602482015275656c3a20696e73756666696369656e742066756e647360501b60448201526064016108f0565b609a5460405163fad1a5db60e01b81526001600160a01b039091169063fad1a5db9061165c90889088903390600401613e62565b600060405180830381600087803b15801561167657600080fd5b505af115801561168a573d6000803e3d6000fd5b505050506000805160206142968339815191523386866116aa89896113df565b60006040516116bd959493929190613d67565b60405180910390a150506001606555505050565b846116db81612b60565b6116e457600080fd5b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd9690611714908490600401613e2d565b60206040518083038186803b15801561172c57600080fd5b505afa158015611740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176491906138cb565b1561176e57600080fd5b600260655414156117915760405162461bcd60e51b81526004016108f090613fe2565b6002606555609e546040516331a9108f60e11b8152600481018790526001600160a01b03868116921690636352211e9060240160206040518083038186803b1580156117dc57600080fd5b505afa1580156117f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611814919061369a565b6001600160a01b03161461183a5760405162461bcd60e51b81526004016108f090613e95565b61184483836128be565b801561185f5750600083815260a3602052604090205460ff16155b61187b5760405162461bcd60e51b81526004016108f090613fbf565b826118863388612be7565b146118a35760405162461bcd60e51b81526004016108f090613eba565b609954600090600160a81b900460ff166118be5760076118c1565b60045b600087815260a0602052604090205460ff9190911691508114156118e457600080fd5b600086815260a0602052604081208054600192906119039084906140bc565b9091555050609a54600087815260a060205260409020546001600160a01b0390911690634872fd149087908a9060041015611942576301e13380611949565b640757b12c005b6040518463ffffffff1660e01b815260040161196793929190613df2565b600060405180830381600087803b15801561198157600080fd5b505af1158015611995573d6000803e3d6000fd5b505050506000805160206141ef83398151915285886001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119fa57600080fd5b505afa158015611a0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a329190613901565b611a3c9190614115565b60008a815260a0602052604090205460041015611a5d576301e13380611a64565b640757b12c005b6000604051611a77959493929190613daa565b60405180910390a1505060016065555050505050565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415611ad65760405162461bcd60e51b81526004016108f090613f00565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611b08612e8f565b6001600160a01b031614611b2e5760405162461bcd60e51b81526004016108f090613f3a565b611b3781612eab565b60408051600080825260208201909252611b5391839190612ec2565b50565b6097546001600160a01b03163314611b6d57600080fd5b60a58054911515600160f81b026001600160f81b03909216919091179055565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415611bd65760405162461bcd60e51b81526004016108f090613f00565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611c08612e8f565b6001600160a01b031614611c2e5760405162461bcd60e51b81526004016108f090613f3a565b611c3782612eab565b611c4382826001612ec2565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ce25760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c6044820152771b1959081d1a1c9bdd59da0819195b1959d85d1958d85b1b60421b60648201526084016108f0565b5060008051602061424f83398151915290565b6098546001600160a01b03163314611d0c57600080fd5b609f80546001600160a01b0319166001600160a01b0392909216919091179055565b60026065541415611d515760405162461bcd60e51b81526004016108f090613fe2565b6002606555609954600160a01b900460ff16611daf5760405162461bcd60e51b815260206004820152601e60248201527f70653a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b60a285604051611dbf9190613c98565b908152602001604051809103902054600014611e1d5760405162461bcd60e51b815260206004820152601d60248201527f70653a2070726f66696c6520697320616c7265616479207374616b656400000060448201526064016108f0565b609954604051636eb1769f60e11b81526001600160a01b039091169063dd62ed3e90611e4f9033903090600401613cb4565b60206040518083038186803b158015611e6757600080fd5b505afa158015611e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9f9190613901565b611eb057611eb03330858585612c65565b611ebe33610e6587876113df565b611f035760405162461bcd60e51b815260206004820152601660248201527570653a20696e73756666696369656e742066756e647360501b60448201526064016108f0565b609a5460405163655d056b60e11b81526001600160a01b039091169063caba0ad690611f3790889088903390600401613e62565b600060405180830381600087803b158015611f5157600080fd5b505af1158015611f65573d6000803e3d6000fd5b50505050600080516020614296833981519152338686611f8589896113df565b60016040516116bd959493929190613d67565b6098546001600160a01b03163314611faf57600080fd5b609b80546001600160a01b0319166001600160a01b0392909216919091179055565b60026065541415611ff45760405162461bcd60e51b81526004016108f090613fe2565b600260655560005b81518110156124b05760008282815181106120195761201961419f565b6020026020010151600001519050600083838151811061203b5761203b61419f565b6020026020010151602001519050600084848151811061205d5761205d61419f565b6020026020010151604001519050600085858151811061207f5761207f61419f565b602002602001015160600151905060008686815181106120a1576120a161419f565b602090810291909101015160800151609e546040516331a9108f60e11b8152600481018790529192506001600160a01b0385811692911690636352211e9060240160206040518083038186803b1580156120fa57600080fd5b505afa15801561210e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612132919061369a565b6001600160a01b0316146121585760405162461bcd60e51b81526004016108f090613e95565b61216185612b60565b61219e5760405162461bcd60e51b815260206004820152600e60248201526d676b703a202176616c696455524960901b60448201526064016108f0565b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd96906121ce908890600401613e2d565b60206040518083038186803b1580156121e657600080fd5b505afa1580156121fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221e91906138cb565b1561225a5760405162461bcd60e51b815260206004820152600c60248201526b19dadc0e88085d5b9d5cd95960a21b60448201526064016108f0565b61226482826128be565b801561227f5750600082815260a3602052604090205460ff16155b61229b5760405162461bcd60e51b81526004016108f090613fbf565b816122a63387612be7565b146122c35760405162461bcd60e51b81526004016108f090613eba565b609954600090600160a81b900460ff166122de5760076122e1565b60045b600086815260a0602052604090205460ff91909116915081141561230457600080fd5b600085815260a0602052604081208054600192906123239084906140bc565b9091555050609a54600086815260a060205260409020546001600160a01b0390911690634872fd14908690899060041015612362576301e13380612369565b640757b12c005b6040518463ffffffff1660e01b815260040161238793929190613df2565b600060405180830381600087803b1580156123a157600080fd5b505af11580156123b5573d6000803e3d6000fd5b505050506000805160206141ef83398151915284876001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561241a57600080fd5b505afa15801561242e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124529190613901565b61245c9190614115565b600089815260a060205260409020546004101561247d576301e13380612484565b640757b12c005b6000604051612497959493929190613daa565b60405180910390a1866001019650505050505050611ffc565b50506001606555565b6097546001600160a01b031633146124d057600080fd5b609780546001600160a01b0316600160a01b6001600160601b038416021790556040517fff9620ed8130071de22ec459745cab5842de31c143a7b9e2e483b56b49699cb49061107f908390614050565b600260655414156125435760405162461bcd60e51b81526004016108f090613fe2565b6002606555609954600160a01b900460ff166125a15760405162461bcd60e51b815260206004820152601e60248201527f72703a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b60a2816040516125b19190613c98565b9081526020016040518091039020546000141561260c5760405162461bcd60e51b81526020600482015260196024820152781c9c0e881c1c9bd99a5b19481a5cc81b9bdd081cdd185ad959603a1b60448201526064016108f0565b609a54604051636f00042160e11b815233916001600160a01b03169063de0008429061263c908590600401613e2d565b60206040518083038186803b15801561265457600080fd5b505afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c919061369a565b6001600160a01b0316146126e25760405162461bcd60e51b815260206004820181905260248201527f72703a2070726f66696c65206973206e6f74206f776e6564206279207573657260448201526064016108f0565b600060a2826040516126f49190613c98565b90815260405190819003602001812091909155609b546001600160a01b0316906323b872dd903090339060a29061272c908790613c98565b908152604051908190036020018120546001600160e01b031960e086901b16825261275b939291600401613cce565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad91906138cb565b6127b657600080fd5b60008051602061420f8339815191528160006040516127d6929190613e40565b60405180910390a1506001606555565b6097546001600160a01b031633146127fd57600080fd5b600082815260a1602090815260409182902083905581518481529081018390527f3452491cd2443733279c902902e8814982d54a692cc1910b1465563aa5625a26910160405180910390a15050565b6097546001600160a01b0316331461286357600080fd5b609780546001600160a01b0319166001600160a01b0392909216919091179055565b6098546001600160a01b0316331461289c57600080fd5b609980546001600160a01b0319166001600160a01b0392909216919091179055565b60006128ca8383613041565b609f546001600160a01b039182169116149392505050565b6097546001600160a01b031633146128f957600080fd5b60998054911515600160a81b0260ff60a81b19909216919091179055565b600054610100900460ff16158080156129375750600054600160ff909116105b8061295857506129463061305d565b158015612958575060005460ff166001145b6129bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108f0565b6000805460ff1916600117905580156129de576000805461ff0019166101001790555b6129e661306c565b6129ee61309d565b609a80546001600160a01b038088166001600160a01b031992831617909255609d8054868416908316179055609e80548584169083161790556099805460ff60a81b1916600160a81b17905560a160209081526104007ff4875fff8b0cf986238a93aa5a1c4dd6cdbe2f1045b9974e1f43ef715569af66556102007f56cd10bd7c5a283404157adf2ba847ac6f7bfee0953fbdea6cae6f66ee17d9ce5560807f82810f81d5d6068ad5b62b5073b1161d037affd3559d84ef47a831e06ad04e865560046000527f452a9a645b43619dc9681d051339fd2836f59d845037283e59145a406fad0d00556556bc75e2d63160b41b91861691909117609755600160a11b3317609855609f8054909116739efcd5075cdfb7f58c26e3fb3f22bb498c6e31741790558015612b59576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b609d54604051634a9df57f60e01b81526000916001600160a01b031690634a9df57f90612b91908590600401613e2d565b60206040518083038186803b158015612ba957600080fd5b505afa158015612bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be191906138cb565b92915050565b6000808383604051602001612bfd929190613c63565b60408051601f198184030181529082905280516020918201207b0ca2ba3432b932bab69029b4b3b732b21026b2b9b9b0b3b29d05199960211b91830191909152603c820152605c0160408051808303601f190181529190528051602090910120949350505050565b60995460405163d505accf60e01b81526001600160a01b038781166004830152868116602483015260001960448301819052606483015260ff8616608483015260a4820185905260c482018490529091169063d505accf9060e401600060405180830381600087803b158015612cda57600080fd5b505af1158015612cee573d6000803e3d6000fd5b505050505050505050565b609954609c546040516323b872dd60e01b81526000926001600160a01b03908116926323b872dd92612d3392889216908790600401613cce565b602060405180830381600087803b158015612d4d57600080fd5b505af1158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8591906138cb565b9392505050565b8051600090819081905b80821015612e86576000858381518110612db257612db261419f565b01602001516001600160f81b0319169050600160ff1b811015612de157612dda6001846140bc565b9250612e73565b600760fd1b6001600160f81b031982161015612e0257612dda6002846140bc565b600f60fc1b6001600160f81b031982161015612e2357612dda6003846140bc565b601f60fb1b6001600160f81b031982161015612e4457612dda6004846140bc565b603f60fa1b6001600160f81b031982161015612e6557612dda6005846140bc565b612e706006846140bc565b92505b5082612e7e81614158565b935050612d96565b50909392505050565b60008051602061424f833981519152546001600160a01b031690565b6098546001600160a01b03163314611b5357600080fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612efa57612ef5836130c4565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f3357600080fd5b505afa925050508015612f63575060408051601f3d908101601f19168201909252612f6091810190613901565b60015b612fc65760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108f0565b60008051602061424f83398151915281146130355760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108f0565b50612ef583838361315e565b60008060006130508585613189565b9150915061144b816131cf565b6001600160a01b03163b151590565b600054610100900460ff166130935760405162461bcd60e51b81526004016108f090613f74565b61309b613385565b565b600054610100900460ff1661309b5760405162461bcd60e51b81526004016108f090613f74565b6130cd8161305d565b61312f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108f0565b60008051602061424f83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613167836133b3565b6000825111806131745750805b15612ef55761318383836133f3565b50505050565b6000808251604114156131c05760208301516040840151606085015160001a6131b4878285856134dc565b945094505050506131c8565b506000905060025b9250929050565b60008160048111156131e3576131e3614189565b14156131ec5750565b600181600481111561320057613200614189565b14156132495760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b60448201526064016108f0565b600281600481111561325d5761325d614189565b14156132ab5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108f0565b60038160048111156132bf576132bf614189565b14156133185760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108f0565b600481600481111561332c5761332c614189565b1415611b535760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016108f0565b600054610100900460ff166133ac5760405162461bcd60e51b81526004016108f090613f74565b6001606555565b6133bc816130c4565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606133fe8361305d565b6134595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108f0565b600080846001600160a01b0316846040516134749190613c98565b600060405180830381855af49150503d80600081146134af576040519150601f19603f3d011682016040523d82523d6000602084013e6134b4565b606091505b509150915061144d828260405180606001604052806027815260200161426f602791396135bf565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b0383111561350957506000905060036135b6565b8460ff16601b1415801561352157508460ff16601c14155b1561353257506000905060046135b6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613586573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135af576000600192509250506135b6565b9150600090505b94509492505050565b606083156135ce575081612d85565b8251156135de5782518084602001fd5b8160405162461bcd60e51b81526004016108f09190613e2d565b600082601f83011261360957600080fd5b81356001600160401b03811115613622576136226141b5565b613635601f8201601f191660200161408c565b81815284602083860101111561364a57600080fd5b816020850160208301376000918101602001919091529392505050565b803560ff8116811461367857600080fd5b919050565b60006020828403121561368f57600080fd5b8135612d85816141cb565b6000602082840312156136ac57600080fd5b8151612d85816141cb565b600080600080608085870312156136cd57600080fd5b84356136d8816141cb565b935060208501356136e8816141cb565b925060408501356136f8816141cb565b91506060850135613708816141cb565b939692955090935050565b6000806040838503121561372657600080fd5b8235613731816141cb565b915060208301356001600160401b0381111561374c57600080fd5b613758858286016135f8565b9150509250929050565b6000602080838503121561377557600080fd5b82356001600160401b038082111561378c57600080fd5b818501915085601f8301126137a057600080fd5b8135818111156137b2576137b26141b5565b8060051b6137c185820161408c565b8281528581019085870183870188018b10156137dc57600080fd5b600093505b848410156138a0578035868111156137f857600080fd5b870160a0818d03601f190181131561380f57600080fd5b613817614064565b8a8301358981111561382857600080fd5b6138368f8d838701016135f8565b8252506040808401358c830152606080850135613852816141cb565b808385015250608091508185013581840152508284013592508983111561387857600080fd5b6138868f8d858701016135f8565b9082015285525050600193909301929187019187016137e1565b509998505050505050505050565b6000602082840312156138c057600080fd5b8135612d85816141e0565b6000602082840312156138dd57600080fd5b8151612d85816141e0565b6000602082840312156138fa57600080fd5b5035919050565b60006020828403121561391357600080fd5b5051919050565b6000806040838503121561392d57600080fd5b8235915060208301356001600160401b0381111561374c57600080fd5b60006020828403121561395c57600080fd5b81356001600160401b0381111561397257600080fd5b61397e848285016135f8565b949350505050565b60008060006060848603121561399b57600080fd5b83356001600160401b03808211156139b257600080fd5b6139be878388016135f8565b94506020860135935060408601359150808211156139db57600080fd5b506139e8868287016135f8565b9150509250925092565b60008060408385031215613a0557600080fd5b82356001600160401b03811115613a1b57600080fd5b613a27858286016135f8565b95602094909401359450505050565b600080600080600060a08688031215613a4e57600080fd5b85356001600160401b0380821115613a6557600080fd5b613a7189838a016135f8565b96506020880135955060408801359150613a8a826141cb565b9093506060870135925060808701359080821115613aa757600080fd5b50613ab4888289016135f8565b9150509295509295909350565b600080600080600060a08688031215613ad957600080fd5b85356001600160401b03811115613aef57600080fd5b613afb888289016135f8565b95505060208601359350613b1160408701613667565b94979396509394606081013594506080013592915050565b600080600080600080600060e0888a031215613b4457600080fd5b87356001600160401b0380821115613b5b57600080fd5b613b678b838c016135f8565b985060208a01359750613b7c60408b01613667565b965060608a0135955060808a0135945060a08a0135935060c08a0135915080821115613ba757600080fd5b50613bb48a828b016135f8565b91505092959891949750929550565b60008060408385031215613bd657600080fd5b50508035926020909101359150565b600060208284031215613bf757600080fd5b81356001600160581b0381168114612d8557600080fd5b600060208284031215613c2057600080fd5b81356001600160601b0381168114612d8557600080fd5b60008151808452613c4f81602086016020860161412c565b601f01601f19169290920160200192915050565b606083901b6001600160601b03191681528151600090613c8a81601485016020870161412c565b919091016014019392505050565b60008251613caa81846020870161412c565b9190910192915050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0384168152606060208201819052600090613d1690830185613c37565b9050826040830152949350505050565b6001600160a01b038616815260a060208201819052600090613d4a90830187613c37565b604083019590955250606081019290925260809091015292915050565b6001600160a01b038616815260a060208201819052600090613d8b90830187613c37565b6040830195909552506060810192909252151560809091015292915050565b6001600160a01b038616815260a060208201819052600090613dce90830187613c37565b60408301959095525064ffffffffff92909216606083015260809091015292915050565b6001600160a01b0384168152606060208201819052600090613e1690830185613c37565b905064ffffffffff83166040830152949350505050565b602081526000612d856020830184613c37565b604081526000613e536040830185613c37565b90508260208301529392505050565b606081526000613e756060830186613c37565b6020830194909452506001600160a01b0391909116604090910152919050565b6020808252600b908201526a33b5b81d1010b7bbb732b960a91b604082015260600190565b6020808252600a90820152690ced6e0744042d0c2e6d60b31b604082015260600190565b602080825260089082015267706d3a202173696760c01b604082015260600190565b6020808252602c9082015260008051602061422f83398151915260408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c9082015260008051602061422f83398151915260408201526b6163746976652070726f787960a01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b602080825260099082015268676b703a202173696760b81b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600990820152680e0da744042d0c2e6d60bb1b604082015260600190565b6001600160581b0391909116815260200190565b6001600160601b0391909116815260200190565b60405160a081016001600160401b0381118282101715614086576140866141b5565b60405290565b604051601f8201601f191681016001600160401b03811182821017156140b4576140b46141b5565b604052919050565b600082198211156140cf576140cf614173565b500190565b6000826140f157634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561411057614110614173565b500290565b60008282101561412757614127614173565b500390565b60005b8381101561414757818101518382015260200161412f565b838111156131835750506000910152565b600060001982141561416c5761416c614173565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611b5357600080fd5b8015158114611b5357600080fdfefdbd996e3e72e8c7d34fc2f374c3c85c80a530bd1cdaa4a748d34e32103c5cc3ecd31a3b3fd701cb98ffce1e0be6f00ff21ab1556ae1c6c3dc2045696ecb90cc46756e6374696f6e206d7573742062652063616c6c6564207468726f75676820360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564954927086ae90e1d7691ecb029f83a9183e8a96e8d94b631d443bdfe68b597d3a164736f6c6343000806000a
Deployed Bytecode
0x6080604052600436106102225760003560e01c8062da7733146102275780630c340a24146102495780630e2d56cf146102865780631015805b146102a657806310d70f24146102e157806313af40351461030157806314dc648e1461032157806317ef67c6146103415780631a8999fb1461036157806329c33853146103815780632a131fe3146103a15780632ebd7c6f146103c157806330334540146103e15780633659cfe614610401578063445601c5146104215780634af6b5c2146104415780634c62d88c146104615780634f1ef2861461048157806351b20ed01461049457806352d1902d146104c85780635b7633d0146104dd5780635f9fe274146104fd5780636c19e7831461051d5780637e2337a51461053d5780638076f0051461055d57806389462c381461059d5780638da5cb5b146105bd5780639b6c0796146105dd5780639b995f5c146105fe5780639db1b5af1461061e578063b0127b6d1461063e578063b6eb4e641461065e578063ba11a7c21461068b578063bc7dbc0d146106ab578063be26cc7b146106df578063c0c93071146106ff578063c42cf5351461071f578063ca291ca81461073f578063cb1468791461075f578063daca6f781461077f578063db64f6871461079f578063dc9db853146107bf578063e1e91f8a146107f7578063eebeb9411461081e578063f8c8765e1461084b578063fc47b8d31461086b578063fdcd61d61461088b578063ff137c87146108ac575b600080fd5b34801561023357600080fd5b5061024761024236600461394a565b6108cd565b005b34801561025557600080fd5b50609754610269906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561029257600080fd5b506102476102a13660046138ae565b610c16565b3480156102b257600080fd5b506102d36102c136600461367d565b60a46020526000908152604090205481565b60405190815260200161027d565b3480156102ed57600080fd5b506102476102fc366004613b29565b610c4b565b34801561030d57600080fd5b5061024761031c36600461367d565b610fdf565b34801561032d57600080fd5b5061024761033c366004613c0e565b611018565b34801561034d57600080fd5b5061024761035c36600461367d565b61108a565b34801561036d57600080fd5b5061024761037c366004613986565b6110c3565b34801561038d57600080fd5b506102d361039c3660046139f2565b6113df565b3480156103ad57600080fd5b506102476103bc366004613be5565b611456565b3480156103cd57600080fd5b506102476103dc366004613ac1565b6114c1565b3480156103ed57600080fd5b506102476103fc366004613a36565b6116d1565b34801561040d57600080fd5b5061024761041c36600461367d565b611a8d565b34801561042d57600080fd5b5061024761043c3660046138ae565b611b56565b34801561044d57600080fd5b50609b54610269906001600160a01b031681565b34801561046d57600080fd5b50609c54610269906001600160a01b031681565b61024761048f366004613713565b611b8d565b3480156104a057600080fd5b5060a5546104bb90600160a01b90046001600160581b031681565b60405161027d919061403c565b3480156104d457600080fd5b506102d3611c47565b3480156104e957600080fd5b50609f54610269906001600160a01b031681565b34801561050957600080fd5b50609d54610269906001600160a01b031681565b34801561052957600080fd5b5061024761053836600461367d565b611cf5565b34801561054957600080fd5b50610247610558366004613ac1565b611d2e565b34801561056957600080fd5b5061058d6105783660046138e8565b60a36020526000908152604090205460ff1681565b604051901515815260200161027d565b3480156105a957600080fd5b506102476105b836600461367d565b611f98565b3480156105c957600080fd5b50609854610269906001600160a01b031681565b3480156105e957600080fd5b5060a55461058d90600160f81b900460ff1681565b34801561060a57600080fd5b50609a54610269906001600160a01b031681565b34801561062a57600080fd5b50610247610639366004613762565b611fd1565b34801561064a57600080fd5b50610247610659366004613c0e565b6124b9565b34801561066a57600080fd5b506102d36106793660046138e8565b60a16020526000908152604090205481565b34801561069757600080fd5b506102476106a636600461394a565b612520565b3480156106b757600080fd5b506097546106d290600160a01b90046001600160601b031681565b60405161027d9190614050565b3480156106eb57600080fd5b50609954610269906001600160a01b031681565b34801561070b57600080fd5b5061024761071a366004613bc3565b6127e6565b34801561072b57600080fd5b5061024761073a36600461367d565b61284c565b34801561074b57600080fd5b50609e54610269906001600160a01b031681565b34801561076b57600080fd5b5061024761077a36600461367d565b612885565b34801561078b57600080fd5b5061058d61079a36600461391a565b6128be565b3480156107ab57600080fd5b506102476107ba3660046138ae565b6128e2565b3480156107cb57600080fd5b506102d36107da36600461394a565b805160208183018101805160a28252928201919093012091525481565b34801561080357600080fd5b506098546106d290600160a01b90046001600160601b031681565b34801561082a57600080fd5b506102d36108393660046138e8565b60a06020526000908152604090205481565b34801561085757600080fd5b506102476108663660046136b7565b612917565b34801561087757600080fd5b5060a554610269906001600160a01b031681565b34801561089757600080fd5b5060995461058d90600160a01b900460ff1681565b3480156108b857600080fd5b5060995461058d90600160a81b900460ff1681565b600260655414156108f95760405162461bcd60e51b81526004016108f090613fe2565b60405180910390fd5b6002606555609954600160a01b900460ff166109575760405162461bcd60e51b815260206004820152601e60248201527f6f703a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b60a2816040516109679190613c98565b90815260200160405180910390205460001461098257600080fd5b609b54604080516312f73d0360e11b815290516000926001600160a01b0316916325ee7a06916004808301926020929190829003018186803b1580156109c757600080fd5b505afa1580156109db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ff9190613901565b609b60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a4d57600080fd5b505afa158015610a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a859190613901565b609854600160a01b90046001600160601b0316610aa6856301e133806113df565b610ab091906140f6565b610aba91906140f6565b610ac491906140d4565b905080610afc5760405162461bcd60e51b815260206004820152600660248201526506f703a2021360d41b60448201526064016108f0565b8060a283604051610b0d9190613c98565b90815260405190819003602001812091909155609b546323b872dd60e01b82526001600160a01b0316906323b872dd90610b4f90339030908690600401613cce565b602060405180830381600087803b158015610b6957600080fd5b505af1158015610b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba191906138cb565b610be65760405162461bcd60e51b81526020600482015260166024820152756f703a20696e73756666696369656e742066756e647360501b60448201526064016108f0565b60008051602061420f8339815191528282604051610c05929190613e40565b60405180910390a150506001606555565b6097546001600160a01b03163314610c2d57600080fd5b60998054911515600160a01b0260ff60a01b19909216919091179055565b60026065541415610c6e5760405162461bcd60e51b81526004016108f090613fe2565b600260655586610c7d81612b60565b610c8657600080fd5b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd9690610cb6908490600401613e2d565b60206040518083038186803b158015610cce57600080fd5b505afa158015610ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0691906138cb565b15610d1057600080fd5b609954600160a01b900460ff16610d5b5760405162461bcd60e51b815260206004820152600f60248201526e1c1b4e88085c1d589b1a58d35a5b9d608a1b60448201526064016108f0565b610d6583836128be565b8015610d805750600083815260a3602052604090205460ff16155b610d9c5760405162461bcd60e51b81526004016108f090613ede565b82610da7338a612be7565b14610dc45760405162461bcd60e51b81526004016108f090614019565b609954604051636eb1769f60e11b81526001600160a01b039091169063dd62ed3e90610df69033903090600401613cb4565b60206040518083038186803b158015610e0e57600080fd5b505afa158015610e22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e469190613901565b610e5757610e573330888888612c65565b610e6a33610e658a8a6113df565b612cf9565b610ea35760405162461bcd60e51b815260206004820152600a602482015269706d3a202166756e647360b01b60448201526064016108f0565b609a5460405163121cbf4560e21b81526001600160a01b0390911690634872fd1490610ed79033908c908c90600401613cf2565b600060405180830381600087803b158015610ef157600080fd5b505af1158015610f05573d6000803e3d6000fd5b505050506000805160206141ef83398151915233896001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f6a57600080fd5b505afa158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190613901565b610fac9190614115565b8a610fb78d8d6113df565b604051610fc8959493929190613d26565b60405180910390a150506001606555505050505050565b6098546001600160a01b03163314610ff657600080fd5b609880546001600160a01b0319166001600160a01b0392909216919091179055565b6097546001600160a01b0316331461102f57600080fd5b609880546001600160a01b0316600160a01b6001600160601b038416021790556040517fb395a37dd4eb95d1e572e09133b8d6458643a806657c23b0448725f46087dd929061107f908390614050565b60405180910390a150565b6098546001600160a01b031633146110a157600080fd5b609c80546001600160a01b0319166001600160a01b0392909216919091179055565b600260655414156110e65760405162461bcd60e51b81526004016108f090613fe2565b6002606555826110f581612b60565b6110fe57600080fd5b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd969061112e908490600401613e2d565b60206040518083038186803b15801561114657600080fd5b505afa15801561115a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117e91906138cb565b1561118857600080fd5b60a554600160f81b900460ff166111d75760405162461bcd60e51b81526020600482015260136024820152721c1b4e881c1d589b1a58d0db185a5b509bdbdb606a1b60448201526064016108f0565b6111e183836128be565b80156111fc5750600083815260a3602052604090205460ff16155b6112185760405162461bcd60e51b81526004016108f090613ede565b826112233386612be7565b146112405760405162461bcd60e51b81526004016108f090614019565b60a55433600090815260a46020526040902054600160a01b9091046001600160581b03161161128257604051639e92c61f60e01b815260040160405180910390fd5b33600090815260a4602052604081208054600192906112a29084906140bc565b9091555050609a5460405163121cbf4560e21b81526001600160a01b0390911690634872fd14906112df90339088906301e1338090600401613cf2565b600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b505050506000805160206141ef83398151915233856001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561137257600080fd5b505afa158015611386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113aa9190613901565b6113b49190614115565b6301e1338060006040516113cc959493929190613d26565b60405180910390a1505060016065555050565b60975460009081906301e1338090611408908590600160a01b90046001600160601b03166140f6565b61141291906140d4565b9050600060a1600061142387612d8c565b81526020019081526020016000205490508060001461144b5761144681836140f6565b61144d565b815b95945050505050565b6097546001600160a01b0316331461146d57600080fd5b60a58054600160a01b600160f81b031916600160a01b6001600160581b038416021790556040517f69bf8e28fdfad65f1c3889032b88ed519c37e782fedc7159de360c2bbce58cf59061107f90839061403c565b600260655414156114e45760405162461bcd60e51b81526004016108f090613fe2565b6002606555609954600160a01b900460ff166115425760405162461bcd60e51b815260206004820152601e60248201527f656c3a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b609954604051636eb1769f60e11b81526001600160a01b039091169063dd62ed3e906115749033903090600401613cb4565b60206040518083038186803b15801561158c57600080fd5b505afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c49190613901565b6115d5576115d53330858585612c65565b6115e333610e6587876113df565b6116285760405162461bcd60e51b8152602060048201526016602482015275656c3a20696e73756666696369656e742066756e647360501b60448201526064016108f0565b609a5460405163fad1a5db60e01b81526001600160a01b039091169063fad1a5db9061165c90889088903390600401613e62565b600060405180830381600087803b15801561167657600080fd5b505af115801561168a573d6000803e3d6000fd5b505050506000805160206142968339815191523386866116aa89896113df565b60006040516116bd959493929190613d67565b60405180910390a150506001606555505050565b846116db81612b60565b6116e457600080fd5b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd9690611714908490600401613e2d565b60206040518083038186803b15801561172c57600080fd5b505afa158015611740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176491906138cb565b1561176e57600080fd5b600260655414156117915760405162461bcd60e51b81526004016108f090613fe2565b6002606555609e546040516331a9108f60e11b8152600481018790526001600160a01b03868116921690636352211e9060240160206040518083038186803b1580156117dc57600080fd5b505afa1580156117f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611814919061369a565b6001600160a01b03161461183a5760405162461bcd60e51b81526004016108f090613e95565b61184483836128be565b801561185f5750600083815260a3602052604090205460ff16155b61187b5760405162461bcd60e51b81526004016108f090613fbf565b826118863388612be7565b146118a35760405162461bcd60e51b81526004016108f090613eba565b609954600090600160a81b900460ff166118be5760076118c1565b60045b600087815260a0602052604090205460ff9190911691508114156118e457600080fd5b600086815260a0602052604081208054600192906119039084906140bc565b9091555050609a54600087815260a060205260409020546001600160a01b0390911690634872fd149087908a9060041015611942576301e13380611949565b640757b12c005b6040518463ffffffff1660e01b815260040161196793929190613df2565b600060405180830381600087803b15801561198157600080fd5b505af1158015611995573d6000803e3d6000fd5b505050506000805160206141ef83398151915285886001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119fa57600080fd5b505afa158015611a0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a329190613901565b611a3c9190614115565b60008a815260a0602052604090205460041015611a5d576301e13380611a64565b640757b12c005b6000604051611a77959493929190613daa565b60405180910390a1505060016065555050505050565b306001600160a01b037f0000000000000000000000000d778388d5250b84e5cb7a1a7a39ac0a45141500161415611ad65760405162461bcd60e51b81526004016108f090613f00565b7f0000000000000000000000000d778388d5250b84e5cb7a1a7a39ac0a451415006001600160a01b0316611b08612e8f565b6001600160a01b031614611b2e5760405162461bcd60e51b81526004016108f090613f3a565b611b3781612eab565b60408051600080825260208201909252611b5391839190612ec2565b50565b6097546001600160a01b03163314611b6d57600080fd5b60a58054911515600160f81b026001600160f81b03909216919091179055565b306001600160a01b037f0000000000000000000000000d778388d5250b84e5cb7a1a7a39ac0a45141500161415611bd65760405162461bcd60e51b81526004016108f090613f00565b7f0000000000000000000000000d778388d5250b84e5cb7a1a7a39ac0a451415006001600160a01b0316611c08612e8f565b6001600160a01b031614611c2e5760405162461bcd60e51b81526004016108f090613f3a565b611c3782612eab565b611c4382826001612ec2565b5050565b6000306001600160a01b037f0000000000000000000000000d778388d5250b84e5cb7a1a7a39ac0a451415001614611ce25760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c6044820152771b1959081d1a1c9bdd59da0819195b1959d85d1958d85b1b60421b60648201526084016108f0565b5060008051602061424f83398151915290565b6098546001600160a01b03163314611d0c57600080fd5b609f80546001600160a01b0319166001600160a01b0392909216919091179055565b60026065541415611d515760405162461bcd60e51b81526004016108f090613fe2565b6002606555609954600160a01b900460ff16611daf5760405162461bcd60e51b815260206004820152601e60248201527f70653a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b60a285604051611dbf9190613c98565b908152602001604051809103902054600014611e1d5760405162461bcd60e51b815260206004820152601d60248201527f70653a2070726f66696c6520697320616c7265616479207374616b656400000060448201526064016108f0565b609954604051636eb1769f60e11b81526001600160a01b039091169063dd62ed3e90611e4f9033903090600401613cb4565b60206040518083038186803b158015611e6757600080fd5b505afa158015611e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9f9190613901565b611eb057611eb03330858585612c65565b611ebe33610e6587876113df565b611f035760405162461bcd60e51b815260206004820152601660248201527570653a20696e73756666696369656e742066756e647360501b60448201526064016108f0565b609a5460405163655d056b60e11b81526001600160a01b039091169063caba0ad690611f3790889088903390600401613e62565b600060405180830381600087803b158015611f5157600080fd5b505af1158015611f65573d6000803e3d6000fd5b50505050600080516020614296833981519152338686611f8589896113df565b60016040516116bd959493929190613d67565b6098546001600160a01b03163314611faf57600080fd5b609b80546001600160a01b0319166001600160a01b0392909216919091179055565b60026065541415611ff45760405162461bcd60e51b81526004016108f090613fe2565b600260655560005b81518110156124b05760008282815181106120195761201961419f565b6020026020010151600001519050600083838151811061203b5761203b61419f565b6020026020010151602001519050600084848151811061205d5761205d61419f565b6020026020010151604001519050600085858151811061207f5761207f61419f565b602002602001015160600151905060008686815181106120a1576120a161419f565b602090810291909101015160800151609e546040516331a9108f60e11b8152600481018790529192506001600160a01b0385811692911690636352211e9060240160206040518083038186803b1580156120fa57600080fd5b505afa15801561210e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612132919061369a565b6001600160a01b0316146121585760405162461bcd60e51b81526004016108f090613e95565b61216185612b60565b61219e5760405162461bcd60e51b815260206004820152600e60248201526d676b703a202176616c696455524960901b60448201526064016108f0565b609a54604051633900decb60e11b81526001600160a01b0390911690637201bd96906121ce908890600401613e2d565b60206040518083038186803b1580156121e657600080fd5b505afa1580156121fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221e91906138cb565b1561225a5760405162461bcd60e51b815260206004820152600c60248201526b19dadc0e88085d5b9d5cd95960a21b60448201526064016108f0565b61226482826128be565b801561227f5750600082815260a3602052604090205460ff16155b61229b5760405162461bcd60e51b81526004016108f090613fbf565b816122a63387612be7565b146122c35760405162461bcd60e51b81526004016108f090613eba565b609954600090600160a81b900460ff166122de5760076122e1565b60045b600086815260a0602052604090205460ff91909116915081141561230457600080fd5b600085815260a0602052604081208054600192906123239084906140bc565b9091555050609a54600086815260a060205260409020546001600160a01b0390911690634872fd14908690899060041015612362576301e13380612369565b640757b12c005b6040518463ffffffff1660e01b815260040161238793929190613df2565b600060405180830381600087803b1580156123a157600080fd5b505af11580156123b5573d6000803e3d6000fd5b505050506000805160206141ef83398151915284876001609a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561241a57600080fd5b505afa15801561242e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124529190613901565b61245c9190614115565b600089815260a060205260409020546004101561247d576301e13380612484565b640757b12c005b6000604051612497959493929190613daa565b60405180910390a1866001019650505050505050611ffc565b50506001606555565b6097546001600160a01b031633146124d057600080fd5b609780546001600160a01b0316600160a01b6001600160601b038416021790556040517fff9620ed8130071de22ec459745cab5842de31c143a7b9e2e483b56b49699cb49061107f908390614050565b600260655414156125435760405162461bcd60e51b81526004016108f090613fe2565b6002606555609954600160a01b900460ff166125a15760405162461bcd60e51b815260206004820152601e60248201527f72703a207075626c6963206d696e74696e672069732064697361626c6564000060448201526064016108f0565b60a2816040516125b19190613c98565b9081526020016040518091039020546000141561260c5760405162461bcd60e51b81526020600482015260196024820152781c9c0e881c1c9bd99a5b19481a5cc81b9bdd081cdd185ad959603a1b60448201526064016108f0565b609a54604051636f00042160e11b815233916001600160a01b03169063de0008429061263c908590600401613e2d565b60206040518083038186803b15801561265457600080fd5b505afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c919061369a565b6001600160a01b0316146126e25760405162461bcd60e51b815260206004820181905260248201527f72703a2070726f66696c65206973206e6f74206f776e6564206279207573657260448201526064016108f0565b600060a2826040516126f49190613c98565b90815260405190819003602001812091909155609b546001600160a01b0316906323b872dd903090339060a29061272c908790613c98565b908152604051908190036020018120546001600160e01b031960e086901b16825261275b939291600401613cce565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad91906138cb565b6127b657600080fd5b60008051602061420f8339815191528160006040516127d6929190613e40565b60405180910390a1506001606555565b6097546001600160a01b031633146127fd57600080fd5b600082815260a1602090815260409182902083905581518481529081018390527f3452491cd2443733279c902902e8814982d54a692cc1910b1465563aa5625a26910160405180910390a15050565b6097546001600160a01b0316331461286357600080fd5b609780546001600160a01b0319166001600160a01b0392909216919091179055565b6098546001600160a01b0316331461289c57600080fd5b609980546001600160a01b0319166001600160a01b0392909216919091179055565b60006128ca8383613041565b609f546001600160a01b039182169116149392505050565b6097546001600160a01b031633146128f957600080fd5b60998054911515600160a81b0260ff60a81b19909216919091179055565b600054610100900460ff16158080156129375750600054600160ff909116105b8061295857506129463061305d565b158015612958575060005460ff166001145b6129bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108f0565b6000805460ff1916600117905580156129de576000805461ff0019166101001790555b6129e661306c565b6129ee61309d565b609a80546001600160a01b038088166001600160a01b031992831617909255609d8054868416908316179055609e80548584169083161790556099805460ff60a81b1916600160a81b17905560a160209081526104007ff4875fff8b0cf986238a93aa5a1c4dd6cdbe2f1045b9974e1f43ef715569af66556102007f56cd10bd7c5a283404157adf2ba847ac6f7bfee0953fbdea6cae6f66ee17d9ce5560807f82810f81d5d6068ad5b62b5073b1161d037affd3559d84ef47a831e06ad04e865560046000527f452a9a645b43619dc9681d051339fd2836f59d845037283e59145a406fad0d00556556bc75e2d63160b41b91861691909117609755600160a11b3317609855609f8054909116739efcd5075cdfb7f58c26e3fb3f22bb498c6e31741790558015612b59576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b609d54604051634a9df57f60e01b81526000916001600160a01b031690634a9df57f90612b91908590600401613e2d565b60206040518083038186803b158015612ba957600080fd5b505afa158015612bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be191906138cb565b92915050565b6000808383604051602001612bfd929190613c63565b60408051601f198184030181529082905280516020918201207b0ca2ba3432b932bab69029b4b3b732b21026b2b9b9b0b3b29d05199960211b91830191909152603c820152605c0160408051808303601f190181529190528051602090910120949350505050565b60995460405163d505accf60e01b81526001600160a01b038781166004830152868116602483015260001960448301819052606483015260ff8616608483015260a4820185905260c482018490529091169063d505accf9060e401600060405180830381600087803b158015612cda57600080fd5b505af1158015612cee573d6000803e3d6000fd5b505050505050505050565b609954609c546040516323b872dd60e01b81526000926001600160a01b03908116926323b872dd92612d3392889216908790600401613cce565b602060405180830381600087803b158015612d4d57600080fd5b505af1158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8591906138cb565b9392505050565b8051600090819081905b80821015612e86576000858381518110612db257612db261419f565b01602001516001600160f81b0319169050600160ff1b811015612de157612dda6001846140bc565b9250612e73565b600760fd1b6001600160f81b031982161015612e0257612dda6002846140bc565b600f60fc1b6001600160f81b031982161015612e2357612dda6003846140bc565b601f60fb1b6001600160f81b031982161015612e4457612dda6004846140bc565b603f60fa1b6001600160f81b031982161015612e6557612dda6005846140bc565b612e706006846140bc565b92505b5082612e7e81614158565b935050612d96565b50909392505050565b60008051602061424f833981519152546001600160a01b031690565b6098546001600160a01b03163314611b5357600080fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612efa57612ef5836130c4565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f3357600080fd5b505afa925050508015612f63575060408051601f3d908101601f19168201909252612f6091810190613901565b60015b612fc65760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108f0565b60008051602061424f83398151915281146130355760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108f0565b50612ef583838361315e565b60008060006130508585613189565b9150915061144b816131cf565b6001600160a01b03163b151590565b600054610100900460ff166130935760405162461bcd60e51b81526004016108f090613f74565b61309b613385565b565b600054610100900460ff1661309b5760405162461bcd60e51b81526004016108f090613f74565b6130cd8161305d565b61312f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108f0565b60008051602061424f83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613167836133b3565b6000825111806131745750805b15612ef55761318383836133f3565b50505050565b6000808251604114156131c05760208301516040840151606085015160001a6131b4878285856134dc565b945094505050506131c8565b506000905060025b9250929050565b60008160048111156131e3576131e3614189565b14156131ec5750565b600181600481111561320057613200614189565b14156132495760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b60448201526064016108f0565b600281600481111561325d5761325d614189565b14156132ab5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108f0565b60038160048111156132bf576132bf614189565b14156133185760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108f0565b600481600481111561332c5761332c614189565b1415611b535760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016108f0565b600054610100900460ff166133ac5760405162461bcd60e51b81526004016108f090613f74565b6001606555565b6133bc816130c4565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606133fe8361305d565b6134595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108f0565b600080846001600160a01b0316846040516134749190613c98565b600060405180830381855af49150503d80600081146134af576040519150601f19603f3d011682016040523d82523d6000602084013e6134b4565b606091505b509150915061144d828260405180606001604052806027815260200161426f602791396135bf565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b0383111561350957506000905060036135b6565b8460ff16601b1415801561352157508460ff16601c14155b1561353257506000905060046135b6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613586573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135af576000600192509250506135b6565b9150600090505b94509492505050565b606083156135ce575081612d85565b8251156135de5782518084602001fd5b8160405162461bcd60e51b81526004016108f09190613e2d565b600082601f83011261360957600080fd5b81356001600160401b03811115613622576136226141b5565b613635601f8201601f191660200161408c565b81815284602083860101111561364a57600080fd5b816020850160208301376000918101602001919091529392505050565b803560ff8116811461367857600080fd5b919050565b60006020828403121561368f57600080fd5b8135612d85816141cb565b6000602082840312156136ac57600080fd5b8151612d85816141cb565b600080600080608085870312156136cd57600080fd5b84356136d8816141cb565b935060208501356136e8816141cb565b925060408501356136f8816141cb565b91506060850135613708816141cb565b939692955090935050565b6000806040838503121561372657600080fd5b8235613731816141cb565b915060208301356001600160401b0381111561374c57600080fd5b613758858286016135f8565b9150509250929050565b6000602080838503121561377557600080fd5b82356001600160401b038082111561378c57600080fd5b818501915085601f8301126137a057600080fd5b8135818111156137b2576137b26141b5565b8060051b6137c185820161408c565b8281528581019085870183870188018b10156137dc57600080fd5b600093505b848410156138a0578035868111156137f857600080fd5b870160a0818d03601f190181131561380f57600080fd5b613817614064565b8a8301358981111561382857600080fd5b6138368f8d838701016135f8565b8252506040808401358c830152606080850135613852816141cb565b808385015250608091508185013581840152508284013592508983111561387857600080fd5b6138868f8d858701016135f8565b9082015285525050600193909301929187019187016137e1565b509998505050505050505050565b6000602082840312156138c057600080fd5b8135612d85816141e0565b6000602082840312156138dd57600080fd5b8151612d85816141e0565b6000602082840312156138fa57600080fd5b5035919050565b60006020828403121561391357600080fd5b5051919050565b6000806040838503121561392d57600080fd5b8235915060208301356001600160401b0381111561374c57600080fd5b60006020828403121561395c57600080fd5b81356001600160401b0381111561397257600080fd5b61397e848285016135f8565b949350505050565b60008060006060848603121561399b57600080fd5b83356001600160401b03808211156139b257600080fd5b6139be878388016135f8565b94506020860135935060408601359150808211156139db57600080fd5b506139e8868287016135f8565b9150509250925092565b60008060408385031215613a0557600080fd5b82356001600160401b03811115613a1b57600080fd5b613a27858286016135f8565b95602094909401359450505050565b600080600080600060a08688031215613a4e57600080fd5b85356001600160401b0380821115613a6557600080fd5b613a7189838a016135f8565b96506020880135955060408801359150613a8a826141cb565b9093506060870135925060808701359080821115613aa757600080fd5b50613ab4888289016135f8565b9150509295509295909350565b600080600080600060a08688031215613ad957600080fd5b85356001600160401b03811115613aef57600080fd5b613afb888289016135f8565b95505060208601359350613b1160408701613667565b94979396509394606081013594506080013592915050565b600080600080600080600060e0888a031215613b4457600080fd5b87356001600160401b0380821115613b5b57600080fd5b613b678b838c016135f8565b985060208a01359750613b7c60408b01613667565b965060608a0135955060808a0135945060a08a0135935060c08a0135915080821115613ba757600080fd5b50613bb48a828b016135f8565b91505092959891949750929550565b60008060408385031215613bd657600080fd5b50508035926020909101359150565b600060208284031215613bf757600080fd5b81356001600160581b0381168114612d8557600080fd5b600060208284031215613c2057600080fd5b81356001600160601b0381168114612d8557600080fd5b60008151808452613c4f81602086016020860161412c565b601f01601f19169290920160200192915050565b606083901b6001600160601b03191681528151600090613c8a81601485016020870161412c565b919091016014019392505050565b60008251613caa81846020870161412c565b9190910192915050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0384168152606060208201819052600090613d1690830185613c37565b9050826040830152949350505050565b6001600160a01b038616815260a060208201819052600090613d4a90830187613c37565b604083019590955250606081019290925260809091015292915050565b6001600160a01b038616815260a060208201819052600090613d8b90830187613c37565b6040830195909552506060810192909252151560809091015292915050565b6001600160a01b038616815260a060208201819052600090613dce90830187613c37565b60408301959095525064ffffffffff92909216606083015260809091015292915050565b6001600160a01b0384168152606060208201819052600090613e1690830185613c37565b905064ffffffffff83166040830152949350505050565b602081526000612d856020830184613c37565b604081526000613e536040830185613c37565b90508260208301529392505050565b606081526000613e756060830186613c37565b6020830194909452506001600160a01b0391909116604090910152919050565b6020808252600b908201526a33b5b81d1010b7bbb732b960a91b604082015260600190565b6020808252600a90820152690ced6e0744042d0c2e6d60b31b604082015260600190565b602080825260089082015267706d3a202173696760c01b604082015260600190565b6020808252602c9082015260008051602061422f83398151915260408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c9082015260008051602061422f83398151915260408201526b6163746976652070726f787960a01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b602080825260099082015268676b703a202173696760b81b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600990820152680e0da744042d0c2e6d60bb1b604082015260600190565b6001600160581b0391909116815260200190565b6001600160601b0391909116815260200190565b60405160a081016001600160401b0381118282101715614086576140866141b5565b60405290565b604051601f8201601f191681016001600160401b03811182821017156140b4576140b46141b5565b604052919050565b600082198211156140cf576140cf614173565b500190565b6000826140f157634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561411057614110614173565b500290565b60008282101561412757614127614173565b500390565b60005b8381101561414757818101518382015260200161412f565b838111156131835750506000910152565b600060001982141561416c5761416c614173565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611b5357600080fd5b8015158114611b5357600080fdfefdbd996e3e72e8c7d34fc2f374c3c85c80a530bd1cdaa4a748d34e32103c5cc3ecd31a3b3fd701cb98ffce1e0be6f00ff21ab1556ae1c6c3dc2045696ecb90cc46756e6374696f6e206d7573742062652063616c6c6564207468726f75676820360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564954927086ae90e1d7691ecb029f83a9183e8a96e8d94b631d443bdfe68b597d3a164736f6c6343000806000a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.