Overview
TokenID
3329
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
Mods
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "./Signature.sol"; import "./Recoverable.sol"; import "@limitbreak/creator-token-standards/src/access/OwnableBasic.sol"; import "@limitbreak/creator-token-standards/src/erc721c/ERC721C.sol"; import "@limitbreak/creator-token-standards/src/programmable-royalties/BasicRoyalties.sol"; contract Mods is OwnableBasic, ERC721C, BasicRoyalties, Signature, Recoverable { string public baseURI; bool public isBurnEnabled = false; bool public isMintEnabled = false; error BurnNotEnabled(); error MintNotEnabled(); error NothingToBurn(); error NotAllowedToBurn(); error NonceAlreadyUsed(); error InvalidSignature(); error InvalidRecipient(); error InvalidCaller(); error RequestExpired(); event Burned(uint tokenId); struct BurnRequest { address from; uint256[] tokenIds; uint128 validityStartTimestamp; uint128 validityEndTimestamp; bytes32 nonce; } struct MintRequest { address to; address from; uint256[] tokenIds; uint128 validityStartTimestamp; uint128 validityEndTimestamp; bytes32 nonce; } constructor( address royaltyReceiver_, uint96 royaltyFeeNumerator_, string memory name_, string memory symbol_) ERC721OpenZeppelin(name_, symbol_) BasicRoyalties(royaltyReceiver_, royaltyFeeNumerator_) { _transferOwnership(royaltyReceiver_); } function mint(MintRequest calldata req_, bytes calldata signature_) external { if (!isMintEnabled) revert MintNotEnabled(); if (req_.to == address(0)) revert InvalidRecipient(); if (req_.from == address(0) || req_.from != _msgSender()) revert InvalidCaller(); if (!isValidNonce(req_.nonce)) revert NonceAlreadyUsed(); if (!isValidTime(req_.validityStartTimestamp, req_.validityEndTimestamp)) revert RequestExpired(); _invalidateNonce(req_.nonce); bytes32 message = getMintMessageHash(req_.to, req_.from, req_.tokenIds, req_.validityStartTimestamp, req_.validityEndTimestamp, req_.nonce); if (!_isValidSignature(message, signature_)) revert InvalidSignature(); for (uint256 i = 0; i < req_.tokenIds.length; i++) { _safeMint(req_.to, req_.tokenIds[i]); } } function burn(BurnRequest calldata req_, bytes calldata signature_) external { if (!isBurnEnabled) revert BurnNotEnabled(); if (req_.from == address(0) || req_.from != _msgSender()) revert InvalidCaller(); if (!isValidNonce(req_.nonce)) revert NonceAlreadyUsed(); if (!isValidTime(req_.validityStartTimestamp, req_.validityEndTimestamp)) revert RequestExpired(); _invalidateNonce(req_.nonce); bytes32 message = getBurnMessageHash(req_.from, req_.tokenIds, req_.validityStartTimestamp, req_.validityEndTimestamp, req_.nonce); if (!_isValidSignature(message, signature_)) revert InvalidSignature(); for (uint256 i = 0; i < req_.tokenIds.length; i++) { if (!_isApprovedOrOwner(_msgSender(), req_.tokenIds[i])) revert NotAllowedToBurn(); _burn(req_.tokenIds[i]); emit Burned(req_.tokenIds[i]); } } function getMintMessageHash( address to_, address from_, uint256[] calldata tokenIds_, uint128 validityStartTimestamp_, uint128 validityEndTimestamp_, bytes32 nonce_ ) public pure returns (bytes32) { return keccak256( abi.encodePacked( to_, from_, tokenIds_, validityStartTimestamp_, validityEndTimestamp_, nonce_ ) ); } function getBurnMessageHash( address from_, uint256[] calldata tokenIds_, uint128 validityStartTimestamp_, uint128 validityEndTimestamp_, bytes32 nonce_ ) public pure returns (bytes32) { return keccak256( abi.encodePacked( from_, tokenIds_, validityStartTimestamp_, validityEndTimestamp_, nonce_ ) ); } function setSigner(address signer_) external onlyOwner { _setSigner(signer_); } function setBurnEnabled(bool burnEnabled_) external onlyOwner { isBurnEnabled = burnEnabled_; } function setMintEnabled(bool mintEnabled_) external onlyOwner { isMintEnabled = mintEnabled_; } function supportsInterface(bytes4 interfaceId_) public view virtual override(ERC721C, ERC2981) returns (bool) { return super.supportsInterface(interfaceId_); } function setBaseURI(string memory baseUri_) external onlyOwner { baseURI = baseUri_; } function _baseURI() internal view override returns (string memory) { return baseURI; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./OwnablePermissions.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; abstract contract OwnableBasic is OwnablePermissions, Ownable { function _requireCallerIsContractOwner() internal view virtual override { _checkOwner(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/Context.sol"; abstract contract OwnablePermissions is Context { function _requireCallerIsContractOwner() internal view virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../utils/AutomaticValidatorTransferApproval.sol"; import "../utils/CreatorTokenBase.sol"; import "../token/erc721/ERC721OpenZeppelin.sol"; import "../interfaces/ITransferValidatorSetTokenType.sol"; import {TOKEN_TYPE_ERC721} from "@limitbreak/permit-c/src/Constants.sol"; /** * @title ERC721C * @author Limit Break, Inc. * @notice Extends OpenZeppelin's ERC721 implementation with Creator Token functionality, which * allows the contract owner to update the transfer validation logic by managing a security policy in * an external transfer validation security policy registry. See {CreatorTokenTransferValidator}. */ abstract contract ERC721C is ERC721OpenZeppelin, CreatorTokenBase, AutomaticValidatorTransferApproval { /** * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved * for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) { isApproved = super.isApprovedForAll(owner, operator); if (!isApproved) { if (autoApproveTransfersFromValidator) { isApproved = operator == address(getTransferValidator()); } } } /** * @notice Indicates whether the contract implements the specified interface. * @dev Overrides supportsInterface in ERC165. * @param interfaceId The interface id * @return true if the contract implements the specified interface, false otherwise */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || interfaceId == type(ICreatorTokenLegacy).interfaceId || super.supportsInterface(interfaceId); } /** * @notice Returns the function selector for the transfer validator's validation function to be called * @notice for transaction simulation. */ function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) { functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256)")); isViewFunction = true; } /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateBeforeTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateAfterTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } function _tokenType() internal pure override returns(uint16) { return uint16(TOKEN_TYPE_ERC721); } } /** * @title ERC721CInitializable * @author Limit Break, Inc. * @notice Initializable implementation of ERC721C to allow for EIP-1167 proxy clones. */ abstract contract ERC721CInitializable is ERC721OpenZeppelinInitializable, CreatorTokenBase, AutomaticValidatorTransferApproval { function initializeERC721(string memory name_, string memory symbol_) public override { super.initializeERC721(name_, symbol_); _emitDefaultTransferValidator(); _registerTokenType(getTransferValidator()); } /** * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved * for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) { isApproved = super.isApprovedForAll(owner, operator); if (!isApproved) { if (autoApproveTransfersFromValidator) { isApproved = operator == address(getTransferValidator()); } } } /** * @notice Indicates whether the contract implements the specified interface. * @dev Overrides supportsInterface in ERC165. * @param interfaceId The interface id * @return true if the contract implements the specified interface, false otherwise */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || interfaceId == type(ICreatorTokenLegacy).interfaceId || super.supportsInterface(interfaceId); } /** * @notice Returns the function selector for the transfer validator's validation function to be called * @notice for transaction simulation. */ function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) { functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256)")); isViewFunction = true; } /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateBeforeTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateAfterTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } function _tokenType() internal pure override returns(uint16) { return uint16(TOKEN_TYPE_ERC721); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface ICreatorToken { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (address validator); function setTransferValidator(address validator) external; function getTransferValidationFunction() external view returns (bytes4 functionSignature, bool isViewFunction); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface ICreatorTokenLegacy { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (address validator); function setTransferValidator(address validator) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface ITransferValidator { function applyCollectionTransferPolicy(address caller, address from, address to) external view; function validateTransfer(address caller, address from, address to) external view; function validateTransfer(address caller, address from, address to, uint256 tokenId) external view; function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external; function beforeAuthorizedTransfer(address operator, address token, uint256 tokenId) external; function afterAuthorizedTransfer(address token, uint256 tokenId) external; function beforeAuthorizedTransfer(address operator, address token) external; function afterAuthorizedTransfer(address token) external; function beforeAuthorizedTransfer(address token, uint256 tokenId) external; function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external; function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface ITransferValidatorSetTokenType { function setTokenTypeOfCollection(address collection, uint16 tokenType) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/common/ERC2981.sol"; /** * @title BasicRoyaltiesBase * @author Limit Break, Inc. * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties. */ abstract contract BasicRoyaltiesBase is ERC2981 { event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator); event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator); function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override { super._setDefaultRoyalty(receiver, feeNumerator); emit DefaultRoyaltySet(receiver, feeNumerator); } function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override { super._setTokenRoyalty(tokenId, receiver, feeNumerator); emit TokenRoyaltySet(tokenId, receiver, feeNumerator); } } /** * @title BasicRoyalties * @author Limit Break, Inc. * @notice Constructable BasicRoyalties Contract implementation. */ abstract contract BasicRoyalties is BasicRoyaltiesBase { constructor(address receiver, uint96 feeNumerator) { _setDefaultRoyalty(receiver, feeNumerator); } } /** * @title BasicRoyaltiesInitializable * @author Limit Break, Inc. * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. */ abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../../access/OwnablePermissions.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; abstract contract ERC721OpenZeppelinBase is ERC721 { // Token name string internal _contractName; // Token symbol string internal _contractSymbol; function name() public view virtual override returns (string memory) { return _contractName; } function symbol() public view virtual override returns (string memory) { return _contractSymbol; } function _setNameAndSymbol(string memory name_, string memory symbol_) internal { _contractName = name_; _contractSymbol = symbol_; } } abstract contract ERC721OpenZeppelin is ERC721OpenZeppelinBase { constructor(string memory name_, string memory symbol_) ERC721("", "") { _setNameAndSymbol(name_, symbol_); } } abstract contract ERC721OpenZeppelinInitializable is OwnablePermissions, ERC721OpenZeppelinBase { error ERC721OpenZeppelinInitializable__AlreadyInitializedERC721(); /// @notice Specifies whether or not the contract is initialized bool private _erc721Initialized; /// @dev Initializes parameters of ERC721 tokens. /// These cannot be set in the constructor because this contract is optionally compatible with EIP-1167. function initializeERC721(string memory name_, string memory symbol_) public virtual { _requireCallerIsContractOwner(); if(_erc721Initialized) { revert ERC721OpenZeppelinInitializable__AlreadyInitializedERC721(); } _erc721Initialized = true; _setNameAndSymbol(name_, symbol_); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../access/OwnablePermissions.sol"; /** * @title AutomaticValidatorTransferApproval * @author Limit Break, Inc. * @notice Base contract mix-in that provides boilerplate code giving the contract owner the * option to automatically approve a 721-C transfer validator implementation for transfers. */ abstract contract AutomaticValidatorTransferApproval is OwnablePermissions { /// @dev Emitted when the automatic approval flag is modified by the creator. event AutomaticApprovalOfTransferValidatorSet(bool autoApproved); /// @dev If true, the collection's transfer validator is automatically approved to transfer holder's tokens. bool public autoApproveTransfersFromValidator; /** * @notice Sets if the transfer validator is automatically approved as an operator for all token owners. * * @dev Throws when the caller is not the contract owner. * * @param autoApprove If true, the collection's transfer validator will be automatically approved to * transfer holder's tokens. */ function setAutomaticApprovalOfTransfersFromValidator(bool autoApprove) external { _requireCallerIsContractOwner(); autoApproveTransfersFromValidator = autoApprove; emit AutomaticApprovalOfTransferValidatorSet(autoApprove); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../access/OwnablePermissions.sol"; import "../interfaces/ICreatorToken.sol"; import "../interfaces/ICreatorTokenLegacy.sol"; import "../interfaces/ITransferValidator.sol"; import "./TransferValidation.sol"; import "../interfaces/ITransferValidatorSetTokenType.sol"; /** * @title CreatorTokenBase * @author Limit Break, Inc. * @notice CreatorTokenBaseV3 is an abstract contract that provides basic functionality for managing token * transfer policies through an implementation of ICreatorTokenTransferValidator/ICreatorTokenTransferValidatorV2/ICreatorTokenTransferValidatorV3. * This contract is intended to be used as a base for creator-specific token contracts, enabling customizable transfer * restrictions and security policies. * * <h4>Features:</h4> * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul> * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul> * * <h4>Benefits:</h4> * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul> * <ul>Allows creators to enforce policies such as account and codehash blacklists, whitelists, and graylists.</ul> * <ul>Can be easily integrated into other token contracts as a base contract.</ul> * * <h4>Intended Usage:</h4> * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and * security policies.</ul> * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the * creator token.</ul> * * <h4>Compatibility:</h4> * <ul>Backward and Forward Compatible - V1/V2/V3 Creator Token Base will work with V1/V2/V3 Transfer Validators.</ul> */ abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken { /// @dev Thrown when setting a transfer validator address that has no deployed code. error CreatorTokenBase__InvalidTransferValidatorContract(); /// @dev The default transfer validator that will be used if no transfer validator has been set by the creator. address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x721C002B0059009a671D00aD1700c9748146cd1B); /// @dev Used to determine if the default transfer validator is applied. /// @dev Set to true when the creator sets a transfer validator address. bool private isValidatorInitialized; /// @dev Address of the transfer validator to apply to transactions. address private transferValidator; constructor() { _emitDefaultTransferValidator(); _registerTokenType(DEFAULT_TRANSFER_VALIDATOR); } /** * @notice Sets the transfer validator for the token contract. * * @dev Throws when provided validator contract is not the zero address and does not have code. * @dev Throws when the caller is not the contract owner. * * @dev <h4>Postconditions:</h4> * 1. The transferValidator address is updated. * 2. The `TransferValidatorUpdated` event is emitted. * * @param transferValidator_ The address of the transfer validator contract. */ function setTransferValidator(address transferValidator_) public { _requireCallerIsContractOwner(); bool isValidTransferValidator = transferValidator_.code.length > 0; if(transferValidator_ != address(0) && !isValidTransferValidator) { revert CreatorTokenBase__InvalidTransferValidatorContract(); } emit TransferValidatorUpdated(address(getTransferValidator()), transferValidator_); isValidatorInitialized = true; transferValidator = transferValidator_; _registerTokenType(transferValidator_); } /** * @notice Returns the transfer validator contract address for this token contract. */ function getTransferValidator() public view override returns (address validator) { validator = transferValidator; if (validator == address(0)) { if (!isValidatorInitialized) { validator = DEFAULT_TRANSFER_VALIDATOR; } } } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the * transfer validator is expected to pre-validate the transfer. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. * @param tokenId The token id being transferred. */ function _preValidateTransfer( address caller, address from, address to, uint256 tokenId, uint256 /*value*/) internal virtual override { address validator = getTransferValidator(); if (validator != address(0)) { if (msg.sender == validator) { return; } ITransferValidator(validator).validateTransfer(caller, from, to, tokenId); } } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the * transfer validator is expected to pre-validate the transfer. * * @dev Used for ERC20 and ERC1155 token transfers which have an amount value to validate in the transfer validator. * @dev The `tokenId` for ERC20 tokens should be set to `0`. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. * @param tokenId The token id being transferred. * @param amount The amount of token being transferred. */ function _preValidateTransfer( address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 /*value*/) internal virtual override { address validator = getTransferValidator(); if (validator != address(0)) { if (msg.sender == validator) { return; } ITransferValidator(validator).validateTransfer(caller, from, to, tokenId, amount); } } function _tokenType() internal virtual pure returns(uint16); function _registerTokenType(address validator) internal { if (validator != address(0)) { uint256 validatorCodeSize; assembly { validatorCodeSize := extcodesize(validator) } if(validatorCodeSize > 0) { try ITransferValidatorSetTokenType(validator).setTokenTypeOfCollection(address(this), _tokenType()) { } catch { } } } } /** * @dev Used during contract deployment for constructable and cloneable creator tokens * @dev to emit the `TransferValidatorUpdated` event signaling the validator for the contract * @dev is the default transfer validator. */ function _emitDefaultTransferValidator() internal { emit TransferValidatorUpdated(address(0), DEFAULT_TRANSFER_VALIDATOR); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/Context.sol"; /** * @title TransferValidation * @author Limit Break, Inc. * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks. * Openzeppelin's ERC721 contract only provides hooks for before and after transfer. This allows * developers to validate or customize transfers within the context of a mint, a burn, or a transfer. */ abstract contract TransferValidation is Context { /// @dev Thrown when the from and to address are both the zero address. error ShouldNotMintToBurnAddress(); /*************************************************************************/ /* Transfers Without Amounts */ /*************************************************************************/ /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /*************************************************************************/ /* Transfers With Amounts */ /*************************************************************************/ /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, amount, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, amount, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, amount, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, amount, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @dev Constant bytes32 value of 0x000...000 bytes32 constant ZERO_BYTES32 = bytes32(0); /// @dev Constant value of 0 uint256 constant ZERO = 0; /// @dev Constant value of 1 uint256 constant ONE = 1; /// @dev Constant value representing an open order in storage uint8 constant ORDER_STATE_OPEN = 0; /// @dev Constant value representing a filled order in storage uint8 constant ORDER_STATE_FILLED = 1; /// @dev Constant value representing a cancelled order in storage uint8 constant ORDER_STATE_CANCELLED = 2; /// @dev Constant value representing the ERC721 token type for signatures and transfer hooks uint256 constant TOKEN_TYPE_ERC721 = 721; /// @dev Constant value representing the ERC1155 token type for signatures and transfer hooks uint256 constant TOKEN_TYPE_ERC1155 = 1155; /// @dev Constant value representing the ERC20 token type for signatures and transfer hooks uint256 constant TOKEN_TYPE_ERC20 = 20; /// @dev Constant value to mask the upper bits of a signature that uses a packed `vs` value to extract `s` bytes32 constant UPPER_BIT_MASK = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; /// @dev EIP-712 typehash used for validating signature based stored approvals bytes32 constant UPDATE_APPROVAL_TYPEHASH = keccak256("UpdateApprovalBySignature(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 approvalExpiration,uint256 sigDeadline,uint256 masterNonce)"); /// @dev EIP-712 typehash used for validating a single use permit without additional data bytes32 constant SINGLE_USE_PERMIT_TYPEHASH = keccak256("PermitTransferFrom(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 expiration,uint256 masterNonce)"); /// @dev EIP-712 typehash used for validating a single use permit with additional data string constant SINGLE_USE_PERMIT_TRANSFER_ADVANCED_TYPEHASH_STUB = "PermitTransferFromWithAdditionalData(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 expiration,uint256 masterNonce,"; /// @dev EIP-712 typehash used for validating an order permit that updates storage as it fills string constant PERMIT_ORDER_ADVANCED_TYPEHASH_STUB = "PermitOrderWithAdditionalData(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 salt,address operator,uint256 expiration,uint256 masterNonce,"; /// @dev Pausable flag for stored approval transfers of ERC721 assets uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC721 = 1 << 0; /// @dev Pausable flag for stored approval transfers of ERC1155 assets uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC1155 = 1 << 1; /// @dev Pausable flag for stored approval transfers of ERC20 assets uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC20 = 1 << 2; /// @dev Pausable flag for single use permit transfers of ERC721 assets uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC721 = 1 << 3; /// @dev Pausable flag for single use permit transfers of ERC1155 assets uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC1155 = 1 << 4; /// @dev Pausable flag for single use permit transfers of ERC20 assets uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC20 = 1 << 5; /// @dev Pausable flag for order fill transfers of ERC1155 assets uint256 constant PAUSABLE_ORDER_TRANSFER_FROM_ERC1155 = 1 << 6; /// @dev Pausable flag for order fill transfers of ERC20 assets uint256 constant PAUSABLE_ORDER_TRANSFER_FROM_ERC20 = 1 << 7;
// 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 v4.4.1 (interfaces/IERC1155.sol) pragma solidity ^0.8.0; import "../token/ERC1155/IERC1155.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// 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 v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721.sol";
// 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.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.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @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, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, 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 (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 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); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/interfaces/IERC721.sol"; import "@openzeppelin/contracts/interfaces/IERC1155.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; abstract contract Recoverable is Ownable { event RecoveredERC20(address indexed token, uint256 amount); event RecoveredERC721(address indexed token, uint256 indexed tokenId); event RecoveredERC1155(address indexed token, uint256 indexed tokenId, uint256 amount); error InvalidTokenAddress(); error NothingToRecover(); function recoverERC1155(address tokenAddress, uint256 tokenId) external onlyOwner { if (tokenAddress == address(0)) revert InvalidTokenAddress(); IERC1155 token = IERC1155(tokenAddress); uint256 balance = token.balanceOf(address(this), tokenId); if (balance == 0) revert NothingToRecover(); token.safeTransferFrom(address(this), owner(), tokenId, balance, ""); emit RecoveredERC1155(tokenAddress, tokenId, balance); } function recoverERC20(address tokenAddress) external onlyOwner { if (tokenAddress == address(0)) revert InvalidTokenAddress(); IERC20 token = IERC20(tokenAddress); uint256 balance = token.balanceOf(address(this)); if (balance == 0) revert NothingToRecover(); token.transfer(owner(), balance); emit RecoveredERC20(tokenAddress, balance); } function recoverERC721(address tokenAddress, uint256 tokenId) external onlyOwner { if (tokenAddress == address(0)) revert InvalidTokenAddress(); IERC721 token = IERC721(tokenAddress); address ownerOfToken = token.ownerOf(tokenId); if (ownerOfToken != address(this)) revert NothingToRecover(); token.safeTransferFrom(address(this), owner(), tokenId); emit RecoveredERC721(tokenAddress, tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; abstract contract Signature { using ECDSA for bytes32; address private signer; mapping(bytes32 => bool) public nonces; function _setSigner(address signer_) internal { require(signer_ != address(0), "Invalid signer address"); signer = signer_; } function _isValidSignature( bytes32 data, bytes memory signature ) public view returns (bool) { return data.toEthSignedMessageHash().recover(signature) == signer; } function isValidNonce(bytes32 _nonce) public view returns (bool) { return !nonces[_nonce]; } function isValidTime(uint128 _start, uint128 _end) public view returns (bool) { return _start <= block.timestamp && _end >= block.timestamp; } function _invalidateNonce(bytes32 _nonce) internal { nonces[_nonce] = true; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"royaltyReceiver_","type":"address"},{"internalType":"uint96","name":"royaltyFeeNumerator_","type":"uint96"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BurnNotEnabled","type":"error"},{"inputs":[],"name":"CreatorTokenBase__InvalidTransferValidatorContract","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[],"name":"MintNotEnabled","type":"error"},{"inputs":[],"name":"NonceAlreadyUsed","type":"error"},{"inputs":[],"name":"NotAllowedToBurn","type":"error"},{"inputs":[],"name":"NothingToBurn","type":"error"},{"inputs":[],"name":"NothingToRecover","type":"error"},{"inputs":[],"name":"RequestExpired","type":"error"},{"inputs":[],"name":"ShouldNotMintToBurnAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"autoApproved","type":"bool"}],"name":"AutomaticApprovalOfTransferValidatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"DefaultRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RecoveredERC1155","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RecoveredERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"RecoveredERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"TokenRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_TRANSFER_VALIDATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"data","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"_isValidSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoApproveTransfersFromValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint128","name":"validityStartTimestamp","type":"uint128"},{"internalType":"uint128","name":"validityEndTimestamp","type":"uint128"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"internalType":"struct Mods.BurnRequest","name":"req_","type":"tuple"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"},{"internalType":"uint128","name":"validityStartTimestamp_","type":"uint128"},{"internalType":"uint128","name":"validityEndTimestamp_","type":"uint128"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"}],"name":"getBurnMessageHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"},{"internalType":"uint128","name":"validityStartTimestamp_","type":"uint128"},{"internalType":"uint128","name":"validityEndTimestamp_","type":"uint128"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"}],"name":"getMintMessageHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransferValidationFunction","outputs":[{"internalType":"bytes4","name":"functionSignature","type":"bytes4"},{"internalType":"bool","name":"isViewFunction","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"address","name":"validator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isApproved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBurnEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_nonce","type":"bytes32"}],"name":"isValidNonce","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"_start","type":"uint128"},{"internalType":"uint128","name":"_end","type":"uint128"}],"name":"isValidTime","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint128","name":"validityStartTimestamp","type":"uint128"},{"internalType":"uint128","name":"validityEndTimestamp","type":"uint128"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"internalType":"struct Mods.MintRequest","name":"req_","type":"tuple"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nonces","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"recoverERC1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"recoverERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"autoApprove","type":"bool"}],"name":"setAutomaticApprovalOfTransfersFromValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseUri_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"burnEnabled_","type":"bool"}],"name":"setBurnEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"mintEnabled_","type":"bool"}],"name":"setMintEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer_","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferValidator_","type":"address"}],"name":"setTransferValidator","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600f805461ffff191690553480156200001c57600080fd5b5060405162003985380380620039858339810160408190526200003f9162000455565b83838383604051806020016040528060008152506040518060200160405280600081525081600090816200007491906200058e565b5060016200008382826200058e565b505050620000988282620000f360201b60201c565b50620000a690503362000115565b620000b062000167565b620000cf73721c002b0059009a671d00ad1700c9748146cd1b620001b6565b620000db828262000234565b50620000e990508462000115565b505050506200065a565b60066200010183826200058e565b5060076200011082826200058e565b505050565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516000815273721c002b0059009a671d00ad1700c9748146cd1b60208201527fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac910160405180910390a1565b6001600160a01b038116156200023157803b80156200022f576040805163fb2de5d760e01b81523060048201526102d1602482015290516001600160a01b0384169163fb2de5d791604480830192600092919082900301818387803b1580156200021f57600080fd5b505af19250505080156200011057505b505b50565b6200024082826200028b565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b6127106001600160601b0382161115620002ff5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620003575760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401620002f6565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600a55565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620003b857600080fd5b81516001600160401b0380821115620003d557620003d562000390565b604051601f8301601f19908116603f0116810190828211818310171562000400576200040062000390565b816040528381526020925086838588010111156200041d57600080fd5b600091505b8382101562000441578582018301518183018401529082019062000422565b600093810190920192909252949350505050565b600080600080608085870312156200046c57600080fd5b84516001600160a01b03811681146200048457600080fd5b60208601519094506001600160601b0381168114620004a257600080fd5b60408601519093506001600160401b0380821115620004c057600080fd5b620004ce88838901620003a6565b93506060870151915080821115620004e557600080fd5b50620004f487828801620003a6565b91505092959194509250565b600181811c908216806200051557607f821691505b6020821081036200053657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200011057600081815260208120601f850160051c81016020861015620005655750805b601f850160051c820191505b81811015620005865782815560010162000571565b505050505050565b81516001600160401b03811115620005aa57620005aa62000390565b620005c281620005bb845462000500565b846200053c565b602080601f831160018114620005fa5760008415620005e15750858301515b600019600386901b1c1916600185901b17855562000586565b600085815260208120601f198616915b828110156200062b578886015182559484019460019091019084016200060a565b50858210156200064a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61331b806200066a6000396000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c80636c19e783116101465780639e8c708e116100c3578063ba0f263711610087578063ba0f26371461053b578063c87b56dd1461055f578063e985e9c514610572578063f2fde38b14610585578063f46a04eb14610598578063fc23eab7146105ab57600080fd5b80639e8c708e146104dc5780639f665bdf146104ef578063a22cb46514610502578063a9fc664e14610515578063b88d4fde1461052857600080fd5b8063825349d41161010a578063825349d41461047a5780638da5cb5b1461048d57806395d89b411461049e5780639e05d240146104a65780639e317f12146104b957600080fd5b80636c19e7831461042657806370a0823114610439578063715018a61461044c5780637b2c835f14610454578063819d4cc61461046757600080fd5b80632a55205a116101d45780635c654ad9116101985780635c654ad9146103c35780636221d13c146103d65780636352211e146103ea578063689e16b3146103fd5780636c0360eb1461041e57600080fd5b80632a55205a14610346578063346de50a1461037857806342842e0e1461038a578063429c97581461039d57806355f804b3146103b057600080fd5b8063081812fc1161021b578063081812fc146102ea578063095ea7b3146102fd578063098144d4146103105780630d705df61461031857806323b872dd1461033357600080fd5b8063014635461461025857806301ffc9a71461029057806304d34f70146102b357806306fdde03146102c857806307ebec27146102dd575b600080fd5b61027373721c002b0059009a671d00ad1700c9748146cd1b81565b6040516001600160a01b0390911681526020015b60405180910390f35b6102a361029e3660046127e0565b6105be565b6040519015158152602001610287565b6102c66102c136600461283e565b6105cf565b005b6102d061088c565b60405161028791906128fe565b600f546102a39060ff1681565b6102736102f8366004612911565b61091e565b6102c661030b36600461293f565b610945565b610273610a5f565b6040805163657711f560e11b81526001602082015201610287565b6102c661034136600461296b565b610a9b565b6103596103543660046129ac565b610acc565b604080516001600160a01b039093168352602083019190915201610287565b600f546102a390610100900460ff1681565b6102c661039836600461296b565b610b7a565b6102a36103ab366004612a79565b610b95565b6102c66103be366004612abf565b610c16565b6102c66103d136600461293f565b610c2e565b6009546102a390600160a01b900460ff1681565b6102736103f8366004612911565b610dd9565b61041061040b366004612b67565b610e39565b604051908152602001610287565b6102d0610e78565b6102c6610434366004612be6565b610f06565b610410610447366004612be6565b610f1a565b6102c6610fa0565b6102c6610462366004612c11565b610fb4565b6102c661047536600461293f565b610fcf565b6102c6610488366004612c2e565b61115c565b6008546001600160a01b0316610273565b6102d06113ca565b6102c66104b4366004612c11565b6113d9565b6102a36104c7366004612911565b600d6020526000908152604090205460ff1681565b6102c66104ea366004612be6565b611439565b6102a36104fd366004612c6e565b6115d3565b6102c6610510366004612ca1565b6115fe565b6102c6610523366004612be6565b611609565b6102c6610536366004612cda565b6116ce565b6102a3610549366004612911565b6000908152600d602052604090205460ff161590565b6102d061056d366004612911565b611706565b6102a3610580366004612d45565b61176c565b6102c6610593366004612be6565b6117d0565b6102c66105a6366004612c11565b611846565b6104106105b9366004612d73565b611868565b60006105c9826118aa565b92915050565b600f5460ff166105f257604051632b7e2ae360e01b815260040160405180910390fd5b60006106016020850185612be6565b6001600160a01b0316148061062b57503361061f6020850185612be6565b6001600160a01b031614155b15610649576040516348f5c3ed60e01b815260040160405180910390fd5b60808301356000908152600d602052604090205460ff161561067d57604051623f613760e71b815260040160405180910390fd5b6106a06106906060850160408601612e06565b6104fd6080860160608701612e06565b6106bd57604051637f780e6960e11b815260040160405180910390fd5b6106e083608001356000908152600d60205260409020805460ff19166001179055565b60006107296106f26020860186612be6565b6106ff6020870187612e21565b61070f6060890160408a01612e06565b61071f60808a0160608b01612e06565b8960800135610e39565b905061076b8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b9592505050565b61078857604051638baa579f60e01b815260040160405180910390fd5b60005b6107986020860186612e21565b9050811015610885576107ce336107b26020880188612e21565b848181106107c2576107c2612e6a565b905060200201356118cf565b6107eb5760405163044bcf2f60e31b815260040160405180910390fd5b6108176107fb6020870187612e21565b8381811061080b5761080b612e6a565b9050602002013561192e565b7fd83c63197e8e676d80ab0122beba9a9d20f3828839e9a1d6fe81d242e9cd7e6e6108456020870187612e21565b8381811061085557610855612e6a565b9050602002013560405161086b91815260200190565b60405180910390a18061087d81612e96565b91505061078b565b5050505050565b60606006805461089b90612eaf565b80601f01602080910402602001604051908101604052809291908181526020018280546108c790612eaf565b80156109145780601f106108e957610100808354040283529160200191610914565b820191906000526020600020905b8154815290600101906020018083116108f757829003601f168201915b5050505050905090565b6000610929826119db565b506000908152600460205260409020546001600160a01b031690565b600061095082610dd9565b9050806001600160a01b0316836001600160a01b0316036109c25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806109de57506109de813361176c565b610a505760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016109b9565b610a5a8383611a3a565b505050565b6009546001600160a01b031680610a9857600854600160a01b900460ff16610a98575073721c002b0059009a671d00ad1700c9748146cd1b5b90565b610aa533826118cf565b610ac15760405162461bcd60e51b81526004016109b990612ee9565b610a5a838383611aa8565b6000828152600b602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610b41575060408051808201909152600a546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610b60906001600160601b031687612f36565b610b6a9190612f4d565b91519350909150505b9250929050565b610a5a838383604051806020016040528060008152506116ce565b600c546000906001600160a01b0316610c0583610bff866040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611c21565b6001600160a01b0316149392505050565b610c1e611c45565b600e610c2a8282612fb5565b5050565b610c36611c45565b6001600160a01b038216610c5d57604051630f58058360e11b815260040160405180910390fd5b604051627eeac760e11b81523060048201526024810182905282906000906001600160a01b0383169062fdd58e90604401602060405180830381865afa158015610cab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190613074565b905080600003610cf25760405163157474a960e31b815260040160405180910390fd5b816001600160a01b031663f242432a30610d146008546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018690526064810184905260a06084820152600060a482015260c401600060405180830381600087803b158015610d7857600080fd5b505af1158015610d8c573d6000803e3d6000fd5b5050505082846001600160a01b03167e04b148840595eb234e6148251c2c9c78d692171f32febbd992963e0c13855383604051610dcb91815260200190565b60405180910390a350505050565b6000818152600260205260408120546001600160a01b0316806105c95760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109b9565b6000868686868686604051602001610e56969594939291906130b6565b6040516020818303038152906040528051906020012090509695505050505050565b600e8054610e8590612eaf565b80601f0160208091040260200160405190810160405280929190818152602001828054610eb190612eaf565b8015610efe5780601f10610ed357610100808354040283529160200191610efe565b820191906000526020600020905b815481529060010190602001808311610ee157829003601f168201915b505050505081565b610f0e611c45565b610f1781611c9f565b50565b60006001600160a01b038216610f845760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016109b9565b506001600160a01b031660009081526003602052604090205490565b610fa8611c45565b610fb26000611d10565b565b610fbc611c45565b600f805460ff1916911515919091179055565b610fd7611c45565b6001600160a01b038216610ffe57604051630f58058360e11b815260040160405180910390fd5b6040516331a9108f60e11b81526004810182905282906000906001600160a01b03831690636352211e90602401602060405180830381865afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c9190613105565b90506001600160a01b03811630146110975760405163157474a960e31b815260040160405180910390fd5b816001600160a01b03166342842e0e306110b96008546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b15801561110857600080fd5b505af115801561111c573d6000803e3d6000fd5b50506040518592506001600160a01b03871691507f57519b6a0997d7d44511836bcee0a36871aa79d445816f6c464abb0cd9d3f3e890600090a350505050565b600f54610100900460ff166111845760405163447691f760e01b815260040160405180910390fd5b60006111936020850185612be6565b6001600160a01b0316036111ba57604051634e46966960e11b815260040160405180910390fd5b60006111cc6040850160208601612be6565b6001600160a01b031614806111f95750336111ed6040850160208601612be6565b6001600160a01b031614155b15611217576040516348f5c3ed60e01b815260040160405180910390fd5b60a08301356000908152600d602052604090205460ff161561124b57604051623f613760e71b815260040160405180910390fd5b61126e61125e6080850160608601612e06565b6104fd60a0860160808701612e06565b61128b57604051637f780e6960e11b815260040160405180910390fd5b6112ae8360a001356000908152600d60205260409020805460ff19166001179055565b60006113076112c06020860186612be6565b6112d06040870160208801612be6565b6112dd6040880188612e21565b6112ed60808a0160608b01612e06565b6112fd60a08b0160808c01612e06565b8a60a00135611868565b90506113498184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b9592505050565b61136657604051638baa579f60e01b815260040160405180910390fd5b60005b6113766040860186612e21565b9050811015610885576113b861138f6020870187612be6565b61139c6040880188612e21565b848181106113ac576113ac612e6a565b90506020020135611d62565b806113c281612e96565b915050611369565b60606007805461089b90612eaf565b6113e1611d7c565b60098054821515600160a01b0260ff60a01b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc9061142e90831515815260200190565b60405180910390a150565b611441611c45565b6001600160a01b03811661146857604051630f58058360e11b815260040160405180910390fd5b6040516370a0823160e01b815230600482015281906000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156114b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d59190613074565b9050806000036114f85760405163157474a960e31b815260040160405180910390fd5b816001600160a01b031663a9059cbb6115196008546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015611566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158a9190613122565b50826001600160a01b03167f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1826040516115c691815260200190565b60405180910390a2505050565b600042836001600160801b0316111580156115f7575042826001600160801b031610155b9392505050565b610c2a338383611d84565b611611611d7c565b6001600160a01b038116803b1515901580159061162c575080155b1561164a576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac611673610a5f565b604080516001600160a01b03928316815291851660208301520160405180910390a16008805460ff60a01b1916600160a01b179055600980546001600160a01b0384166001600160a01b0319909116179055610c2a82611e52565b6116d833836118cf565b6116f45760405162461bcd60e51b81526004016109b990612ee9565b61170084848484611ed2565b50505050565b6060611711826119db565b600061171b611f05565b9050600081511161173b57604051806020016040528060008152506115f7565b8061174584611f14565b60405160200161175692919061313f565b6040516020818303038152906040529392505050565b6001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff16806105c957600954600160a01b900460ff16156105c9576117b4610a5f565b6001600160a01b0316826001600160a01b031614905092915050565b6117d8611c45565b6001600160a01b03811661183d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109b9565b610f1781611d10565b61184e611c45565b600f80549115156101000261ff0019909216919091179055565b600087878787878787604051602001611887979695949392919061316e565b604051602081830303815290604052805190602001209050979650505050505050565b60006001600160e01b0319821663152a902d60e11b14806105c957506105c982611fa6565b6000806118db83610dd9565b9050806001600160a01b0316846001600160a01b031614806119025750611902818561176c565b806119265750836001600160a01b031661191b8461091e565b6001600160a01b0316145b949350505050565b600061193982610dd9565b9050611949816000846001611fe6565b61195282610dd9565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4610c2a81600084600161200d565b6000818152600260205260409020546001600160a01b0316610f175760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109b9565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a6f82610dd9565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b826001600160a01b0316611abb82610dd9565b6001600160a01b031614611ae15760405162461bcd60e51b81526004016109b9906131cb565b6001600160a01b038216611b435760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109b9565b611b508383836001611fe6565b826001600160a01b0316611b6382610dd9565b6001600160a01b031614611b895760405162461bcd60e51b81526004016109b9906131cb565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4610a5a838383600161200d565b6000806000611c308585612034565b91509150611c3d81612076565b509392505050565b6008546001600160a01b03163314610fb25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b9565b6001600160a01b038116611cee5760405162461bcd60e51b8152602060048201526016602482015275496e76616c6964207369676e6572206164647265737360501b60448201526064016109b9565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610c2a8282604051806020016040528060008152506121c0565b610fb2611c45565b816001600160a01b0316836001600160a01b031603611de55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109b9565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b03811615610f1757803b8015610c2a576040805163fb2de5d760e01b81523060048201526102d1602482015290516001600160a01b0384169163fb2de5d791604480830192600092919082900301818387803b158015611eb857600080fd5b505af1925050508015611ec9575060015b15610c2a575050565b611edd848484611aa8565b611ee9848484846121f3565b6117005760405162461bcd60e51b81526004016109b990613210565b6060600e805461089b90612eaf565b60606000611f21836122f4565b60010190506000816001600160401b03811115611f4057611f406129ce565b6040519080825280601f01601f191660200182016040528015611f6a576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611f7457509392505050565b60006001600160e01b03198216632b435fdb60e21b1480611fd757506001600160e01b0319821663503e914d60e11b145b806105c957506105c9826123cc565b60005b818110156108855761200585856120008487613262565b61241c565b600101611fe9565b60005b818110156108855761202c85856120278487613262565b612472565b600101612010565b600080825160410361206a5760208301516040840151606085015160001a61205e878285856124b9565b94509450505050610b73565b50600090506002610b73565b600081600481111561208a5761208a613275565b036120925750565b60018160048111156120a6576120a6613275565b036120f35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109b9565b600281600481111561210757612107613275565b036121545760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109b9565b600381600481111561216857612168613275565b03610f175760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016109b9565b6121ca838361257d565b6121d760008484846121f3565b610a5a5760405162461bcd60e51b81526004016109b990613210565b60006001600160a01b0384163b156122e957604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061223790339089908890889060040161328b565b6020604051808303816000875af1925050508015612272575060408051601f3d908101601f1916820190925261226f918101906132c8565b60015b6122cf573d8080156122a0576040519150601f19603f3d011682016040523d82523d6000602084013e6122a5565b606091505b5080516000036122c75760405162461bcd60e51b81526004016109b990613210565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611926565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106123335772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061235f576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061237d57662386f26fc10000830492506010015b6305f5e1008310612395576305f5e100830492506008015b61271083106123a957612710830492506004015b606483106123bb576064830492506002015b600a83106105c95760010192915050565b60006001600160e01b031982166380ac58cd60e01b14806123fd57506001600160e01b03198216635b5e139f60e01b145b806105c957506301ffc9a760e01b6001600160e01b03198316146105c9565b6001600160a01b0383811615908316158180156124365750805b1561245457604051635cbd944160e01b815260040160405180910390fd5b8115612460575b610885565b8061245b576108853386868634612720565b6001600160a01b03838116159083161581801561248c5750805b156124aa57604051635cbd944160e01b815260040160405180910390fd5b8161245b578061245b57610885565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156124f05750600090506003612574565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612544573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661256d57600060019250925050612574565b9150600090505b94509492505050565b6001600160a01b0382166125d35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109b9565b6000818152600260205260409020546001600160a01b0316156126385760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109b9565b612646600083836001611fe6565b6000818152600260205260409020546001600160a01b0316156126ab5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109b9565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4610c2a60008383600161200d565b600061272a610a5f565b90506001600160a01b038116156127c2576001600160a01b03811633036127515750610885565b60405163657711f560e11b81526001600160a01b038781166004830152868116602483015285811660448301526064820185905282169063caee23ea9060840160006040518083038186803b1580156127a957600080fd5b505afa1580156127bd573d6000803e3d6000fd5b505050505b505050505050565b6001600160e01b031981168114610f1757600080fd5b6000602082840312156127f257600080fd5b81356115f7816127ca565b60008083601f84011261280f57600080fd5b5081356001600160401b0381111561282657600080fd5b602083019150836020828501011115610b7357600080fd5b60008060006040848603121561285357600080fd5b83356001600160401b038082111561286a57600080fd5b9085019060a0828803121561287e57600080fd5b9093506020850135908082111561289457600080fd5b506128a1868287016127fd565b9497909650939450505050565b60005b838110156128c95781810151838201526020016128b1565b50506000910152565b600081518084526128ea8160208601602086016128ae565b601f01601f19169290920160200192915050565b6020815260006115f760208301846128d2565b60006020828403121561292357600080fd5b5035919050565b6001600160a01b0381168114610f1757600080fd5b6000806040838503121561295257600080fd5b823561295d8161292a565b946020939093013593505050565b60008060006060848603121561298057600080fd5b833561298b8161292a565b9250602084013561299b8161292a565b929592945050506040919091013590565b600080604083850312156129bf57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b03808411156129fe576129fe6129ce565b604051601f8501601f19908116603f01168101908282118183101715612a2657612a266129ce565b81604052809350858152868686011115612a3f57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112612a6a57600080fd5b6115f7838335602085016129e4565b60008060408385031215612a8c57600080fd5b8235915060208301356001600160401b03811115612aa957600080fd5b612ab585828601612a59565b9150509250929050565b600060208284031215612ad157600080fd5b81356001600160401b03811115612ae757600080fd5b8201601f81018413612af857600080fd5b611926848235602084016129e4565b60008083601f840112612b1957600080fd5b5081356001600160401b03811115612b3057600080fd5b6020830191508360208260051b8501011115610b7357600080fd5b80356001600160801b0381168114612b6257600080fd5b919050565b60008060008060008060a08789031215612b8057600080fd5b8635612b8b8161292a565b955060208701356001600160401b03811115612ba657600080fd5b612bb289828a01612b07565b9096509450612bc5905060408801612b4b565b9250612bd360608801612b4b565b9150608087013590509295509295509295565b600060208284031215612bf857600080fd5b81356115f78161292a565b8015158114610f1757600080fd5b600060208284031215612c2357600080fd5b81356115f781612c03565b600080600060408486031215612c4357600080fd5b83356001600160401b0380821115612c5a57600080fd5b9085019060c0828803121561287e57600080fd5b60008060408385031215612c8157600080fd5b612c8a83612b4b565b9150612c9860208401612b4b565b90509250929050565b60008060408385031215612cb457600080fd5b8235612cbf8161292a565b91506020830135612ccf81612c03565b809150509250929050565b60008060008060808587031215612cf057600080fd5b8435612cfb8161292a565b93506020850135612d0b8161292a565b92506040850135915060608501356001600160401b03811115612d2d57600080fd5b612d3987828801612a59565b91505092959194509250565b60008060408385031215612d5857600080fd5b8235612d638161292a565b91506020830135612ccf8161292a565b600080600080600080600060c0888a031215612d8e57600080fd5b8735612d998161292a565b96506020880135612da98161292a565b955060408801356001600160401b03811115612dc457600080fd5b612dd08a828b01612b07565b9096509450612de3905060608901612b4b565b9250612df160808901612b4b565b915060a0880135905092959891949750929550565b600060208284031215612e1857600080fd5b6115f782612b4b565b6000808335601e19843603018112612e3857600080fd5b8301803591506001600160401b03821115612e5257600080fd5b6020019150600581901b3603821315610b7357600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612ea857612ea8612e80565b5060010190565b600181811c90821680612ec357607f821691505b602082108103612ee357634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b80820281158282048414176105c9576105c9612e80565b600082612f6a57634e487b7160e01b600052601260045260246000fd5b500490565b601f821115610a5a57600081815260208120601f850160051c81016020861015612f965750805b601f850160051c820191505b818110156127c257828155600101612fa2565b81516001600160401b03811115612fce57612fce6129ce565b612fe281612fdc8454612eaf565b84612f6f565b602080601f8311600181146130175760008415612fff5750858301515b600019600386901b1c1916600185901b1785556127c2565b600085815260208120601f198616915b8281101561304657888601518255948401946001909101908401613027565b50858210156130645787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121561308657600080fd5b5051919050565b60006001600160fb1b038311156130a357600080fd5b8260051b80838637939093019392505050565b6001600160601b03198760601b16815260006130d660148301878961308d565b6001600160801b0319608096871b811682529490951b9093166010850152506020830152506040019392505050565b60006020828403121561311757600080fd5b81516115f78161292a565b60006020828403121561313457600080fd5b81516115f781612c03565b600083516131518184602088016128ae565b8351908301906131658183602088016128ae565b01949350505050565b60006001600160601b0319808a60601b168352808960601b1660148401525061319b60288301878961308d565b6001600160801b0319608096871b811682529490951b909316601085015250602083015250604001949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b808201808211156105c9576105c9612e80565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906132be908301846128d2565b9695505050505050565b6000602082840312156132da57600080fd5b81516115f7816127ca56fea2646970667358221220c7bd7662a591e7e581f770adcf44ee4db2168c5fd14c8ff51767ae9c2d1c07f564736f6c634300081500330000000000000000000000006bee03a601874abfad5143a83a3199dba71fa29500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000e54686520383130323a204d6f647300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d4f445300000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102535760003560e01c80636c19e783116101465780639e8c708e116100c3578063ba0f263711610087578063ba0f26371461053b578063c87b56dd1461055f578063e985e9c514610572578063f2fde38b14610585578063f46a04eb14610598578063fc23eab7146105ab57600080fd5b80639e8c708e146104dc5780639f665bdf146104ef578063a22cb46514610502578063a9fc664e14610515578063b88d4fde1461052857600080fd5b8063825349d41161010a578063825349d41461047a5780638da5cb5b1461048d57806395d89b411461049e5780639e05d240146104a65780639e317f12146104b957600080fd5b80636c19e7831461042657806370a0823114610439578063715018a61461044c5780637b2c835f14610454578063819d4cc61461046757600080fd5b80632a55205a116101d45780635c654ad9116101985780635c654ad9146103c35780636221d13c146103d65780636352211e146103ea578063689e16b3146103fd5780636c0360eb1461041e57600080fd5b80632a55205a14610346578063346de50a1461037857806342842e0e1461038a578063429c97581461039d57806355f804b3146103b057600080fd5b8063081812fc1161021b578063081812fc146102ea578063095ea7b3146102fd578063098144d4146103105780630d705df61461031857806323b872dd1461033357600080fd5b8063014635461461025857806301ffc9a71461029057806304d34f70146102b357806306fdde03146102c857806307ebec27146102dd575b600080fd5b61027373721c002b0059009a671d00ad1700c9748146cd1b81565b6040516001600160a01b0390911681526020015b60405180910390f35b6102a361029e3660046127e0565b6105be565b6040519015158152602001610287565b6102c66102c136600461283e565b6105cf565b005b6102d061088c565b60405161028791906128fe565b600f546102a39060ff1681565b6102736102f8366004612911565b61091e565b6102c661030b36600461293f565b610945565b610273610a5f565b6040805163657711f560e11b81526001602082015201610287565b6102c661034136600461296b565b610a9b565b6103596103543660046129ac565b610acc565b604080516001600160a01b039093168352602083019190915201610287565b600f546102a390610100900460ff1681565b6102c661039836600461296b565b610b7a565b6102a36103ab366004612a79565b610b95565b6102c66103be366004612abf565b610c16565b6102c66103d136600461293f565b610c2e565b6009546102a390600160a01b900460ff1681565b6102736103f8366004612911565b610dd9565b61041061040b366004612b67565b610e39565b604051908152602001610287565b6102d0610e78565b6102c6610434366004612be6565b610f06565b610410610447366004612be6565b610f1a565b6102c6610fa0565b6102c6610462366004612c11565b610fb4565b6102c661047536600461293f565b610fcf565b6102c6610488366004612c2e565b61115c565b6008546001600160a01b0316610273565b6102d06113ca565b6102c66104b4366004612c11565b6113d9565b6102a36104c7366004612911565b600d6020526000908152604090205460ff1681565b6102c66104ea366004612be6565b611439565b6102a36104fd366004612c6e565b6115d3565b6102c6610510366004612ca1565b6115fe565b6102c6610523366004612be6565b611609565b6102c6610536366004612cda565b6116ce565b6102a3610549366004612911565b6000908152600d602052604090205460ff161590565b6102d061056d366004612911565b611706565b6102a3610580366004612d45565b61176c565b6102c6610593366004612be6565b6117d0565b6102c66105a6366004612c11565b611846565b6104106105b9366004612d73565b611868565b60006105c9826118aa565b92915050565b600f5460ff166105f257604051632b7e2ae360e01b815260040160405180910390fd5b60006106016020850185612be6565b6001600160a01b0316148061062b57503361061f6020850185612be6565b6001600160a01b031614155b15610649576040516348f5c3ed60e01b815260040160405180910390fd5b60808301356000908152600d602052604090205460ff161561067d57604051623f613760e71b815260040160405180910390fd5b6106a06106906060850160408601612e06565b6104fd6080860160608701612e06565b6106bd57604051637f780e6960e11b815260040160405180910390fd5b6106e083608001356000908152600d60205260409020805460ff19166001179055565b60006107296106f26020860186612be6565b6106ff6020870187612e21565b61070f6060890160408a01612e06565b61071f60808a0160608b01612e06565b8960800135610e39565b905061076b8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b9592505050565b61078857604051638baa579f60e01b815260040160405180910390fd5b60005b6107986020860186612e21565b9050811015610885576107ce336107b26020880188612e21565b848181106107c2576107c2612e6a565b905060200201356118cf565b6107eb5760405163044bcf2f60e31b815260040160405180910390fd5b6108176107fb6020870187612e21565b8381811061080b5761080b612e6a565b9050602002013561192e565b7fd83c63197e8e676d80ab0122beba9a9d20f3828839e9a1d6fe81d242e9cd7e6e6108456020870187612e21565b8381811061085557610855612e6a565b9050602002013560405161086b91815260200190565b60405180910390a18061087d81612e96565b91505061078b565b5050505050565b60606006805461089b90612eaf565b80601f01602080910402602001604051908101604052809291908181526020018280546108c790612eaf565b80156109145780601f106108e957610100808354040283529160200191610914565b820191906000526020600020905b8154815290600101906020018083116108f757829003601f168201915b5050505050905090565b6000610929826119db565b506000908152600460205260409020546001600160a01b031690565b600061095082610dd9565b9050806001600160a01b0316836001600160a01b0316036109c25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806109de57506109de813361176c565b610a505760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016109b9565b610a5a8383611a3a565b505050565b6009546001600160a01b031680610a9857600854600160a01b900460ff16610a98575073721c002b0059009a671d00ad1700c9748146cd1b5b90565b610aa533826118cf565b610ac15760405162461bcd60e51b81526004016109b990612ee9565b610a5a838383611aa8565b6000828152600b602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610b41575060408051808201909152600a546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610b60906001600160601b031687612f36565b610b6a9190612f4d565b91519350909150505b9250929050565b610a5a838383604051806020016040528060008152506116ce565b600c546000906001600160a01b0316610c0583610bff866040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611c21565b6001600160a01b0316149392505050565b610c1e611c45565b600e610c2a8282612fb5565b5050565b610c36611c45565b6001600160a01b038216610c5d57604051630f58058360e11b815260040160405180910390fd5b604051627eeac760e11b81523060048201526024810182905282906000906001600160a01b0383169062fdd58e90604401602060405180830381865afa158015610cab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190613074565b905080600003610cf25760405163157474a960e31b815260040160405180910390fd5b816001600160a01b031663f242432a30610d146008546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018690526064810184905260a06084820152600060a482015260c401600060405180830381600087803b158015610d7857600080fd5b505af1158015610d8c573d6000803e3d6000fd5b5050505082846001600160a01b03167e04b148840595eb234e6148251c2c9c78d692171f32febbd992963e0c13855383604051610dcb91815260200190565b60405180910390a350505050565b6000818152600260205260408120546001600160a01b0316806105c95760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109b9565b6000868686868686604051602001610e56969594939291906130b6565b6040516020818303038152906040528051906020012090509695505050505050565b600e8054610e8590612eaf565b80601f0160208091040260200160405190810160405280929190818152602001828054610eb190612eaf565b8015610efe5780601f10610ed357610100808354040283529160200191610efe565b820191906000526020600020905b815481529060010190602001808311610ee157829003601f168201915b505050505081565b610f0e611c45565b610f1781611c9f565b50565b60006001600160a01b038216610f845760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016109b9565b506001600160a01b031660009081526003602052604090205490565b610fa8611c45565b610fb26000611d10565b565b610fbc611c45565b600f805460ff1916911515919091179055565b610fd7611c45565b6001600160a01b038216610ffe57604051630f58058360e11b815260040160405180910390fd5b6040516331a9108f60e11b81526004810182905282906000906001600160a01b03831690636352211e90602401602060405180830381865afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c9190613105565b90506001600160a01b03811630146110975760405163157474a960e31b815260040160405180910390fd5b816001600160a01b03166342842e0e306110b96008546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b15801561110857600080fd5b505af115801561111c573d6000803e3d6000fd5b50506040518592506001600160a01b03871691507f57519b6a0997d7d44511836bcee0a36871aa79d445816f6c464abb0cd9d3f3e890600090a350505050565b600f54610100900460ff166111845760405163447691f760e01b815260040160405180910390fd5b60006111936020850185612be6565b6001600160a01b0316036111ba57604051634e46966960e11b815260040160405180910390fd5b60006111cc6040850160208601612be6565b6001600160a01b031614806111f95750336111ed6040850160208601612be6565b6001600160a01b031614155b15611217576040516348f5c3ed60e01b815260040160405180910390fd5b60a08301356000908152600d602052604090205460ff161561124b57604051623f613760e71b815260040160405180910390fd5b61126e61125e6080850160608601612e06565b6104fd60a0860160808701612e06565b61128b57604051637f780e6960e11b815260040160405180910390fd5b6112ae8360a001356000908152600d60205260409020805460ff19166001179055565b60006113076112c06020860186612be6565b6112d06040870160208801612be6565b6112dd6040880188612e21565b6112ed60808a0160608b01612e06565b6112fd60a08b0160808c01612e06565b8a60a00135611868565b90506113498184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b9592505050565b61136657604051638baa579f60e01b815260040160405180910390fd5b60005b6113766040860186612e21565b9050811015610885576113b861138f6020870187612be6565b61139c6040880188612e21565b848181106113ac576113ac612e6a565b90506020020135611d62565b806113c281612e96565b915050611369565b60606007805461089b90612eaf565b6113e1611d7c565b60098054821515600160a01b0260ff60a01b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc9061142e90831515815260200190565b60405180910390a150565b611441611c45565b6001600160a01b03811661146857604051630f58058360e11b815260040160405180910390fd5b6040516370a0823160e01b815230600482015281906000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156114b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d59190613074565b9050806000036114f85760405163157474a960e31b815260040160405180910390fd5b816001600160a01b031663a9059cbb6115196008546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015611566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158a9190613122565b50826001600160a01b03167f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1826040516115c691815260200190565b60405180910390a2505050565b600042836001600160801b0316111580156115f7575042826001600160801b031610155b9392505050565b610c2a338383611d84565b611611611d7c565b6001600160a01b038116803b1515901580159061162c575080155b1561164a576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac611673610a5f565b604080516001600160a01b03928316815291851660208301520160405180910390a16008805460ff60a01b1916600160a01b179055600980546001600160a01b0384166001600160a01b0319909116179055610c2a82611e52565b6116d833836118cf565b6116f45760405162461bcd60e51b81526004016109b990612ee9565b61170084848484611ed2565b50505050565b6060611711826119db565b600061171b611f05565b9050600081511161173b57604051806020016040528060008152506115f7565b8061174584611f14565b60405160200161175692919061313f565b6040516020818303038152906040529392505050565b6001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff16806105c957600954600160a01b900460ff16156105c9576117b4610a5f565b6001600160a01b0316826001600160a01b031614905092915050565b6117d8611c45565b6001600160a01b03811661183d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109b9565b610f1781611d10565b61184e611c45565b600f80549115156101000261ff0019909216919091179055565b600087878787878787604051602001611887979695949392919061316e565b604051602081830303815290604052805190602001209050979650505050505050565b60006001600160e01b0319821663152a902d60e11b14806105c957506105c982611fa6565b6000806118db83610dd9565b9050806001600160a01b0316846001600160a01b031614806119025750611902818561176c565b806119265750836001600160a01b031661191b8461091e565b6001600160a01b0316145b949350505050565b600061193982610dd9565b9050611949816000846001611fe6565b61195282610dd9565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4610c2a81600084600161200d565b6000818152600260205260409020546001600160a01b0316610f175760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109b9565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a6f82610dd9565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b826001600160a01b0316611abb82610dd9565b6001600160a01b031614611ae15760405162461bcd60e51b81526004016109b9906131cb565b6001600160a01b038216611b435760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109b9565b611b508383836001611fe6565b826001600160a01b0316611b6382610dd9565b6001600160a01b031614611b895760405162461bcd60e51b81526004016109b9906131cb565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4610a5a838383600161200d565b6000806000611c308585612034565b91509150611c3d81612076565b509392505050565b6008546001600160a01b03163314610fb25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b9565b6001600160a01b038116611cee5760405162461bcd60e51b8152602060048201526016602482015275496e76616c6964207369676e6572206164647265737360501b60448201526064016109b9565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610c2a8282604051806020016040528060008152506121c0565b610fb2611c45565b816001600160a01b0316836001600160a01b031603611de55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109b9565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b03811615610f1757803b8015610c2a576040805163fb2de5d760e01b81523060048201526102d1602482015290516001600160a01b0384169163fb2de5d791604480830192600092919082900301818387803b158015611eb857600080fd5b505af1925050508015611ec9575060015b15610c2a575050565b611edd848484611aa8565b611ee9848484846121f3565b6117005760405162461bcd60e51b81526004016109b990613210565b6060600e805461089b90612eaf565b60606000611f21836122f4565b60010190506000816001600160401b03811115611f4057611f406129ce565b6040519080825280601f01601f191660200182016040528015611f6a576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611f7457509392505050565b60006001600160e01b03198216632b435fdb60e21b1480611fd757506001600160e01b0319821663503e914d60e11b145b806105c957506105c9826123cc565b60005b818110156108855761200585856120008487613262565b61241c565b600101611fe9565b60005b818110156108855761202c85856120278487613262565b612472565b600101612010565b600080825160410361206a5760208301516040840151606085015160001a61205e878285856124b9565b94509450505050610b73565b50600090506002610b73565b600081600481111561208a5761208a613275565b036120925750565b60018160048111156120a6576120a6613275565b036120f35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109b9565b600281600481111561210757612107613275565b036121545760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109b9565b600381600481111561216857612168613275565b03610f175760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016109b9565b6121ca838361257d565b6121d760008484846121f3565b610a5a5760405162461bcd60e51b81526004016109b990613210565b60006001600160a01b0384163b156122e957604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061223790339089908890889060040161328b565b6020604051808303816000875af1925050508015612272575060408051601f3d908101601f1916820190925261226f918101906132c8565b60015b6122cf573d8080156122a0576040519150601f19603f3d011682016040523d82523d6000602084013e6122a5565b606091505b5080516000036122c75760405162461bcd60e51b81526004016109b990613210565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611926565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106123335772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061235f576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061237d57662386f26fc10000830492506010015b6305f5e1008310612395576305f5e100830492506008015b61271083106123a957612710830492506004015b606483106123bb576064830492506002015b600a83106105c95760010192915050565b60006001600160e01b031982166380ac58cd60e01b14806123fd57506001600160e01b03198216635b5e139f60e01b145b806105c957506301ffc9a760e01b6001600160e01b03198316146105c9565b6001600160a01b0383811615908316158180156124365750805b1561245457604051635cbd944160e01b815260040160405180910390fd5b8115612460575b610885565b8061245b576108853386868634612720565b6001600160a01b03838116159083161581801561248c5750805b156124aa57604051635cbd944160e01b815260040160405180910390fd5b8161245b578061245b57610885565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156124f05750600090506003612574565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612544573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661256d57600060019250925050612574565b9150600090505b94509492505050565b6001600160a01b0382166125d35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109b9565b6000818152600260205260409020546001600160a01b0316156126385760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109b9565b612646600083836001611fe6565b6000818152600260205260409020546001600160a01b0316156126ab5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109b9565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4610c2a60008383600161200d565b600061272a610a5f565b90506001600160a01b038116156127c2576001600160a01b03811633036127515750610885565b60405163657711f560e11b81526001600160a01b038781166004830152868116602483015285811660448301526064820185905282169063caee23ea9060840160006040518083038186803b1580156127a957600080fd5b505afa1580156127bd573d6000803e3d6000fd5b505050505b505050505050565b6001600160e01b031981168114610f1757600080fd5b6000602082840312156127f257600080fd5b81356115f7816127ca565b60008083601f84011261280f57600080fd5b5081356001600160401b0381111561282657600080fd5b602083019150836020828501011115610b7357600080fd5b60008060006040848603121561285357600080fd5b83356001600160401b038082111561286a57600080fd5b9085019060a0828803121561287e57600080fd5b9093506020850135908082111561289457600080fd5b506128a1868287016127fd565b9497909650939450505050565b60005b838110156128c95781810151838201526020016128b1565b50506000910152565b600081518084526128ea8160208601602086016128ae565b601f01601f19169290920160200192915050565b6020815260006115f760208301846128d2565b60006020828403121561292357600080fd5b5035919050565b6001600160a01b0381168114610f1757600080fd5b6000806040838503121561295257600080fd5b823561295d8161292a565b946020939093013593505050565b60008060006060848603121561298057600080fd5b833561298b8161292a565b9250602084013561299b8161292a565b929592945050506040919091013590565b600080604083850312156129bf57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b03808411156129fe576129fe6129ce565b604051601f8501601f19908116603f01168101908282118183101715612a2657612a266129ce565b81604052809350858152868686011115612a3f57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112612a6a57600080fd5b6115f7838335602085016129e4565b60008060408385031215612a8c57600080fd5b8235915060208301356001600160401b03811115612aa957600080fd5b612ab585828601612a59565b9150509250929050565b600060208284031215612ad157600080fd5b81356001600160401b03811115612ae757600080fd5b8201601f81018413612af857600080fd5b611926848235602084016129e4565b60008083601f840112612b1957600080fd5b5081356001600160401b03811115612b3057600080fd5b6020830191508360208260051b8501011115610b7357600080fd5b80356001600160801b0381168114612b6257600080fd5b919050565b60008060008060008060a08789031215612b8057600080fd5b8635612b8b8161292a565b955060208701356001600160401b03811115612ba657600080fd5b612bb289828a01612b07565b9096509450612bc5905060408801612b4b565b9250612bd360608801612b4b565b9150608087013590509295509295509295565b600060208284031215612bf857600080fd5b81356115f78161292a565b8015158114610f1757600080fd5b600060208284031215612c2357600080fd5b81356115f781612c03565b600080600060408486031215612c4357600080fd5b83356001600160401b0380821115612c5a57600080fd5b9085019060c0828803121561287e57600080fd5b60008060408385031215612c8157600080fd5b612c8a83612b4b565b9150612c9860208401612b4b565b90509250929050565b60008060408385031215612cb457600080fd5b8235612cbf8161292a565b91506020830135612ccf81612c03565b809150509250929050565b60008060008060808587031215612cf057600080fd5b8435612cfb8161292a565b93506020850135612d0b8161292a565b92506040850135915060608501356001600160401b03811115612d2d57600080fd5b612d3987828801612a59565b91505092959194509250565b60008060408385031215612d5857600080fd5b8235612d638161292a565b91506020830135612ccf8161292a565b600080600080600080600060c0888a031215612d8e57600080fd5b8735612d998161292a565b96506020880135612da98161292a565b955060408801356001600160401b03811115612dc457600080fd5b612dd08a828b01612b07565b9096509450612de3905060608901612b4b565b9250612df160808901612b4b565b915060a0880135905092959891949750929550565b600060208284031215612e1857600080fd5b6115f782612b4b565b6000808335601e19843603018112612e3857600080fd5b8301803591506001600160401b03821115612e5257600080fd5b6020019150600581901b3603821315610b7357600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612ea857612ea8612e80565b5060010190565b600181811c90821680612ec357607f821691505b602082108103612ee357634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b80820281158282048414176105c9576105c9612e80565b600082612f6a57634e487b7160e01b600052601260045260246000fd5b500490565b601f821115610a5a57600081815260208120601f850160051c81016020861015612f965750805b601f850160051c820191505b818110156127c257828155600101612fa2565b81516001600160401b03811115612fce57612fce6129ce565b612fe281612fdc8454612eaf565b84612f6f565b602080601f8311600181146130175760008415612fff5750858301515b600019600386901b1c1916600185901b1785556127c2565b600085815260208120601f198616915b8281101561304657888601518255948401946001909101908401613027565b50858210156130645787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121561308657600080fd5b5051919050565b60006001600160fb1b038311156130a357600080fd5b8260051b80838637939093019392505050565b6001600160601b03198760601b16815260006130d660148301878961308d565b6001600160801b0319608096871b811682529490951b9093166010850152506020830152506040019392505050565b60006020828403121561311757600080fd5b81516115f78161292a565b60006020828403121561313457600080fd5b81516115f781612c03565b600083516131518184602088016128ae565b8351908301906131658183602088016128ae565b01949350505050565b60006001600160601b0319808a60601b168352808960601b1660148401525061319b60288301878961308d565b6001600160801b0319608096871b811682529490951b909316601085015250602083015250604001949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b808201808211156105c9576105c9612e80565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906132be908301846128d2565b9695505050505050565b6000602082840312156132da57600080fd5b81516115f7816127ca56fea2646970667358221220c7bd7662a591e7e581f770adcf44ee4db2168c5fd14c8ff51767ae9c2d1c07f564736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006bee03a601874abfad5143a83a3199dba71fa29500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000e54686520383130323a204d6f647300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d4f445300000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : royaltyReceiver_ (address): 0x6bEE03a601874ABFad5143A83a3199DBA71Fa295
Arg [1] : royaltyFeeNumerator_ (uint96): 420
Arg [2] : name_ (string): The 8102: Mods
Arg [3] : symbol_ (string): MODS
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000006bee03a601874abfad5143a83a3199dba71fa295
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001a4
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [5] : 54686520383130323a204d6f6473000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 4d4f445300000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
350:4637:34:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2205:104:10;;2266:42;2205:104;;;;;-1:-1:-1;;;;;178:32:35;;;160:51;;148:2;133:18;2205:104:10;;;;;;;;4606:171:34;;;;;;:::i;:::-;;:::i;:::-;;;773:14:35;;766:22;748:41;;736:2;721:18;4606:171:34;608:187:35;2375:908:34;;;;;;:::i;:::-;;:::i;:::-;;333:106:8;;;:::i;:::-;;;;;;;:::i;462:33:34:-;;;;;;;;;3935:167:20;;;;;;:::i;:::-;;:::i;3468:406::-;;;;;;:::i;:::-;;:::i;3958:290:10:-;;;:::i;2159:249:2:-;;;;-1:-1:-1;;;3419:52:35;;2397:4:2;3502:2:35;3487:18;;3480:50;3392:18;2159:249:2;3253:283:35;4612:326:20;;;;;;:::i;:::-;;:::i;1671:432:24:-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4447:32:35;;;4429:51;;4511:2;4496:18;;4489:34;;;;4402:18;1671:432:24;4255:274:35;501:33:34;;;;;;;;;;;;5004:179:20;;;;;;:::i;:::-;;:::i;411:196:33:-;;;;;;:::i;:::-;;:::i;4783:98:34:-;;;;;;:::i;:::-;;:::i;628:471:32:-;;;;;;:::i;:::-;;:::i;724:45:9:-;;;;;-1:-1:-1;;;724:45:9;;;;;;2190:219:20;;;;;;:::i;:::-;;:::i;3807:470:34:-;;;;;;:::i;:::-;;:::i;:::-;;;7881:25:35;;;7869:2;7854:18;3807:470:34;7735:177:35;435:21:34;;;:::i;4283:91::-;;;;;;:::i;:::-;;:::i;1929:204:20:-;;;;;;:::i;:::-;;:::i;1831:101:13:-;;;:::i;4380:107:34:-;;;;;;:::i;:::-;;:::i;1503:450:32:-;;;;;;:::i;:::-;;:::i;1516:853:34:-;;;;;;:::i;:::-;;:::i;1201:85:13:-;1273:6;;-1:-1:-1;;;;;1273:6:13;1201:85;;445:110:8;;;:::i;1139:253:9:-;;;;;;:::i;:::-;;:::i;215:38:33:-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;1105:392:32;;;;;;:::i;:::-;;:::i;723:154:33:-;;;;;;:::i;:::-;;:::i;4169:153:20:-;;;;;;:::i;:::-;;:::i;3268:580:10:-;;;;;;:::i;:::-;;:::i;5249:314:20:-;;;;;;:::i;:::-;;:::i;613:104:33:-;;;;;;:::i;:::-;672:4;696:14;;;:6;:14;;;;;;;;695:15;;613:104;2801:276:20;;;;;;:::i;:::-;;:::i;1053:362:2:-;;;;;;:::i;:::-;;:::i;2081:198:13:-;;;;;;:::i;:::-;;:::i;4493:107:34:-;;;;;;:::i;:::-;;:::i;3289:512::-;;;;;;:::i;:::-;;:::i;4606:171::-;4710:4;4733:37;4757:12;4733:23;:37::i;:::-;4726:44;4606:171;-1:-1:-1;;4606:171:34:o;2375:908::-;2467:13;;;;2462:43;;2489:16;;-1:-1:-1;;;2489:16:34;;;;;;;;;;;2462:43;2540:1;2519:9;;;;:4;:9;:::i;:::-;-1:-1:-1;;;;;2519:23:34;;:52;;;-1:-1:-1;719:10:26;2546:9:34;;;;;;:::i;:::-;-1:-1:-1;;;;;2546:25:34;;;2519:52;2515:80;;;2580:15;;-1:-1:-1;;;2580:15:34;;;;;;;;;;;2515:80;2623:10;;;;672:4:33;696:14;;;:6;:14;;;;;;;;695:15;2605:56:34;;2643:18;;-1:-1:-1;;;2643:18:34;;;;;;;;;;;2605:56;2676:67;2688:27;;;;;;;;:::i;:::-;2717:25;;;;;;;;:::i;2676:67::-;2671:97;;2752:16;;-1:-1:-1;;;2752:16:34;;;;;;;;;;;2671:97;2779:28;2796:4;:10;;;944:14:33;;;;:6;:14;;;;;:21;;-1:-1:-1;;944:21:33;961:4;944:21;;;883:89;2779:28:34;2818:15;2836:112;2855:9;;;;:4;:9;:::i;:::-;2866:13;;;;:4;:13;:::i;:::-;2881:27;;;;;;;;:::i;:::-;2910:25;;;;;;;;:::i;:::-;2937:4;:10;;;2836:18;:112::i;:::-;2818:130;;2963:38;2981:7;2990:10;;2963:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2963:17:34;;-1:-1:-1;;;2963:38:34:i;:::-;2958:70;;3010:18;;-1:-1:-1;;;3010:18:34;;;;;;;;;;;2958:70;3044:9;3039:238;3063:13;;;;:4;:13;:::i;:::-;:20;;3059:1;:24;3039:238;;;3109:50;719:10:26;3142:13:34;;;;:4;:13;:::i;:::-;3156:1;3142:16;;;;;;;:::i;:::-;;;;;;;3109:18;:50::i;:::-;3104:82;;3168:18;;-1:-1:-1;;;3168:18:34;;;;;;;;;;;3104:82;3200:23;3206:13;;;;:4;:13;:::i;:::-;3220:1;3206:16;;;;;;;:::i;:::-;;;;;;;3200:5;:23::i;:::-;3242:24;3249:13;;;;:4;:13;:::i;:::-;3263:1;3249:16;;;;;;;:::i;:::-;;;;;;;3242:24;;;;7881:25:35;;7869:2;7854:18;;7735:177;3242:24:34;;;;;;;;3085:3;;;;:::i;:::-;;;;3039:238;;;;2452:831;2375:908;;;:::o;333:106:8:-;387:13;419;412:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;333:106;:::o;3935:167:20:-;4011:7;4030:23;4045:7;4030:14;:23::i;:::-;-1:-1:-1;4071:24:20;;;;:15;:24;;;;;;-1:-1:-1;;;;;4071:24:20;;3935:167::o;3468:406::-;3548:13;3564:23;3579:7;3564:14;:23::i;:::-;3548:39;;3611:5;-1:-1:-1;;;;;3605:11:20;:2;-1:-1:-1;;;;;3605:11:20;;3597:57;;;;-1:-1:-1;;;3597:57:20;;13993:2:35;3597:57:20;;;13975:21:35;14032:2;14012:18;;;14005:30;14071:34;14051:18;;;14044:62;-1:-1:-1;;;14122:18:35;;;14115:31;14163:19;;3597:57:20;;;;;;;;;719:10:26;-1:-1:-1;;;;;3686:21:20;;;;:62;;-1:-1:-1;3711:37:20;3728:5;719:10:26;1053:362:2;:::i;3711:37:20:-;3665:170;;;;-1:-1:-1;;;3665:170:20;;14395:2:35;3665:170:20;;;14377:21:35;14434:2;14414:18;;;14407:30;14473:34;14453:18;;;14446:62;14544:31;14524:18;;;14517:59;14593:19;;3665:170:20;14193:425:35;3665:170:20;3846:21;3855:2;3859:7;3846:8;:21::i;:::-;3538:336;3468:406;;:::o;3958:290:10:-;4061:17;;-1:-1:-1;;;;;4061:17:10;;4089:153;;4137:22;;-1:-1:-1;;;4137:22:10;;;;4132:100;;-1:-1:-1;2266:42:10;4132:100;3958:290;:::o;4612:326:20:-;4801:41;719:10:26;4834:7:20;4801:18;:41::i;:::-;4793:99;;;;-1:-1:-1;;;4793:99:20;;;;;;;:::i;:::-;4903:28;4913:4;4919:2;4923:7;4903:9;:28::i;1671:432:24:-;1768:7;1825:27;;;:17;:27;;;;;;;;1796:56;;;;;;;;;-1:-1:-1;;;;;1796:56:24;;;;;-1:-1:-1;;;1796:56:24;;;-1:-1:-1;;;;;1796:56:24;;;;;;;;1768:7;;1863:90;;-1:-1:-1;1913:29:24;;;;;;;;;1923:19;1913:29;-1:-1:-1;;;;;1913:29:24;;;;-1:-1:-1;;;1913:29:24;;-1:-1:-1;;;;;1913:29:24;;;;;1863:90;2001:23;;;;1963:21;;2461:5;;1988:36;;-1:-1:-1;;;;;1988:36:24;:10;:36;:::i;:::-;1987:58;;;;:::i;:::-;2064:16;;;-1:-1:-1;1963:82:24;;-1:-1:-1;;1671:432:24;;;;;;:::o;5004:179:20:-;5137:39;5154:4;5160:2;5164:7;5137:39;;;;;;;;;;;;:16;:39::i;411:196:33:-;594:6;;519:4;;-1:-1:-1;;;;;594:6:33;542:48;580:9;542:29;:4;7455:58:28;;24280:66:35;7455:58:28;;;24268:79:35;24363:12;;;24356:28;;;7325:7:28;;24400:12:35;;7455:58:28;;;;;;;;;;;;7445:69;;;;;;7438:76;;7256:265;;;;542:29:33;:37;;:48::i;:::-;-1:-1:-1;;;;;542:58:33;;;411:196;-1:-1:-1;;;411:196:33:o;4783:98:34:-;1094:13:13;:11;:13::i;:::-;4856:7:34::1;:18;4866:8:::0;4856:7;:18:::1;:::i;:::-;;4783:98:::0;:::o;628:471:32:-;1094:13:13;:11;:13::i;:::-;-1:-1:-1;;;;;724:26:32;::::1;720:60;;759:21;;-1:-1:-1::0;;;759:21:32::1;;;;;;;;;;;720:60;858:39;::::0;-1:-1:-1;;;858:39:32;;882:4:::1;858:39;::::0;::::1;4429:51:35::0;4496:18;;;4489:34;;;817:12:32;;791:14:::1;::::0;-1:-1:-1;;;;;858:15:32;::::1;::::0;::::1;::::0;4402:18:35;;858:39:32::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;840:57;;911:7;922:1;911:12:::0;907:43:::1;;932:18;;-1:-1:-1::0;;;932:18:32::1;;;;;;;;;;;907:43;961:5;-1:-1:-1::0;;;;;961:22:32::1;;992:4;999:7;1273:6:13::0;;-1:-1:-1;;;;;1273:6:13;;1201:85;999:7:32::1;961:68;::::0;-1:-1:-1;;;;;;961:68:32::1;::::0;;;;;;-1:-1:-1;;;;;18308:15:35;;;961:68:32::1;::::0;::::1;18290:34:35::0;18360:15;;18340:18;;;18333:43;18392:18;;;18385:34;;;18435:18;;;18428:34;;;18270:3;18478:19;;;18471:32;-1:-1:-1;18519:19:35;;;18512:30;18559:19;;961:68:32::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1075:7;1061:12;-1:-1:-1::0;;;;;1044:48:32::1;;1084:7;1044:48;;;;7881:25:35::0;;7869:2;7854:18;;7735:177;1044:48:32::1;;;;;;;;710:389;;628:471:::0;;:::o;2190:219:20:-;2262:7;6930:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6930:16:20;;2324:56;;;;-1:-1:-1;;;2324:56:20;;18791:2:35;2324:56:20;;;18773:21:35;18830:2;18810:18;;;18803:30;-1:-1:-1;;;18849:18:35;;;18842:54;18913:18;;2324:56:20;18589:348:35;3807:470:34;4027:7;4110:5;4133:9;;4160:23;4201:21;4240:6;4076:184;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4053:217;;;;;;4046:224;;3807:470;;;;;;;;:::o;435:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4283:91::-;1094:13:13;:11;:13::i;:::-;4348:19:34::1;4359:7;4348:10;:19::i;:::-;4283:91:::0;:::o;1929:204:20:-;2001:7;-1:-1:-1;;;;;2028:19:20;;2020:73;;;;-1:-1:-1;;;2020:73:20;;20111:2:35;2020:73:20;;;20093:21:35;20150:2;20130:18;;;20123:30;20189:34;20169:18;;;20162:62;-1:-1:-1;;;20240:18:35;;;20233:39;20289:19;;2020:73:20;19909:405:35;2020:73:20;-1:-1:-1;;;;;;2110:16:20;;;;;:9;:16;;;;;;;1929:204::o;1831:101:13:-;1094:13;:11;:13::i;:::-;1895:30:::1;1922:1;1895:18;:30::i;:::-;1831:101::o:0;4380:107:34:-;1094:13:13;:11;:13::i;:::-;4452::34::1;:28:::0;;-1:-1:-1;;4452:28:34::1;::::0;::::1;;::::0;;;::::1;::::0;;4380:107::o;1503:450:32:-;1094:13:13;:11;:13::i;:::-;-1:-1:-1;;;;;1598:26:32;::::1;1594:60;;1633:21;;-1:-1:-1::0;;;1633:21:32::1;;;;;;;;;;;1594:60;1735:22;::::0;-1:-1:-1;;;1735:22:32;;::::1;::::0;::::1;7881:25:35::0;;;1689:12:32;;1665:13:::1;::::0;-1:-1:-1;;;;;1735:13:32;::::1;::::0;::::1;::::0;7854:18:35;;1735:22:32::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1712:45:::0;-1:-1:-1;;;;;;1771:29:32;::::1;1795:4;1771:29;1767:60;;1809:18;;-1:-1:-1::0;;;1809:18:32::1;;;;;;;;;;;1767:60;1838:5;-1:-1:-1::0;;;;;1838:22:32::1;;1869:4;1876:7;1273:6:13::0;;-1:-1:-1;;;;;1273:6:13;;1201:85;1876:7:32::1;1838:55;::::0;-1:-1:-1;;;;;;1838:55:32::1;::::0;;;;;;-1:-1:-1;;;;;20833:15:35;;;1838:55:32::1;::::0;::::1;20815:34:35::0;20885:15;;20865:18;;;20858:43;20917:18;;;20910:34;;;20750:18;;1838:55:32::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;1908:38:32::1;::::0;1938:7;;-1:-1:-1;;;;;;1908:38:32;::::1;::::0;-1:-1:-1;1908:38:32::1;::::0;;;::::1;1584:369;;1503:450:::0;;:::o;1516:853:34:-;1608:13;;;;;;;1603:43;;1630:16;;-1:-1:-1;;;1630:16:34;;;;;;;;;;;1603:43;1679:1;1660:7;;;;:4;:7;:::i;:::-;-1:-1:-1;;;;;1660:21:34;;1656:52;;1690:18;;-1:-1:-1;;;1690:18:34;;;;;;;;;;;1656:52;1743:1;1722:9;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1722:23:34;;:52;;;-1:-1:-1;719:10:26;1749:9:34;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1749:25:34;;;1722:52;1718:80;;;1783:15;;-1:-1:-1;;;1783:15:34;;;;;;;;;;;1718:80;1826:10;;;;672:4:33;696:14;;;:6;:14;;;;;;;;695:15;1808:56:34;;1846:18;;-1:-1:-1;;;1846:18:34;;;;;;;;;;;1808:56;1879:67;1891:27;;;;;;;;:::i;:::-;1920:25;;;;;;;;:::i;1879:67::-;1874:97;;1955:16;;-1:-1:-1;;;1955:16:34;;;;;;;;;;;1874:97;1982:28;1999:4;:10;;;944:14:33;;;;:6;:14;;;;;:21;;-1:-1:-1;;944:21:33;961:4;944:21;;;883:89;1982:28:34;2021:15;2039:121;2058:7;;;;:4;:7;:::i;:::-;2067:9;;;;;;;;:::i;:::-;2078:13;;;;:4;:13;:::i;:::-;2093:27;;;;;;;;:::i;:::-;2122:25;;;;;;;;:::i;:::-;2149:4;:10;;;2039:18;:121::i;:::-;2021:139;;2175:38;2193:7;2202:10;;2175:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2175:17:34;;-1:-1:-1;;;2175:38:34:i;:::-;2170:70;;2222:18;;-1:-1:-1;;;2222:18:34;;;;;;;;;;;2170:70;2256:9;2251:112;2275:13;;;;:4;:13;:::i;:::-;:20;;2271:1;:24;2251:112;;;2316:36;2326:7;;;;:4;:7;:::i;:::-;2335:13;;;;:4;:13;:::i;:::-;2349:1;2335:16;;;;;;;:::i;:::-;;;;;;;2316:9;:36::i;:::-;2297:3;;;;:::i;:::-;;;;2251:112;;445:110:8;501:13;533:15;526:22;;;;;:::i;1139:253:9:-;1230:31;:29;:31::i;:::-;1271:33;:47;;;;;-1:-1:-1;;;1271:47:9;-1:-1:-1;;;;1271:47:9;;;;;;1333:52;;;;;;1307:11;773:14:35;766:22;748:41;;736:2;721:18;;608:187;1333:52:9;;;;;;;;1139:253;:::o;1105:392:32:-;1094:13:13;:11;:13::i;:::-;-1:-1:-1;;;;;1182:26:32;::::1;1178:60;;1217:21;;-1:-1:-1::0;;;1217:21:32::1;;;;;;;;;;;1178:60;1312:30;::::0;-1:-1:-1;;;1312:30:32;;1336:4:::1;1312:30;::::0;::::1;160:51:35::0;1271:12:32;;1249::::1;::::0;-1:-1:-1;;;;;1312:15:32;::::1;::::0;::::1;::::0;133:18:35;;1312:30:32::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1294:48;;1356:7;1367:1;1356:12:::0;1352:43:::1;;1377:18;;-1:-1:-1::0;;;1377:18:32::1;;;;;;;;;;;1352:43;1406:5;-1:-1:-1::0;;;;;1406:14:32::1;;1421:7;1273:6:13::0;;-1:-1:-1;;;;;1273:6:13;;1201:85;1421:7:32::1;1406:32;::::0;-1:-1:-1;;;;;;1406:32:32::1;::::0;;;;;;-1:-1:-1;;;;;4447:32:35;;;1406::32::1;::::0;::::1;4429:51:35::0;4496:18;;;4489:34;;;4402:18;;1406:32:32::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;1468:12;-1:-1:-1::0;;;;;1453:37:32::1;;1482:7;1453:37;;;;7881:25:35::0;;7869:2;7854:18;;7735:177;1453:37:32::1;;;;;;;;1168:329;;1105:392:::0;:::o;723:154:33:-;795:4;828:15;818:6;-1:-1:-1;;;;;818:25:33;;;:52;;;;;855:15;847:4;-1:-1:-1;;;;;847:23:33;;;818:52;811:59;723:154;-1:-1:-1;;;723:154:33:o;4169:153:20:-;4263:52;719:10:26;4296:8:20;4306;4263:18;:52::i;3268:580:10:-;3343:31;:29;:31::i;:::-;-1:-1:-1;;;;;3417:30:10;;;;:34;;;3465:32;;;;:61;;;3502:24;3501:25;3465:61;3462:150;;;3549:52;;-1:-1:-1;;;3549:52:10;;;;;;;;;;;3462:150;3627:77;3660:22;:20;:22::i;:::-;3627:77;;;-1:-1:-1;;;;;21435:15:35;;;21417:34;;21487:15;;;21482:2;21467:18;;21460:43;21352:18;3627:77:10;;;;;;;3715:22;:29;;-1:-1:-1;;;;3715:29:10;-1:-1:-1;;;3715:29:10;;;3754:17;:38;;-1:-1:-1;;;;;3754:38:10;;-1:-1:-1;;;;;;3754:38:10;;;;;;3803;3774:18;3803;:38::i;5249:314:20:-;5417:41;719:10:26;5450:7:20;5417:18;:41::i;:::-;5409:99;;;;-1:-1:-1;;;5409:99:20;;;;;;;:::i;:::-;5518:38;5532:4;5538:2;5542:7;5551:4;5518:13;:38::i;:::-;5249:314;;;;:::o;2801:276::-;2874:13;2899:23;2914:7;2899:14;:23::i;:::-;2933:21;2957:10;:8;:10::i;:::-;2933:34;;3008:1;2990:7;2984:21;:25;:86;;;;;;;;;;;;;;;;;3036:7;3045:18;:7;:16;:18::i;:::-;3019:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2977:93;2801:276;-1:-1:-1;;;2801:276:20:o;1053:362:2:-;-1:-1:-1;;;;;4508:25:20;;;1150:15:2;4508:25:20;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;1240:169:2;;1275:33;;-1:-1:-1;;;1275:33:2;;;;1271:128;;;1361:22;:20;:22::i;:::-;-1:-1:-1;;;;;1341:43:2;:8;-1:-1:-1;;;;;1341:43:2;;1328:56;;1053:362;;;;:::o;2081:198:13:-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2169:22:13;::::1;2161:73;;;::::0;-1:-1:-1;;;2161:73:13;;22217:2:35;2161:73:13::1;::::0;::::1;22199:21:35::0;22256:2;22236:18;;;22229:30;22295:34;22275:18;;;22268:62;-1:-1:-1;;;22346:18:35;;;22339:36;22392:19;;2161:73:13::1;22015:402:35::0;2161:73:13::1;2244:28;2263:8;2244:18;:28::i;4493:107:34:-:0;1094:13:13;:11;:13::i;:::-;4565::34::1;:28:::0;;;::::1;;;;-1:-1:-1::0;;4565:28:34;;::::1;::::0;;;::::1;::::0;;4493:107::o;3289:512::-;3530:7;3613:3;3634:5;3657:9;;3684:23;3725:21;3764:6;3579:205;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3556:238;;;;;;3549:245;;3289:512;;;;;;;;;:::o;1408:213:24:-;1510:4;-1:-1:-1;;;;;;1533:41:24;;-1:-1:-1;;;1533:41:24;;:81;;;1578:36;1602:11;1578:23;:36::i;7540:261:20:-;7633:4;7649:13;7665:23;7680:7;7665:14;:23::i;:::-;7649:39;;7717:5;-1:-1:-1;;;;;7706:16:20;:7;-1:-1:-1;;;;;7706:16:20;;:52;;;;7726:32;7743:5;7750:7;7726:16;:32::i;:::-;7706:87;;;;7786:7;-1:-1:-1;;;;;7762:31:20;:20;7774:7;7762:11;:20::i;:::-;-1:-1:-1;;;;;7762:31:20;;7706:87;7698:96;7540:261;-1:-1:-1;;;;7540:261:20:o;10337:762::-;10396:13;10412:23;10427:7;10412:14;:23::i;:::-;10396:39;;10446:51;10467:5;10482:1;10486:7;10495:1;10446:20;:51::i;:::-;10607:23;10622:7;10607:14;:23::i;:::-;10675:24;;;;:15;:24;;;;;;;;10668:31;;-1:-1:-1;;;;;;10668:31:20;;;;;;-1:-1:-1;;;;;10915:16:20;;;;;:9;:16;;;;;:21;;-1:-1:-1;;10915:21:20;;;10963:16;;;:7;:16;;;;;;10956:23;;;;;;;10995:36;10599:31;;-1:-1:-1;10691:7:20;;10995:36;;10675:24;;10995:36;11042:50;11062:5;11077:1;11081:7;11090:1;11042:19;:50::i;13466:133::-;7321:4;6930:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6930:16:20;13539:53;;;;-1:-1:-1;;;13539:53:20;;18791:2:35;13539:53:20;;;18773:21:35;18830:2;18810:18;;;18803:30;-1:-1:-1;;;18849:18:35;;;18842:54;18913:18;;13539:53:20;18589:348:35;12768:171:20;12842:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;12842:29:20;-1:-1:-1;;;;;12842:29:20;;;;;;;;:24;;12895:23;12842:24;12895:14;:23::i;:::-;-1:-1:-1;;;;;12886:46:20;;;;;;;;;;;12768:171;;:::o;11423:1233::-;11577:4;-1:-1:-1;;;;;11550:31:20;:23;11565:7;11550:14;:23::i;:::-;-1:-1:-1;;;;;11550:31:20;;11542:81;;;;-1:-1:-1;;;11542:81:20;;;;;;;:::i;:::-;-1:-1:-1;;;;;11641:16:20;;11633:65;;;;-1:-1:-1;;;11633:65:20;;23835:2:35;11633:65:20;;;23817:21:35;23874:2;23854:18;;;23847:30;23913:34;23893:18;;;23886:62;-1:-1:-1;;;23964:18:35;;;23957:34;24008:19;;11633:65:20;23633:400:35;11633:65:20;11709:42;11730:4;11736:2;11740:7;11749:1;11709:20;:42::i;:::-;11878:4;-1:-1:-1;;;;;11851:31:20;:23;11866:7;11851:14;:23::i;:::-;-1:-1:-1;;;;;11851:31:20;;11843:81;;;;-1:-1:-1;;;11843:81:20;;;;;;;:::i;:::-;11993:24;;;;:15;:24;;;;;;;;11986:31;;-1:-1:-1;;;;;;11986:31:20;;;;;;-1:-1:-1;;;;;12461:15:20;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;12461:20:20;;;12495:13;;;;;;;;;:18;;11986:31;12495:18;;;12533:16;;;:7;:16;;;;;;:21;;;;;;;;;;12570:27;;12009:7;;12570:27;;;12608:41;12628:4;12634:2;12638:7;12647:1;12608:19;:41::i;3661:227:28:-;3739:7;3759:17;3778:18;3800:27;3811:4;3817:9;3800:10;:27::i;:::-;3758:69;;;;3837:18;3849:5;3837:11;:18::i;:::-;-1:-1:-1;3872:9:28;3661:227;-1:-1:-1;;;3661:227:28:o;1359:130:13:-;1273:6;;-1:-1:-1;;;;;1273:6:13;719:10:26;1422:23:13;1414:68;;;;-1:-1:-1;;;1414:68:13;;24625:2:35;1414:68:13;;;24607:21:35;;;24644:18;;;24637:30;24703:34;24683:18;;;24676:62;24755:18;;1414:68:13;24423:356:35;260:145:33;-1:-1:-1;;;;;324:21:33;;316:56;;;;-1:-1:-1;;;316:56:33;;24986:2:35;316:56:33;;;24968:21:35;25025:2;25005:18;;;24998:30;-1:-1:-1;;;25044:18:35;;;25037:52;25106:18;;316:56:33;24784:346:35;316:56:33;382:6;:16;;-1:-1:-1;;;;;;382:16:33;-1:-1:-1;;;;;382:16:33;;;;;;;;;;260:145::o;2433:187:13:-;2525:6;;;-1:-1:-1;;;;;2541:17:13;;;-1:-1:-1;;;;;;2541:17:13;;;;;;;2573:40;;2525:6;;;2541:17;2525:6;;2573:40;;2506:16;;2573:40;2496:124;2433:187;:::o;8131:108:20:-;8206:26;8216:2;8220:7;8206:26;;;;;;;;;;;;:9;:26::i;215:102:0:-;297:13;:11;:13::i;13075:307:20:-;13225:8;-1:-1:-1;;;;;13216:17:20;:5;-1:-1:-1;;;;;13216:17:20;;13208:55;;;;-1:-1:-1;;;13208:55:20;;25337:2:35;13208:55:20;;;25319:21:35;25376:2;25356:18;;;25349:30;25415:27;25395:18;;;25388:55;25460:18;;13208:55:20;25135:349:35;13208:55:20;-1:-1:-1;;;;;13273:25:20;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13273:46:20;;;;;;;;;;13334:41;;748::35;;;13334::20;;721:18:35;13334:41:20;;;;;;;13075:307;;;:::o;7405:448:10:-;-1:-1:-1;;;;;7475:23:10;;;7471:376;;7601:22;;7653:21;;7650:187;;7698:95;;;-1:-1:-1;;;7698:95:10;;7773:4;7698:95;;;25661:51:35;701:3:12;25728:18:35;;;25721:47;7698:95:10;;-1:-1:-1;;;;;7698:66:10;;;;;25634:18:35;;;;;-1:-1:-1;;7698:95:10;;;;;;;-1:-1:-1;7698:66:10;:95;;;;;;;;;;;;;;;;;;;;;;;;;7694:129;;;7500:347;7405:448;:::o;6424:305:20:-;6574:28;6584:4;6590:2;6594:7;6574:9;:28::i;:::-;6620:47;6643:4;6649:2;6653:7;6662:4;6620:22;:47::i;:::-;6612:110;;;;-1:-1:-1;;;6612:110:20;;;;;;;:::i;4887:98:34:-;4939:13;4971:7;4964:14;;;;;:::i;415:696:27:-;471:13;520:14;537:17;548:5;537:10;:17::i;:::-;557:1;537:21;520:38;;572:20;606:6;-1:-1:-1;;;;;595:18:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;595:18:27;-1:-1:-1;572:41:27;-1:-1:-1;733:28:27;;;749:2;733:28;788:280;-1:-1:-1;;819:5:27;-1:-1:-1;;;953:2:27;942:14;;937:30;819:5;924:44;1012:2;1003:11;;;-1:-1:-1;1032:21:27;788:280;1032:21;-1:-1:-1;1088:6:27;415:696;-1:-1:-1;;;415:696:27:o;1701:284:2:-;1786:4;-1:-1:-1;;;;;;1818:46:2;;-1:-1:-1;;;1818:46:2;;:111;;-1:-1:-1;;;;;;;1877:52:2;;-1:-1:-1;;;1877:52:2;1818:111;:160;;;;1942:36;1966:11;1942:23;:36::i;2519:343::-;2690:9;2685:171;2709:9;2705:1;:13;2685:171;;;2735:51;2759:4;2765:2;2769:16;2784:1;2769:12;:16;:::i;:::-;2735:23;:51::i;:::-;2828:3;;2685:171;;2972:341;3142:9;3137:170;3161:9;3157:1;:13;3137:170;;;3187:50;3210:4;3216:2;3220:16;3235:1;3220:12;:16;:::i;:::-;3187:22;:50::i;:::-;3279:3;;3137:170;;2145:730:28;2226:7;2235:12;2263:9;:16;2283:2;2263:22;2259:610;;2599:4;2584:20;;2578:27;2648:4;2633:20;;2627:27;2705:4;2690:20;;2684:27;2301:9;2676:36;2746:25;2757:4;2676:36;2578:27;2627;2746:10;:25::i;:::-;2739:32;;;;;;;;;2259:610;-1:-1:-1;2818:1:28;;-1:-1:-1;2822:35:28;2802:56;;570:511;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:28;;26662:2:35;788:34:28;;;26644:21:35;26701:2;26681:18;;;26674:30;26740:26;26720:18;;;26713:54;26784:18;;788:34:28;26460:348:35;730:345:28;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:28;;27015:2:35;903:41:28;;;26997:21:35;27054:2;27034:18;;;27027:30;27093:33;27073:18;;;27066:61;27144:18;;903:41:28;26813:355:35;839:236:28;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:28;;27375:2:35;1020:44:28;;;27357:21:35;27414:2;27394:18;;;27387:30;27453:34;27433:18;;;27426:62;-1:-1:-1;;;27504:18:35;;;27497:32;27546:19;;1020:44:28;27173:398:35;8460:309:20;8584:18;8590:2;8594:7;8584:5;:18::i;:::-;8633:53;8664:1;8668:2;8672:7;8681:4;8633:22;:53::i;:::-;8612:150;;;;-1:-1:-1;;;8612:150:20;;;;;;;:::i;14151:831::-;14300:4;-1:-1:-1;;;;;14320:13:20;;1465:19:25;:23;14316:660:20;;14355:71;;-1:-1:-1;;;14355:71:20;;-1:-1:-1;;;;;14355:36:20;;;;;:71;;719:10:26;;14406:4:20;;14412:7;;14421:4;;14355:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14355:71:20;;;;;;;;-1:-1:-1;;14355:71:20;;;;;;;;;;;;:::i;:::-;;;14351:573;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14593:6;:13;14610:1;14593:18;14589:321;;14635:60;;-1:-1:-1;;;14635:60:20;;;;;;;:::i;14589:321::-;14862:6;14856:13;14847:6;14843:2;14839:15;14832:38;14351:573;-1:-1:-1;;;;;;14476:51:20;-1:-1:-1;;;14476:51:20;;-1:-1:-1;14469:58:20;;14316:660;-1:-1:-1;14961:4:20;14151:831;;;;;;:::o;9889:890:31:-;9942:7;;-1:-1:-1;;;10017:15:31;;10013:99;;-1:-1:-1;;;10052:15:31;;;-1:-1:-1;10095:2:31;10085:12;10013:99;10138:6;10129:5;:15;10125:99;;10173:6;10164:15;;;-1:-1:-1;10207:2:31;10197:12;10125:99;10250:6;10241:5;:15;10237:99;;10285:6;10276:15;;;-1:-1:-1;10319:2:31;10309:12;10237:99;10362:5;10353;:14;10349:96;;10396:5;10387:14;;;-1:-1:-1;10429:1:31;10419:11;10349:96;10471:5;10462;:14;10458:96;;10505:5;10496:14;;;-1:-1:-1;10538:1:31;10528:11;10458:96;10580:5;10571;:14;10567:96;;10614:5;10605:14;;;-1:-1:-1;10647:1:31;10637:11;10567:96;10689:5;10680;:14;10676:64;;10724:1;10714:11;10766:6;9889:890;-1:-1:-1;;9889:890:31:o;1570:300:20:-;1672:4;-1:-1:-1;;;;;;1707:40:20;;-1:-1:-1;;;1707:40:20;;:104;;-1:-1:-1;;;;;;;1763:48:20;;-1:-1:-1;;;1763:48:20;1707:104;:156;;;-1:-1:-1;;;;;;;;;;937:40:29;;;1827:36:20;829:155:29;1014:610:11;-1:-1:-1;;;;;1140:18:11;;;;;1189:16;;;1140:18;1219:32;;;;;1238:13;1219:32;1216:402;;;1274:28;;-1:-1:-1;;;1274:28:11;;;;;;;;;;;1216:402;1322:15;1319:299;;;1353:54;1319:299;;;1427:13;1456:56;1424:194;1543:64;719:10:26;1578:4:11;1584:2;1588:7;1597:9;1543:20;:64::i;1754:612::-;-1:-1:-1;;;;;1879:18:11;;;;;1928:16;;;1879:18;1958:32;;;;;1977:13;1958:32;1955:405;;;2013:28;;-1:-1:-1;;;2013:28:11;;;;;;;;;;;1955:405;2061:15;2092:55;2058:302;2167:13;2196:57;2164:196;2284:65;4283:91:34:o;5069:1494:28:-;5195:7;;6119:66;6106:79;;6102:161;;;-1:-1:-1;6217:1:28;;-1:-1:-1;6221:30:28;6201:51;;6102:161;6374:24;;;6357:14;6374:24;;;;;;;;;28551:25:35;;;28624:4;28612:17;;28592:18;;;28585:45;;;;28646:18;;;28639:34;;;28689:18;;;28682:34;;;6374:24:28;;28523:19:35;;6374:24:28;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6374:24:28;;-1:-1:-1;;6374:24:28;;;-1:-1:-1;;;;;;;6412:20:28;;6408:101;;6464:1;6468:29;6448:50;;;;;;;6408:101;6527:6;-1:-1:-1;6535:20:28;;-1:-1:-1;5069:1494:28;;;;;;;;:::o;9091:920:20:-;-1:-1:-1;;;;;9170:16:20;;9162:61;;;;-1:-1:-1;;;9162:61:20;;28929:2:35;9162:61:20;;;28911:21:35;;;28948:18;;;28941:30;29007:34;28987:18;;;28980:62;29059:18;;9162:61:20;28727:356:35;9162:61:20;7321:4;6930:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6930:16:20;7344:31;9233:58;;;;-1:-1:-1;;;9233:58:20;;29290:2:35;9233:58:20;;;29272:21:35;29329:2;29309:18;;;29302:30;29368;29348:18;;;29341:58;29416:18;;9233:58:20;29088:352:35;9233:58:20;9302:48;9331:1;9335:2;9339:7;9348:1;9302:20;:48::i;:::-;7321:4;6930:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6930:16:20;7344:31;9437:58;;;;-1:-1:-1;;;9437:58:20;;29290:2:35;9437:58:20;;;29272:21:35;29329:2;29309:18;;;29302:30;29368;29348:18;;;29341:58;29416:18;;9437:58:20;29088:352:35;9437:58:20;-1:-1:-1;;;;;9837:13:20;;;;;;:9;:13;;;;;;;;:18;;9854:1;9837:18;;;9876:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9876:21:20;;;;;9913:33;9884:7;;9837:13;;9913:33;;9837:13;;9913:33;9957:47;9985:1;9989:2;9993:7;10002:1;9957:19;:47::i;5190:457:10:-;5379:17;5399:22;:20;:22::i;:::-;5379:42;-1:-1:-1;;;;;;5436:23:10;;;5432:209;;-1:-1:-1;;;;;5479:23:10;;:10;:23;5475:68;;5522:7;;;5475:68;5557:73;;-1:-1:-1;;;5557:73:10;;-1:-1:-1;;;;;29732:15:35;;;5557:73:10;;;29714:34:35;29784:15;;;29764:18;;;29757:43;29836:15;;;29816:18;;;29809:43;29868:18;;;29861:34;;;5557:46:10;;;;;29648:19:35;;5557:73:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5432:209;5369:278;5190:457;;;;;:::o;222:131:35:-;-1:-1:-1;;;;;;296:32:35;;286:43;;276:71;;343:1;340;333:12;358:245;416:6;469:2;457:9;448:7;444:23;440:32;437:52;;;485:1;482;475:12;437:52;524:9;511:23;543:30;567:5;543:30;:::i;800:347::-;851:8;861:6;915:3;908:4;900:6;896:17;892:27;882:55;;933:1;930;923:12;882:55;-1:-1:-1;956:20:35;;-1:-1:-1;;;;;988:30:35;;985:50;;;1031:1;1028;1021:12;985:50;1068:4;1060:6;1056:17;1044:29;;1120:3;1113:4;1104:6;1096;1092:19;1088:30;1085:39;1082:59;;;1137:1;1134;1127:12;1152:699;1262:6;1270;1278;1331:2;1319:9;1310:7;1306:23;1302:32;1299:52;;;1347:1;1344;1337:12;1299:52;1387:9;1374:23;-1:-1:-1;;;;;1457:2:35;1449:6;1446:14;1443:34;;;1473:1;1470;1463:12;1443:34;1496:22;;;;1552:3;1534:16;;;1530:26;1527:46;;;1569:1;1566;1559:12;1527:46;1592:2;;-1:-1:-1;1647:2:35;1632:18;;1619:32;;1663:16;;;1660:36;;;1692:1;1689;1682:12;1660:36;;1731:60;1783:7;1772:8;1761:9;1757:24;1731:60;:::i;:::-;1152:699;;1810:8;;-1:-1:-1;1705:86:35;;-1:-1:-1;;;;1152:699:35:o;1856:250::-;1941:1;1951:113;1965:6;1962:1;1959:13;1951:113;;;2041:11;;;2035:18;2022:11;;;2015:39;1987:2;1980:10;1951:113;;;-1:-1:-1;;2098:1:35;2080:16;;2073:27;1856:250::o;2111:271::-;2153:3;2191:5;2185:12;2218:6;2213:3;2206:19;2234:76;2303:6;2296:4;2291:3;2287:14;2280:4;2273:5;2269:16;2234:76;:::i;:::-;2364:2;2343:15;-1:-1:-1;;2339:29:35;2330:39;;;;2371:4;2326:50;;2111:271;-1:-1:-1;;2111:271:35:o;2387:220::-;2536:2;2525:9;2518:21;2499:4;2556:45;2597:2;2586:9;2582:18;2574:6;2556:45;:::i;2612:180::-;2671:6;2724:2;2712:9;2703:7;2699:23;2695:32;2692:52;;;2740:1;2737;2730:12;2692:52;-1:-1:-1;2763:23:35;;2612:180;-1:-1:-1;2612:180:35:o;2797:131::-;-1:-1:-1;;;;;2872:31:35;;2862:42;;2852:70;;2918:1;2915;2908:12;2933:315;3001:6;3009;3062:2;3050:9;3041:7;3037:23;3033:32;3030:52;;;3078:1;3075;3068:12;3030:52;3117:9;3104:23;3136:31;3161:5;3136:31;:::i;:::-;3186:5;3238:2;3223:18;;;;3210:32;;-1:-1:-1;;;2933:315:35:o;3541:456::-;3618:6;3626;3634;3687:2;3675:9;3666:7;3662:23;3658:32;3655:52;;;3703:1;3700;3693:12;3655:52;3742:9;3729:23;3761:31;3786:5;3761:31;:::i;:::-;3811:5;-1:-1:-1;3868:2:35;3853:18;;3840:32;3881:33;3840:32;3881:33;:::i;:::-;3541:456;;3933:7;;-1:-1:-1;;;3987:2:35;3972:18;;;;3959:32;;3541:456::o;4002:248::-;4070:6;4078;4131:2;4119:9;4110:7;4106:23;4102:32;4099:52;;;4147:1;4144;4137:12;4099:52;-1:-1:-1;;4170:23:35;;;4240:2;4225:18;;;4212:32;;-1:-1:-1;4002:248:35:o;4534:127::-;4595:10;4590:3;4586:20;4583:1;4576:31;4626:4;4623:1;4616:15;4650:4;4647:1;4640:15;4666:631;4730:5;-1:-1:-1;;;;;4801:2:35;4793:6;4790:14;4787:40;;;4807:18;;:::i;:::-;4882:2;4876:9;4850:2;4936:15;;-1:-1:-1;;4932:24:35;;;4958:2;4928:33;4924:42;4912:55;;;4982:18;;;5002:22;;;4979:46;4976:72;;;5028:18;;:::i;:::-;5068:10;5064:2;5057:22;5097:6;5088:15;;5127:6;5119;5112:22;5167:3;5158:6;5153:3;5149:16;5146:25;5143:45;;;5184:1;5181;5174:12;5143:45;5234:6;5229:3;5222:4;5214:6;5210:17;5197:44;5289:1;5282:4;5273:6;5265;5261:19;5257:30;5250:41;;;;4666:631;;;;;:::o;5302:220::-;5344:5;5397:3;5390:4;5382:6;5378:17;5374:27;5364:55;;5415:1;5412;5405:12;5364:55;5437:79;5512:3;5503:6;5490:20;5483:4;5475:6;5471:17;5437:79;:::i;5527:388::-;5604:6;5612;5665:2;5653:9;5644:7;5640:23;5636:32;5633:52;;;5681:1;5678;5671:12;5633:52;5717:9;5704:23;5694:33;;5778:2;5767:9;5763:18;5750:32;-1:-1:-1;;;;;5797:6:35;5794:30;5791:50;;;5837:1;5834;5827:12;5791:50;5860:49;5901:7;5892:6;5881:9;5877:22;5860:49;:::i;:::-;5850:59;;;5527:388;;;;;:::o;5920:450::-;5989:6;6042:2;6030:9;6021:7;6017:23;6013:32;6010:52;;;6058:1;6055;6048:12;6010:52;6098:9;6085:23;-1:-1:-1;;;;;6123:6:35;6120:30;6117:50;;;6163:1;6160;6153:12;6117:50;6186:22;;6239:4;6231:13;;6227:27;-1:-1:-1;6217:55:35;;6268:1;6265;6258:12;6217:55;6291:73;6356:7;6351:2;6338:16;6333:2;6329;6325:11;6291:73;:::i;6375:367::-;6438:8;6448:6;6502:3;6495:4;6487:6;6483:17;6479:27;6469:55;;6520:1;6517;6510:12;6469:55;-1:-1:-1;6543:20:35;;-1:-1:-1;;;;;6575:30:35;;6572:50;;;6618:1;6615;6608:12;6572:50;6655:4;6647:6;6643:17;6631:29;;6715:3;6708:4;6698:6;6695:1;6691:14;6683:6;6679:27;6675:38;6672:47;6669:67;;;6732:1;6729;6722:12;6747:188;6815:20;;-1:-1:-1;;;;;6864:46:35;;6854:57;;6844:85;;6925:1;6922;6915:12;6844:85;6747:188;;;:::o;6940:790::-;7062:6;7070;7078;7086;7094;7102;7155:3;7143:9;7134:7;7130:23;7126:33;7123:53;;;7172:1;7169;7162:12;7123:53;7211:9;7198:23;7230:31;7255:5;7230:31;:::i;:::-;7280:5;-1:-1:-1;7336:2:35;7321:18;;7308:32;-1:-1:-1;;;;;7352:30:35;;7349:50;;;7395:1;7392;7385:12;7349:50;7434:70;7496:7;7487:6;7476:9;7472:22;7434:70;:::i;:::-;7523:8;;-1:-1:-1;7408:96:35;-1:-1:-1;7577:38:35;;-1:-1:-1;7611:2:35;7596:18;;7577:38;:::i;:::-;7567:48;;7634:38;7668:2;7657:9;7653:18;7634:38;:::i;:::-;7624:48;;7719:3;7708:9;7704:19;7691:33;7681:43;;6940:790;;;;;;;;:::o;7917:247::-;7976:6;8029:2;8017:9;8008:7;8004:23;8000:32;7997:52;;;8045:1;8042;8035:12;7997:52;8084:9;8071:23;8103:31;8128:5;8103:31;:::i;8351:118::-;8437:5;8430:13;8423:21;8416:5;8413:32;8403:60;;8459:1;8456;8449:12;8474:241;8530:6;8583:2;8571:9;8562:7;8558:23;8554:32;8551:52;;;8599:1;8596;8589:12;8551:52;8638:9;8625:23;8657:28;8679:5;8657:28;:::i;8720:699::-;8830:6;8838;8846;8899:2;8887:9;8878:7;8874:23;8870:32;8867:52;;;8915:1;8912;8905:12;8867:52;8955:9;8942:23;-1:-1:-1;;;;;9025:2:35;9017:6;9014:14;9011:34;;;9041:1;9038;9031:12;9011:34;9064:22;;;;9120:3;9102:16;;;9098:26;9095:46;;;9137:1;9134;9127:12;9609:260;9677:6;9685;9738:2;9726:9;9717:7;9713:23;9709:32;9706:52;;;9754:1;9751;9744:12;9706:52;9777:29;9796:9;9777:29;:::i;:::-;9767:39;;9825:38;9859:2;9848:9;9844:18;9825:38;:::i;:::-;9815:48;;9609:260;;;;;:::o;9874:382::-;9939:6;9947;10000:2;9988:9;9979:7;9975:23;9971:32;9968:52;;;10016:1;10013;10006:12;9968:52;10055:9;10042:23;10074:31;10099:5;10074:31;:::i;:::-;10124:5;-1:-1:-1;10181:2:35;10166:18;;10153:32;10194:30;10153:32;10194:30;:::i;:::-;10243:7;10233:17;;;9874:382;;;;;:::o;10261:665::-;10356:6;10364;10372;10380;10433:3;10421:9;10412:7;10408:23;10404:33;10401:53;;;10450:1;10447;10440:12;10401:53;10489:9;10476:23;10508:31;10533:5;10508:31;:::i;:::-;10558:5;-1:-1:-1;10615:2:35;10600:18;;10587:32;10628:33;10587:32;10628:33;:::i;:::-;10680:7;-1:-1:-1;10734:2:35;10719:18;;10706:32;;-1:-1:-1;10789:2:35;10774:18;;10761:32;-1:-1:-1;;;;;10805:30:35;;10802:50;;;10848:1;10845;10838:12;10802:50;10871:49;10912:7;10903:6;10892:9;10888:22;10871:49;:::i;:::-;10861:59;;;10261:665;;;;;;;:::o;10931:388::-;10999:6;11007;11060:2;11048:9;11039:7;11035:23;11031:32;11028:52;;;11076:1;11073;11066:12;11028:52;11115:9;11102:23;11134:31;11159:5;11134:31;:::i;:::-;11184:5;-1:-1:-1;11241:2:35;11226:18;;11213:32;11254:33;11213:32;11254:33;:::i;11324:932::-;11455:6;11463;11471;11479;11487;11495;11503;11556:3;11544:9;11535:7;11531:23;11527:33;11524:53;;;11573:1;11570;11563:12;11524:53;11612:9;11599:23;11631:31;11656:5;11631:31;:::i;:::-;11681:5;-1:-1:-1;11738:2:35;11723:18;;11710:32;11751:33;11710:32;11751:33;:::i;:::-;11803:7;-1:-1:-1;11861:2:35;11846:18;;11833:32;-1:-1:-1;;;;;11877:30:35;;11874:50;;;11920:1;11917;11910:12;11874:50;11959:70;12021:7;12012:6;12001:9;11997:22;11959:70;:::i;:::-;12048:8;;-1:-1:-1;11933:96:35;-1:-1:-1;12102:38:35;;-1:-1:-1;12136:2:35;12121:18;;12102:38;:::i;:::-;12092:48;;12159:39;12193:3;12182:9;12178:19;12159:39;:::i;:::-;12149:49;;12245:3;12234:9;12230:19;12217:33;12207:43;;11324:932;;;;;;;;;;:::o;12261:186::-;12320:6;12373:2;12361:9;12352:7;12348:23;12344:32;12341:52;;;12389:1;12386;12379:12;12341:52;12412:29;12431:9;12412:29;:::i;12452:545::-;12545:4;12551:6;12611:11;12598:25;12705:2;12701:7;12690:8;12674:14;12670:29;12666:43;12646:18;12642:68;12632:96;;12724:1;12721;12714:12;12632:96;12751:33;;12803:20;;;-1:-1:-1;;;;;;12835:30:35;;12832:50;;;12878:1;12875;12868:12;12832:50;12911:4;12899:17;;-1:-1:-1;12962:1:35;12958:14;;;12942;12938:35;12928:46;;12925:66;;;12987:1;12984;12977:12;13002:127;13063:10;13058:3;13054:20;13051:1;13044:31;13094:4;13091:1;13084:15;13118:4;13115:1;13108:15;13134:127;13195:10;13190:3;13186:20;13183:1;13176:31;13226:4;13223:1;13216:15;13250:4;13247:1;13240:15;13266:135;13305:3;13326:17;;;13323:43;;13346:18;;:::i;:::-;-1:-1:-1;13393:1:35;13382:13;;13266:135::o;13406:380::-;13485:1;13481:12;;;;13528;;;13549:61;;13603:4;13595:6;13591:17;13581:27;;13549:61;13656:2;13648:6;13645:14;13625:18;13622:38;13619:161;;13702:10;13697:3;13693:20;13690:1;13683:31;13737:4;13734:1;13727:15;13765:4;13762:1;13755:15;13619:161;;13406:380;;;:::o;14623:409::-;14825:2;14807:21;;;14864:2;14844:18;;;14837:30;14903:34;14898:2;14883:18;;14876:62;-1:-1:-1;;;14969:2:35;14954:18;;14947:43;15022:3;15007:19;;14623:409::o;15037:168::-;15110:9;;;15141;;15158:15;;;15152:22;;15138:37;15128:71;;15179:18;;:::i;15342:217::-;15382:1;15408;15398:132;;15452:10;15447:3;15443:20;15440:1;15433:31;15487:4;15484:1;15477:15;15515:4;15512:1;15505:15;15398:132;-1:-1:-1;15544:9:35;;15342:217::o;15690:545::-;15792:2;15787:3;15784:11;15781:448;;;15828:1;15853:5;15849:2;15842:17;15898:4;15894:2;15884:19;15968:2;15956:10;15952:19;15949:1;15945:27;15939:4;15935:38;16004:4;15992:10;15989:20;15986:47;;;-1:-1:-1;16027:4:35;15986:47;16082:2;16077:3;16073:12;16070:1;16066:20;16060:4;16056:31;16046:41;;16137:82;16155:2;16148:5;16145:13;16137:82;;;16200:17;;;16181:1;16170:13;16137:82;;16411:1352;16537:3;16531:10;-1:-1:-1;;;;;16556:6:35;16553:30;16550:56;;;16586:18;;:::i;:::-;16615:97;16705:6;16665:38;16697:4;16691:11;16665:38;:::i;:::-;16659:4;16615:97;:::i;:::-;16767:4;;16831:2;16820:14;;16848:1;16843:663;;;;17550:1;17567:6;17564:89;;;-1:-1:-1;17619:19:35;;;17613:26;17564:89;-1:-1:-1;;16368:1:35;16364:11;;;16360:24;16356:29;16346:40;16392:1;16388:11;;;16343:57;17666:81;;16813:944;;16843:663;15637:1;15630:14;;;15674:4;15661:18;;-1:-1:-1;;16879:20:35;;;16997:236;17011:7;17008:1;17005:14;16997:236;;;17100:19;;;17094:26;17079:42;;17192:27;;;;17160:1;17148:14;;;;17027:19;;16997:236;;;17001:3;17261:6;17252:7;17249:19;17246:201;;;17322:19;;;17316:26;-1:-1:-1;;17405:1:35;17401:14;;;17417:3;17397:24;17393:37;17389:42;17374:58;17359:74;;17246:201;-1:-1:-1;;;;;17493:1:35;17477:14;;;17473:22;17460:36;;-1:-1:-1;16411:1352:35:o;17768:184::-;17838:6;17891:2;17879:9;17870:7;17866:23;17862:32;17859:52;;;17907:1;17904;17897:12;17859:52;-1:-1:-1;17930:16:35;;17768:184;-1:-1:-1;17768:184:35:o;18942:261::-;19012:3;-1:-1:-1;;;;;19033:31:35;;19030:51;;;19077:1;19074;19067:12;19030:51;19113:6;19110:1;19106:14;19154:8;19147:5;19142:3;19129:34;19179:18;;;;;18942:261;-1:-1:-1;;;18942:261:35:o;19208:696::-;-1:-1:-1;;;;;19542:31:35;19533:6;19529:2;19525:15;19521:53;19516:3;19509:66;19491:3;19597:67;19660:2;19655:3;19651:12;19643:6;19635;19597:67;:::i;:::-;-1:-1:-1;;;;;;19753:3:35;19749:16;;;19745:25;;19731:40;;19807:16;;;;19803:25;;;19798:2;19787:14;;19780:49;-1:-1:-1;19856:2:35;19845:14;;19838:30;-1:-1:-1;19895:2:35;19884:14;;;-1:-1:-1;;;19208:696:35:o;20319:251::-;20389:6;20442:2;20430:9;20421:7;20417:23;20413:32;20410:52;;;20458:1;20455;20448:12;20410:52;20490:9;20484:16;20509:31;20534:5;20509:31;:::i;20955:245::-;21022:6;21075:2;21063:9;21054:7;21050:23;21046:32;21043:52;;;21091:1;21088;21081:12;21043:52;21123:9;21117:16;21142:28;21164:5;21142:28;:::i;21514:496::-;21693:3;21731:6;21725:13;21747:66;21806:6;21801:3;21794:4;21786:6;21782:17;21747:66;:::i;:::-;21876:13;;21835:16;;;;21898:70;21876:13;21835:16;21945:4;21933:17;;21898:70;:::i;:::-;21984:20;;21514:496;-1:-1:-1;;;;21514:496:35:o;22422:800::-;22733:3;-1:-1:-1;;;;;22761:31:35;22834:2;22825:6;22821:2;22817:15;22813:24;22808:3;22801:37;22889:2;22880:6;22876:2;22872:15;22868:24;22863:2;22858:3;22854:12;22847:46;;22915:67;22978:2;22973:3;22969:12;22961:6;22953;22915:67;:::i;:::-;-1:-1:-1;;;;;;23071:3:35;23067:16;;;23063:25;;23049:40;;23125:16;;;;23121:25;;;23116:2;23105:14;;23098:49;-1:-1:-1;23174:2:35;23163:14;;23156:30;-1:-1:-1;23213:2:35;23202:14;;;-1:-1:-1;;;;22422:800:35:o;23227:401::-;23429:2;23411:21;;;23468:2;23448:18;;;23441:30;23507:34;23502:2;23487:18;;23480:62;-1:-1:-1;;;23573:2:35;23558:18;;23551:35;23618:3;23603:19;;23227:401::o;25779:414::-;25981:2;25963:21;;;26020:2;26000:18;;;25993:30;26059:34;26054:2;26039:18;;26032:62;-1:-1:-1;;;26125:2:35;26110:18;;26103:48;26183:3;26168:19;;25779:414::o;26198:125::-;26263:9;;;26284:10;;;26281:36;;;26297:18;;:::i;26328:127::-;26389:10;26384:3;26380:20;26377:1;26370:31;26420:4;26417:1;26410:15;26444:4;26441:1;26434:15;27576:489;-1:-1:-1;;;;;27845:15:35;;;27827:34;;27897:15;;27892:2;27877:18;;27870:43;27944:2;27929:18;;27922:34;;;27992:3;27987:2;27972:18;;27965:31;;;27770:4;;28013:46;;28039:19;;28031:6;28013:46;:::i;:::-;28005:54;27576:489;-1:-1:-1;;;;;;27576:489:35:o;28070:249::-;28139:6;28192:2;28180:9;28171:7;28167:23;28163:32;28160:52;;;28208:1;28205;28198:12;28160:52;28240:9;28234:16;28259:30;28283:5;28259:30;:::i
Swarm Source
ipfs://c7bd7662a591e7e581f770adcf44ee4db2168c5fd14c8ff51767ae9c2d1c07f5
[ 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.