ERC-1155
Overview
Max Total Supply
0
Holders
34
Total Transfers
-
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
KultDolceResources
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol"; import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; import "@openzeppelin/contracts/token/common/ERC2981.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; /// @custom:security-contact [email protected] contract KultDolceResources is ERC1155, Ownable, AccessControl, ERC1155Burnable, ERC1155Supply, ERC2981, ReentrancyGuard, EIP712 { using Counters for Counters.Counter; string public name; string public version; Token[] public tokens; struct Token { string name; uint256 maxSupply; } mapping(address => mapping(address => Counters.Counter)) private _nonces; bytes32 private constant _CLAIM_BATCH_TYPEHASH = keccak256( "ClaimBatch(address signer,address account,uint256[] ids,uint256[] amounts,uint256[] burnIds,uint256[] burnAmounts,uint256 nonce)" ); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); event ClaimBatch( address signer, address account, uint256[] ids, uint256[] amounts, uint256[] burnIds, uint256[] burnAmounts, uint256 nonce ); constructor( string memory name_, string memory version_, string memory uri_ ) ERC1155(uri_) EIP712(name_, version_) { name = name_; version = version_; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(MINTER_ROLE, msg.sender); } function _withinSupply( uint256 tokenId, uint256 quantity ) internal view returns (bool isWithinSupply) { isWithinSupply = tokens[tokenId].maxSupply == 0 || totalSupply(tokenId) + quantity <= tokens[tokenId].maxSupply; } function setURI(string memory newuri) public onlyOwner { _setURI(newuri); } function setTokens(Token[] memory _tokens) public onlyOwner { delete tokens; for (uint256 i = 0; i < _tokens.length; i++) { tokens.push(_tokens[i]); } } function tokenCount() external view returns (uint256 _tokenCount) { _tokenCount = tokens.length; } function mint( address account, uint256 id, uint256 amount, bytes memory data ) public onlyRole(MINTER_ROLE) { require(_withinSupply(id, amount), "AMOUNT_EXCEED_MAX_SUPPLY"); _mint(account, id, amount, data); } function mintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public onlyRole(MINTER_ROLE) { for (uint256 i = 0; i < ids.length; i++) { require( _withinSupply(ids[i], amounts[i]), "AMOUNT_EXCEED_MAX_SUPPLY" ); } _mintBatch(to, ids, amounts, data); } // Claim functions function claimBatch( address signer, address account, uint256[] memory ids, uint256[] memory amounts, uint256[] memory burnIds, uint256[] memory burnAmounts, bytes memory data, uint8 v, bytes32 r, bytes32 s ) public nonReentrant { require(hasRole(MINTER_ROLE, signer), "MINTER_NOT_ALLOWED"); uint256 nonce = _useNonce(signer, account); bytes32 structHash = keccak256( abi.encode( _CLAIM_BATCH_TYPEHASH, signer, account, keccak256(abi.encodePacked(ids)), keccak256(abi.encodePacked(amounts)), keccak256(abi.encodePacked(burnIds)), keccak256(abi.encodePacked(burnAmounts)), nonce ) ); bytes32 typedHash = _hashTypedDataV4(structHash); address recoveredSigner = ECDSA.recover(typedHash, v, r, s); require(recoveredSigner == signer, "INVALID_SIGNATURE"); for (uint256 i = 0; i < ids.length; i++) { require( _withinSupply(ids[i], amounts[i]), "AMOUNT_EXCEED_MAX_SUPPLY" ); } _mintBatch(account, ids, amounts, data); _burnBatch(account, burnIds, burnAmounts); emit ClaimBatch( signer, account, ids, amounts, burnIds, burnAmounts, nonce ); } function nonces( address signer, address account ) public view returns (uint256) { return _nonces[signer][account].current(); } function DOMAIN_SEPARATOR() external view returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. */ function _useNonce( address signer, address account ) internal returns (uint256 current) { Counters.Counter storage nonce = _nonces[signer][account]; current = nonce.current(); nonce.increment(); } // Royalty functions function setDefaultRoyalty( address receiver, uint96 feeNumerator ) public onlyOwner { _setDefaultRoyalty(receiver, feeNumerator); } function deleteDefaultRoyalty() public onlyOwner { _deleteDefaultRoyalty(); } function setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) public onlyOwner { _setTokenRoyalty(tokenId, receiver, feeNumerator); } function resetTokenRoyalty(uint256 tokenId) public onlyOwner { _resetTokenRoyalty(tokenId); } // The following functions are overrides required by Solidity. function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal override(ERC1155, ERC1155Supply) { super._beforeTokenTransfer(operator, from, to, ids, amounts, data); } function supportsInterface( bytes4 interfaceId ) public view override(ERC1155, AccessControl, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) pragma solidity ^0.8.0; import "../../interfaces/IERC2981.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol) pragma solidity ^0.8.0; import "./IERC1155.sol"; import "./IERC1155Receiver.sol"; import "./extensions/IERC1155MetadataURI.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of the basic standard multi-token. * See https://eips.ethereum.org/EIPS/eip-1155 * Originally based on code by Enjin: https://github.com/enjin/erc-1155 * * _Available since v3.1._ */ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { using Address for address; // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json string private _uri; /** * @dev See {_setURI}. */ constructor(string memory uri_) { _setURI(uri_); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155).interfaceId || interfaceId == type(IERC1155MetadataURI).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return _uri; } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { require(account != address(0), "ERC1155: address zero is not a valid owner"); return _balances[id][account]; } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual override returns (uint256[] memory) { require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); uint256[] memory batchBalances = new uint256[](accounts.length); for (uint256 i = 0; i < accounts.length; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } return batchBalances; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner or approved" ); _safeTransferFrom(from, to, id, amount, data); } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner or approved" ); _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, to, ids, amounts, data); uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); _beforeTokenTransfer(operator, from, to, ids, amounts, data); for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; } emit TransferBatch(operator, from, to, ids, amounts); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * By this mechanism, any occurrence of the `\{id\}` substring in either the * URI or any of the amounts in the JSON file at said URI will be replaced by * clients with the token type ID. * * For example, the `https://token-cdn-domain/\{id\}.json` URI would be * interpreted by clients as * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` * for token type ID 0x4cce0. * * See {uri}. * * Because these URIs cannot be meaningfully represented by the {URI} event, * this function emits no events. */ function _setURI(string memory newuri) internal virtual { _uri = newuri; } /** * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); _balances[id][to] += amount; emit TransferSingle(operator, address(0), to, id, amount); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _mintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); for (uint256 i = 0; i < ids.length; i++) { _balances[ids[i]][to] += amounts[i]; } emit TransferBatch(operator, address(0), to, ids, amounts); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); } /** * @dev Destroys `amount` tokens of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have at least `amount` tokens of token type `id`. */ function _burn( address from, uint256 id, uint256 amount ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); unchecked { _balances[id][from] = fromBalance - amount; } emit TransferSingle(operator, from, address(0), id, amount); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. */ function _burnBatch( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); address operator = _msgSender(); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); for (uint256 i = 0; i < ids.length; i++) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); unchecked { _balances[id][from] = fromBalance - amount; } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC1155: setting approval status for self"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `ids` and `amounts` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `id` and `amount` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { if (response != IERC1155Receiver.onERC1155Received.selector) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non-ERC1155Receiver implementer"); } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response ) { if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non-ERC1155Receiver implementer"); } } } function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { uint256[] memory array = new uint256[](1); array[0] = element; return array; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/extensions/ERC1155Burnable.sol) pragma solidity ^0.8.0; import "../ERC1155.sol"; /** * @dev Extension of {ERC1155} that allows token holders to destroy both their * own tokens and those that they have been approved to use. * * _Available since v3.1._ */ abstract contract ERC1155Burnable is ERC1155 { function burn( address account, uint256 id, uint256 value ) public virtual { require( account == _msgSender() || isApprovedForAll(account, _msgSender()), "ERC1155: caller is not token owner or approved" ); _burn(account, id, value); } function burnBatch( address account, uint256[] memory ids, uint256[] memory values ) public virtual { require( account == _msgSender() || isApprovedForAll(account, _msgSender()), "ERC1155: caller is not token owner or approved" ); _burnBatch(account, ids, values); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol) pragma solidity ^0.8.0; import "../ERC1155.sol"; /** * @dev Extension of ERC1155 that adds tracking of total supply per id. * * Useful for scenarios where Fungible and Non-fungible tokens have to be * clearly identified. Note: While a totalSupply of 1 might mean the * corresponding is an NFT, there is no guarantees that no other token with the * same id are not going to be minted. */ abstract contract ERC1155Supply is ERC1155 { mapping(uint256 => uint256) private _totalSupply; /** * @dev Total amount of tokens in with a given id. */ function totalSupply(uint256 id) public view virtual returns (uint256) { return _totalSupply[id]; } /** * @dev Indicates whether any token exist with a given id, or not. */ function exists(uint256 id) public view virtual returns (bool) { return ERC1155Supply.totalSupply(id) > 0; } /** * @dev See {ERC1155-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual override { super._beforeTokenTransfer(operator, from, to, ids, amounts, data); if (from == address(0)) { for (uint256 i = 0; i < ids.length; ++i) { _totalSupply[ids[i]] += amounts[i]; } } if (to == address(0)) { for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 supply = _totalSupply[id]; require(supply >= amount, "ERC1155: burn amount exceeds totalSupply"); unchecked { _totalSupply[id] = supply - amount; } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURI is IERC1155 { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.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 ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } 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"); } } /** * @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 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", Strings.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 (last updated v4.8.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.0; import "./ECDSA.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; address private immutable _CACHED_THIS; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_THIS = address(this); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _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) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _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); } }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"version_","type":"string"},{"internalType":"string","name":"uri_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"burnIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"burnAmounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"ClaimBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"burnIds","type":"uint256[]"},{"internalType":"uint256[]","name":"burnAmounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"claimBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deleteDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"nonces","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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"resetTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"internalType":"struct KultDolceResources.Token[]","name":"_tokens","type":"tuple[]"}],"name":"setTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenCount","outputs":[{"internalType":"uint256","name":"_tokenCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
610140604090808252346200064e5762005599803803809162000023828562000653565b83398101916060828403126200064e5781516001600160401b0392908381116200064e57846200005591830162000677565b92602091828101518281116200064e57866200007391830162000677565b95848201518381116200064e576200008c920162000677565b908151958187116200048957600254966001938489811c9916801562000643575b868a101462000468578190601f998a8111620005ec575b5086908a8311600114620005825760009262000576575b5050600019600383901b1c191690841b176002555b60038054336001600160a01b0319821681178355875199916001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a384600855875186890120978351878501208960e0526101009a818c524660a052888101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f9b8c84528b83015260608201524660808201523060a082015260a0815260c081018181108882111762000489578a525190206080523060c0526101209889528051908582116200048957600954908782811c921680156200056b575b898310146200046857818484931162000514575b508890848311600114620004ab576000926200049f575b505060001982851b1c191690861b176009555b82519384116200048957600a54928584811c941680156200047e575b87851014620004685783828695116200040d575b5086918411600114620003a05760009362000394575b505082841b92600019911b1c191617600a555b60008052600482528260002033600052825260ff8360002054161562000357575b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a69182600052600481528360002033600052815260ff8460002054161562000316575b5050505190614e8a9283620006ef843960805183614d00015260a05183614dcc015260c05183614cd1015260e05183614d4f01525182614d7501525181614d2c0152f35b826000526004815283600020903360005252826000209060ff198254161790553390339060008051602062005579833981519152600080a4388080620002d2565b600080526004825282600020336000528252826000208160ff1982541617905533336000600080516020620055798339815191528180a46200028f565b0151915038806200025b565b9190859450601f19841692600a600052876000209360005b89828210620003f65750508511620003db575b50505050811b01600a556200026e565b01519060f884600019921b161c1916905538808080620003cb565b8385015187558998909601959384019301620003b8565b9091929350600a600052866000208380870160051c8201928988106200045e575b9188918897969594930160051c01915b8281106200044e57505062000245565b600081558796508891016200043e565b925081926200042e565b634e487b7160e01b600052602260045260246000fd5b93607f169362000231565b634e487b7160e01b600052604160045260246000fd5b01519050388062000202565b90889350601f1983169160096000528a6000209260005b8c828210620004fd5750508411620004e4575b505050811b0160095562000215565b015160001983871b60f8161c19169055388080620004d5565b8385015186558c97909501949384019301620004c2565b9091506009600052886000208480850160051c8201928b861062000561575b918a91869594930160051c01915b82811062000551575050620001eb565b600081558594508a910162000541565b9250819262000533565b91607f1691620001d7565b015190503880620000db565b90869350601f198316916002600052886000209260005b8a828210620005d55750508411620005bb575b505050811b01600255620000f0565b015160001960f88460031b161c19169055388080620005ac565b8385015186558a9790950194938401930162000599565b9091506002600052866000208a80850160051c82019289861062000639575b918891869594930160051c01915b82811062000629575050620000c4565b6000815585945088910162000619565b925081926200060b565b98607f1698620000ad565b600080fd5b601f909101601f19168101906001600160401b038211908210176200048957604052565b919080601f840112156200064e578251906001600160401b038211620004895760405191602091620006b3601f8301601f191684018562000653565b8184528282870101116200064e5760005b818110620006da57508260009394955001015290565b8581018301518482018401528201620006c456fe6080604052600436101561001257600080fd5b60003560e01c8062fdd58e1461337b57806301ffc9a71461322557806302fe53051461303e57806304634d8d14612f2457806306fdde0314612e605780630e89341c14612d425780631f7fdffa14612c73578063248a9ca314612c265780632a55205a14612b1d5780632eb2c2d6146126255780632f2ff15d146125285780633644e515146124e757806336568abe146124035780634e1273f4146121e25780634f558e79146121965780634f64b2be1461207c57806354fd4d5014611f5a57806356240e2814611b135780635944c753146119d75780636b20c4541461190c578063715018a61461186e578063731133e9146115995780638a616bc01461154e5780638da5cb5b146114fc57806391d14854146114835780639333fbda146114065780639f181b5e146113ca578063a217fddf14611390578063a22cb46514611236578063aa1b103f146111f8578063afaba0a414610c1b578063bd85b03914610bd1578063d539139314610b78578063d547741f14610b1b578063e985e9c514610a99578063f242432a14610574578063f2fde38b1461043f5763f5298aca146101bd57600080fd5b3461043a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576101f46133c0565b6024908135604473ffffffffffffffffffffffffffffffffffffffff81359316913383148015610411575b61022890613d38565b82159261023584156140a1565b61023e8261407c565b916102488661407c565b94600060405161025781613422565b526103b7575b60005b835181101561033a576102738185613d24565b5161027e8288613d24565b51908060005260056020818152604060002054928484106102b757906102b295949392916000525203604060002055613cf7565b610260565b506084907f455243313135353a206275726e20616d6f756e74206578636565647320746f748a60288f604051947f08c379a000000000000000000000000000000000000000000000000000000000865260048601528401528201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b600083838981845283602052604084208385526020528060408520546103628282101561412c565b838652856020526040862085875260205203604085205560405191825260208201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a46103b5604051613422565b005b949195929060005b875181101561040657806103d66104019288613d24565b516103e1828b613d24565b5160005260056020526103fa6040600020918254613ed9565b9055613cf7565b6103bf565b50909295919461025d565b5082600052600160205260406000203360005260205261022860ff60406000205416905061021f565b600080fd5b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576104766133c0565b61047e613bba565b73ffffffffffffffffffffffffffffffffffffffff8091169081156104f057600354827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617600355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b3461043a5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576105ab6133c0565b6105b36133e3565b906084803567ffffffffffffffff811161043a576105d590369060040161349b565b9073ffffffffffffffffffffffffffffffffffffffff9133838516148015610a6e575b61060190613d38565b8285161561060f8115613dc3565b61061a60443561407c565b61062560643561407c565b9185871615610a2e575b610940575b50506044356000526020946000865260406000208486166000528652604060002054610664606435821015613e4e565b60443560005260008752604060002085871660005287526064359003604060002055604435600052600086526040600020848216600052865260406000206106af6064358254613ed9565b905560405160443581526064358782015284821690858716907fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a4803b6106f657005b60a0600061075995889560405197889687958693857ff23a6e61000000000000000000000000000000000000000000000000000000009d8e87523360048801521660248601526044356044860152606435606486015284015260a4830190613586565b0393165af160009181610911575b50610863575050600190610779613fd1565b6308c379a014610814575b5061078b57005b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608490fd5b0390fd5b61081c613fef565b90816108285750610784565b6108106040519283927f08c379a000000000000000000000000000000000000000000000000000000000845260048401526024830190613586565b7fffffffff00000000000000000000000000000000000000000000000000000000161490506103b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b610932919250843d8611610939575b61092a818361345a565b810190613f99565b9084610767565b503d610920565b92959194909360005b8451811015610a1f5761095c8186613d24565b51906109688188613d24565b5182600052600560205260406000205481811061099c5761099793600052600560205203604060002055613cf7565b610949565b8a6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b50935093909491508580610634565b959260009794919592975b8651811015610a605780610a50610a5b928b613d24565b516103e1828a613d24565b610a39565b50929596919490939661062f565b50828416600052600160205260406000203360005260205261060160ff6040600020541690506105f8565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57610ad06133c0565b610ad86133e3565b9073ffffffffffffffffffffffffffffffffffffffff809116600052600160205260406000209116600052602052602060ff604060002054166040519015158152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576103b5600435610b586133e3565b90806000526004602052610b736001604060002001546139da565b613b18565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760206040517f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a68152f35b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760043560005260056020526020604060002054604051908152f35b3461043a576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57610c536133c0565b610c5b6133e3565b60443567ffffffffffffffff811161043a57610c7b9036906004016135e1565b60643567ffffffffffffffff811161043a57610c9b9036906004016135e1565b9260843567ffffffffffffffff811161043a57610cbc9036906004016135e1565b9260a43567ffffffffffffffff811161043a57610cdd9036906004016135e1565b60c43567ffffffffffffffff811161043a57610cfd90369060040161349b565b9460ff60e4351660e4350361043a5760026008541461119a57600260085573ffffffffffffffffffffffffffffffffffffffff841660009081527fc8a67ff93cd072913f31c50776e9da9e00867535cbaa98368a69dafa551e5534602052604090205460ff161561113c5773ffffffffffffffffffffffffffffffffffffffff8416600052600c602052604060002073ffffffffffffffffffffffffffffffffffffffff84166000526020526040600020928354936001850190556040516020810181610dca828a614a58565b0391610dfc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09384810183528261345a565b5190209089604051610e2281610e16602082018095614a58565b0384810183528261345a565b519020906040516020810190610e3c81610e16848a614a58565b51902090604051610e62602082019282610e56858c614a58565b0390810183528261345a565b51902091604051937f825818f0cb53651b94bf6e91d43674b609b5aa3085b2472fde1638121c17fcf5602086015273ffffffffffffffffffffffffffffffffffffffff8a16604086015273ffffffffffffffffffffffffffffffffffffffff86166060860152608085015260a084015260c083015260e0820152610100858183015281528061012081011067ffffffffffffffff6101208301111761110d57610120810160405260208151910120610f18614cba565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152608081019080821067ffffffffffffffff83111761110d57610f9492610f8c926040526101243591610104359160e43591519020614c1e565b919091614a85565b73ffffffffffffffffffffffffffffffffffffffff8087169116036110af5760005b8651811015610ff55780610feb610fe68b610fdf84610fd8610ff0978e613d24565b5192613d24565b5190614670565b614580565b613cf7565b610fb6565b5061109f92916110838961107573ffffffffffffffffffffffffffffffffffffffff998a6110919661104a7f2e0da0fed1a851d56355916ee3ceac58913c9724a8a3ac621090d2c2df89dcce9e8685846146b9565b6110558988836141b6565b6040519c8d9c168c521660208b015260e060408b015260e08a019061363f565b9088820360608a015261363f565b90868203608088015261363f565b9084820360a086015261363f565b9060c08301520390a16001600855005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f5349474e41545552450000000000000000000000000000006044820152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4d494e5445525f4e4f545f414c4c4f57454400000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761122f613bba565b6000600655005b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761126d6133c0565b6024359081151580920361043a5773ffffffffffffffffffffffffffffffffffffffff169081331461130c5733600052600160205260406000208260005260205260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152fd5b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57602060405160008152f35b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576020600b54604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761143d6133c0565b6114456133e3565b9073ffffffffffffffffffffffffffffffffffffffff809116600052600c602052604060002091166000526020526020604060002054604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576114ba6133e3565b600435600052600460205273ffffffffffffffffffffffffffffffffffffffff60406000209116600052602052602060ff604060002054166040519015158152f35b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57611585613bba565b600435600090815260076020526040812055005b3461043a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576115d06133c0565b60643567ffffffffffffffff811161043a576115f090369060040161349b565b906115f96136dc565b61160a610fe6604435602435614670565b73ffffffffffffffffffffffffffffffffffffffff8116159161162d83156145e5565b61163860243561407c565b9161164460443561407c565b9160005b845181101561166f578061165f61166a9286613d24565b516103e18288613d24565b611648565b50929093611787575b505060243560005260209160008352604060002073ffffffffffffffffffffffffffffffffffffffff8216600052835260406000206116ba6044358254613ed9565b9055604051602435815260443584820152600073ffffffffffffffffffffffffffffffffffffffff8316917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a4803b61171357005b82604051809281600073ffffffffffffffffffffffffffffffffffffffff826107597ff23a6e6100000000000000000000000000000000000000000000000000000000998a83523360048401528460248401526024356044840152604435606484015260a0608484015260a4830190613586565b909260005b82518110156118635761179f8184613d24565b51906117ab8187613d24565b518260005260056020526040600020548181106117df576117da93600052600560205203604060002055613cf7565b61178c565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b509250508280611678565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576118a5613bba565b600073ffffffffffffffffffffffffffffffffffffffff6003547fffffffffffffffffffffffff00000000000000000000000000000000000000008116600355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461043a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576119436133c0565b67ffffffffffffffff9060243582811161043a576119659036906004016135e1565b60443592831161043a576119806103b59336906004016135e1565b9173ffffffffffffffffffffffffffffffffffffffff811633811480156119b1575b6119ac9150613d38565b6141b6565b5060005260016020526040600020336000526020526119ac60ff604060002054166119a2565b3461043a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57611a0e6133e3565b6044356bffffffffffffffffffffffff811680910361043a57611a2f613bba565b611a3d612710821115614df2565b73ffffffffffffffffffffffffffffffffffffffff809216918215611ab5577fffffffffffffffffffffffff00000000000000000000000000000000000000009060405193611a8b85613406565b84526020840192835260043560005260076020526040600020935116915160a01b16179055600080f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152fd5b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5767ffffffffffffffff9060043582811161043a573660238201121561043a578060040135611b70816135c9565b92611b7e604051948561345a565b8184528084019260249384600594851b8301019136831161043a57858101915b838310611ee25750505050611bb1613bba565b600b9182546000845580611df2575b5060005b85518110156103b557611bd78187613d24565b5190845468010000000000000000811015611dc457611bfc6001918281018855613673565b919091611d96578351938451948b8611611d6857908791611c1d8554613510565b90601f91828111611d32575b5083918811600114611c8e57611c7e979160009183611c83575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82861b9260031b1c19161784555b0151910155613cf7565b611bc4565b015190508e80611c43565b96907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082169786600052846000209860005b818110611d1c575091611c7e99918488959410611ce5575b505050811b018455611c74565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611cd8565b828401518b55998701998c969384019301611cc0565b611d5990876000528560002084808c018d1c820192888d10611d5f575b018c1c0190614569565b8e611c29565b92508192611d4f565b897f4e487b710000000000000000000000000000000000000000000000000000000060005260416004526000fd5b877f4e487b710000000000000000000000000000000000000000000000000000000060005260006004526000fd5b867f4e487b710000000000000000000000000000000000000000000000000000000060005260416004526000fd5b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168103611eb4578360005260017f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db991811b8201915b828110611e57575050611bc0565b80611e6460029254613510565b80611e77575b5060008382015501611e49565b601f90818111600114611e91575050600081555b8a611e6a565b611eab6000928484528984209201881c8201868301614569565b81835555611e8b565b847f4e487b710000000000000000000000000000000000000000000000000000000060005260116004526000fd5b823589811161043a57820160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc823603011261043a5760405191611f2683613406565b88820135928b841161043a576044889493611f4786958d369184010161349b565b8352013583820152815201920191611b9e565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576040516000600a54611f9a81613510565b808452906001908181169081156120375750600114611fdc575b611fd884611fc48186038261345a565b604051918291602083526020830190613586565b0390f35b600a600090815292507fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a85b82841061201f575050508101602001611fc482611fb4565b80546020858701810191909152909301928101612007565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660208087019190915292151560051b85019092019250611fc49150839050611fb4565b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57600435600b5481101561043a576120c290613673565b506040518154909160006120d583613510565b80855260019380851690811561215c575060011461211f575b509061210184612117969493038561345a565b0154604051938493604085526040850190613586565b918301520390f35b60008381528681209694939250905b80821061214757509294509091830184016121016120ee565b8654868301860152958301959084019061212e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168688015250151560051b8401850190506121016120ee565b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57600435600052600560205260206040600020541515604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760043567ffffffffffffffff80821161043a573660238301121561043a5781600401359061223e826135c9565b9261224c604051948561345a565b82845260209260248486019160051b8301019136831161043a57602401905b8282106123d75750505060243590811161043a5761228d9036906004016135e1565b8251815103612353578251927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06122dc6122c6866135c9565b956122d4604051978861345a565b8087526135c9565b01368486013760005b815181101561233c578061232773ffffffffffffffffffffffffffffffffffffffff6123146123379486613d24565b51166123208387613d24565b5190613c39565b6123318288613d24565b52613cf7565b6122e5565b505050611fd860405192828493845283019061363f565b608482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152fd5b813573ffffffffffffffffffffffffffffffffffffffff8116810361043a57815290840190840161226b565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761243a6133e3565b3373ffffffffffffffffffffffffffffffffffffffff821603612463576103b590600435613b18565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576020612520614cba565b604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576004356125626133e3565b81600052600460205261257c6001604060002001546139da565b81600052600460205273ffffffffffffffffffffffffffffffffffffffff60406000209116908160005260205260ff60406000205416156125b957005b816000526004602052604060002081600052602052604060002060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d600080a4005b3461043a577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60a08136011261043a5761265d6133c0565b906126666133e3565b60449081359267ffffffffffffffff9384811161043a5761268b9036906004016135e1565b6064803586811161043a576126a49036906004016135e1565b94608496873590811161043a576126bf90369060040161349b565b73ffffffffffffffffffffffffffffffffffffffff9433868b16148015612af2575b6126ea90613d38565b6126f78551895114613ee6565b858716156127058115613dc3565b868b1615612ab6575b6129c0575b60005b85518110156127ac578061272d6127a79288613d24565b518c612739838d613d24565b519180600052826020926000845260406000208d821660005284526040600020549061276783831015613e4e565b83600052600085528d60406000209116600052845203604060002055600052600081526040600020908a8c16600052526103fa6040600020918254613ed9565b612716565b50888a989796949789604051887f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89808d16941692806127ee87339583613f71565b0390a4873b6127f957005b6040519889978896887fbc197c81000000000000000000000000000000000000000000000000000000009d8e8a523360048b0152166024890152870160a0905260a487016128469161363f565b908487830301908701526128599161363f565b91848303019084015261286b91613586565b03921691815a602094600091f1600091816129a0575b506128f45750506001612892613fd1565b6308c379a0146128a3575b61078b57005b6128ab613fef565b806128b6575061289d565b610810906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352602060048401526024830190613586565b7fffffffff0000000000000000000000000000000000000000000000000000000016146103b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b6129b991925060203d81116109395761092a818361345a565b9083612881565b9796949060009993999692965b8551811015612aa6576129e08187613d24565b516129eb8289613d24565b51908060005260206005815260406000205491838310612a2457612a1f949392916005916000525203604060002055613cf7565b6129cd565b508b907f616c537570706c790000000000000000000000000000000000000000000000008f7f455243313135353a206275726e20616d6f756e74206578636565647320746f748e604051947f08c379a0000000000000000000000000000000000000000000000000000000008652600486015260286024860152840152820152fd5b5090949697989298959195612713565b99969498959392919060005b8a51811015612ae357808b6103e182610fd8612ade958f613d24565b612ac2565b5090919293959894969961270e565b50858a1660005260016020526040600020336000526020526126ea60ff6040600020541690506126e1565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57602435600435600052600760205260406000209060405191612b6d83613406565b5473ffffffffffffffffffffffffffffffffffffffff928382169182825260a01c60208201529015612c04575b6bffffffffffffffffffffffff60208201511691828102928184041490151715612bd557604092612710915116918351928352046020820152f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50604051612c1181613406565b600654838116825260a01c6020820152612b9a565b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760043560005260046020526020600160406000200154604051908152f35b3461043a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57612caa6133c0565b67ffffffffffffffff9060243582811161043a57612ccc9036906004016135e1565b9160443581811161043a57612ce59036906004016135e1565b9060643590811161043a57612cfe90369060040161349b565b612d066136dc565b60005b8451811015612d365780610feb610fe6612d26612d319489613d24565b51610fdf8488613d24565b612d09565b5091926103b5936146b9565b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576040519060008260025491612d8683613510565b92838352600190858282169182600014612e22575050600114612dc5575b50612db19250038361345a565b611fd8604051928284938452830190613586565b84915060026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace906000915b858310612e0a575050612db1935082010185612da4565b80548389018501528794508693909201918101612df3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685820152612db195151560051b8501019250879150612da49050565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576040516000600954612ea081613510565b808452906001908181169081156120375750600114612ec957611fd884611fc48186038261345a565b6009600090815292507f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af5b828410612f0c575050508101602001611fc482611fb4565b80546020858701810191909152909301928101612ef4565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57612f5b6133c0565b602435906bffffffffffffffffffffffff82169081830361043a57612fa161271073ffffffffffffffffffffffffffffffffffffffff93612f9a613bba565b1115614df2565b16908115612fe0577fffffffffffffffffffffffff000000000000000000000000000000000000000090612fd6604051613406565b60a01b1617600655005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152fd5b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5767ffffffffffffffff60043581811161043a5761308f90369060040161349b565b91613098613bba565b825191821161110d576130ac600254613510565b601f81116131cc575b5080601f831160011461310f57508192600092613104575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c191617600255600080f35b0151905082806130cd565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe083169360026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace926000905b8682106131b4575050836001951061317d575b505050811b01600255005b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19169055828080613172565b8060018596829496860151815501950193019061315f565b6132159060026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace601f850160051c81019184861061321b575b601f0160051c0190614569565b836130b5565b9091508190613208565b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361043a57807f2a55205a00000000000000000000000000000000000000000000000000000000602092149081156132ba575b506040519015158152f35b7f7965db0b000000000000000000000000000000000000000000000000000000008114915081156132ed575b50826132af565b7fd9b67a2600000000000000000000000000000000000000000000000000000000811491508115613351575b8115613327575b50826132e6565b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482613320565b7f0e89341c0000000000000000000000000000000000000000000000000000000081149150613319565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760206125206133b76133c0565b60243590613c39565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361043a57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361043a57565b6040810190811067ffffffffffffffff82111761110d57604052565b6020810190811067ffffffffffffffff82111761110d57604052565b6080810190811067ffffffffffffffff82111761110d57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761110d57604052565b81601f8201121561043a5780359067ffffffffffffffff821161110d57604051926134ee60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116018561345a565b8284526020838301011161043a57816000926020809301838601378301015290565b90600182811c92168015613559575b602083101461352a57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f169161351f565b60005b8381106135765750506000910152565b8181015183820152602001613566565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936135c281518092818752878088019101613563565b0116010190565b67ffffffffffffffff811161110d5760051b60200190565b81601f8201121561043a578035916135f8836135c9565b92613606604051948561345a565b808452602092838086019260051b82010192831161043a578301905b828210613630575050505090565b81358152908301908301613622565b90815180825260208080930193019160005b82811061365f575050505090565b835185529381019392810192600101613651565b600b548110156136ad57600b60005260011b7f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b3360009081527fc8a67ff93cd072913f31c50776e9da9e00867535cbaa98368a69dafa551e5534602090815260408083205491926004927f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6919060ff1615613745575050505050565b61374e336143e3565b9183519061375b8261343e565b604282528682019260603685378251156139ae57603084538251906001918210156139825790607860218501536041915b8183116138ba5750505061385f57604861381c93859361382b9361081097519687937f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008c8601526137e78c8251928391603789019101613563565b8401917f206973206d697373696e6720726f6c6520000000000000000000000000000000603784015251809386840190613563565b0103602881018552018361345a565b519384937f08c379a00000000000000000000000000000000000000000000000000000000085528401526024830190613586565b60648587808751927f08c379a000000000000000000000000000000000000000000000000000000000845283015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f81166010811015613956577f3031323334353637383961626364656600000000000000000000000000000000901a6138f785876143d2565b53881c92801561392a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01919061378c565b60248260118b7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b60248360328c7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b806032897f4e487b71000000000000000000000000000000000000000000000000000000006024945252fd5b806032887f4e487b71000000000000000000000000000000000000000000000000000000006024945252fd5b6000818152600490602092828452604091828120338252855260ff838220541615613a06575050505050565b613a0f336143e3565b91835190613a1c8261343e565b604282528682019260603685378251156139ae57603084538251906001918210156139825790607860218501536041915b818311613aa85750505061385f57604861381c93859361382b9361081097519687937f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008c8601526137e78c8251928391603789019101613563565b909192600f81166010811015613956577f3031323334353637383961626364656600000000000000000000000000000000901a613ae585876143d2565b53881c92801561392a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019190613a4d565b90600091808352600460205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416613b5757505050565b808352600460205260408320828452602052604083207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b73ffffffffffffffffffffffffffffffffffffffff600354163303613bdb57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b73ffffffffffffffffffffffffffffffffffffffff16908115613c7357600052600060205260406000209060005260205260406000205490565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e6572000000000000000000000000000000000000000000006064820152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612bd55760010190565b80518210156136ad5760209160051b010190565b15613d3f57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152fd5b15613dca57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152fd5b15613e5557565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152fd5b91908201809211612bd557565b15613eed57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152fd5b9091613f88613f969360408452604084019061363f565b91602081840391015261363f565b90565b9081602091031261043a57517fffffffff000000000000000000000000000000000000000000000000000000008116810361043a5790565b60009060033d11613fde57565b905060046000803e60005160e01c90565b600060443d10613f96576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d60248401111761406b57818401948551938411614073573d8501016020848701011161406b5750613f969291016020019061345a565b949350505050565b50949350505050565b6040519061408982613406565b600182526020820160203682378251156136ad575290565b156140a857565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152fd5b1561413357565b60846040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e6365000000000000000000000000000000000000000000000000000000006064820152fd5b73ffffffffffffffffffffffffffffffffffffffff9093929316918215916141de83156140a1565b6141eb8151865114613ee6565b6040918251936141fa85613422565b6000809552614386575b835b82518110156142d8576142198184613d24565b516142248289613d24565b519080875260056020818152878920549284841061425557895252858720919003905561425090613cf7565b614206565b6084828a51907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b509390835b815181101561433e57806142f46143399284613d24565b516142ff828a613d24565b51908088526020888152878920878a52815287892054916143228484101561412c565b895288815287892090878a52520385872055613cf7565b6142dd565b507f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb6143768596979594958651918291339583613f71565b0390a45161438381613422565b52565b938391935b84518110156143c857806143a26143c39289613d24565b516143ad8288613d24565b51855260056020526103fa868620918254613ed9565b61438b565b5093929092614204565b9081518110156136ad570160200190565b604051906060820182811067ffffffffffffffff82111761110d57604052602a82526020820160403682378251156136ad576030905381516001908110156136ad57607860218401536029905b80821161449e5750506144405790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f8116601081101561453b577f3031323334353637383961626364656600000000000000000000000000000000901a6144da84866143d2565b5360041c91801561450d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190614430565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b818110614574575050565b60008155600101614569565b1561458757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f414d4f554e545f4558434545445f4d41585f535550504c5900000000000000006044820152fd5b156145ec57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b600161467b82613673565b5001541591821561468b57505090565b8192506146ab6146b1916001936000526005602052604060002054613ed9565b92613673565b500154101590565b9390919373ffffffffffffffffffffffffffffffffffffffff81168015946146e186156145e5565b6146ee8551885114613ee6565b60005b85518110156147185780614708614713928a613d24565b516103e18289613d24565b6146f1565b50909295919461496a575b60005b8451811015614772578061473d61476d9285613d24565b516147488288613d24565b516000526103fa60206000815260409081600020908960005252600020918254613ed9565b614726565b509192938360006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb3391806147ab888c83613f71565b0390a43b6147ba575b50505050565b6148549260209260006040518096819582946148456148147fbc197c81000000000000000000000000000000000000000000000000000000009c8d875233600488015287602488015260a0604488015260a487019061363f565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc938487830301606488015261363f565b91848303016084850152613586565b03925af16000918161494a575b5061489e5750506001614872613fd1565b6308c379a01461488b575b61078b575b388080806147b4565b614893613fef565b806128b6575061487d565b7fffffffff000000000000000000000000000000000000000000000000000000001614614882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b61496391925060203d81116109395761092a818361345a565b9038614861565b9390949160005b8451811015614a4e576149848186613d24565b5161498f8289613d24565b51816000526005916020928084526040938460002054928484106149cb57906149c696959493929160005252039060002055613cf7565b614971565b6084828751907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b5091949093614723565b805160208092019160005b828110614a71575050505090565b835185529381019392810192600101614a63565b6005811015614bef5780614a965750565b60018103614afc5760646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152fd5b60028103614b625760646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152fd5b600314614b6b57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9291907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311614cae5791608094939160ff602094604051948552168484015260408301526060820152600093849182805260015afa15614ca157815173ffffffffffffffffffffffffffffffffffffffff811615614c9b579190565b50600190565b50604051903d90823e3d90fd5b50505050600090600390565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016301480614dc9575b15614d22577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f000000000000000000000000000000000000000000000000000000000000000082527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a0815260c0810181811067ffffffffffffffff82111761110d5760405251902090565b507f00000000000000000000000000000000000000000000000000000000000000004614614cf9565b15614df957565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152fdfea164736f6c6343000812000a2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000144b756c7420446f6c6365205265736f757263657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000013100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b68747470733a2f2f6b756c74646f6c63652e696f2f6170692f6b756c74446f6c63655265736f757263652f000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436101561001257600080fd5b60003560e01c8062fdd58e1461337b57806301ffc9a71461322557806302fe53051461303e57806304634d8d14612f2457806306fdde0314612e605780630e89341c14612d425780631f7fdffa14612c73578063248a9ca314612c265780632a55205a14612b1d5780632eb2c2d6146126255780632f2ff15d146125285780633644e515146124e757806336568abe146124035780634e1273f4146121e25780634f558e79146121965780634f64b2be1461207c57806354fd4d5014611f5a57806356240e2814611b135780635944c753146119d75780636b20c4541461190c578063715018a61461186e578063731133e9146115995780638a616bc01461154e5780638da5cb5b146114fc57806391d14854146114835780639333fbda146114065780639f181b5e146113ca578063a217fddf14611390578063a22cb46514611236578063aa1b103f146111f8578063afaba0a414610c1b578063bd85b03914610bd1578063d539139314610b78578063d547741f14610b1b578063e985e9c514610a99578063f242432a14610574578063f2fde38b1461043f5763f5298aca146101bd57600080fd5b3461043a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576101f46133c0565b6024908135604473ffffffffffffffffffffffffffffffffffffffff81359316913383148015610411575b61022890613d38565b82159261023584156140a1565b61023e8261407c565b916102488661407c565b94600060405161025781613422565b526103b7575b60005b835181101561033a576102738185613d24565b5161027e8288613d24565b51908060005260056020818152604060002054928484106102b757906102b295949392916000525203604060002055613cf7565b610260565b506084907f455243313135353a206275726e20616d6f756e74206578636565647320746f748a60288f604051947f08c379a000000000000000000000000000000000000000000000000000000000865260048601528401528201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b600083838981845283602052604084208385526020528060408520546103628282101561412c565b838652856020526040862085875260205203604085205560405191825260208201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a46103b5604051613422565b005b949195929060005b875181101561040657806103d66104019288613d24565b516103e1828b613d24565b5160005260056020526103fa6040600020918254613ed9565b9055613cf7565b6103bf565b50909295919461025d565b5082600052600160205260406000203360005260205261022860ff60406000205416905061021f565b600080fd5b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576104766133c0565b61047e613bba565b73ffffffffffffffffffffffffffffffffffffffff8091169081156104f057600354827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617600355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b3461043a5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576105ab6133c0565b6105b36133e3565b906084803567ffffffffffffffff811161043a576105d590369060040161349b565b9073ffffffffffffffffffffffffffffffffffffffff9133838516148015610a6e575b61060190613d38565b8285161561060f8115613dc3565b61061a60443561407c565b61062560643561407c565b9185871615610a2e575b610940575b50506044356000526020946000865260406000208486166000528652604060002054610664606435821015613e4e565b60443560005260008752604060002085871660005287526064359003604060002055604435600052600086526040600020848216600052865260406000206106af6064358254613ed9565b905560405160443581526064358782015284821690858716907fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a4803b6106f657005b60a0600061075995889560405197889687958693857ff23a6e61000000000000000000000000000000000000000000000000000000009d8e87523360048801521660248601526044356044860152606435606486015284015260a4830190613586565b0393165af160009181610911575b50610863575050600190610779613fd1565b6308c379a014610814575b5061078b57005b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608490fd5b0390fd5b61081c613fef565b90816108285750610784565b6108106040519283927f08c379a000000000000000000000000000000000000000000000000000000000845260048401526024830190613586565b7fffffffff00000000000000000000000000000000000000000000000000000000161490506103b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b610932919250843d8611610939575b61092a818361345a565b810190613f99565b9084610767565b503d610920565b92959194909360005b8451811015610a1f5761095c8186613d24565b51906109688188613d24565b5182600052600560205260406000205481811061099c5761099793600052600560205203604060002055613cf7565b610949565b8a6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b50935093909491508580610634565b959260009794919592975b8651811015610a605780610a50610a5b928b613d24565b516103e1828a613d24565b610a39565b50929596919490939661062f565b50828416600052600160205260406000203360005260205261060160ff6040600020541690506105f8565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57610ad06133c0565b610ad86133e3565b9073ffffffffffffffffffffffffffffffffffffffff809116600052600160205260406000209116600052602052602060ff604060002054166040519015158152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576103b5600435610b586133e3565b90806000526004602052610b736001604060002001546139da565b613b18565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760206040517f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a68152f35b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760043560005260056020526020604060002054604051908152f35b3461043a576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57610c536133c0565b610c5b6133e3565b60443567ffffffffffffffff811161043a57610c7b9036906004016135e1565b60643567ffffffffffffffff811161043a57610c9b9036906004016135e1565b9260843567ffffffffffffffff811161043a57610cbc9036906004016135e1565b9260a43567ffffffffffffffff811161043a57610cdd9036906004016135e1565b60c43567ffffffffffffffff811161043a57610cfd90369060040161349b565b9460ff60e4351660e4350361043a5760026008541461119a57600260085573ffffffffffffffffffffffffffffffffffffffff841660009081527fc8a67ff93cd072913f31c50776e9da9e00867535cbaa98368a69dafa551e5534602052604090205460ff161561113c5773ffffffffffffffffffffffffffffffffffffffff8416600052600c602052604060002073ffffffffffffffffffffffffffffffffffffffff84166000526020526040600020928354936001850190556040516020810181610dca828a614a58565b0391610dfc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09384810183528261345a565b5190209089604051610e2281610e16602082018095614a58565b0384810183528261345a565b519020906040516020810190610e3c81610e16848a614a58565b51902090604051610e62602082019282610e56858c614a58565b0390810183528261345a565b51902091604051937f825818f0cb53651b94bf6e91d43674b609b5aa3085b2472fde1638121c17fcf5602086015273ffffffffffffffffffffffffffffffffffffffff8a16604086015273ffffffffffffffffffffffffffffffffffffffff86166060860152608085015260a084015260c083015260e0820152610100858183015281528061012081011067ffffffffffffffff6101208301111761110d57610120810160405260208151910120610f18614cba565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152608081019080821067ffffffffffffffff83111761110d57610f9492610f8c926040526101243591610104359160e43591519020614c1e565b919091614a85565b73ffffffffffffffffffffffffffffffffffffffff8087169116036110af5760005b8651811015610ff55780610feb610fe68b610fdf84610fd8610ff0978e613d24565b5192613d24565b5190614670565b614580565b613cf7565b610fb6565b5061109f92916110838961107573ffffffffffffffffffffffffffffffffffffffff998a6110919661104a7f2e0da0fed1a851d56355916ee3ceac58913c9724a8a3ac621090d2c2df89dcce9e8685846146b9565b6110558988836141b6565b6040519c8d9c168c521660208b015260e060408b015260e08a019061363f565b9088820360608a015261363f565b90868203608088015261363f565b9084820360a086015261363f565b9060c08301520390a16001600855005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f5349474e41545552450000000000000000000000000000006044820152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4d494e5445525f4e4f545f414c4c4f57454400000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761122f613bba565b6000600655005b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761126d6133c0565b6024359081151580920361043a5773ffffffffffffffffffffffffffffffffffffffff169081331461130c5733600052600160205260406000208260005260205260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152fd5b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57602060405160008152f35b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576020600b54604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761143d6133c0565b6114456133e3565b9073ffffffffffffffffffffffffffffffffffffffff809116600052600c602052604060002091166000526020526020604060002054604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576114ba6133e3565b600435600052600460205273ffffffffffffffffffffffffffffffffffffffff60406000209116600052602052602060ff604060002054166040519015158152f35b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57611585613bba565b600435600090815260076020526040812055005b3461043a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576115d06133c0565b60643567ffffffffffffffff811161043a576115f090369060040161349b565b906115f96136dc565b61160a610fe6604435602435614670565b73ffffffffffffffffffffffffffffffffffffffff8116159161162d83156145e5565b61163860243561407c565b9161164460443561407c565b9160005b845181101561166f578061165f61166a9286613d24565b516103e18288613d24565b611648565b50929093611787575b505060243560005260209160008352604060002073ffffffffffffffffffffffffffffffffffffffff8216600052835260406000206116ba6044358254613ed9565b9055604051602435815260443584820152600073ffffffffffffffffffffffffffffffffffffffff8316917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a4803b61171357005b82604051809281600073ffffffffffffffffffffffffffffffffffffffff826107597ff23a6e6100000000000000000000000000000000000000000000000000000000998a83523360048401528460248401526024356044840152604435606484015260a0608484015260a4830190613586565b909260005b82518110156118635761179f8184613d24565b51906117ab8187613d24565b518260005260056020526040600020548181106117df576117da93600052600560205203604060002055613cf7565b61178c565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b509250508280611678565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576118a5613bba565b600073ffffffffffffffffffffffffffffffffffffffff6003547fffffffffffffffffffffffff00000000000000000000000000000000000000008116600355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461043a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576119436133c0565b67ffffffffffffffff9060243582811161043a576119659036906004016135e1565b60443592831161043a576119806103b59336906004016135e1565b9173ffffffffffffffffffffffffffffffffffffffff811633811480156119b1575b6119ac9150613d38565b6141b6565b5060005260016020526040600020336000526020526119ac60ff604060002054166119a2565b3461043a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57611a0e6133e3565b6044356bffffffffffffffffffffffff811680910361043a57611a2f613bba565b611a3d612710821115614df2565b73ffffffffffffffffffffffffffffffffffffffff809216918215611ab5577fffffffffffffffffffffffff00000000000000000000000000000000000000009060405193611a8b85613406565b84526020840192835260043560005260076020526040600020935116915160a01b16179055600080f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152fd5b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5767ffffffffffffffff9060043582811161043a573660238201121561043a578060040135611b70816135c9565b92611b7e604051948561345a565b8184528084019260249384600594851b8301019136831161043a57858101915b838310611ee25750505050611bb1613bba565b600b9182546000845580611df2575b5060005b85518110156103b557611bd78187613d24565b5190845468010000000000000000811015611dc457611bfc6001918281018855613673565b919091611d96578351938451948b8611611d6857908791611c1d8554613510565b90601f91828111611d32575b5083918811600114611c8e57611c7e979160009183611c83575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82861b9260031b1c19161784555b0151910155613cf7565b611bc4565b015190508e80611c43565b96907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082169786600052846000209860005b818110611d1c575091611c7e99918488959410611ce5575b505050811b018455611c74565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611cd8565b828401518b55998701998c969384019301611cc0565b611d5990876000528560002084808c018d1c820192888d10611d5f575b018c1c0190614569565b8e611c29565b92508192611d4f565b897f4e487b710000000000000000000000000000000000000000000000000000000060005260416004526000fd5b877f4e487b710000000000000000000000000000000000000000000000000000000060005260006004526000fd5b867f4e487b710000000000000000000000000000000000000000000000000000000060005260416004526000fd5b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168103611eb4578360005260017f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db991811b8201915b828110611e57575050611bc0565b80611e6460029254613510565b80611e77575b5060008382015501611e49565b601f90818111600114611e91575050600081555b8a611e6a565b611eab6000928484528984209201881c8201868301614569565b81835555611e8b565b847f4e487b710000000000000000000000000000000000000000000000000000000060005260116004526000fd5b823589811161043a57820160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc823603011261043a5760405191611f2683613406565b88820135928b841161043a576044889493611f4786958d369184010161349b565b8352013583820152815201920191611b9e565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576040516000600a54611f9a81613510565b808452906001908181169081156120375750600114611fdc575b611fd884611fc48186038261345a565b604051918291602083526020830190613586565b0390f35b600a600090815292507fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a85b82841061201f575050508101602001611fc482611fb4565b80546020858701810191909152909301928101612007565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660208087019190915292151560051b85019092019250611fc49150839050611fb4565b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57600435600b5481101561043a576120c290613673565b506040518154909160006120d583613510565b80855260019380851690811561215c575060011461211f575b509061210184612117969493038561345a565b0154604051938493604085526040850190613586565b918301520390f35b60008381528681209694939250905b80821061214757509294509091830184016121016120ee565b8654868301860152958301959084019061212e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168688015250151560051b8401850190506121016120ee565b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57600435600052600560205260206040600020541515604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760043567ffffffffffffffff80821161043a573660238301121561043a5781600401359061223e826135c9565b9261224c604051948561345a565b82845260209260248486019160051b8301019136831161043a57602401905b8282106123d75750505060243590811161043a5761228d9036906004016135e1565b8251815103612353578251927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06122dc6122c6866135c9565b956122d4604051978861345a565b8087526135c9565b01368486013760005b815181101561233c578061232773ffffffffffffffffffffffffffffffffffffffff6123146123379486613d24565b51166123208387613d24565b5190613c39565b6123318288613d24565b52613cf7565b6122e5565b505050611fd860405192828493845283019061363f565b608482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152fd5b813573ffffffffffffffffffffffffffffffffffffffff8116810361043a57815290840190840161226b565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5761243a6133e3565b3373ffffffffffffffffffffffffffffffffffffffff821603612463576103b590600435613b18565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576020612520614cba565b604051908152f35b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576004356125626133e3565b81600052600460205261257c6001604060002001546139da565b81600052600460205273ffffffffffffffffffffffffffffffffffffffff60406000209116908160005260205260ff60406000205416156125b957005b816000526004602052604060002081600052602052604060002060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d600080a4005b3461043a577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60a08136011261043a5761265d6133c0565b906126666133e3565b60449081359267ffffffffffffffff9384811161043a5761268b9036906004016135e1565b6064803586811161043a576126a49036906004016135e1565b94608496873590811161043a576126bf90369060040161349b565b73ffffffffffffffffffffffffffffffffffffffff9433868b16148015612af2575b6126ea90613d38565b6126f78551895114613ee6565b858716156127058115613dc3565b868b1615612ab6575b6129c0575b60005b85518110156127ac578061272d6127a79288613d24565b518c612739838d613d24565b519180600052826020926000845260406000208d821660005284526040600020549061276783831015613e4e565b83600052600085528d60406000209116600052845203604060002055600052600081526040600020908a8c16600052526103fa6040600020918254613ed9565b612716565b50888a989796949789604051887f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89808d16941692806127ee87339583613f71565b0390a4873b6127f957005b6040519889978896887fbc197c81000000000000000000000000000000000000000000000000000000009d8e8a523360048b0152166024890152870160a0905260a487016128469161363f565b908487830301908701526128599161363f565b91848303019084015261286b91613586565b03921691815a602094600091f1600091816129a0575b506128f45750506001612892613fd1565b6308c379a0146128a3575b61078b57005b6128ab613fef565b806128b6575061289d565b610810906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352602060048401526024830190613586565b7fffffffff0000000000000000000000000000000000000000000000000000000016146103b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b6129b991925060203d81116109395761092a818361345a565b9083612881565b9796949060009993999692965b8551811015612aa6576129e08187613d24565b516129eb8289613d24565b51908060005260206005815260406000205491838310612a2457612a1f949392916005916000525203604060002055613cf7565b6129cd565b508b907f616c537570706c790000000000000000000000000000000000000000000000008f7f455243313135353a206275726e20616d6f756e74206578636565647320746f748e604051947f08c379a0000000000000000000000000000000000000000000000000000000008652600486015260286024860152840152820152fd5b5090949697989298959195612713565b99969498959392919060005b8a51811015612ae357808b6103e182610fd8612ade958f613d24565b612ac2565b5090919293959894969961270e565b50858a1660005260016020526040600020336000526020526126ea60ff6040600020541690506126e1565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57602435600435600052600760205260406000209060405191612b6d83613406565b5473ffffffffffffffffffffffffffffffffffffffff928382169182825260a01c60208201529015612c04575b6bffffffffffffffffffffffff60208201511691828102928184041490151715612bd557604092612710915116918351928352046020820152f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50604051612c1181613406565b600654838116825260a01c6020820152612b9a565b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760043560005260046020526020600160406000200154604051908152f35b3461043a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57612caa6133c0565b67ffffffffffffffff9060243582811161043a57612ccc9036906004016135e1565b9160443581811161043a57612ce59036906004016135e1565b9060643590811161043a57612cfe90369060040161349b565b612d066136dc565b60005b8451811015612d365780610feb610fe6612d26612d319489613d24565b51610fdf8488613d24565b612d09565b5091926103b5936146b9565b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576040519060008260025491612d8683613510565b92838352600190858282169182600014612e22575050600114612dc5575b50612db19250038361345a565b611fd8604051928284938452830190613586565b84915060026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace906000915b858310612e0a575050612db1935082010185612da4565b80548389018501528794508693909201918101612df3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685820152612db195151560051b8501019250879150612da49050565b3461043a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576040516000600954612ea081613510565b808452906001908181169081156120375750600114612ec957611fd884611fc48186038261345a565b6009600090815292507f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af5b828410612f0c575050508101602001611fc482611fb4565b80546020858701810191909152909301928101612ef4565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a57612f5b6133c0565b602435906bffffffffffffffffffffffff82169081830361043a57612fa161271073ffffffffffffffffffffffffffffffffffffffff93612f9a613bba565b1115614df2565b16908115612fe0577fffffffffffffffffffffffff000000000000000000000000000000000000000090612fd6604051613406565b60a01b1617600655005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152fd5b3461043a576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5767ffffffffffffffff60043581811161043a5761308f90369060040161349b565b91613098613bba565b825191821161110d576130ac600254613510565b601f81116131cc575b5080601f831160011461310f57508192600092613104575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c191617600255600080f35b0151905082806130cd565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe083169360026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace926000905b8682106131b4575050836001951061317d575b505050811b01600255005b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19169055828080613172565b8060018596829496860151815501950193019061315f565b6132159060026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace601f850160051c81019184861061321b575b601f0160051c0190614569565b836130b5565b9091508190613208565b3461043a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361043a57807f2a55205a00000000000000000000000000000000000000000000000000000000602092149081156132ba575b506040519015158152f35b7f7965db0b000000000000000000000000000000000000000000000000000000008114915081156132ed575b50826132af565b7fd9b67a2600000000000000000000000000000000000000000000000000000000811491508115613351575b8115613327575b50826132e6565b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482613320565b7f0e89341c0000000000000000000000000000000000000000000000000000000081149150613319565b3461043a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261043a5760206125206133b76133c0565b60243590613c39565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361043a57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361043a57565b6040810190811067ffffffffffffffff82111761110d57604052565b6020810190811067ffffffffffffffff82111761110d57604052565b6080810190811067ffffffffffffffff82111761110d57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761110d57604052565b81601f8201121561043a5780359067ffffffffffffffff821161110d57604051926134ee60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116018561345a565b8284526020838301011161043a57816000926020809301838601378301015290565b90600182811c92168015613559575b602083101461352a57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f169161351f565b60005b8381106135765750506000910152565b8181015183820152602001613566565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936135c281518092818752878088019101613563565b0116010190565b67ffffffffffffffff811161110d5760051b60200190565b81601f8201121561043a578035916135f8836135c9565b92613606604051948561345a565b808452602092838086019260051b82010192831161043a578301905b828210613630575050505090565b81358152908301908301613622565b90815180825260208080930193019160005b82811061365f575050505090565b835185529381019392810192600101613651565b600b548110156136ad57600b60005260011b7f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b3360009081527fc8a67ff93cd072913f31c50776e9da9e00867535cbaa98368a69dafa551e5534602090815260408083205491926004927f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6919060ff1615613745575050505050565b61374e336143e3565b9183519061375b8261343e565b604282528682019260603685378251156139ae57603084538251906001918210156139825790607860218501536041915b8183116138ba5750505061385f57604861381c93859361382b9361081097519687937f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008c8601526137e78c8251928391603789019101613563565b8401917f206973206d697373696e6720726f6c6520000000000000000000000000000000603784015251809386840190613563565b0103602881018552018361345a565b519384937f08c379a00000000000000000000000000000000000000000000000000000000085528401526024830190613586565b60648587808751927f08c379a000000000000000000000000000000000000000000000000000000000845283015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f81166010811015613956577f3031323334353637383961626364656600000000000000000000000000000000901a6138f785876143d2565b53881c92801561392a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01919061378c565b60248260118b7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b60248360328c7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b806032897f4e487b71000000000000000000000000000000000000000000000000000000006024945252fd5b806032887f4e487b71000000000000000000000000000000000000000000000000000000006024945252fd5b6000818152600490602092828452604091828120338252855260ff838220541615613a06575050505050565b613a0f336143e3565b91835190613a1c8261343e565b604282528682019260603685378251156139ae57603084538251906001918210156139825790607860218501536041915b818311613aa85750505061385f57604861381c93859361382b9361081097519687937f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008c8601526137e78c8251928391603789019101613563565b909192600f81166010811015613956577f3031323334353637383961626364656600000000000000000000000000000000901a613ae585876143d2565b53881c92801561392a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019190613a4d565b90600091808352600460205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416613b5757505050565b808352600460205260408320828452602052604083207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b73ffffffffffffffffffffffffffffffffffffffff600354163303613bdb57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b73ffffffffffffffffffffffffffffffffffffffff16908115613c7357600052600060205260406000209060005260205260406000205490565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e6572000000000000000000000000000000000000000000006064820152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612bd55760010190565b80518210156136ad5760209160051b010190565b15613d3f57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152fd5b15613dca57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152fd5b15613e5557565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152fd5b91908201809211612bd557565b15613eed57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152fd5b9091613f88613f969360408452604084019061363f565b91602081840391015261363f565b90565b9081602091031261043a57517fffffffff000000000000000000000000000000000000000000000000000000008116810361043a5790565b60009060033d11613fde57565b905060046000803e60005160e01c90565b600060443d10613f96576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d60248401111761406b57818401948551938411614073573d8501016020848701011161406b5750613f969291016020019061345a565b949350505050565b50949350505050565b6040519061408982613406565b600182526020820160203682378251156136ad575290565b156140a857565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152fd5b1561413357565b60846040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e6365000000000000000000000000000000000000000000000000000000006064820152fd5b73ffffffffffffffffffffffffffffffffffffffff9093929316918215916141de83156140a1565b6141eb8151865114613ee6565b6040918251936141fa85613422565b6000809552614386575b835b82518110156142d8576142198184613d24565b516142248289613d24565b519080875260056020818152878920549284841061425557895252858720919003905561425090613cf7565b614206565b6084828a51907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b509390835b815181101561433e57806142f46143399284613d24565b516142ff828a613d24565b51908088526020888152878920878a52815287892054916143228484101561412c565b895288815287892090878a52520385872055613cf7565b6142dd565b507f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb6143768596979594958651918291339583613f71565b0390a45161438381613422565b52565b938391935b84518110156143c857806143a26143c39289613d24565b516143ad8288613d24565b51855260056020526103fa868620918254613ed9565b61438b565b5093929092614204565b9081518110156136ad570160200190565b604051906060820182811067ffffffffffffffff82111761110d57604052602a82526020820160403682378251156136ad576030905381516001908110156136ad57607860218401536029905b80821161449e5750506144405790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f8116601081101561453b577f3031323334353637383961626364656600000000000000000000000000000000901a6144da84866143d2565b5360041c91801561450d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190614430565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b818110614574575050565b60008155600101614569565b1561458757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f414d4f554e545f4558434545445f4d41585f535550504c5900000000000000006044820152fd5b156145ec57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b600161467b82613673565b5001541591821561468b57505090565b8192506146ab6146b1916001936000526005602052604060002054613ed9565b92613673565b500154101590565b9390919373ffffffffffffffffffffffffffffffffffffffff81168015946146e186156145e5565b6146ee8551885114613ee6565b60005b85518110156147185780614708614713928a613d24565b516103e18289613d24565b6146f1565b50909295919461496a575b60005b8451811015614772578061473d61476d9285613d24565b516147488288613d24565b516000526103fa60206000815260409081600020908960005252600020918254613ed9565b614726565b509192938360006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb3391806147ab888c83613f71565b0390a43b6147ba575b50505050565b6148549260209260006040518096819582946148456148147fbc197c81000000000000000000000000000000000000000000000000000000009c8d875233600488015287602488015260a0604488015260a487019061363f565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc938487830301606488015261363f565b91848303016084850152613586565b03925af16000918161494a575b5061489e5750506001614872613fd1565b6308c379a01461488b575b61078b575b388080806147b4565b614893613fef565b806128b6575061487d565b7fffffffff000000000000000000000000000000000000000000000000000000001614614882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b61496391925060203d81116109395761092a818361345a565b9038614861565b9390949160005b8451811015614a4e576149848186613d24565b5161498f8289613d24565b51816000526005916020928084526040938460002054928484106149cb57906149c696959493929160005252039060002055613cf7565b614971565b6084828751907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c790000000000000000000000000000000000000000000000006064820152fd5b5091949093614723565b805160208092019160005b828110614a71575050505090565b835185529381019392810192600101614a63565b6005811015614bef5780614a965750565b60018103614afc5760646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152fd5b60028103614b625760646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152fd5b600314614b6b57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9291907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311614cae5791608094939160ff602094604051948552168484015260408301526060820152600093849182805260015afa15614ca157815173ffffffffffffffffffffffffffffffffffffffff811615614c9b579190565b50600190565b50604051903d90823e3d90fd5b50505050600090600390565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000007437da8bb2144aa4d1060b7669ea155e427990b16301480614dc9575b15614d22577f6bc00f20f843b21e5ea44cb367178d572d0f00651397486b9f93c9d66383238f90565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527fa42e16115f29aca4425eb2dd4fbbbb73a3c20429096e0e76d33a35189f8302ad60408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a0815260c0810181811067ffffffffffffffff82111761110d5760405251902090565b507f00000000000000000000000000000000000000000000000000000000000000014614614cf9565b15614df957565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152fdfea164736f6c6343000812000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000144b756c7420446f6c6365205265736f757263657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000013100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b68747470733a2f2f6b756c74646f6c63652e696f2f6170692f6b756c74446f6c63655265736f757263652f000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): Kult Dolce Resources
Arg [1] : version_ (string): 1
Arg [2] : uri_ (string): https://kultdolce.io/api/kultDolceResource/
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [4] : 4b756c7420446f6c6365205265736f7572636573000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 3100000000000000000000000000000000000000000000000000000000000000
Arg [7] : 000000000000000000000000000000000000000000000000000000000000002b
Arg [8] : 68747470733a2f2f6b756c74646f6c63652e696f2f6170692f6b756c74446f6c
Arg [9] : 63655265736f757263652f000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.