Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xC4bD13d85C8050e55f456ccEDeA799e2dF2A1f8C
Balance 0 ETH
Nonce 5481
Code Size 3643 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

3643 bytes
0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80638bad0c0a11610076578063cd5ad4c51161005b578063cd5ad4c514610133578063e8ac653314610146578063f851a4401461015957600080fd5b80638bad0c0a14610118578063a61e660d1461012057600080fd5b806301ffc9a7146100a85780630e18b681146100d057806343264347146100da57806344a0e477146100ed575b600080fd5b6100bb6100b6366004610b5e565b610171565b60405190151581526020015b60405180910390f35b6100d86101d8565b005b6100d86100e8366004610bb7565b61025a565b6101006100fb366004610bd2565b6102f0565b6040516001600160a01b0390911681526020016100c7565b6100d861050d565b61010061012e366004610c4e565b610521565b6100d8610141366004610bb7565b610873565b600154610100906001600160a01b031681565b6000546101009061010090046001600160a01b031681565b60007fffffffff000000000000000000000000000000000000000000000000000000008216634326434760e01b14806101d257506301ffc9a760e01b7fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6001546001600160a01b031680336001600160a01b0316146040518060400160405280601281526020017f496e76616c6964206d73672e73656e64657200000000000000000000000000008152509061024d5760405162461bcd60e51b81526004016102449190610d1c565b60405180910390fd5b50610257816108aa565b50565b60005460408051808201909152601f81527f52652d696e697469616c697a6174696f6e206e6f74207065726d69747465640060208201529060ff16156102b35760405162461bcd60e51b81526004016102449190610d1c565b506002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790556000805460ff19166001179055565b60006102fa610937565b6040516301ffc9a760e01b81527ff572b6d80000000000000000000000000000000000000000000000000000000060048201526001600160a01b038416906301ffc9a79060240160206040518083038186803b15801561035957600080fd5b505afa15801561036d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103919190610d71565b6103dd5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420612076616c6964204d657461646174612047656e657261746f7200006044820152606401610244565b60006103e884610aa3565b6040516001600160a01b03821681529091507f02d8dfece1f364cfc8b72f071e17076099f10b3ab878a43375637c65784c26629060200160405180910390a16040516301ffc9a760e01b8152634326434760e01b60048201526001600160a01b038516906301ffc9a79060240160206040518083038186803b15801561046d57600080fd5b505afa158015610481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a59190610d71565b1561050657604051634326434760e01b81526001600160a01b038481166004830152821690634326434790602401600060405180830381600087803b1580156104ed57600080fd5b505af1158015610501573d6000803e3d6000fd5b505050505b9392505050565b610515610937565b61051f60006108aa565b565b600061052b610937565b6040516301ffc9a760e01b81526330287a4760e11b60048201526001600160a01b038b16906301ffc9a79060240160206040518083038186803b15801561057157600080fd5b505afa158015610585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a99190610d71565b6105f55760405162461bcd60e51b815260206004820152601860248201527f4e6f7420612076616c69642045524337323120546f6b656e00000000000000006044820152606401610244565b60006106008b610aa3565b6040516001600160a01b03821681529091507fce0e0d62bcd9e242c589cac7830ddf79b8c46fd26eb07e5c71d3eccde86dedf29060200160405180910390a16040516330287a4760e11b81526001600160a01b03821690636050f48e90610675908b908b908b908b908b908b90600401610dbc565b600060405180830381600087803b15801561068f57600080fd5b505af11580156106a3573d6000803e3d6000fd5b50506040516301ffc9a760e01b8152634326434760e01b60048201526001600160a01b038e1692506301ffc9a7915060240160206040518083038186803b1580156106ed57600080fd5b505afa158015610701573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107259190610d71565b1561078657604051634326434760e01b81526001600160a01b038b81166004830152821690634326434790602401600060405180830381600087803b15801561076d57600080fd5b505af1158015610781573d6000803e3d6000fd5b505050505b6040516301ffc9a760e01b81526303c9666760e51b60048201526001600160a01b038c16906301ffc9a79060240160206040518083038186803b1580156107cc57600080fd5b505afa1580156107e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108049190610d71565b15610865576040516303c9666760e51b81526001600160a01b038a8116600483015282169063792ccce090602401600060405180830381600087803b15801561084c57600080fd5b505af1158015610860573d6000803e3d6000fd5b505050505b9a9950505050505050505050565b61087b610937565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600080546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff85161785556001805473ffffffffffffffffffffffffffffffffffffffff1916905560405193049190911692909183917ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec691a35050565b60005461010090046001600160a01b031680610a46576002546001600160a01b031663e37ce6fa336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156109b657600080fd5b505afa1580156109ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ee9190610d71565b6040518060400160405280601281526020017f496e76616c6964206d73672e73656e646572000000000000000000000000000081525090610a425760405162461bcd60e51b81526004016102449190610d1c565b5050565b60408051808201909152601281527f496e76616c6964206d73672e73656e64657200000000000000000000000000006020820152336001600160a01b03831614610a425760405162461bcd60e51b81526004016102449190610d1c565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f09150506001600160a01b038116610b595760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c6564000000000000000000006044820152606401610244565b919050565b600060208284031215610b7057600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461050657600080fd5b80356001600160a01b0381168114610b5957600080fd5b600060208284031215610bc957600080fd5b61050682610ba0565b60008060408385031215610be557600080fd5b610bee83610ba0565b9150610bfc60208401610ba0565b90509250929050565b60008083601f840112610c1757600080fd5b50813567ffffffffffffffff811115610c2f57600080fd5b602083019150836020828501011115610c4757600080fd5b9250929050565b600080600080600080600080600060c08a8c031215610c6c57600080fd5b610c758a610ba0565b9850610c8360208b01610ba0565b9750610c9160408b01610ba0565b965060608a013567ffffffffffffffff80821115610cae57600080fd5b610cba8d838e01610c05565b909850965060808c0135915080821115610cd357600080fd5b610cdf8d838e01610c05565b909650945060a08c0135915080821115610cf857600080fd5b50610d058c828d01610c05565b915080935050809150509295985092959850929598565b600060208083528351808285015260005b81811015610d4957858101830151858201604001528201610d2d565b81811115610d5b576000604083870101525b50601f01601f1916929092016040019392505050565b600060208284031215610d8357600080fd5b8151801515811461050657600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606081526000610dd060608301888a610d93565b8281036020840152610de3818789610d93565b90508281036040840152610df8818587610d93565b999850505050505050505056fea2646970667358221220ea726f7ba378e24ee3ba71db432059aab0c57f6e5bca7c81a6056d425c71c35864736f6c63430008090033

Verified Source Code Full Match

Compiler: v0.8.9+commit.e5eed63a EVM: london Optimization: Yes (1500 runs)
ERC165.sol 28 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "../interfaces/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;
    }
}
Clones.sol 82 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 *
 */
library Clones {
    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create(0, ptr, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create2(0, ptr, 0x37, salt)
        }
        require(instance != address(0), "ERC1167: create2 failed");
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
            mstore(add(ptr, 0x38), shl(0x60, deployer))
            mstore(add(ptr, 0x4c), salt)
            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
            predicted := keccak256(add(ptr, 0x37), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(address implementation, bytes32 salt)
        internal
        view
        returns (address predicted)
    {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}
Context.sol 23 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

/**
 * @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;
    }
}
IERC165.sol 24 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

/**
 * @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);
}
IERC721.sol 142 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "./IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}
GenericErrors.sol 19 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

abstract contract GenericErrors {
    string internal constant ERROR_INPUT_ARRAY_EMPTY = "Input array empty";
    string internal constant ERROR_INPUT_ARRAY_SIZE_MISMATCH = "Input array size mismatch";
    string internal constant ERROR_INVALID_MSG_SENDER = "Invalid msg.sender";
    string internal constant ERROR_UNEXPECTED_DATA_SIGNER = "Unexpected data signer";
    string internal constant ERROR_INSUFFICIENT_BALANCE = "Insufficient balance";
    string internal constant ERROR_WITHDRAW_UNSUCCESSFUL = "Withdraw unsuccessful";
    string internal constant ERROR_CONTRACT_IS_FINALIZED = "Contract is finalized";
    string internal constant ERROR_CANNOT_CHANGE_DEFAULT_OWNER = "Cannot change default owner";
    string internal constant ERROR_UNCLONEABLE_REFERENCE_CONTRACT = "Uncloneable reference contract";
    string internal constant ERROR_BIPS_OVER_100_PERCENT = "Bips over 100%";
    string internal constant ERROR_NO_ROYALTY_RECEIVER = "No royalty receiver";
    string internal constant ERROR_REINITIALIZATION_NOT_PERMITTED = "Re-initialization not permitted";
    string internal constant ERROR_ZERO_ETH_TRANSFER = "Zero ETH Transfer";
}
NiftyPermissions.sol 72 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "./ERC165.sol";
import "./GenericErrors.sol";
import "../interfaces/INiftyEntityCloneable.sol";
import "../interfaces/INiftyRegistry.sol";
import "../libraries/Context.sol";

abstract contract NiftyPermissions is Context, ERC165, GenericErrors, INiftyEntityCloneable {    

    event AdminTransferred(address indexed previousAdmin, address indexed newAdmin);

    // Only allow Nifty Entity to be initialized once
    bool internal initializedNiftyEntity;

    // If address(0), use enable Nifty Gateway permissions - otherwise, specifies the address with permissions
    address public admin;

    // To prevent a mistake, transferring admin rights will be a two step process
    // First, the current admin nominates a new admin
    // Second, the nominee accepts admin
    address public nominatedAdmin;

    // Nifty Registry Contract
    INiftyRegistry internal permissionsRegistry;    

    function initializeNiftyEntity(address niftyRegistryContract_) public {
        require(!initializedNiftyEntity, ERROR_REINITIALIZATION_NOT_PERMITTED);
        permissionsRegistry = INiftyRegistry(niftyRegistryContract_);
        initializedNiftyEntity = true;
    }       
    
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return         
        interfaceId == type(INiftyEntityCloneable).interfaceId ||
        super.supportsInterface(interfaceId);
    }        

    function renounceAdmin() external {
        _requireOnlyValidSender();
        _transferAdmin(address(0));
    }    

    function nominateAdmin(address nominee) external {
        _requireOnlyValidSender();
        nominatedAdmin = nominee;
    }

    function acceptAdmin() external {
        address nominee = nominatedAdmin;
        require(_msgSender() == nominee, ERROR_INVALID_MSG_SENDER);
        _transferAdmin(nominee);
    }
    
    function _requireOnlyValidSender() internal view {       
        address currentAdmin = admin;     
        if(currentAdmin == address(0)) {
            require(permissionsRegistry.isValidNiftySender(_msgSender()), ERROR_INVALID_MSG_SENDER);
        } else {
            require(_msgSender() == currentAdmin, ERROR_INVALID_MSG_SENDER);
        }
    }        

    function _transferAdmin(address newAdmin) internal {
        address oldAdmin = admin;
        admin = newAdmin;
        delete nominatedAdmin;        
        emit AdminTransferred(oldAdmin, newAdmin);
    }
}
INiftyRegistry.sol 7 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

interface INiftyRegistry {
   function isValidNiftySender(address sendingKey) external view returns (bool);
}
IERC721Cloneable.sol 9 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "./IERC721.sol";

interface IERC721Cloneable is IERC721 {
    function initializeERC721(string calldata name_, string calldata symbol_, string calldata baseURI_) external;    
}
NiftyCloneFactory.sol 77 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

//                ,|||||<              ~|||||'         `_+7ykKD%RDqmI*~`          
//                8@@@@@@8'           `Q@@@@@`     `^oB@@@@@@@@@@@@@@@@@R|`       
//               !@@@@@@@@Q;          L@@@@@J    '}Q@@@@@@QqonzJfk8@@@@@@@Q,      
//               Q@@@@@@@@@@j        `Q@@@@Q`  `m@@@@@@h^`         `?Q@@@@@*      
//              =@@@@@@@@@@@@D.      7@@@@@i  ~Q@@@@@w'              ^@@@@@*      
//              Q@@@@@m@@@@@@@Q!    `@@@@@Q  ;@@@@@@;                .txxxx:      
//             |@@@@@u *@@@@@@@@z   u@@@@@* `Q@@@@@^                              
//            `Q@@@@Q`  'W@@@@@@@R.'@@@@@B  7@@@@@%        :DDDDDDDDDDDDDD5       
//            c@@@@@7    `Z@@@@@@@QK@@@@@+  6@@@@@K        aQQQQQQQ@@@@@@@*       
//           `@@@@@Q`      ^Q@@@@@@@@@@@W   j@@@@@@;             ,6@@@@@@#        
//           t@@@@@L        ,8@@@@@@@@@@!   'Q@@@@@@u,        .=A@@@@@@@@^        
//          .@@@@@Q           }@@@@@@@@D     'd@@@@@@@@gUwwU%Q@@@@@@@@@@g         
//          j@@@@@<            +@@@@@@@;       ;wQ@@@@@@@@@@@@@@@Wf;8@@@;         
//          ~;;;;;              .;;;;;~           '!Lx5mEEmyt|!'    ;;;~          
//
// Powered By:    @niftygateway
// Author:        @niftynathang
// Collaborators: @conviction_1 
//                @stormihoebe
//                @smatthewenglish
//                @dccockfoster
//                @blainemalone

import "../interfaces/IERC721Cloneable.sol";
import "../interfaces/IERC721DefaultOwnerCloneable.sol";
import "../interfaces/IERC721MetadataGenerator.sol";
import "../interfaces/INiftyEntityCloneable.sol";
import "../libraries/Clones.sol";
import "../utils/NiftyPermissions.sol";

contract NiftyCloneFactory is NiftyPermissions {

    event ClonedERC721(address newToken);    
    event ClonedERC721MetadataGenerator(address metadataGenerator);    
    
    constructor(address niftyRegistryContract_) {
        initializeNiftyEntity(niftyRegistryContract_);
    }
        
    function cloneERC721(address implementation, address niftyRegistryContract_, address defaultOwner_, string calldata name_, string calldata symbol_, string calldata baseURI_) external returns (address) {
        _requireOnlyValidSender();
        require(IERC165(implementation).supportsInterface(type(IERC721Cloneable).interfaceId), "Not a valid ERC721 Token");        
        address clone = Clones.clone(implementation);

        emit ClonedERC721(clone);

        IERC721Cloneable(clone).initializeERC721(name_, symbol_, baseURI_);        

        if(IERC165(implementation).supportsInterface(type(INiftyEntityCloneable).interfaceId)) {
            INiftyEntityCloneable(clone).initializeNiftyEntity(niftyRegistryContract_);
        }

        if(IERC165(implementation).supportsInterface(type(IERC721DefaultOwnerCloneable).interfaceId)) {
            IERC721DefaultOwnerCloneable(clone).initializeDefaultOwner(defaultOwner_);
        }        

        return clone;
    }
    
    function cloneMetadataGenerator(address implementation, address niftyRegistryContract_) external returns (address) {
        _requireOnlyValidSender();
        require(IERC165(implementation).supportsInterface(type(IERC721MetadataGenerator).interfaceId), "Not a valid Metadata Generator");
        address clone = Clones.clone(implementation);        

        emit ClonedERC721MetadataGenerator(clone);
        
        if(IERC165(implementation).supportsInterface(type(INiftyEntityCloneable).interfaceId)) {
            INiftyEntityCloneable(clone).initializeNiftyEntity(niftyRegistryContract_);
        }        

        return clone;
    }
}
INiftyEntityCloneable.sol 9 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "./IERC165.sol";

interface INiftyEntityCloneable is IERC165 {
    function initializeNiftyEntity(address niftyRegistryContract_) external;
}
IERC721MetadataGenerator.sol 9 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "./IERC165.sol";

interface IERC721MetadataGenerator is IERC165 {    
    function tokenMetadata(uint256 tokenId, uint256 niftyType, bytes calldata data) external view returns (string memory);
}
IERC721DefaultOwnerCloneable.sol 9 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "./IERC165.sol";

interface IERC721DefaultOwnerCloneable is IERC165 {
    function initializeDefaultOwner(address defaultOwner_) external;    
}

Read Contract

admin 0xf851a440 → address
nominatedAdmin 0xe8ac6533 → address
supportsInterface 0x01ffc9a7 → bool

Write Contract 6 functions

These functions modify contract state and require a wallet transaction to execute.

acceptAdmin 0x0e18b681
No parameters
cloneERC721 0xa61e660d
address implementation
address niftyRegistryContract_
address defaultOwner_
string name_
string symbol_
string baseURI_
returns: address
cloneMetadataGenerator 0x44a0e477
address implementation
address niftyRegistryContract_
returns: address
initializeNiftyEntity 0x43264347
address niftyRegistryContract_
nominateAdmin 0xcd5ad4c5
address nominee
renounceAdmin 0x8bad0c0a
No parameters

Recent Transactions

No transactions found for this address