ETH Price: $2,520.10 (-0.17%)

Contract

0x4571246C26F062DCCfFdfc9bd9Faf6f6eec8D083
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040178699032023-08-08 11:27:23388 days ago1691494043IN
 Create: Subscription
0 ETH0.0332980424.73123941

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Subscription

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : Subscription.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {ISubscription} from "./interfaces/ISubscription.sol";
import {ERC5643} from "./abstracts/ERC5643.sol";

contract Subscription is ISubscription, ERC5643 {
    /*//////////////////////////////////////////////////////////////
                             PRIVATE STORAGE
    //////////////////////////////////////////////////////////////*/

    /// @notice A boolean value indicating whether the subscription can be renewed
    bool private _renewable = true;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    /// @param cre8orsNFT_ The address of the cre8orsNFT contract.
    /// @param minRenewalDuration_ The minimum duration allowed for subscription renewal, can be zero.
    /// @param pricePerSecond_ The price per second for the subscription, can be zero.
    constructor(address cre8orsNFT_, uint64 minRenewalDuration_, uint256 pricePerSecond_)
        ERC5643(cre8orsNFT_, minRenewalDuration_, pricePerSecond_)
    {}

    /*//////////////////////////////////////////////////////////////
                     USER-FACING CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc ISubscription
    function checkSubscription(uint256 tokenId) external view override {
        bool isValid = isSubscriptionValid(tokenId);

        if (!isValid) {
            revert InvalidSubscription();
        }
    }

    /// @inheritdoc ISubscription
    function isSubscriptionValid(uint256 tokenId) public view override returns (bool) {
        return expiresAt(tokenId) > block.timestamp;
    }

    /*//////////////////////////////////////////////////////////////
                    ONLY-ADMIN NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Sets the renewability status of subscriptions.
    /// @dev This function can only be called by the admin.
    /// @param renewable Boolean flag to indicate if subscriptions are renewable.
    function setRenewable(address target, bool renewable) external onlyAdmin(target) {
        _renewable = renewable;
        emit RenewableUpdate(renewable);
    }

    /// @notice Sets the minimum duration for subscription renewal.
    /// @dev This function can only be called by the admin.
    /// @param duration The minimum duration (in seconds) for subscription renewal.
    function setMinRenewalDuration(address target, uint64 duration) external onlyAdmin(target) {
        _setMinimumRenewalDuration(duration);
        emit MinRenewalDurationUpdate(duration);
    }

    /// @notice Sets the maximum duration for subscription renewal.
    /// @dev This function can only be called by the admin.
    /// @param duration The maximum duration (in seconds) for subscription renewal.
    function setMaxRenewalDuration(address target, uint64 duration) external onlyAdmin(target) {
        _setMaximumRenewalDuration(duration);
        emit MaxRenewalDurationUpdate(duration);
    }

    /*//////////////////////////////////////////////////////////////
               ONLY-ADMIN-OR-MINTER NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /*//////////   updateSubscriptionForFree variants   //////////*/

    /// @inheritdoc ISubscription
    function updateSubscriptionForFree(address target, uint64 duration, uint256 tokenId)
        external
        override
        onlyRoleOrAdmin(target, MINTER_ROLE)
        isDurationBetweenMinAndMax(duration)
    {
        _updateSubscriptionExpiration(tokenId, duration);
    }

    /// @inheritdoc ISubscription
    function updateSubscriptionForFree(address target, uint64 duration, uint256[] calldata tokenIds)
        external
        override
        onlyRoleOrAdmin(target, MINTER_ROLE)
        isDurationBetweenMinAndMax(duration)
    {
        uint256 tokenId;

        for (uint256 i = 0; i < tokenIds.length;) {
            tokenId = tokenIds[i];

            _updateSubscriptionExpiration(tokenId, duration);

            unchecked {
                ++i;
            }
        }
    }

    /*//////////////   updateSubscription variants   /////////////*/

    /// @inheritdoc ISubscription
    function updateSubscription(address target, uint64 duration, uint256 tokenId)
        external
        payable
        override
        onlyRoleOrAdmin(target, MINTER_ROLE)
        isDurationBetweenMinAndMax(duration)
        isRenewalPriceValid(msg.value, duration)
    {
        // extend subscription
        _updateSubscriptionExpiration(tokenId, duration);
    }

    /// @inheritdoc ISubscription
    /// @dev No need to check for `tokenIds.length` as `isRenewalPriceValid` checks duration to not be zero.
    function updateSubscription(address target, uint64 duration, uint256[] calldata tokenIds)
        external
        payable
        override
        onlyRoleOrAdmin(target, MINTER_ROLE)
        isDurationBetweenMinAndMax(duration)
        isRenewalPriceValid(msg.value, uint64(tokenIds.length * duration))
    {
        uint256 tokenId;

        for (uint256 i = 0; i < tokenIds.length;) {
            tokenId = tokenIds[i];

            _updateSubscriptionExpiration(tokenId, duration);

            unchecked {
                ++i;
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                       INTERNAL CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc ERC5643
    function _isRenewable() internal view override returns (bool) {
        return _renewable;
    }

    /// @inheritdoc ERC5643
    function _getRenewalPrice(uint64 duration) internal view override returns (uint256) {
        return duration * pricePerSecond;
    }
}

File 2 of 13 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 3 of 13 : IERC721.sol
// 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);
}

File 4 of 13 : IERC165.sol
// 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);
}

File 5 of 13 : IERC721Drop.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {IMetadataRenderer} from "../interfaces/IMetadataRenderer.sol";

/**
 ██████╗██████╗ ███████╗ █████╗  ██████╗ ██████╗ ███████╗
██╔════╝██╔══██╗██╔════╝██╔══██╗██╔═══██╗██╔══██╗██╔════╝
██║     ██████╔╝█████╗  ╚█████╔╝██║   ██║██████╔╝███████╗
██║     ██╔══██╗██╔══╝  ██╔══██╗██║   ██║██╔══██╗╚════██║
╚██████╗██║  ██║███████╗╚█████╔╝╚██████╔╝██║  ██║███████║
 ╚═════╝╚═╝  ╚═╝╚══════╝ ╚════╝  ╚═════╝ ╚═╝  ╚═╝╚══════╝                                                       
*/
/// @notice Interface for Cre8ors Drop contract
interface IERC721Drop {
    // Access errors

    /// @notice Only admin can access this function
    error Access_OnlyAdmin();
    /// @notice Missing the given role or admin access
    error Access_MissingRoleOrAdmin(bytes32 role);
    /// @notice Withdraw is not allowed by this user
    error Access_WithdrawNotAllowed();
    /// @notice Cannot withdraw funds due to ETH send failure.
    error Withdraw_FundsSendFailure();
    /// @notice Missing the owner role.
    error Access_OnlyOwner();
    /// @notice Missing the owner role or approved nft access.
    error Access_MissingOwnerOrApproved();

    // Sale/Purchase errors
    /// @notice Sale is inactive
    error Sale_Inactive();
    /// @notice Presale is inactive
    error Presale_Inactive();
    /// @notice Presale merkle root is invalid
    error Presale_MerkleNotApproved();
    /// @notice Wrong price for purchase
    error Purchase_WrongPrice(uint256 correctPrice);
    /// @notice NFT sold out
    error Mint_SoldOut();
    /// @notice Too many purchase for address
    error Purchase_TooManyForAddress();
    /// @notice Too many presale for address
    error Presale_TooManyForAddress();

    // Admin errors
    /// @notice Royalty percentage too high
    error Setup_RoyaltyPercentageTooHigh(uint16 maxRoyaltyBPS);
    /// @notice Invalid admin upgrade address
    error Admin_InvalidUpgradeAddress(address proposedAddress);
    /// @notice Unable to finalize an edition not marked as open (size set to uint64_max_value)
    error Admin_UnableToFinalizeNotOpenEdition();

    /// @notice Event emitted for each sale
    /// @param to address sale was made to
    /// @param quantity quantity of the minted nfts
    /// @param pricePerToken price for each token
    /// @param firstPurchasedTokenId first purchased token ID (to get range add to quantity for max)
    event Sale(
        address indexed to,
        uint256 indexed quantity,
        uint256 indexed pricePerToken,
        uint256 firstPurchasedTokenId
    );

    /// @notice Sales configuration has been changed
    /// @dev To access new sales configuration, use getter function.
    /// @param changedBy Changed by user
    event SalesConfigChanged(address indexed changedBy);

    /// @notice Event emitted when the funds recipient is changed
    /// @param newAddress new address for the funds recipient
    /// @param changedBy address that the recipient is changed by
    event FundsRecipientChanged(
        address indexed newAddress,
        address indexed changedBy
    );

    /// @notice Event emitted when the funds are withdrawn from the minting contract
    /// @param withdrawnBy address that issued the withdraw
    /// @param withdrawnTo address that the funds were withdrawn to
    /// @param amount amount that was withdrawn
    event FundsWithdrawn(
        address indexed withdrawnBy,
        address indexed withdrawnTo,
        uint256 amount
    );

    /// @notice Event emitted when an open mint is finalized and further minting is closed forever on the contract.
    /// @param sender address sending close mint
    /// @param numberOfMints number of mints the contract is finalized at
    event OpenMintFinalized(address indexed sender, uint256 numberOfMints);

    /// @notice Event emitted when metadata renderer is updated.
    /// @param sender address of the updater
    /// @param renderer new metadata renderer address
    event UpdatedMetadataRenderer(address sender, IMetadataRenderer renderer);

    /// @notice General configuration for NFT Minting and bookkeeping
    struct Configuration {
        /// @dev Metadata renderer (uint160)
        IMetadataRenderer metadataRenderer;
        /// @dev Total size of edition that can be minted (uint160+64 = 224)
        uint64 editionSize;
        /// @dev Royalty amount in bps (uint224+16 = 240)
        uint16 royaltyBPS;
        /// @dev Funds recipient for sale (new slot, uint160)
        address payable fundsRecipient;
    }

    /// @notice Sales states and configuration
    /// @dev Uses 3 storage slots
    struct SalesConfiguration {
        /// @dev Public sale price (max ether value > 1000 ether with this value)
        uint104 publicSalePrice;
        /// @dev ERC20 Token
        address erc20PaymentToken;
        /// @notice Purchase mint limit per address (if set to 0 === unlimited mints)
        /// @dev Max purchase number per txn (90+32 = 122)
        uint32 maxSalePurchasePerAddress;
        /// @dev uint64 type allows for dates into 292 billion years
        /// @notice Public sale start timestamp (136+64 = 186)
        uint64 publicSaleStart;
        /// @notice Public sale end timestamp (186+64 = 250)
        uint64 publicSaleEnd;
        /// @notice Presale start timestamp
        /// @dev new storage slot
        uint64 presaleStart;
        /// @notice Presale end timestamp
        uint64 presaleEnd;
        /// @notice Presale merkle root
        bytes32 presaleMerkleRoot;
    }

    /// @notice CRE8ORS - General configuration for Builder Rewards burn requirements
    struct BurnConfiguration {
        /// @dev Token to burn
        address burnToken;
        /// @dev Required number of tokens to burn
        uint256 burnQuantity;
    }

    /// @notice Sales states and configuration
    /// @dev Uses 3 storage slots
    struct ERC20SalesConfiguration {
        /// @notice Public sale price
        /// @dev max ether value > 1000 ether with this value
        uint104 publicSalePrice;
        /// @dev ERC20 Token
        address erc20PaymentToken;
        /// @notice Purchase mint limit per address (if set to 0 === unlimited mints)
        /// @dev Max purchase number per txn (90+32 = 122)
        uint32 maxSalePurchasePerAddress;
        /// @dev uint64 type allows for dates into 292 billion years
        /// @notice Public sale start timestamp (136+64 = 186)
        uint64 publicSaleStart;
        /// @notice Public sale end timestamp (186+64 = 250)
        uint64 publicSaleEnd;
        /// @notice Presale start timestamp
        /// @dev new storage slot
        uint64 presaleStart;
        /// @notice Presale end timestamp
        uint64 presaleEnd;
        /// @notice Presale merkle root
        bytes32 presaleMerkleRoot;
    }

    /// @notice Return value for sales details to use with front-ends
    struct SaleDetails {
        // Synthesized status variables for sale and presale
        bool publicSaleActive;
        bool presaleActive;
        // Price for public sale
        uint256 publicSalePrice;
        // Timed sale actions for public sale
        uint64 publicSaleStart;
        uint64 publicSaleEnd;
        // Timed sale actions for presale
        uint64 presaleStart;
        uint64 presaleEnd;
        // Merkle root (includes address, quantity, and price data for each entry)
        bytes32 presaleMerkleRoot;
        // Limit public sale to a specific number of mints per wallet
        uint256 maxSalePurchasePerAddress;
        // Information about the rest of the supply
        // Total that have been minted
        uint256 totalMinted;
        // The total supply available
        uint256 maxSupply;
    }

    /// @notice Return value for sales details to use with front-ends
    struct ERC20SaleDetails {
        /// @notice Synthesized status variables for sale
        bool publicSaleActive;
        /// @notice Synthesized status variables for presale
        bool presaleActive;
        /// @notice Price for public sale
        uint256 publicSalePrice;
        /// @notice ERC20 contract address for payment. address(0) for ETH.
        address erc20PaymentToken;
        /// @notice public sale start
        uint64 publicSaleStart;
        /// @notice public sale end
        uint64 publicSaleEnd;
        /// @notice Timed sale actions for presale start
        uint64 presaleStart;
        /// @notice Timed sale actions for presale end
        uint64 presaleEnd;
        /// @notice Merkle root (includes address, quantity, and price data for each entry)
        bytes32 presaleMerkleRoot;
        /// @notice Limit public sale to a specific number of mints per wallet
        uint256 maxSalePurchasePerAddress;
        /// @notice Total that have been minted
        uint256 totalMinted;
        /// @notice The total supply available
        uint256 maxSupply;
    }

    /// @notice Return type of specific mint counts and details per address
    struct AddressMintDetails {
        /// Number of total mints from the given address
        uint256 totalMints;
        /// Number of presale mints from the given address
        uint256 presaleMints;
        /// Number of public mints from the given address
        uint256 publicMints;
    }

    /// @notice External purchase function (payable in eth)
    /// @param quantity to purchase
    /// @return first minted token ID
    function purchase(uint256 quantity) external payable returns (uint256);

    /// @notice External purchase presale function (takes a merkle proof and matches to root) (payable in eth)
    /// @param quantity to purchase
    /// @param maxQuantity can purchase (verified by merkle root)
    /// @param pricePerToken price per token allowed (verified by merkle root)
    /// @param merkleProof input for merkle proof leaf verified by merkle root
    /// @return first minted token ID
    function purchasePresale(
        uint256 quantity,
        uint256 maxQuantity,
        uint256 pricePerToken,
        bytes32[] memory merkleProof
    ) external payable returns (uint256);

    /// @notice Function to return the global sales details for the given drop
    function saleDetails() external view returns (ERC20SaleDetails memory);

    /// @notice Function to return the specific sales details for a given address
    /// @param minter address for minter to return mint information for
    function mintedPerAddress(
        address minter
    ) external view returns (AddressMintDetails memory);

    /// @notice This is the opensea/public owner setting that can be set by the contract admin
    function owner() external view returns (address);

    /// @notice Update the metadata renderer
    /// @param newRenderer new address for renderer
    /// @param setupRenderer data to call to bootstrap data for the new renderer (optional)
    function setMetadataRenderer(
        IMetadataRenderer newRenderer,
        bytes memory setupRenderer
    ) external;

    /// @notice This is an admin mint function to mint a quantity to a specific address
    /// @param to address to mint to
    /// @param quantity quantity to mint
    /// @return the id of the first minted NFT
    function adminMint(address to, uint256 quantity) external returns (uint256);

    /// @notice This is an admin mint function to mint a single nft each to a list of addresses
    /// @param to list of addresses to mint an NFT each to
    /// @return the id of the first minted NFT
    function adminMintAirdrop(address[] memory to) external returns (uint256);

    /// @dev Getter for admin role associated with the contract to handle metadata
    /// @return boolean if address is admin
    function isAdmin(address user) external view returns (bool);
}

File 6 of 13 : IMetadataRenderer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/**
 ██████╗██████╗ ███████╗ █████╗  ██████╗ ██████╗ ███████╗
██╔════╝██╔══██╗██╔════╝██╔══██╗██╔═══██╗██╔══██╗██╔════╝
██║     ██████╔╝█████╗  ╚█████╔╝██║   ██║██████╔╝███████╗
██║     ██╔══██╗██╔══╝  ██╔══██╗██║   ██║██╔══██╗╚════██║
╚██████╗██║  ██║███████╗╚█████╔╝╚██████╔╝██║  ██║███████║
 ╚═════╝╚═╝  ╚═╝╚══════╝ ╚════╝  ╚═════╝ ╚═╝  ╚═╝╚══════╝                                                     
 */

/// @dev credit: https://github.com/ourzora/zora-drops-contracts
interface IMetadataRenderer {
    function tokenURI(uint256) external view returns (string memory);

    function contractURI() external view returns (string memory);

    function initializeWithData(bytes memory initData) external;
}

File 7 of 13 : Admin.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {IERC721Drop} from "../../interfaces/IERC721Drop.sol";
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
import {Base} from "./Base.sol";

/// @title Admin
/// @notice An abstract contract with access control functionality.
abstract contract Admin is Base {
    /// @notice Access control roles
    bytes32 public constant MINTER_ROLE = keccak256("MINTER");

    /// @notice Modifier to allow only users with admin access
    /// @param target The address of the contract implementing the access control
    modifier onlyAdmin(address target) {
        if (!isAdmin(target, msg.sender)) {
            revert IERC721Drop.Access_OnlyAdmin();
        }

        _;
    }

    /// @notice Modifier to allow only a given role or admin access
    /// @param target The address of the contract implementing the access control
    /// @param role The role to check for alongside the admin role
    modifier onlyRoleOrAdmin(address target, bytes32 role) {
        if (!isAdmin(target, msg.sender) && !IAccessControl(target).hasRole(role, msg.sender)) {
            revert IERC721Drop.Access_MissingRoleOrAdmin(role);
        }

        _;
    }

    /// @notice Getter for admin role associated with the contract to handle minting
    /// @param target The address of the contract implementing the access control
    /// @param user The address to check for admin access
    /// @return Whether the address has admin access or not
    function isAdmin(address target, address user) public view returns (bool) {
        return IERC721Drop(target).isAdmin(user);
    }
}

File 8 of 13 : Base.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @title Base
/// @notice A base abstract contract implementing common functionality for other contracts.
abstract contract Base {
    /// @notice given address is invalid.
    error AddressCannotBeZero();

    /// @dev Modifier to check if the provided address is not the zero address.
    /// @param addr The address to be checked.
    modifier notZeroAddress(address addr) {
        if (addr == address(0)) {
            revert AddressCannotBeZero();
        }

        _;
    }
}

File 9 of 13 : ERC5643.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC5643} from "../interfaces/IERC5643.sol";
import {PaymentSystem} from "../abstracts/PaymentSystem.sol";
import {IERC721Drop} from "../../interfaces/IERC721Drop.sol";

/// @title ERC5643
/// @notice An abstract contract implementing the IERC5643 interface for managing subscriptions to ERC721 tokens.
abstract contract ERC5643 is IERC5643, PaymentSystem {
    /*//////////////////////////////////////////////////////////////
                             PRIVATE STORAGE
    //////////////////////////////////////////////////////////////*/

    /// @notice Mapping to store the expiration timestamps for each tokenId representing an active subscription.
    mapping(uint256 => uint64) private _expirations;

    /*//////////////////////////////////////////////////////////////
                             PUBLIC STORAGE
    //////////////////////////////////////////////////////////////*/

    /// @notice The minimum duration allowed for subscription renewal.
    uint64 public minRenewalDuration;

    /// @notice The maximum duration allowed for subscription renewal. A value of 0 means lifetime extension is allowed.
    uint64 public maxRenewalDuration; // 0 value means lifetime extension

    ///@notice The address of the collection contract that mints and manages the tokens.
    address public cre8orsNFT;

    /*//////////////////////////////////////////////////////////////
                                MODIFIERS
    //////////////////////////////////////////////////////////////*/

    /// @dev Modifier to check if `spender` is the owner or approved for the `tokenId`.
    modifier onlyApprovedOrOwner(address spender, uint256 tokenId) {
        if (!_isApprovedOrOwner(spender, tokenId)) {
            revert IERC721Drop.Access_MissingOwnerOrApproved();
        }

        _;
    }

    /// @dev Modifier to check if the `duration` is between `minRenewalDuration` and `maxRenewalDuration`.
    modifier isDurationBetweenMinAndMax(uint64 duration) {
        if (duration < minRenewalDuration) {
            revert RenewalTooShort();
        } else if (maxRenewalDuration != 0 && duration > maxRenewalDuration) {
            revert RenewalTooLong();
        }

        _;
    }

    /// @dev Modifier to check if the payment for `duration` is valid.
    modifier isRenewalPriceValid(uint256 value, uint64 duration) {
        if (duration == 0) {
            revert DurationForRenewalPriceCannotBeZero();
        }

        if (value < _getRenewalPrice(duration)) {
            revert InsufficientPayment();
        }

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    /// @dev Checks zero address validation
    /// @param cre8orsNFT_ The address of the cre8orsNFT contract.
    /// @param minRenewalDuration_ The minimum duration allowed for subscription renewal, can be zero.
    /// @param pricePerSecond_ The price per second for the subscription, can be zero.
    constructor(
        address cre8orsNFT_,
        uint64 minRenewalDuration_,
        uint256 pricePerSecond_
    ) notZeroAddress(cre8orsNFT_) PaymentSystem(pricePerSecond_) {
        cre8orsNFT = cre8orsNFT_;
        minRenewalDuration = minRenewalDuration_;
    }

    /*//////////////////////////////////////////////////////////////
                     USER-FACING CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc IERC5643
    function isRenewable(
        uint256 /*tokenId*/
    ) external view virtual override returns (bool) {
        return _isRenewable();
    }

    /// @inheritdoc IERC5643
    function expiresAt(
        uint256 tokenId
    ) public view virtual override returns (uint64) {
        return _expirations[tokenId];
    }

    /// @dev See {IERC165-supportsInterface}.
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual returns (bool) {
        return
            interfaceId == type(IERC5643).interfaceId ||
            IERC721(cre8orsNFT).supportsInterface(interfaceId);
    }

    /*//////////////////////////////////////////////////////////////
                   USER-FACING NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc IERC5643
    function renewSubscription(
        uint256 tokenId,
        uint64 duration
    )
        external
        payable
        virtual
        override
        isDurationBetweenMinAndMax(duration)
        isRenewalPriceValid(msg.value, duration)
    {
        // extend subscription
        _updateSubscriptionExpiration(tokenId, duration);
    }

    /// @inheritdoc IERC5643
    function cancelSubscription(
        uint256 tokenId
    )
        external
        payable
        virtual
        override
        onlyApprovedOrOwner(msg.sender, tokenId)
    {
        delete _expirations[tokenId];

        emit SubscriptionUpdate(tokenId, 0);
    }

    /*//////////////////////////////////////////////////////////////
                    ONLY-ADMIN NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Set the address of the cre8ors contract.
    /// @dev This function can only be called by the contract admin.
    /// @param target The address of the new cre8ors contract.
    function setCre8orsNFT(address target) external onlyAdmin(target) {
        cre8orsNFT = target;
    }

    /*//////////////////////////////////////////////////////////////
                       INTERNAL CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Checks whether the subscription is renewable.
    /// @dev This Internal function should be implemented in derived contracts to determine if renewability should be
    /// disabled for all or some tokens.
    /// @return A boolean value indicating whether the subscription can be renewed (true) or not (false).
    function _isRenewable() internal view virtual returns (bool);

    /// @notice Gets the price to renew a subscription for a specified `duration` in seconds.
    /// @dev This Internal function should be implemented in derived contracts to calculate the renewal price for the
    /// subscription.
    /// @param duration The duration (in seconds) for which the subscription is to be extended.
    /// @return The price (in native currency) required to renew the subscription for the given duration.
    function _getRenewalPrice(
        uint64 duration
    ) internal view virtual returns (uint256);

    /*//////////////////////////////////////////////////////////////
                     INTERNAL NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Updates the expiration timestamp for a subscription represented by the given `tokenId`.
    /// @dev this function won't check that the tokenId is valid, responsibility is delegated to the caller.
    /// @param tokenId The unique identifier of the subscription token.
    /// @param duration The duration (in seconds) to extend the subscription from the current timestamp.
    function _updateSubscriptionExpiration(
        uint256 tokenId,
        uint64 duration
    ) internal virtual {
        uint64 currentExpiration = _expirations[tokenId];
        uint64 newExpiration;

        // Check if the current subscription is new or has expired
        if ((currentExpiration == 0) || (currentExpiration < block.timestamp)) {
            newExpiration = uint64(block.timestamp) + duration;
        } else {
            // If current subscription not expired (extend)
            if (!_isRenewable()) {
                revert SubscriptionNotRenewable();
            }
            newExpiration = currentExpiration + duration;
        }

        _expirations[tokenId] = newExpiration;

        _sendValue(payable(cre8orsNFT), msg.value);

        emit SubscriptionUpdate(tokenId, newExpiration);
    }

    /// @dev Internal function to set the minimum renewal duration.
    /// @param duration The new minimum renewal duration (in seconds).
    function _setMinimumRenewalDuration(uint64 duration) internal virtual {
        minRenewalDuration = duration;
    }

    /// @dev Internal function to set the maximum renewal duration.
    /// @param duration The new maximum renewal duration (in seconds).
    function _setMaximumRenewalDuration(uint64 duration) internal virtual {
        maxRenewalDuration = duration;
    }

    /// @notice Requires that spender owns or is approved for the token.
    function _isApprovedOrOwner(
        address spender,
        uint256 tokenId
    ) internal view virtual returns (bool) {
        address cre8orsNFT_ = cre8orsNFT;
        address owner = IERC721(cre8orsNFT_).ownerOf(tokenId);
        return (spender == owner ||
            IERC721(cre8orsNFT_).isApprovedForAll(owner, spender) ||
            IERC721(cre8orsNFT_).getApproved(tokenId) == spender);
    }
}

File 10 of 13 : PaymentSystem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {IPaymentSystem} from "../interfaces/IPaymentSystem.sol";
import {Admin} from "./Admin.sol";

abstract contract PaymentSystem is IPaymentSystem, Admin {
    /*//////////////////////////////////////////////////////////////
                             PUBLIC STORAGE
    //////////////////////////////////////////////////////////////*/

    /// @notice The price per second for the subscription in native currency.
    uint256 public pricePerSecond;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    /// @param pricePerSecond_ The price per second for the subscription, can be zero.
    constructor(uint256 pricePerSecond_) {
        pricePerSecond = pricePerSecond_;
    }

    /*//////////////////////////////////////////////////////////////
                    ONLY-ADMIN NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc IPaymentSystem
    function setPricePerSecond(address target, uint256 newPrice) external override onlyAdmin(target) {
        pricePerSecond = newPrice;
        emit PricePerSecondUpdated(newPrice);
    }

    function _sendValue(address payable to, uint256 amount) internal {
        (bool success,) = to.call{value: amount}("");
        if (!success) revert ETHTransferFailed();
    }
}

File 11 of 13 : IERC5643.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @title IERC5643
/// @notice https://eips.ethereum.org/EIPS/eip-5643
/// @dev type(IERC5643).interfaceId should return 0x8c65f84d
interface IERC5643 {
    /*//////////////////////////////////////////////////////////////
                             ERRORS
    //////////////////////////////////////////////////////////////*/

    /// @notice The duration provided for renewal is too short to extend the subscription.
    error RenewalTooShort();

    /// @notice The duration provided for renewal exceeds the allowed maximum for subscription extension.
    error RenewalTooLong();

    /// @notice The payment received for the subscription renewal is insufficient.
    error InsufficientPayment();

    /// @notice The subscription associated with the token is not renewable and cannot be extended.
    error SubscriptionNotRenewable();

    /// @notice The duration provided for renewal price calculation cannot be zero.
    error DurationForRenewalPriceCannotBeZero();

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    /// @notice Emitted when a subscription expiration changes
    /// @dev When a subscription is canceled, the expiration value should also be 0.
    event SubscriptionUpdate(uint256 indexed tokenId, uint64 expiration);

    /*//////////////////////////////////////////////////////////////
                           CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Gets the expiration date of a subscription
    /// @dev Throws if `tokenId` is not a valid NFT
    /// @param tokenId The NFT to get the expiration date of
    /// @return The expiration date of the subscription
    function expiresAt(uint256 tokenId) external view returns (uint64);

    /// @notice Determines whether a subscription can be renewed
    /// @dev Throws if `tokenId` is not a valid NFT
    /// @param tokenId The NFT to get the expiration date of
    /// @return The renewability of a the subscription
    function isRenewable(uint256 tokenId) external view returns (bool);

    /*//////////////////////////////////////////////////////////////
                         NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Renews the subscription to an NFT
    /// Throws if `tokenId` is not a valid NFT
    /// @param tokenId The NFT to renew the subscription for
    /// @param duration The number of seconds to extend a subscription for
    function renewSubscription(uint256 tokenId, uint64 duration) external payable;

    /// @notice Cancels the subscription of an NFT
    /// @dev Throws if `tokenId` is not a valid NFT
    /// @param tokenId The NFT to cancel the subscription for
    function cancelSubscription(uint256 tokenId) external payable;
}

File 12 of 13 : IPaymentSystem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @title Payment System Interface
/// @notice An interface for the PaymentSystem contract.
interface IPaymentSystem {
    /// @notice Error message for zero value.
    error ValueCannotBeZero();

    /// @notice Error message for failed ETH transfer.
    error ETHTransferFailed();

    /// @dev Emitted when the native currency price is updated.
    /// @param newPrice The new price per second of the native currency.
    event PricePerSecondUpdated(uint256 newPrice);

    /// @notice Sets the price per second of the native currency.
    /// @param target The address of the contract implementing the access control.
    /// @param newPrice The new price per second to be set.
    function setPricePerSecond(address target, uint256 newPrice) external;
}

File 13 of 13 : ISubscription.sol
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @title ISubscription
/// @dev Interface for managing subscriptions to NFTs.
interface ISubscription {
    /*//////////////////////////////////////////////////////////////
                                 ERRORS
    //////////////////////////////////////////////////////////////*/

    /// @notice The subscription associated with the provided token ID is invalid or has expired.
    error InvalidSubscription();

    /// @notice Attempting to set a subscription contract address with a zero address value.
    error SubscriptionCannotBeZeroAddress();

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    /// @dev Emitted when the renewability status of subscriptions is updated.
    event RenewableUpdate(bool renewable);

    /// @dev Emitted when the minimum duration for subscription renewal is updated.
    event MinRenewalDurationUpdate(uint64 duration);

    /// @dev Emitted when the maximum duration for subscription renewal is updated.
    event MaxRenewalDurationUpdate(uint64 duration);

    /*//////////////////////////////////////////////////////////////
                           CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Checks the subscription for the given `tokenId`.
    /// Throws if `tokenId` subscription has expired.
    /// @param tokenId The unique identifier of the NFT token.
    function checkSubscription(uint256 tokenId) external view;

    /// @notice Returns whether the subscription for the given `tokenId` is valid.
    /// @param tokenId The unique identifier of the NFT token.
    /// @return A boolean indicating if the subscription is valid.
    function isSubscriptionValid(uint256 tokenId) external view returns (bool);

    /*//////////////////////////////////////////////////////////////
                         NON-CONSTANT FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /*//////////   updateSubscriptionForFree variants   //////////*/

    /// @notice Extends the subscription for the given `tokenId` with a specified `duration` for free.
    /// @dev This function is meant to be called by the minter when minting the NFT to subscribe.
    /// @param target The address of the contract implementing the access control
    /// @param duration The duration (in seconds) to extend the subscription for.
    /// @param tokenId The unique identifier of the NFT token to be subscribed.
    function updateSubscriptionForFree(address target, uint64 duration, uint256 tokenId) external;

    /// @notice Extends the subscription for the given `tokenIds` with a specified `duration` for free.
    /// @dev This function is meant to be called by the minter when minting the NFT to subscribe.
    /// @param target The address of the contract implementing the access control
    /// @param duration The duration (in seconds) to extend the subscription for.
    /// @param tokenIds An array of unique identifiers of the NFT tokens to update the subscriptions for.
    function updateSubscriptionForFree(address target, uint64 duration, uint256[] calldata tokenIds) external;

    /*//////////////   updateSubscription variants   /////////////*/

    /// @notice Extends the subscription for the given `tokenId` with a specified `duration`, using native currency as
    /// payment.
    /// @dev This function is meant to be called by the minter when minting the NFT to subscribe.
    /// @param target The address of the contract implementing the access control
    /// @param duration The duration (in seconds) to extend the subscription for.
    /// @param tokenId The unique identifier of the NFT token to be subscribed.
    function updateSubscription(address target, uint64 duration, uint256 tokenId) external payable;

    /// @notice Extends the subscription for the given `tokenIds` with a specified `duration`, using native currency as
    /// payment.
    /// @dev This function is meant to be called by the minter when minting the NFT to subscribe.
    /// @param target The address of the contract implementing the access control
    /// @param duration The duration (in seconds) to extend the subscription for.
    /// @param tokenIds An array of unique identifiers of the NFT tokens to update the subscriptions for.
    function updateSubscription(address target, uint64 duration, uint256[] calldata tokenIds) external payable;
}

Settings
{
  "remappings": [
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ERC6551/=lib/ERC6551/src/",
    "ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
    "ERC721A/=lib/ERC721A/contracts/",
    "ERC721C/=lib/creator-token-contracts/contracts/",
    "ERC721H/=lib/ERC721H/src/",
    "account-abstraction/=lib/account-abstraction/contracts/",
    "creator-token-contracts/=lib/creator-token-contracts/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "erc6551/=lib/tokenbound/lib/reference/src/",
    "erc721a/=lib/ERC721A/",
    "forge-std/=lib/forge-std/src/",
    "hardhat/=lib/creator-token-contracts/node_modules/hardhat/",
    "murky/=lib/creator-token-contracts/lib/murky/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
    "reference/=lib/tokenbound/lib/reference/src/",
    "sstore2/=lib/ERC6551/lib/sstore2/contracts/",
    "tokenbound/=lib/tokenbound/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"cre8orsNFT_","type":"address"},{"internalType":"uint64","name":"minRenewalDuration_","type":"uint64"},{"internalType":"uint256","name":"pricePerSecond_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Access_MissingOwnerOrApproved","type":"error"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"Access_MissingRoleOrAdmin","type":"error"},{"inputs":[],"name":"Access_OnlyAdmin","type":"error"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[],"name":"DurationForRenewalPriceCannotBeZero","type":"error"},{"inputs":[],"name":"ETHTransferFailed","type":"error"},{"inputs":[],"name":"InsufficientPayment","type":"error"},{"inputs":[],"name":"InvalidSubscription","type":"error"},{"inputs":[],"name":"RenewalTooLong","type":"error"},{"inputs":[],"name":"RenewalTooShort","type":"error"},{"inputs":[],"name":"SubscriptionCannotBeZeroAddress","type":"error"},{"inputs":[],"name":"SubscriptionNotRenewable","type":"error"},{"inputs":[],"name":"ValueCannotBeZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"duration","type":"uint64"}],"name":"MaxRenewalDurationUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"duration","type":"uint64"}],"name":"MinRenewalDurationUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"PricePerSecondUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"renewable","type":"bool"}],"name":"RenewableUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"expiration","type":"uint64"}],"name":"SubscriptionUpdate","type":"event"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"cancelSubscription","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"checkSubscription","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cre8orsNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"expiresAt","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isRenewable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isSubscriptionValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRenewalDuration","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minRenewalDuration","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint64","name":"duration","type":"uint64"}],"name":"renewSubscription","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"setCre8orsNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint64","name":"duration","type":"uint64"}],"name":"setMaxRenewalDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint64","name":"duration","type":"uint64"}],"name":"setMinRenewalDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setPricePerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"renewable","type":"bool"}],"name":"setRenewable","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":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint64","name":"duration","type":"uint64"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"updateSubscription","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint64","name":"duration","type":"uint64"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"updateSubscription","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint64","name":"duration","type":"uint64"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"updateSubscriptionForFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint64","name":"duration","type":"uint64"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"updateSubscriptionForFree","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526003805460ff60a01b1916600160a01b17905534801561002357600080fd5b5060405161173c38038061173c833981016040819052610042916100bd565b6000819055828282826001600160a01b038116610072576040516303988b8160e61b815260040160405180910390fd5b5050600380546001600160a01b0319166001600160a01b039390931692909217909155600280546001600160401b0319166001600160401b0390921691909117905550610118915050565b6000806000606084860312156100d257600080fd5b83516001600160a01b03811681146100e957600080fd5b60208501519093506001600160401b038116811461010657600080fd5b80925050604084015190509250925092565b611615806101276000396000f3fe6080604052600436106101355760003560e01c806363d20de7116100ab578063b4695d8c1161006f578063b4695d8c14610395578063bab4dd46146103b5578063cde317af146103d5578063d5391393146103f5578063d5dca19f14610417578063f3b8f6631461042a57600080fd5b806363d20de7146102e8578063776ce86814610308578063910067451461031b578063954689ca1461033b578063a8fef4a71461037557600080fd5b806317c95709116100fd57806317c9570914610203578063212350831461023957806332fb5c481461024c5780633804fd1f146102845780634073377c146102a857806357064afe146102c857600080fd5b806301ffc9a71461013a57806304394ed91461016f578063090db02914610184578063147e9782146101c3578063176f7d7c146101e3575b600080fd5b34801561014657600080fd5b5061015a6101553660046112b2565b61044a565b60405190151581526020015b60405180910390f35b61018261017d366004611310565b6104e2565b005b34801561019057600080fd5b506002546101ab90600160401b90046001600160401b031681565b6040516001600160401b039091168152602001610166565b3480156101cf57600080fd5b506002546101ab906001600160401b031681565b3480156101ef57600080fd5b506101826101fe3660046113a2565b6106ce565b34801561020f57600080fd5b506101ab61021e3660046113d7565b6000908152600160205260409020546001600160401b031690565b6101826102473660046113d7565b610762565b34801561025857600080fd5b5060035461026c906001600160a01b031681565b6040516001600160a01b039091168152602001610166565b34801561029057600080fd5b5061029a60005481565b604051908152602001610166565b3480156102b457600080fd5b506101826102c33660046113a2565b6107e1565b3480156102d457600080fd5b506101826102e33660046113f0565b61085e565b3480156102f457600080fd5b5061018261030336600461141c565b6108bb565b61018261031636600461145a565b610a07565b34801561032757600080fd5b5061015a61033636600461147d565b610af3565b34801561034757600080fd5b5061015a6103563660046113d7565b600090815260016020526040902054426001600160401b039091161190565b34801561038157600080fd5b506101826103903660046113d7565b610b68565b3480156103a157600080fd5b506101826103b0366004611310565b610ba6565b3480156103c157600080fd5b506101826103d03660046114b6565b610d24565b3480156103e157600080fd5b5061015a6103f03660046113d7565b610d6f565b34801561040157600080fd5b5061029a6000805160206115c083398151915281565b61018261042536600461141c565b610d84565b34801561043657600080fd5b506101826104453660046114e1565b610f27565b60006001600160e01b03198216638c65f84d60e01b14806104dc57506003546040516301ffc9a760e01b81526001600160e01b0319841660048201526001600160a01b03909116906301ffc9a790602401602060405180830381865afa1580156104b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104dc919061150f565b92915050565b836000805160206115c08339815191526104fc8233610af3565b1580156105755750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa15801561054f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610573919061150f565b155b1561059b576040516333ba055f60e21b8152600481018290526024015b60405180910390fd5b60025485906001600160401b0390811690821610156105cd5760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b03161580159061060357506002546001600160401b03600160401b9091048116908216115b1561062157604051633b44021f60e01b815260040160405180910390fd5b346106356001600160401b03881686611542565b806001600160401b031660000361065f57604051634beba9c560e01b815260040160405180910390fd5b61066881610f9c565b8210156106885760405163cd1c886760e01b815260040160405180910390fd5b6000805b878110156106c1578888828181106106a6576106a6611561565b9050602002013591506106b9828b610fb3565b60010161068c565b5050505050505050505050565b816106d98133610af3565b6106f6576040516302bd6bd160e01b815260040160405180910390fd5b600280546fffffffffffffffff00000000000000001916600160401b6001600160401b038516021790556040516001600160401b03831681527f7184449cafc5778c3392f4611de8de52280e7534422b8afbed32112693a8e21b906020015b60405180910390a1505050565b338161076e82826110b0565b61078b57604051632a60827160e21b815260040160405180910390fd5b6000838152600160209081526040808320805467ffffffffffffffff191690555191825284917f2ec2be2c4b90c2cf13ecb6751a24daed6bb741ae5ed3f7371aabf9402f6d62e8910160405180910390a2505050565b816107ec8133610af3565b610809576040516302bd6bd160e01b815260040160405180910390fd5b6002805467ffffffffffffffff19166001600160401b0384161790556040516001600160401b03831681527f62b10fb74dcc07849919c457af8ebac640f6df11273f29e798abe1c43ae5825790602001610755565b816108698133610af3565b610886576040516302bd6bd160e01b815260040160405180910390fd5b60008290556040518281527f9bb66cb13f624f691aedcc04a2be58c5c1d73cf9d41593070f0ff9d4f9e410b390602001610755565b826000805160206115c08339815191526108d58233610af3565b15801561094e5750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094c919061150f565b155b1561096f576040516333ba055f60e21b815260048101829052602401610592565b60025484906001600160401b0390811690821610156109a15760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b0316158015906109d757506002546001600160401b03600160401b9091048116908216115b156109f557604051633b44021f60e01b815260040160405180910390fd5b6109ff8486610fb3565b505050505050565b60025481906001600160401b039081169082161015610a395760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b031615801590610a6f57506002546001600160401b03600160401b9091048116908216115b15610a8d57604051633b44021f60e01b815260040160405180910390fd5b3482806001600160401b0316600003610ab957604051634beba9c560e01b815260040160405180910390fd5b610ac281610f9c565b821015610ae25760405163cd1c886760e01b815260040160405180910390fd5b610aec8585610fb3565b5050505050565b604051630935e01b60e21b81526001600160a01b038281166004830152600091908416906324d7806c90602401602060405180830381865afa158015610b3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b61919061150f565b9392505050565b600081815260016020526040902054426001600160401b039091161180610ba257604051630fb532db60e11b815260040160405180910390fd5b5050565b836000805160206115c0833981519152610bc08233610af3565b158015610c395750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa158015610c13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c37919061150f565b155b15610c5a576040516333ba055f60e21b815260048101829052602401610592565b60025485906001600160401b039081169082161015610c8c5760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b031615801590610cc257506002546001600160401b03600160401b9091048116908216115b15610ce057604051633b44021f60e01b815260040160405180910390fd5b6000805b85811015610d1957868682818110610cfe57610cfe611561565b905060200201359150610d118289610fb3565b600101610ce4565b505050505050505050565b80610d2f8133610af3565b610d4c576040516302bd6bd160e01b815260040160405180910390fd5b50600380546001600160a01b0319166001600160a01b0392909216919091179055565b600354600090600160a01b900460ff166104dc565b826000805160206115c0833981519152610d9e8233610af3565b158015610e175750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa158015610df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e15919061150f565b155b15610e38576040516333ba055f60e21b815260048101829052602401610592565b60025484906001600160401b039081169082161015610e6a5760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b031615801590610ea057506002546001600160401b03600160401b9091048116908216115b15610ebe57604051633b44021f60e01b815260040160405180910390fd5b3485806001600160401b0316600003610eea57604051634beba9c560e01b815260040160405180910390fd5b610ef381610f9c565b821015610f135760405163cd1c886760e01b815260040160405180910390fd5b610f1d8688610fb3565b5050505050505050565b81610f328133610af3565b610f4f576040516302bd6bd160e01b815260040160405180910390fd5b60038054831515600160a01b0260ff60a01b199091161790556040517f24ec1c131fb5947a129795cb5f89b24f524bd817e733843a630d641b681dfb369061075590841515815260200190565b600080546104dc906001600160401b038416611542565b6000828152600160205260408120546001600160401b031690811580610fe1575042826001600160401b0316105b15610ff757610ff08342611577565b905061102e565b600354600160a01b900460ff1661102157604051638b9bff4560e01b815260040160405180910390fd5b61102b8383611577565b90505b6000848152600160205260409020805467ffffffffffffffff19166001600160401b03831617905560035461106c906001600160a01b031634611239565b6040516001600160401b038216815284907f2ec2be2c4b90c2cf13ecb6751a24daed6bb741ae5ed3f7371aabf9402f6d62e89060200160405180910390a250505050565b6003546040516331a9108f60e11b8152600481018390526000916001600160a01b03169082908290636352211e90602401602060405180830381865afa1580156110fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112291906115a2565b9050806001600160a01b0316856001600160a01b031614806111b1575060405163e985e9c560e01b81526001600160a01b038281166004830152868116602483015283169063e985e9c590604401602060405180830381865afa15801561118d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b1919061150f565b80611230575060405163020604bf60e21b8152600481018590526001600160a01b03808716919084169063081812fc90602401602060405180830381865afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122591906115a2565b6001600160a01b0316145b95945050505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611286576040519150601f19603f3d011682016040523d82523d6000602084013e61128b565b606091505b50509050806112ad5760405163b12d13eb60e01b815260040160405180910390fd5b505050565b6000602082840312156112c457600080fd5b81356001600160e01b031981168114610b6157600080fd5b6001600160a01b03811681146112f157600080fd5b50565b80356001600160401b038116811461130b57600080fd5b919050565b6000806000806060858703121561132657600080fd5b8435611331816112dc565b935061133f602086016112f4565b925060408501356001600160401b038082111561135b57600080fd5b818701915087601f83011261136f57600080fd5b81358181111561137e57600080fd5b8860208260051b850101111561139357600080fd5b95989497505060200194505050565b600080604083850312156113b557600080fd5b82356113c0816112dc565b91506113ce602084016112f4565b90509250929050565b6000602082840312156113e957600080fd5b5035919050565b6000806040838503121561140357600080fd5b823561140e816112dc565b946020939093013593505050565b60008060006060848603121561143157600080fd5b833561143c816112dc565b925061144a602085016112f4565b9150604084013590509250925092565b6000806040838503121561146d57600080fd5b823591506113ce602084016112f4565b6000806040838503121561149057600080fd5b823561149b816112dc565b915060208301356114ab816112dc565b809150509250929050565b6000602082840312156114c857600080fd5b8135610b61816112dc565b80151581146112f157600080fd5b600080604083850312156114f457600080fd5b82356114ff816112dc565b915060208301356114ab816114d3565b60006020828403121561152157600080fd5b8151610b61816114d3565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561155c5761155c61152c565b500290565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b038083168185168083038211156115995761159961152c565b01949350505050565b6000602082840312156115b457600080fd5b8151610b61816112dc56fef0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9a26469706673582212205fce709240743ebe3a1ce74fb81dec7fc9e4b44a87a75f9e4e69b24cb25bd24364736f6c634300080f00330000000000000000000000008ddef0396d4b61fcbb0e4a821dfac52c011f79da000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000008fb8fd981

Deployed Bytecode

0x6080604052600436106101355760003560e01c806363d20de7116100ab578063b4695d8c1161006f578063b4695d8c14610395578063bab4dd46146103b5578063cde317af146103d5578063d5391393146103f5578063d5dca19f14610417578063f3b8f6631461042a57600080fd5b806363d20de7146102e8578063776ce86814610308578063910067451461031b578063954689ca1461033b578063a8fef4a71461037557600080fd5b806317c95709116100fd57806317c9570914610203578063212350831461023957806332fb5c481461024c5780633804fd1f146102845780634073377c146102a857806357064afe146102c857600080fd5b806301ffc9a71461013a57806304394ed91461016f578063090db02914610184578063147e9782146101c3578063176f7d7c146101e3575b600080fd5b34801561014657600080fd5b5061015a6101553660046112b2565b61044a565b60405190151581526020015b60405180910390f35b61018261017d366004611310565b6104e2565b005b34801561019057600080fd5b506002546101ab90600160401b90046001600160401b031681565b6040516001600160401b039091168152602001610166565b3480156101cf57600080fd5b506002546101ab906001600160401b031681565b3480156101ef57600080fd5b506101826101fe3660046113a2565b6106ce565b34801561020f57600080fd5b506101ab61021e3660046113d7565b6000908152600160205260409020546001600160401b031690565b6101826102473660046113d7565b610762565b34801561025857600080fd5b5060035461026c906001600160a01b031681565b6040516001600160a01b039091168152602001610166565b34801561029057600080fd5b5061029a60005481565b604051908152602001610166565b3480156102b457600080fd5b506101826102c33660046113a2565b6107e1565b3480156102d457600080fd5b506101826102e33660046113f0565b61085e565b3480156102f457600080fd5b5061018261030336600461141c565b6108bb565b61018261031636600461145a565b610a07565b34801561032757600080fd5b5061015a61033636600461147d565b610af3565b34801561034757600080fd5b5061015a6103563660046113d7565b600090815260016020526040902054426001600160401b039091161190565b34801561038157600080fd5b506101826103903660046113d7565b610b68565b3480156103a157600080fd5b506101826103b0366004611310565b610ba6565b3480156103c157600080fd5b506101826103d03660046114b6565b610d24565b3480156103e157600080fd5b5061015a6103f03660046113d7565b610d6f565b34801561040157600080fd5b5061029a6000805160206115c083398151915281565b61018261042536600461141c565b610d84565b34801561043657600080fd5b506101826104453660046114e1565b610f27565b60006001600160e01b03198216638c65f84d60e01b14806104dc57506003546040516301ffc9a760e01b81526001600160e01b0319841660048201526001600160a01b03909116906301ffc9a790602401602060405180830381865afa1580156104b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104dc919061150f565b92915050565b836000805160206115c08339815191526104fc8233610af3565b1580156105755750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa15801561054f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610573919061150f565b155b1561059b576040516333ba055f60e21b8152600481018290526024015b60405180910390fd5b60025485906001600160401b0390811690821610156105cd5760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b03161580159061060357506002546001600160401b03600160401b9091048116908216115b1561062157604051633b44021f60e01b815260040160405180910390fd5b346106356001600160401b03881686611542565b806001600160401b031660000361065f57604051634beba9c560e01b815260040160405180910390fd5b61066881610f9c565b8210156106885760405163cd1c886760e01b815260040160405180910390fd5b6000805b878110156106c1578888828181106106a6576106a6611561565b9050602002013591506106b9828b610fb3565b60010161068c565b5050505050505050505050565b816106d98133610af3565b6106f6576040516302bd6bd160e01b815260040160405180910390fd5b600280546fffffffffffffffff00000000000000001916600160401b6001600160401b038516021790556040516001600160401b03831681527f7184449cafc5778c3392f4611de8de52280e7534422b8afbed32112693a8e21b906020015b60405180910390a1505050565b338161076e82826110b0565b61078b57604051632a60827160e21b815260040160405180910390fd5b6000838152600160209081526040808320805467ffffffffffffffff191690555191825284917f2ec2be2c4b90c2cf13ecb6751a24daed6bb741ae5ed3f7371aabf9402f6d62e8910160405180910390a2505050565b816107ec8133610af3565b610809576040516302bd6bd160e01b815260040160405180910390fd5b6002805467ffffffffffffffff19166001600160401b0384161790556040516001600160401b03831681527f62b10fb74dcc07849919c457af8ebac640f6df11273f29e798abe1c43ae5825790602001610755565b816108698133610af3565b610886576040516302bd6bd160e01b815260040160405180910390fd5b60008290556040518281527f9bb66cb13f624f691aedcc04a2be58c5c1d73cf9d41593070f0ff9d4f9e410b390602001610755565b826000805160206115c08339815191526108d58233610af3565b15801561094e5750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094c919061150f565b155b1561096f576040516333ba055f60e21b815260048101829052602401610592565b60025484906001600160401b0390811690821610156109a15760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b0316158015906109d757506002546001600160401b03600160401b9091048116908216115b156109f557604051633b44021f60e01b815260040160405180910390fd5b6109ff8486610fb3565b505050505050565b60025481906001600160401b039081169082161015610a395760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b031615801590610a6f57506002546001600160401b03600160401b9091048116908216115b15610a8d57604051633b44021f60e01b815260040160405180910390fd5b3482806001600160401b0316600003610ab957604051634beba9c560e01b815260040160405180910390fd5b610ac281610f9c565b821015610ae25760405163cd1c886760e01b815260040160405180910390fd5b610aec8585610fb3565b5050505050565b604051630935e01b60e21b81526001600160a01b038281166004830152600091908416906324d7806c90602401602060405180830381865afa158015610b3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b61919061150f565b9392505050565b600081815260016020526040902054426001600160401b039091161180610ba257604051630fb532db60e11b815260040160405180910390fd5b5050565b836000805160206115c0833981519152610bc08233610af3565b158015610c395750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa158015610c13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c37919061150f565b155b15610c5a576040516333ba055f60e21b815260048101829052602401610592565b60025485906001600160401b039081169082161015610c8c5760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b031615801590610cc257506002546001600160401b03600160401b9091048116908216115b15610ce057604051633b44021f60e01b815260040160405180910390fd5b6000805b85811015610d1957868682818110610cfe57610cfe611561565b905060200201359150610d118289610fb3565b600101610ce4565b505050505050505050565b80610d2f8133610af3565b610d4c576040516302bd6bd160e01b815260040160405180910390fd5b50600380546001600160a01b0319166001600160a01b0392909216919091179055565b600354600090600160a01b900460ff166104dc565b826000805160206115c0833981519152610d9e8233610af3565b158015610e175750604051632474521560e21b8152600481018290523360248201526001600160a01b038316906391d1485490604401602060405180830381865afa158015610df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e15919061150f565b155b15610e38576040516333ba055f60e21b815260048101829052602401610592565b60025484906001600160401b039081169082161015610e6a5760405163e3061ca960e01b815260040160405180910390fd5b600254600160401b90046001600160401b031615801590610ea057506002546001600160401b03600160401b9091048116908216115b15610ebe57604051633b44021f60e01b815260040160405180910390fd5b3485806001600160401b0316600003610eea57604051634beba9c560e01b815260040160405180910390fd5b610ef381610f9c565b821015610f135760405163cd1c886760e01b815260040160405180910390fd5b610f1d8688610fb3565b5050505050505050565b81610f328133610af3565b610f4f576040516302bd6bd160e01b815260040160405180910390fd5b60038054831515600160a01b0260ff60a01b199091161790556040517f24ec1c131fb5947a129795cb5f89b24f524bd817e733843a630d641b681dfb369061075590841515815260200190565b600080546104dc906001600160401b038416611542565b6000828152600160205260408120546001600160401b031690811580610fe1575042826001600160401b0316105b15610ff757610ff08342611577565b905061102e565b600354600160a01b900460ff1661102157604051638b9bff4560e01b815260040160405180910390fd5b61102b8383611577565b90505b6000848152600160205260409020805467ffffffffffffffff19166001600160401b03831617905560035461106c906001600160a01b031634611239565b6040516001600160401b038216815284907f2ec2be2c4b90c2cf13ecb6751a24daed6bb741ae5ed3f7371aabf9402f6d62e89060200160405180910390a250505050565b6003546040516331a9108f60e11b8152600481018390526000916001600160a01b03169082908290636352211e90602401602060405180830381865afa1580156110fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112291906115a2565b9050806001600160a01b0316856001600160a01b031614806111b1575060405163e985e9c560e01b81526001600160a01b038281166004830152868116602483015283169063e985e9c590604401602060405180830381865afa15801561118d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b1919061150f565b80611230575060405163020604bf60e21b8152600481018590526001600160a01b03808716919084169063081812fc90602401602060405180830381865afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122591906115a2565b6001600160a01b0316145b95945050505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611286576040519150601f19603f3d011682016040523d82523d6000602084013e61128b565b606091505b50509050806112ad5760405163b12d13eb60e01b815260040160405180910390fd5b505050565b6000602082840312156112c457600080fd5b81356001600160e01b031981168114610b6157600080fd5b6001600160a01b03811681146112f157600080fd5b50565b80356001600160401b038116811461130b57600080fd5b919050565b6000806000806060858703121561132657600080fd5b8435611331816112dc565b935061133f602086016112f4565b925060408501356001600160401b038082111561135b57600080fd5b818701915087601f83011261136f57600080fd5b81358181111561137e57600080fd5b8860208260051b850101111561139357600080fd5b95989497505060200194505050565b600080604083850312156113b557600080fd5b82356113c0816112dc565b91506113ce602084016112f4565b90509250929050565b6000602082840312156113e957600080fd5b5035919050565b6000806040838503121561140357600080fd5b823561140e816112dc565b946020939093013593505050565b60008060006060848603121561143157600080fd5b833561143c816112dc565b925061144a602085016112f4565b9150604084013590509250925092565b6000806040838503121561146d57600080fd5b823591506113ce602084016112f4565b6000806040838503121561149057600080fd5b823561149b816112dc565b915060208301356114ab816112dc565b809150509250929050565b6000602082840312156114c857600080fd5b8135610b61816112dc565b80151581146112f157600080fd5b600080604083850312156114f457600080fd5b82356114ff816112dc565b915060208301356114ab816114d3565b60006020828403121561152157600080fd5b8151610b61816114d3565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561155c5761155c61152c565b500290565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b038083168185168083038211156115995761159961152c565b01949350505050565b6000602082840312156115b457600080fd5b8151610b61816112dc56fef0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9a26469706673582212205fce709240743ebe3a1ce74fb81dec7fc9e4b44a87a75f9e4e69b24cb25bd24364736f6c634300080f0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000008ddef0396d4b61fcbb0e4a821dfac52c011f79da000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000008fb8fd981

-----Decoded View---------------
Arg [0] : cre8orsNFT_ (address): 0x8dDeF0396d4B61Fcbb0e4a821DfAC52c011f79dA
Arg [1] : minRenewalDuration_ (uint64): 86400
Arg [2] : pricePerSecond_ (uint256): 38580246913

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000008ddef0396d4b61fcbb0e4a821dfac52c011f79da
Arg [1] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [2] : 00000000000000000000000000000000000000000000000000000008fb8fd981


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.