Contract 0x78A903e897C0Fc039211B62a9CBbc26C12E1B8DC

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x36ad34061dc95ed08f4e7f477b17d65311e123178708860fb7a6ab726801f7dbBurn266178382022-04-01 13:17:06133 days 5 hrs ago0xe43ae6e90c0b1fcb56733def02633a3e1fbfd727 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000786206539 30.054915679
0xc45cdf2d9acfcab6a71dcf22ef58adfceae1f1c1010782f44ba05e223d7b64d5Set Approval For...255600492022-03-04 5:55:02161 days 12 hrs ago0xbaac559fde662a97bdda8332c9596d43647d5959 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.0014033669 30.070000005
0x298c50ffb2f9ffbaaba041038840e0e2fa59fc474ccf545d8edce73bf0bd38d7Set Approval For...255383352022-03-03 16:29:04162 days 2 hrs ago0xf95d0ac7f613c31d09cf4fbaf0bb3b933be085eb IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.001400525806 30.009123776
0xc62b0c2ca6dde2b2c570c81c5d12c8f6fce1bc2aed2f96569ee52341a3aca334Burn249380622022-02-14 16:38:55179 days 1 hr ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000881383166 33.693305035
0xc4a7d74a9dfa8386a0f5ae9653f5a6a4b4c888f8e29ca591a56ec11b61aa0e91Burn249379642022-02-14 16:35:31179 days 1 hr ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000798747154 30.534315339
0x32d67cbbf8af1860f7468090be798a1dc7140031d18bc4bf3f4a0344175c698bBurn249378722022-02-14 16:32:09179 days 2 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000809534553 30.946693438
0xe4bac34d191bdf443c06a4ace27d345c400067c68d1d689e378b9188615e10b0Burn249375822022-02-14 16:22:09179 days 2 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000789682015 30.187775367
0xc914c1a4efed17e38cad2fb4b14f2d303794f2d93201b3c4ff62a268e00055b0Burn249264902022-02-14 9:43:28179 days 8 hrs ago0x5319834ae66756f593b222635b282695d551433c IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.001124522731 42.987986206
0x4a5c542e33777126b2bf8212423f68f8be19b2810b6a640b0ff982b406d140b8Burn249257042022-02-14 9:14:20179 days 9 hrs ago0x50e3a4cade73fdab29703d8e7dbad99ec70adc00 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000141386627 5.407374762
0x36b8bcf3db846bd487ba8982c06a812d97fe118c72eb4086f6ad85922bd4290eBurn249247942022-02-14 8:38:44179 days 9 hrs ago0x50e3a4cade73fdab29703d8e7dbad99ec70adc00 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000820766809 31.390477267
0x398ed92ffac5251c0d63abce006c538936395852067b5d4b59e53c6236ca77e6Burn249247652022-02-14 8:37:46179 days 9 hrs ago0x50e3a4cade73fdab29703d8e7dbad99ec70adc00 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.000838341658 32.06263275
0x8d06967b53debf78540ac90b744dab8873686e454157fb2500ef82bccdd72ff0Set Approval For...249207152022-02-14 6:14:11179 days 12 hrs ago0x50e3a4cade73fdab29703d8e7dbad99ec70adc00 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.00144677 31.000000012
0xae7fc995e21ee39622a8c4c72b3a93bdbb1b09ee74d75fc746ffdd3c6d53122fSet Approval For...247036332022-02-08 17:49:27185 days 45 mins ago0x690c6fb8521d3e01c4f3c9e94a2fe7e60f0628a9 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.002041942196 43.752779014
0x7401bfff7ba09a10e538751bf1ae7563a2d40b950dc9f7e486c15fdbb89d4760Set Approval For...244712382022-02-02 18:33:14191 days 2 mins ago0x5ad92155a67b1ee5031b75a1cdd08b48e638a550 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.001411331505 30.240657934
0xf2a081efcc6fce07eb1134cec5433bda7de3fd8df9b1439c6a26cc5b6f9754dfSet Approval For...241825982022-01-26 10:29:35198 days 8 hrs ago0xaf33423f92c91bb95b52abefa204afa5e8fdb0f7 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.002877029792 61.646235106
0x256f91ab24ab98783d42e0d299aebdc1dc8bd7145b498751e423891c0e4ce85aSet Approval For...241137402022-01-24 17:36:01200 days 59 mins ago0xf47fe532be622ca5aac43a2472d7c62556f7f041 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.017086328264 366.109455
0xd3320f962a7041ff2de98d7d12a66ae0c0f5d1df247641b979a59cfd109d0c08Set Approval For...241135832022-01-24 17:30:35200 days 1 hr ago0x0a3a356085b4a1f0dcfdb5a54a4124862de95fb2 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.01225627064 262.615612613
0x5f90cf77d4ded47c306ebae8804da8e97a207523be36c98a81cddf8147c684a8Set Approval For...239931162022-01-21 16:43:24203 days 1 hr ago0xbb68238523b4fd7bae30ae81a1dbb24667a63c39 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.022725683347 486.944147144
0x917f3b64ce21d4c6678434f18cc691f58672e13aaacc4a33096d1328965181a9Burn239824392022-01-21 9:55:00203 days 8 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.001403177272 53.640325414
0xae891522a8f5a857ef5de1544bb471ab2d13b89655b499e940bf269321852c1bBurn239819092022-01-21 9:36:48203 days 8 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.001300597133 49.718916395
0xe833f0f53194195603281c82040123e2024da6af55d5425046156a5e6c746cc6Burn239523312022-01-20 16:12:17204 days 2 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.002336500526 89.319183707
0x9b1f474c3436d48de18255d34d67c4db11bad6bc73d8e1b2b5883adbdee678adSet Approval For...239512572022-01-20 15:32:59204 days 3 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.006199838476 132.844192768
0x2db9058c646ca2045672a1a732c33bad4f7716fc7e97a628270701c8e81bd1a9Burn239476762022-01-20 13:25:05204 days 5 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.002656885163 101.566771021
0xc744fdb03dd4e78fe3ad67396a2257de414695172ef9c8975bbf51ef7fbc9960Burn239473632022-01-20 13:14:19204 days 5 hrs ago0xf3f9d1d30ab6f4af253acbbb7db549eb44646fd4 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.00274780523 105.042441637
0x8df253a55aac1323367e5561ed233f500537547d4fe2eb95aa9144c93e27b7f0Set Approval For...239417992022-01-20 9:58:19204 days 8 hrs ago0xb907e0baa83a9cbc27a66f1952d5ece6174f3596 IN  0x78a903e897c0fc039211b62a9cbbc26c12e1b8dc0 MATIC0.001611114407 34.521414341
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FERC1155V1

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 20 : FERC1155V1.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

import {IFERC1155V1} from "./IFERC1155V1.sol";
import {IERC1155MetadataURI} from "./IERC1155MetadataURI.sol";
import {ERC2981Base} from "./ERC2981Base.sol";
import {ERC2981PerTokenRoyalties} from './ERC2981PerTokenRoyalties.sol';
import {MintERC1155Order, MintERC1155BatchOrder} from "../shared/libraries/LibOrders.sol"; 

/// @dev Funrise ERC1155-compliant contract.
/// @dev Based on code by OpenZeppelin.
/// @author Nypox
contract FERC1155V1 is Context, ERC165, IFERC1155V1, IERC1155MetadataURI, ERC2981PerTokenRoyalties, AccessControl {
    using Address for address;

//  Child chain manager proxy
    bytes32 public constant DEPOSITOR_ROLE = keccak256("DEPOSITOR_ROLE");

//  Only minter is allowed to mint
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

//  EIP-1155: Multi Token Standard
    bytes4 private constant _INTERFACE_ERC1155 = 0xd9b67a26;

//  EIP-1155: Multi Token Standard. Metadata Extension
    bytes4 private constant _INTERFACE_ERC1155_METADATA_URI = 0x0e89341c; // bytes4(keccak256('uri(uint256)')) == 0x0e89341c

//  Contract-level metadata
    bytes4 private constant _INTERFACE_CONTRACT_URI = 0xe8a3d485; // bytes4(keccak256('contractURI()')) == 0xe8a3d485

//  Token name
    string public name;
    
//  Token symbol
    string public symbol;

//  Contract-level metadata
    string public contractURI;

//  Shared token URI prefix
    string private _baseTokenURI;

//  Token ID => account => balance
    mapping(uint256 => mapping(address => uint256)) private _balances;

//  Account => operator => approval
    mapping(address => mapping(address => bool)) private _operatorApprovals;

//  Token ID => token URI
    mapping(uint256 => string) private _tokenURIs;

//  Token ID => token URI is permanent
    mapping(uint256 => bool) public isPermanentURI;

//  Token ID => creator
    mapping (uint256 => address) private _creators;

//  Token ID => token supply
    mapping (uint256 => uint256) public tokenSupply;

    constructor(
        address minter,
        address childChainManager,
        string memory name_,
        string memory symbol_,
        string memory baseTokenURI,
        string memory contractURI_
    ) {
        name = name_;
        symbol = symbol_;

        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        grantRole(MINTER_ROLE, minter);
        grantRole(DEPOSITOR_ROLE, childChainManager);

        setBaseTokenURI(baseTokenURI);
        setContractURI(contractURI_);
    }

    function setBaseTokenURI(string memory baseTokenURI) public onlyRole(DEFAULT_ADMIN_ROLE) {

        _baseTokenURI = baseTokenURI;
    }

    function setContractURI(string memory contractURI_) public onlyRole(DEFAULT_ADMIN_ROLE) {

        contractURI = contractURI_;
    }

/// @dev Sets token URI for token `id`.
/// @dev The creator must own the full supply of the token.
    function setTokenURI(
        uint256 id,
        string calldata newUri,
        bool freeze
    ) public override creatorOrMinterOnly(id) creatorIsFullTokenOwner(id) onlyImpermanentURI(id) {

        if (freeze) {
            require(
                bytes(newUri).length > 0,
                "invalid uri"
            );
            isPermanentURI[id] = true;
        }

        _tokenURIs[id] = newUri;
        emit URI(uri(id), id);
    }

/// @dev EIP-1155: Multi Token Standard. Metadata Extension.
/// @dev {IERC1155MetadataURI}.
    function uri(uint256 id) public view virtual override returns (string memory) {
 
        return string(abi.encodePacked(_baseTokenURI, _tokenURIs[id]));
    }

/// @dev Returns the amount of tokens of token type `id` owned by `account`.
/// @dev `account` cannot be the zero address.
    function balanceOf(address account, uint256 id)
        public
        view
        override
        returns (uint256) {

        require(account != address(0), "balance query for the zero address");
        return _balances[id][account];
    }

/// @dev Returns the creator of `id` token.
    function creatorOf(uint256 id) public view returns (address) {
      return _creators[id];
    }

/// @dev Batched version of {balanceOf}.
/// @dev `accounts` and `ids` must have the same length.
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        override
        returns (uint256[] memory) {

        require(accounts.length == ids.length, "accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

/// @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`.
/// @dev `operator` cannot be the caller if not minter.
/// @dev Emits a {ApprovalForAll} event.
    function setApprovalForAll(address operator, bool approved)
        public
        override {

        address caller = _msgSender();

        if (caller == operator) {
            revert("setting approval status for self");
        }
        _operatorApprovals[caller][operator] = approved;
        emit ApprovalForAll(caller, operator, approved);
    }

/// @dev Returns true if `operator` is approved to transfer `account`'s tokens.
    function isApprovedForAll(address account, address operator)
        public
        view
        override
        returns (bool) {

        return _operatorApprovals[account][operator];
    } 

/// @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
/// @dev `to` cannot be the zero address.
/// @dev If the caller is not `from`, it must be have been approved to spend `from`'s tokens via {setApprovalForAll}.
/// @dev `from` must have a balance of tokens of type `id` of at least `amount`.
/// @dev If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received}.
/// @dev Emits a {TransferSingle} event.
    function safeTransferFrom(
        address from,
        address to, 
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public override {

        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "caller is not owner nor approved"
        );

        require(to != address(0), "transfer to the zero address");

        address operator = _msgSender();

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

/// @dev Batched version of {safeTransferFrom}.
/// @dev Emits a {TransferBatch} event.
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public override {

        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "transfer caller is not owner nor approved"
        );

        require(ids.length == amounts.length, "ids and amounts length mismatch");
        require(to != address(0), "transfer to the zero address");

        address operator = _msgSender();

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

/// @dev Mints `order.amount` tokens of token type `order.id` to `order.to`.
/// @dev Enables approval for contract owner to transfer tokens if `approve` is true.
/// @dev Only contract owner is allowed to call this function.
/// @dev Emits a {TransferSingle} event.
/// @dev Emits a {URI} event.
    function mint(
        MintERC1155Order calldata order,
        bool approve,
        bool freezeTokenURI,
        bytes memory data
    ) external override onlyRole(MINTER_ROLE) {

        require(_creators[order.id] == address(0), "token is already minted");
        require(order.to != address(0), "mint to the zero address");
        require(order.amount > 0, "zero supply");
        require(bytes(order.uri).length > 0, "invalid uri");

        address minter = _msgSender();

        _balances[order.id][order.to] += order.amount;
        _creators[order.id] = order.to;
        tokenSupply[order.id] = order.amount;
        _tokenURIs[order.id] = order.uri;

        if (freezeTokenURI) {
            isPermanentURI[order.id] = true;
        }

        emit TransferSingle(minter, address(0), order.to, order.id, order.amount);

        _doSafeTransferAcceptanceCheck(minter, address(0), order.to, order.id, order.amount, data);

        if (order.royalty.amount > 0) {
            _setTokenRoyalty(order.id, order.royalty.recipient, order.royalty.amount);
        }

        emit URI(uri(order.id), order.id);

        if (approve) {
            _operatorApprovals[order.to][minter] = true;
            emit ApprovalForAll(order.to, minter, true);
        }
    }

/// @dev Batched version of {mint}.
/// @dev Emits a {TransferBatch} event.
/// @dev Emits {URI} events.
    function mintBatch(
        MintERC1155BatchOrder calldata order,
        bool approve,
        bool freezeTokenURI,
        bytes memory data
    ) external override onlyRole(MINTER_ROLE) {

        require(order.ids.length == order.uris.length, "ids and uris length mismatch");

        address minter = _msgSender();

        _mintBatch(
            order.to,
            order.ids,
            order.amounts,
            data
        );

        for (uint256 i = 0; i < order.ids.length; i++) {
            uint256 id = order.ids[i];

            require(bytes(order.uris[i]).length > 0, "invalid uri");

            _tokenURIs[id] = order.uris[i];

            if (freezeTokenURI) {
                isPermanentURI[id] = true;
            }

            emit URI(uri(id), id);

            if (approve) {
                _operatorApprovals[order.to][minter] = true;
                emit ApprovalForAll(order.to, minter, true);
            }

            if (order.royalty.amount > 0) {
                _setTokenRoyalty(id, order.royalty.recipient, order.royalty.amount);
            }
        }
    }

    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "mint to the zero address");
        require(ids.length == amounts.length, "ids and amounts length mismatch");

        address operator = _msgSender();

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];

            require(_creators[id] == address(0), "token is already minted");
            require(amounts[i] > 0, "zero supply");

            _balances[id][to] += amounts[i];
            _creators[id] = to;
            tokenSupply[id] = amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

/// @dev Burns `value` tokens of token `id` from `account`.
/// @dev Burned token cannot be re-minted
/// @dev Emits a {TransferSingle} event.
    function burn(
        address account,
        uint256 id,
        uint256 amount
    ) public override {

        require(account != address(0), "burn from the zero address");
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "caller is not owner nor approved"
        );

        uint256 fromBalance = _balances[id][account];
        require(fromBalance >= amount, "burn amount exceeds balance");
        unchecked {
            _balances[id][account] = fromBalance - amount;
        }

        emit TransferSingle(_msgSender(), account, address(0), id, amount);
    }

/// @dev Batched version of {burn}.
/// @dev Emits a {TransferBatch} event.
    function burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) public override {

        require(account != address(0), "burn from the zero address");
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "caller is not owner nor approved"
        );
        require(ids.length == amounts.length, "ids and amounts length mismatch");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][account];
            require(fromBalance >= amount, "burn amount exceeds balance");
            unchecked {
                _balances[id][account] = fromBalance - amount;
            }
        }

        emit TransferBatch(_msgSender(), account, address(0), ids, amounts);
    }

/// @dev Called when tokens are deposited on root chain.
/// @param user user address for whom deposit is being done.
/// @param depositData abi encoded ids array and amounts array.
    function deposit(
        address user,
        bytes calldata depositData
    ) external override onlyRole(DEPOSITOR_ROLE) {
        (
            uint256[] memory ids,
            uint256[] memory amounts,
            bytes memory data
        ) = abi.decode(depositData, (uint256[], uint256[], bytes));

        require(
            user != address(0),
            "invalid deposit user"
        );

        _mintBatch(user, ids, amounts, data);
    }

/// @dev Called when user wants to batch withdraw tokens to root chain.
    function withdrawBatch(
        uint256[] calldata ids,
        uint256[] calldata amounts
    ) external override {
        burnBatch(_msgSender(), ids, amounts);
    }

/// @dev {IERC165}.
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override (ERC165, IERC165, ERC2981Base, AccessControl)
        returns (bool) {

        return
            interfaceId == _INTERFACE_ERC1155 || 
            interfaceId == _INTERFACE_ERC1155_METADATA_URI ||
            interfaceId == _INTERFACE_CONTRACT_URI || 
            super.supportsInterface(interfaceId);
    }

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {

        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("transfer to non ERC1155Receiver implementer");
            }
        }
    }

    modifier onlyImpermanentURI(uint256 id) {

        require(
            !isPermanentURI[id],
            "uri is frozen"
        );
        _;
    }

    modifier creatorIsFullTokenOwner(uint256 id) {

        require(
            balanceOf(_creators[id], id) == tokenSupply[id],
            "creator is not full owner"
        );
        _;
    } 

    modifier creatorOrMinterOnly(uint256 id) {

        address caller = _msgSender();

        require(
            _creators[id] == caller || hasRole(MINTER_ROLE, caller),
            "not allowed"
        );
        _;
    } 
}

File 2 of 20 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 3 of 20 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 4 of 20 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {

    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external
        returns(bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external
        returns(bytes4);
}

File 5 of 20 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 6 of 20 : AccessControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    function hasRole(bytes32 role, address account) external view returns (bool);
    function getRoleAdmin(bytes32 role) external view returns (bytes32);
    function grantRole(bytes32 role, address account) external;
    function revokeRole(bytes32 role, address account) external;
    function renounceRole(bytes32 role, address account) external;
}

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping (address => bool) members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev 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 {_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 Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId
            || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if(!hasRole(role, account)) {
            revert(string(abi.encodePacked(
                "AccessControl: account ",
                Strings.toHexString(uint160(account), 20),
                " is missing role ",
                Strings.toHexString(uint256(role), 32)
            )));
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

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

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

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

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        emit RoleAdminChanged(role, getRoleAdmin(role), adminRole);
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 7 of 20 : IFERC1155V1.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

import {MintERC1155Order, MintERC1155BatchOrder} from "../shared/libraries/LibOrders.sol"; 

/// @dev Required interface of Funrise ERC1155-compliant contract.
/// @dev Based on code by OpenZeppelin.
/// @author Nypox
interface IFERC1155V1 is IERC165 {

/// @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

/// @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all transfers.
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

/// @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`.
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

/// @dev Emitted when the URI for token type `id` changes to `value`
    event URI(string value, uint256 indexed id);

/// @dev Returns the amount of tokens of token type `id` owned by `account`.
/// @dev `account` cannot be the zero address.
    function balanceOf(address account, uint256 id) external view returns (uint256);

/// @dev Batched version of {balanceOf}.
/// @dev `accounts` and `ids` must have the same length.
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

/// @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`.
/// @dev `operator` cannot be the caller.
    function setApprovalForAll(address operator, bool approved) external;

/// @dev Returns true if `operator` is approved to transfer `account`'s tokens.
    function isApprovedForAll(address account, address operator) external view returns (bool);

/// @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
/// @dev `to` cannot be the zero address.
/// @dev If the caller is not `from`, it must be have been approved to spend `from`'s tokens via {setApprovalForAll}.
/// @dev `from` must have a balance of tokens of type `id` of at least `amount`.
/// @dev If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received}.
/// @dev Emits a {TransferSingle} event.
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

/// @dev Batched version of {safeTransferFrom}.
/// @dev Emits a {TransferBatch} event.
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;

/// @dev Returns the creator of `id` token.
    function creatorOf(uint256 id) external view returns (address);

/// @dev Mints `order.amount` tokens of token type `order.id` to `order.to`.
/// @dev Enables approval for minter to transfer tokens if `approve` is true.
/// @dev Only minter is allowed to call this function.
/// @dev Emits a {TransferSingle} event.
/// @dev Emits a {URI} event.
    function mint(
        MintERC1155Order calldata order,
        bool approve,
        bool freezeTokenURI,
        bytes memory data
    ) external;

/// @dev Batched version of {mint}.
/// @dev Emits a {TransferBatch} event.
/// @dev Emits {URI} events.
    function mintBatch(
        MintERC1155BatchOrder calldata order,
        bool approve,
        bool freezeTokenURI,
        bytes memory data
    ) external;

/// @dev Burns `value` tokens of token `id` from `account`.
/// @dev Burned token cannot be re-minted
/// @dev Emits a {TransferSingle} event.
    function burn(
        address account,
        uint256 id,
        uint256 value
    ) external;

/// @dev Batched version of {burn}.
/// @dev Emits a {TransferBatch} event.
    function burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory values
    ) external;

/// @dev Sets token URI for token `id`.
/// @dev The creator must own the full supply of the token.
    function setTokenURI(
        uint256 id,
        string calldata newUri,
        bool freeze
    ) external;

/// @notice Called when tokens are deposited on root chain.
/// @param user user address for whom deposit is being done.
/// @param depositData abi encoded ids array and amounts array.
    function deposit(
        address user,
        bytes calldata depositData
    ) external;

// /// @notice Called when user wants to withdraw single token to root chain.
//     function withdrawSingle(
//         uint256 id,
//         uint256 amount
//     ) external;

/// @notice Called when user wants to batch withdraw tokens to root chain.
    function withdrawBatch(
        uint256[] calldata ids,
        uint256[] calldata amounts
    ) external;
}

File 8 of 20 : IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title ERC-1155: Multi Token Standard, optional metadata extension.
interface IERC1155MetadataURI {

/// @notice A distinct Uniform Resource Identifier (URI) for a given token.
    function uri(uint256 _id) external view returns (string memory);
}

File 9 of 20 : ERC2981Base.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/utils/introspection/ERC165.sol';

import {IERC2981Royalties} from './IERC2981Royalties.sol';

/// @dev Adds ERC2981 support to ERC721 and ERC1155
abstract contract ERC2981Base is ERC165, IERC2981Royalties {
    
    struct RoyaltyInfo {
        address recipient;
        uint24 amount;
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override
        returns (bool)
    {
        return
            interfaceId == type(IERC2981Royalties).interfaceId ||
            super.supportsInterface(interfaceId);
    }
}

File 10 of 20 : ERC2981PerTokenRoyalties.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/utils/introspection/ERC165.sol';

import {ERC2981Base} from './ERC2981Base.sol';

/// @dev Adds ERC2981 support to ERC721 and ERC1155
abstract contract ERC2981PerTokenRoyalties is ERC2981Base {
    
    mapping(uint256 => RoyaltyInfo) internal _royalties;

/// @dev Sets token royalties
/// @param tokenId the token id fir which we register the royalties
/// @param recipient recipient of the royalties
/// @param value percentage (using 2 decimals - 10000 = 100, 0 = 0)
    function _setTokenRoyalty(
        uint256 tokenId,
        address recipient,
        uint256 value
    ) internal {
        require(value <= 10000, 'ERC2981Royalties: Too high');
        _royalties[tokenId] = RoyaltyInfo(recipient, uint24(value));
    }

    function royaltyInfo(uint256 tokenId, uint256 value)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        RoyaltyInfo memory royalties = _royalties[tokenId];
        receiver = royalties.recipient;
        royaltyAmount = (value * royalties.amount) / 10000;
    }
}

File 11 of 20 : LibOrders.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

import {ERC2981Base} from "../../tokens/ERC2981Base.sol";
import {
    LibAppStorage,
    AppStorage,
    AssetStandard,
    AssetVersion
} from "../../marketplace/libraries/LibAppStorage.sol";

// Mint / Off-chain fixed price listing

struct MintERC721Order {
    address token;
    address to;
    uint256 id;
    string uri;
    ERC2981Base.RoyaltyInfo royalty;
}

struct MintERC721BatchOrder {
    address token;
    address to;
    uint256[] ids;
    string[] uris;
    ERC2981Base.RoyaltyInfo royalty;
}

struct MintERC1155Order {
    address token;
    address to;
    uint256 id;
    uint256 amount;
    string uri;
    ERC2981Base.RoyaltyInfo royalty;
}

struct MintERC1155BatchOrder {
    address token;
    address to;
    uint256[] ids;
    uint256[] amounts;
    string[] uris;
    ERC2981Base.RoyaltyInfo royalty;
}

struct RedeemERC721Order {
    address token;
    address paymentToken;
    address targetToken;
    address from;
    address to;
    uint256 id;
    uint256 price;
}

struct RedeemERC721BundleOrder {
    address[] tokens;
    address paymentToken;
    address targetToken;
    address from;
    address to;
    uint256[] ids;
    uint256[] prices;
}

struct RedeemERC1155Order {
    address token;
    address paymentToken;
    address targetToken;
    address from;
    address to;
    uint256 id;
    uint256 amount;
    uint256 price;
}

struct RedeemERC1155BundleOrder {
    address[] tokens;
    address paymentToken;
    address targetToken;
    address from;
    address to;
    uint256[] ids;
    uint256[] amounts;
    uint256[] prices;
}

// FixedPrice

struct FixedPriceListOrder {
    address owner;                          // owner of assets, seller
    address paymentToken;                   // this token is transferred from a buyer
    address targetToken;                    // this token is transferred to a seller
    uint256 bundleId;                       // target bundle (edit bundle if exists)
    address[] tokens;                       // asset tokens
    uint256[] ids;                          // asset token IDs
    uint256[] amounts;                      // asset token amounts
    uint256[] prices;                       // asset prices
    string[] uris;                          // asset token URIs (lazy mint only)
    AssetStandard[] standards;              // asset type
    ERC2981Base.RoyaltyInfo[] royalties;    // ERC2981 royalties (lazy mint only)
    bool minted;                            // assets existence (lazy mint if false)
}

struct FixedPriceUnlistOrder {
    address owner;
    uint256 bundleId;          
}

struct FixedPriceRedeemOrder {
    address buyer;                          // payer and buyer
    uint256 bundleId;                       // target bundle
    uint256[] amounts;                      // asset token amounts
}

// Auction

struct AuctionListOrder {
    address owner;                          // bundle owner
    address paymentToken;                   // this token is transferred from a bidder
    address targetToken;                    // this token is transferred to the seller
    uint256 bundleId;                       // target bundle (edit bundle if exists)
    address[] tokens;                       // NFT contract addresses
    uint256[] ids;                          // token IDs
    uint256[] amounts;                      // token amounts
    uint256[] startingPrices;               // bids below cumulative starting price are rejectd
    uint256 reservePrice;                   // do not auto sell if final highest bid is below this value
    uint64 duration;                        // auction dutation in seconds
    string[] uris;                          // asset token URIs (lazy mint / virtual only)
    AssetStandard[] standards;              // asset type
    ERC2981Base.RoyaltyInfo[] royalties;    // ERC2981 royalties (lazy mint / virtual only)
    bool minted;                            // assets existence (lazy mint if false)
    bool deferred;                          // virtual if true (lazy mint if true)
}

struct AuctionBidOrder {
    address bidder;                         // bid maker
    uint256 bundleId;                       // target bundle
    uint256 value;                          // total bid value
}

struct AuctionSetOwnerOrder {
    address owner;                          // bundle owner
    address targetToken;                    // this token is transferred to the seller
    uint256 bundleId;                       // target bundle
    string[] uris;                          // asset token URIs
    ERC2981Base.RoyaltyInfo royalty;        // ERC2981 royalty
}

struct AuctionResolveOrder {
    uint256 bundleId;                       // target bundle
    bool accept;                            // accept the highest bid or close the auction and return assets
}

/// @title Order structures.
/// @author Nypox
library LibOrders {

    function hashMintOrderId(
        address token,
        uint256 id
    ) internal view returns (bytes32) {
        
        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    token,
                    id,
                    block.chainid
                )
            )
        );
    }

    function hashMintOrderIds(
        address token,
        uint256[] memory ids
    ) internal view returns (bytes32) {
        
        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    token,
                    ids,
                    block.chainid
                )
            )
        );
    }

    function hashMintERC721Order(
        MintERC721Order calldata order
    ) internal view returns (bytes32) {
        
        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.token,
                    order.to,
                    order.id,
                    order.uri,
                    order.royalty.recipient,
                    order.royalty.amount,
                    block.chainid
                )
            )
        );
    }

    function hashMintERC721BatchOrder(
        MintERC721BatchOrder calldata order
    ) internal view returns (bytes32) {

        bytes memory uris;
        for (uint i = 0; i < order.uris.length; i++) {
            uris = abi.encodePacked(uris, order.uris[i]);
        }
        
        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.token,
                    order.to,
                    order.ids,
                    uris,
                    order.royalty.recipient,
                    order.royalty.amount,
                    block.chainid
                )
            )
        );
    }

    function hashMintERC1155Order(
        MintERC1155Order calldata order
    ) internal view returns (bytes32) {
        
        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.token,
                    order.to,
                    order.id,
                    order.amount,
                    order.uri,
                    order.royalty.recipient,
                    order.royalty.amount,
                    block.chainid
                )
            )
        );
    }

    function hashMintERC1155BatchOrder(
        MintERC1155BatchOrder calldata order
    ) internal view returns (bytes32) {
        
        bytes memory uris;
        for (uint i = 0; i < order.uris.length; i++) {
            uris = abi.encodePacked(uris, order.uris[i]);
        }

        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.token,
                    order.to,
                    order.ids,
                    order.amounts,
                    uris,
                    order.royalty.recipient,
                    order.royalty.amount,
                    block.chainid
                )
            )
        );
    }

    function hashRedeemERC721Order(
        RedeemERC721Order calldata order
    ) internal view returns (bytes32) {

        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.token,
                    order.from,
                    order.id,
                    order.paymentToken,
                    order.targetToken,
                    order.price,
                    block.chainid
                )
            )
        );
    }

    function hashRedeemERC721BundleOrder(
        RedeemERC721BundleOrder calldata order
    ) internal view returns (bytes32) {

        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.tokens,
                    order.from,
                    order.ids,
                    order.paymentToken,
                    order.targetToken,
                    order.prices,
                    block.chainid
                )
            )
        );
    }

    function hashRedeemERC1155Order(
        RedeemERC1155Order calldata order
    ) internal view returns (bytes32) {

        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.token,
                    order.from,
                    order.id,
                    order.paymentToken,
                    order.targetToken,
                    order.amount,
                    order.price,
                    block.chainid
                )
            )
        );
    }

    function hashRedeemERC1155BundleOrder(
        RedeemERC1155BundleOrder memory order
    ) internal view returns (bytes32) {

        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.tokens,
                    order.from,
                    order.ids,
                    order.paymentToken,
                    order.targetToken,
                    order.amounts,
                    order.prices,
                    block.chainid
                )
            )
        );
    }

    function hashAuctionSetOwnerOrder(
        AuctionSetOwnerOrder memory order
    ) internal view returns (bytes32) {

        bytes memory uris;
        for (uint i = 0; i < order.uris.length; i++) {
            uris = abi.encodePacked(uris, order.uris[i]);
        }

        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.owner,
                    order.targetToken,
                    order.bundleId,
                    uris,
                    order.royalty.recipient,
                    order.royalty.amount,
                    block.chainid
                )
            )
        );
    }

    function hashAuctionResolveOrder(
        AuctionResolveOrder memory order
    ) internal view returns (bytes32) {

        return ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    order.bundleId,
                    block.chainid
                )
            )
        );
    }
}

File 12 of 20 : IERC165.sol
// SPDX-License-Identifier: MIT

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 13 of 20 : Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = alphabet[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

}

File 14 of 20 : ECDSA.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
        } else if (signature.length == 64) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                let vs := mload(add(signature, 0x40))
                r := mload(add(signature, 0x20))
                s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
                v := add(shr(255, vs), 27)
            }
        } else {
            revert("ECDSA: invalid signature length");
        }

        return recover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
        require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");

        return signer;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 15 of 20 : LibAppStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {LibDiamond} from "../../shared/libraries/LibDiamond.sol";
import {LibCommon} from "../../shared/libraries/LibCommon.sol";
import {ERC2981Base} from "../../tokens/ERC2981Base.sol";

enum AssetStandard {
    ERC721,
    ERC1155
}

enum AssetVersion {
    None,                                // standard-compliant external contract
    V1                                   // Funrise mintable contract V1
}

enum BundleState {
    Idle,                                // not on sale, default
    OnSale,                              // on sale, minted
    Pending                              // on sale, not minted
}

enum ListingType {
    Offchain,                            // not listed / listed off-chain
    FixedPrice,                          // fixed price listing
    Auction,                             // auction listing
    VirtualAuction                       // virtual auction listing
}

// Represents ERC721 / ERC1155 token
struct Asset {
    uint256 bundleId;                    // current bundle
    uint256 amount;                      // amount of token
    uint256 price;                       // fixed price / starting price
    string uri;                          // token URI
    AssetStandard standard;    
    AssetVersion version;    
    ERC2981Base.RoyaltyInfo royalty;
}

// Represents a bid on a {Bundle}
struct Bid {
    address bidder;                 // payer and bundle recipient
    uint256 value;                  // bid value
    // uint64 timestamp;               // block time
    bool active;                    // bid is active: payment token is locked
}

// Represents a set of {Asset}s
struct Bundle {
    address owner;                       // owner of assets, seller
    address paymentToken;                // this token is transferred from a buyer
    address targetToken;                 // this token is transferred to a seller
    address[] tokens;                    // asset tokens
    uint256[] ids;                       // asset token IDs
    uint256 reservePrice;                // do not accept the highest bid if its value is below this price
    uint64 listingTime;                  // listing block time
    uint64 duration;                     // auction duration
    Bid bid;                             // current bid
    BundleState state;
    ListingType listingType;
}

struct Market {
    // owner -> token -> token id -> asset id
    mapping(address => mapping(address => mapping(uint256 => Asset))) assets;

    // bundle id -> bundle
    mapping(uint256 => Bundle) bundles;
}

struct MarketConfig {
    mapping(address => bool) signers;                                           // newly minted tokens must have IDs signed by a signer
    mapping(address => bool) resolvers;                                         // resolves listings

    mapping(AssetStandard => mapping(AssetVersion => address)) assetTokens;     // native mitable asset tokens
    mapping(AssetStandard => AssetVersion) defaultTokenVersions;                // default asset token versions
    mapping(address => AssetStandard) assetTokenStandards;                      // asset token standards
    mapping(address => AssetVersion) assetTokenVersions;                        // asset token versions

    mapping(address => uint256[]) comissionSteps;                               // payment token => comission steps
    mapping(address => uint24[]) comissionPercentages;                          // payment token => comission step values
    mapping(address => uint256) minPrices;                                      // minimum asset prices (payment token => minimum price)
    mapping(address => bool) targetTokens;                                      // seller receives these ERC20 tokens (whitelist)
    address comissionReceiver;                                                  // comissions are transfered to this address
    address platformToken;                                                      // FNR ERC20 token

    uint24 maxRoyalty;                                                          // maximum royalty value
    uint256 maxBundleSize;                                                      // maximum number of assets in a bundle

    mapping(address => uint256) auctionSteps;                                   // payment token => minimal value difference required for overbid
    mapping(address => uint256) minReservePriceTotal;                           // payment token -> value
    uint256 minAuctionDuration;                                                 // in seconds
    uint256 maxAuctionDuration;                                                 // in seconds
    uint64 auctionProlongation;                                                 // duration is increased by this value after each successful bid
    uint64 auctionRelaxationTime;                                               // resolver can resolve an auction after {auction duration + relaxation time}

    bool skipPlatformToken;                                                     // skip platform token for the path {payment token => platform token => target token}
}

struct ExchangeConfig {
    address router;                                                             // swap router
    uint256 maxSwapDelay;                                                       // deadline = block.timestamp + maxDelay
}

struct Accounts {
    mapping(bytes32 => bool) roots;                                             // Merkle roots
    mapping(address => bool) refillBlacklist;                                   // do not refill these accounts
    uint256 refillValue;                                                        // registered accounts are refilled with this amount
}

struct AppStorage {
    Accounts accounts;
    Market market;
    MarketConfig marketConfig;
    ExchangeConfig exchangeConfig;
}

library LibAppStorage {

    function diamondStorage() internal pure returns (AppStorage storage ds) {
        assembly {
            ds.slot := 0
        }
    }
}

contract Modifiers {

    modifier onlyDiamondOwner() {
        LibDiamond.enforceIsContractOwner();
        _;
    }

    modifier isSender(address _address) {
        require(
            _address == LibCommon.msgSender(),
            "NOT_SENDER"
        );
        _;
    }

    modifier notEqual(address _address1, address _address2) {
        require(
            _address1 != _address2,
            "WRONG_ADDRESS"
        );
        _;
    }
}

File 16 of 20 : IERC2981Royalties.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title IERC2981Royalties
/// @dev Interface for the ERC2981 - Token Royalty standard
interface IERC2981Royalties {

/// @notice Called with the sale price to determine how much royalty is owed and to whom.
/// @param tokenId - the NFT asset queried for royalty information
/// @param value - the sale price of the NFT asset specified by tokenId
/// @return receiver - address of who should be sent the royalty payment
/// @return royaltyAmount - the royalty payment amount for value sale price
    function royaltyInfo(uint256 tokenId, uint256 value)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 17 of 20 : LibDiamond.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
import { IDiamondCut } from "../interfaces/IDiamondCut.sol";

library LibDiamond {
    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

    struct FacetAddressAndPosition {
        address facetAddress;
        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
    }

    struct FacetFunctionSelectors {
        bytes4[] functionSelectors;
        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
    }

    struct DiamondStorage {
        // maps function selector to the facet address and
        // the position of the selector in the facetFunctionSelectors.selectors array
        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
        // maps facet addresses to function selectors
        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
        // facet addresses
        address[] facetAddresses;
        // Used to query if a contract implements an interface.
        // Used to implement ERC-165.
        mapping(bytes4 => bool) supportedInterfaces;
        // owner of the contract
        address contractOwner;
    }

    function diamondStorage() internal pure returns (DiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position
        }
    }

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function setContractOwner(address _newOwner) internal {
        DiamondStorage storage ds = diamondStorage();
        address previousOwner = ds.contractOwner;
        ds.contractOwner = _newOwner;
        emit OwnershipTransferred(previousOwner, _newOwner);
    }

    function contractOwner() internal view returns (address contractOwner_) {
        contractOwner_ = diamondStorage().contractOwner;
    }

    function enforceIsContractOwner() internal view {
        require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner");
    }

    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);

    // Internal function version of diamondCut
    function diamondCut(
        IDiamondCut.FacetCut[] memory _diamondCut,
        address _init,
        bytes memory _calldata
    ) internal {
        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
            if (action == IDiamondCut.FacetCutAction.Add) {
                addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Replace) {
                replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Remove) {
                removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else {
                revert("LibDiamondCut: Incorrect FacetCutAction");
            }
        }
        emit DiamondCut(_diamondCut, _init, _calldata);
        initializeDiamondCut(_init, _calldata);
    }

    function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();        
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);            
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
            removeFunction(ds, oldFacetAddress, selector);
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        // if function does not exist then do nothing and return
        require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            removeFunction(ds, oldFacetAddress, selector);
        }
    }

    function addFacet(DiamondStorage storage ds, address _facetAddress) internal {
        enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
        ds.facetAddresses.push(_facetAddress);
    }    


    function addFunction(DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress) internal {
        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
    }

    function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {        
        require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
        // an immutable function is a function defined directly in a diamond
        require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
        // replace selector with last selector, then delete last selector
        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
        // if not the same then replace _selector with lastSelector
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
            ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
            ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
        }
        // delete the last selector
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
        delete ds.selectorToFacetAndPosition[_selector];

        // if no more selectors for facet address then delete the facet address
        if (lastSelectorPosition == 0) {
            // replace facet address with last facet address and delete last facet address
            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
            uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
            if (facetAddressPosition != lastFacetAddressPosition) {
                address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
            }
            ds.facetAddresses.pop();
            delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
        }
    }

    function initializeDiamondCut(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty");
        } else {
            require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)");
            if (_init != address(this)) {
                enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
            }
            (bool success, bytes memory error) = _init.delegatecall(_calldata);
            if (!success) {
                if (error.length > 0) {
                    // bubble up the error
                    revert(string(error));
                } else {
                    revert("LibDiamondCut: _init function reverted");
                }
            }
        }
    }

    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}

File 18 of 20 : LibCommon.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

library LibCommon {

    function msgSender() internal view returns (address sender) {
        return msg.sender;
    }

    function msgData() internal pure returns (bytes calldata) {
        return msg.data;
    }

    function verifyLeaf(bytes32 _leaf, bytes32[] memory _proof, bytes32 _root)
    internal pure returns (bool)
    {
        return MerkleProof.verify(_proof, _root, _leaf);
    }

    function verify(
        bytes32 digest,
        address signer,
        bytes memory signature
    ) internal pure returns (bool) {

        return signer == ECDSA.recover(digest, signature);
    }
}

File 19 of 20 : IDiamondCut.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/

interface IDiamondCut {
    enum FacetCutAction {Add, Replace, Remove}
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(
        FacetCut[] calldata _diamondCut,
        address _init,
        bytes calldata _calldata
    ) external;

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}

File 20 of 20 : MerkleProof.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        bytes32 computedHash = leaf;

        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];

            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        // Check if the computed hash (root) is equal to the provided root
        return computedHash == root;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"childChainManager","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"baseTokenURI","type":"string"},{"internalType":"string","name":"contractURI_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSITOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"creatorOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes","name":"depositData","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isPermanentURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"uri","type":"string"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint24","name":"amount","type":"uint24"}],"internalType":"struct ERC2981Base.RoyaltyInfo","name":"royalty","type":"tuple"}],"internalType":"struct MintERC1155Order","name":"order","type":"tuple"},{"internalType":"bool","name":"approve","type":"bool"},{"internalType":"bool","name":"freezeTokenURI","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"string[]","name":"uris","type":"string[]"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint24","name":"amount","type":"uint24"}],"internalType":"struct ERC2981Base.RoyaltyInfo","name":"royalty","type":"tuple"}],"internalType":"struct MintERC1155BatchOrder","name":"order","type":"tuple"},{"internalType":"bool","name":"approve","type":"bool"},{"internalType":"bool","name":"freezeTokenURI","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseTokenURI","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"contractURI_","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"newUri","type":"string"},{"internalType":"bool","name":"freeze","type":"bool"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"withdrawBatch","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162006d3138038062006d31833981810160405281019062000037919062000948565b83600290805190602001906200004f92919062000696565b5082600390805190602001906200006892919062000696565b506200007e6000801b336200011060201b60201c565b620000b07f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6876200012660201b60201c565b620000e27f8f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a9866200012660201b60201c565b620000f3826200016f60201b60201c565b6200010481620001b160201b60201c565b50505050505062000e31565b620001228282620001f360201b60201c565b5050565b6200013782620002e460201b60201c565b62000158816200014c6200030460201b60201c565b6200030c60201b60201c565b6200016a8383620001f360201b60201c565b505050565b6000801b6200019481620001886200030460201b60201c565b6200030c60201b60201c565b8160059080519060200190620001ac92919062000696565b505050565b6000801b620001d681620001ca6200030460201b60201c565b6200030c60201b60201c565b8160049080519060200190620001ee92919062000696565b505050565b620002058282620003d060201b60201c565b620002e057600180600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620002856200030460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600060016000838152602001908152602001600020600101549050919050565b600033905090565b6200031e8282620003d060201b60201c565b620003cc57620003518173ffffffffffffffffffffffffffffffffffffffff1660146200043b60201b62002b5f1760201c565b6200036c8360001c60206200043b60201b62002b5f1760201c565b6040516020016200037f92919062000b4d565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003c3919062000be1565b60405180910390fd5b5050565b60006001600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60606000600283600262000450919062000c3e565b6200045c919062000c9f565b67ffffffffffffffff811115620004785762000477620007da565b5b6040519080825280601f01601f191660200182016040528015620004ab5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110620004e657620004e562000cfc565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106200054d576200054c62000cfc565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026200058f919062000c3e565b6200059b919062000c9f565b90505b600181111562000645577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110620005e157620005e062000cfc565b5b1a60f81b828281518110620005fb57620005fa62000cfc565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806200063d9062000d2b565b90506200059e565b50600084146200068c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006839062000daa565b60405180910390fd5b8091505092915050565b828054620006a49062000dfb565b90600052602060002090601f016020900481019282620006c8576000855562000714565b82601f10620006e357805160ff191683800117855562000714565b8280016001018555821562000714579182015b8281111562000713578251825591602001919060010190620006f6565b5b50905062000723919062000727565b5090565b5b808211156200074257600081600090555060010162000728565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000787826200075a565b9050919050565b62000799816200077a565b8114620007a557600080fd5b50565b600081519050620007b9816200078e565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200081482620007c9565b810181811067ffffffffffffffff82111715620008365762000835620007da565b5b80604052505050565b60006200084b62000746565b905062000859828262000809565b919050565b600067ffffffffffffffff8211156200087c576200087b620007da565b5b6200088782620007c9565b9050602081019050919050565b60005b83811015620008b457808201518184015260208101905062000897565b83811115620008c4576000848401525b50505050565b6000620008e1620008db846200085e565b6200083f565b9050828152602081018484840111156200090057620008ff620007c4565b5b6200090d84828562000894565b509392505050565b600082601f8301126200092d576200092c620007bf565b5b81516200093f848260208601620008ca565b91505092915050565b60008060008060008060c0878903121562000968576200096762000750565b5b60006200097889828a01620007a8565b96505060206200098b89828a01620007a8565b955050604087015167ffffffffffffffff811115620009af57620009ae62000755565b5b620009bd89828a0162000915565b945050606087015167ffffffffffffffff811115620009e157620009e062000755565b5b620009ef89828a0162000915565b935050608087015167ffffffffffffffff81111562000a135762000a1262000755565b5b62000a2189828a0162000915565b92505060a087015167ffffffffffffffff81111562000a455762000a4462000755565b5b62000a5389828a0162000915565b9150509295509295509295565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b600062000aa360178362000a60565b915062000ab08262000a6b565b601782019050919050565b600081519050919050565b600062000ad38262000abb565b62000adf818562000a60565b935062000af181856020860162000894565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600062000b3560118362000a60565b915062000b428262000afd565b601182019050919050565b600062000b5a8262000a94565b915062000b68828562000ac6565b915062000b758262000b26565b915062000b83828462000ac6565b91508190509392505050565b600082825260208201905092915050565b600062000bad8262000abb565b62000bb9818562000b8f565b935062000bcb81856020860162000894565b62000bd681620007c9565b840191505092915050565b6000602082019050818103600083015262000bfd818462000ba0565b905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000c4b8262000c05565b915062000c588362000c05565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161562000c945762000c9362000c0f565b5b828202905092915050565b600062000cac8262000c05565b915062000cb98362000c05565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111562000cf15762000cf062000c0f565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600062000d388262000c05565b9150600082141562000d4f5762000d4e62000c0f565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b600062000d9260208362000b8f565b915062000d9f8262000d5a565b602082019050919050565b6000602082019050818103600083015262000dc58162000d83565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000e1457607f821691505b6020821081141562000e2b5762000e2a62000dcc565b5b50919050565b615ef08062000e416000396000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80636b20c4541161010f578063cf2c52cb116100a2578063e8a3d48511610071578063e8a3d485146105d7578063e985e9c5146105f5578063f242432a14610625578063f5298aca14610641576101ef565b8063cf2c52cb14610565578063d539139314610581578063d547741f1461059f578063da8438ac146105bb576101ef565b8063a217fddf116100de578063a217fddf146104f1578063a22cb4651461050f578063a3b0b5a31461052b578063b841bb8914610549576101ef565b80636b20c4541461046b57806391d1485414610487578063938e3d7b146104b757806395d89b41146104d3576101ef565b80632eb2c2d6116101875780634b43fdd1116101565780634b43fdd1146103d35780634e1273f4146103ef578063589a17431461041f5780635c5fb5211461044f576101ef565b80632eb2c2d6146103635780632f2ff15d1461037f57806330176e131461039b57806336568abe146103b7576101ef565b80631e7d9dbb116101c35780631e7d9dbb146102a2578063248a9ca3146102d25780632693ebf2146103025780632a55205a14610332576101ef565b8062fdd58e146101f457806301ffc9a71461022457806306fdde03146102545780630e89341c14610272575b600080fd5b61020e60048036038101906102099190613ba6565b61065d565b60405161021b9190613bf5565b60405180910390f35b61023e60048036038101906102399190613c68565b610727565b60405161024b9190613cb0565b60405180910390f35b61025c610826565b6040516102699190613d64565b60405180910390f35b61028c60048036038101906102879190613d86565b6108b4565b6040516102999190613d64565b60405180910390f35b6102bc60048036038101906102b79190613d86565b6108f2565b6040516102c99190613cb0565b60405180910390f35b6102ec60048036038101906102e79190613de9565b610912565b6040516102f99190613e25565b60405180910390f35b61031c60048036038101906103179190613d86565b610932565b6040516103299190613bf5565b60405180910390f35b61034c60048036038101906103479190613e40565b61094a565b60405161035a929190613e8f565b60405180910390f35b61037d600480360381019061037891906140b5565b610a1a565b005b61039960048036038101906103949190614184565b610db0565b005b6103b560048036038101906103b09190614265565b610dd9565b005b6103d160048036038101906103cc9190614184565b610e09565b005b6103ed60048036038101906103e891906142fe565b610e8c565b005b61040960048036038101906104049190614460565b611311565b6040516104169190614596565b60405180910390f35b61043960048036038101906104349190613d86565b61142a565b60405161044691906145b8565b60405180910390f35b6104696004803603810190610464919061462e565b611467565b005b610485600480360381019061048091906146af565b611501565b005b6104a1600480360381019061049c9190614184565b61181d565b6040516104ae9190613cb0565b60405180910390f35b6104d160048036038101906104cc9190614265565b611888565b005b6104db6118b8565b6040516104e89190613d64565b60405180910390f35b6104f9611946565b6040516105069190613e25565b60405180910390f35b6105296004803603810190610524919061473a565b61194d565b005b610533611ac6565b6040516105409190613e25565b60405180910390f35b610563600480360381019061055e9190614799565b611aea565b005b61057f600480360381019061057a919061488e565b6120fa565b005b6105896121cb565b6040516105969190613e25565b60405180910390f35b6105b960048036038101906105b49190614184565b6121ef565b005b6105d560048036038101906105d09190614944565b612218565b005b6105df6124d1565b6040516105ec9190613d64565b60405180910390f35b61060f600480360381019061060a91906149b8565b61255f565b60405161061c9190613cb0565b60405180910390f35b61063f600480360381019061063a91906149f8565b6125f3565b005b61065b60048036038101906106569190614a8f565b6128e7565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156106ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c590614b54565b60405180910390fd5b6006600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600063d9b67a2660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107c05750630e89341c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061080f575063e8a3d48560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061081f575061081e82612d9b565b5b9050919050565b6002805461083390614ba3565b80601f016020809104026020016040519081016040528092919081815260200182805461085f90614ba3565b80156108ac5780601f10610881576101008083540402835291602001916108ac565b820191906000526020600020905b81548152906001019060200180831161088f57829003601f168201915b505050505081565b60606005600860008481526020019081526020016000206040516020016108dc929190614c74565b6040516020818303038152906040529050919050565b60096020528060005260406000206000915054906101000a900460ff1681565b600060016000838152602001908152602001600020600101549050919050565b600b6020528060005260406000206000915090505481565b60008060008060008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900462ffffff1662ffffff1662ffffff1681525050905080600001519250612710816020015162ffffff1685610a069190614cc7565b610a109190614d50565b9150509250929050565b610a22612e15565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480610a685750610a6785610a62612e15565b61255f565b5b610aa7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9e90614df3565b60405180910390fd5b8151835114610aeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae290614e5f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415610b5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5290614ecb565b60405180910390fd5b6000610b65612e15565b905060005b8451811015610d1b576000858281518110610b8857610b87614eeb565b5b602002602001015190506000858381518110610ba757610ba6614eeb565b5b6020026020010151905060006006600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4090614f8c565b60405180910390fd5b8181036006600085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816006600085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d009190614fac565b9250508190555050505080610d1490615002565b9050610b6a565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d9292919061504b565b60405180910390a4610da8818787878787612e1d565b505050505050565b610db982610912565b610dca81610dc5612e15565b613004565b610dd483836130a1565b505050565b6000801b610dee81610de9612e15565b613004565b8160059080519060200190610e049291906139d5565b505050565b610e11612e15565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e75906150f4565b60405180910390fd5b610e888282613181565b5050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610ebe81610eb9612e15565b613004565b848060800190610ece9190615123565b9050858060400190610ee09190615186565b905014610f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1990615235565b60405180910390fd5b6000610f2c612e15565b9050610fea866020016020810190610f449190615255565b878060400190610f549190615186565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050888060600190610fa49190615186565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505086613263565b60005b868060400190610ffd9190615186565b90508110156113085760008780604001906110189190615186565b8381811061102957611028614eeb565b5b90506020020135905060008880608001906110449190615123565b8481811061105557611054614eeb565b5b90506020028101906110679190615282565b9050116110a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a090615331565b60405180910390fd5b8780608001906110b99190615123565b838181106110ca576110c9614eeb565b5b90506020028101906110dc9190615282565b6008600084815260200190815260200160002091906110fc929190613a5b565b5085156111305760016009600083815260200190815260200160002060006101000a81548160ff0219169083151502179055505b807f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b61115b836108b4565b6040516111689190613d64565b60405180910390a28615611296576001600760008a602001602081019061118f9190615255565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff168860200160208101906112479190615255565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31600160405161128d9190613cb0565b60405180910390a35b60008860a00160200160208101906112ae919061538c565b62ffffff1611156112f4576112f3818960a00160000160208101906112d39190615255565b8a60a00160200160208101906112e9919061538c565b62ffffff166135fc565b5b50808061130090615002565b915050610fed565b50505050505050565b60608151835114611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134e90615405565b60405180910390fd5b6000835167ffffffffffffffff81111561137457611373613ebd565b5b6040519080825280602002602001820160405280156113a25781602001602082028036833780820191505090505b50905060005b845181101561141f576113ef8582815181106113c7576113c6614eeb565b5b60200260200101518583815181106113e2576113e1614eeb565b5b602002602001015161065d565b82828151811061140257611401614eeb565b5b6020026020010181815250508061141890615002565b90506113a8565b508091505092915050565b6000600a600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6114fb611472612e15565b858580806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050611501565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611571576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156890615471565b60405180910390fd5b611579612e15565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806115bf57506115be836115b9612e15565b61255f565b5b6115fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f5906154dd565b60405180910390fd5b8051825114611642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163990614e5f565b60405180910390fd5b60005b825181101561179157600083828151811061166357611662614eeb565b5b60200260200101519050600083838151811061168257611681614eeb565b5b6020026020010151905060006006600084815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171b90615549565b60405180910390fd5b8181036006600085815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050808061178990615002565b915050611645565b50600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff166117c9612e15565b73ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb858560405161181092919061504b565b60405180910390a4505050565b60006001600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000801b61189d81611898612e15565b613004565b81600490805190602001906118b39291906139d5565b505050565b600380546118c590614ba3565b80601f01602080910402602001604051908101604052809291908181526020018280546118f190614ba3565b801561193e5780601f106119135761010080835404028352916020019161193e565b820191906000526020600020905b81548152906001019060200180831161192157829003601f168201915b505050505081565b6000801b81565b6000611957612e15565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156119c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bf906155b5565b60405180910390fd5b81600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3184604051611ab99190613cb0565b60405180910390a3505050565b7f8f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a981565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6611b1c81611b17612e15565b613004565b600073ffffffffffffffffffffffffffffffffffffffff16600a60008760400135815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611bc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb990615621565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16856020016020810190611bed9190615255565b73ffffffffffffffffffffffffffffffffffffffff161415611c44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3b9061568d565b60405180910390fd5b6000856060013511611c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c82906156f9565b60405180910390fd5b6000858060800190611c9d9190615282565b905011611cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd690615331565b60405180910390fd5b6000611ce9612e15565b9050856060013560066000886040013581526020019081526020016000206000886020016020810190611d1c9190615255565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d659190614fac565b92505081905550856020016020810190611d7f9190615255565b600a60008860400135815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560600135600b60008860400135815260200190815260200160002081905550858060800190611e049190615282565b60086000896040013581526020019081526020016000209190611e28929190613a5b565b508315611e60576001600960008860400135815260200190815260200160002060006101000a81548160ff0219169083151502179055505b856020016020810190611e739190615255565b73ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289604001358a60600135604051611ef1929190615719565b60405180910390a4611f22816000886020016020810190611f129190615255565b89604001358a60600135886136f7565b60008660a0016020016020810190611f3a919061538c565b62ffffff161115611f8457611f8386604001358760a0016000016020810190611f639190615255565b8860a0016020016020810190611f79919061538c565b62ffffff166135fc565b5b85604001357f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b611fb788604001356108b4565b604051611fc49190613d64565b60405180910390a284156120f257600160076000886020016020810190611feb9190615255565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff168660200160208101906120a39190615255565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160016040516120e99190613cb0565b60405180910390a35b505050505050565b7f8f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a961212c81612127612e15565b613004565b600080600085858101906121409190615742565b925092509250600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614156121b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ad90615835565b60405180910390fd5b6121c287848484613263565b50505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6121f882610912565b61220981612204612e15565b613004565b6122138383613181565b505050565b836000612223612e15565b90508073ffffffffffffffffffffffffffffffffffffffff16600a600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614806122b857506122b77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a68261181d565b5b6122f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122ee906158a1565b60405180910390fd5b85600b600082815260200190815260200160002054612349600a600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168361065d565b14612389576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123809061590d565b60405180910390fd5b866009600082815260200190815260200160002060009054906101000a900460ff16156123eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e290615979565b60405180910390fd5b84156124645760008787905011612437576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242e90615331565b60405180910390fd5b6001600960008a815260200190815260200160002060006101000a81548160ff0219169083151502179055505b8686600860008b81526020019081526020016000209190612486929190613a5b565b50877f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b6124b28a6108b4565b6040516124bf9190613d64565b60405180910390a25050505050505050565b600480546124de90614ba3565b80601f016020809104026020016040519081016040528092919081815260200182805461250a90614ba3565b80156125575780601f1061252c57610100808354040283529160200191612557565b820191906000526020600020905b81548152906001019060200180831161253a57829003601f168201915b505050505081565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6125fb612e15565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061264157506126408561263b612e15565b61255f565b5b612680576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612677906154dd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156126f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126e790614ecb565b60405180910390fd5b60006126fa612e15565b905060006006600086815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905083811015612794576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161278b90614f8c565b60405180910390fd5b8381036006600087815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836006600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461284b9190614fac565b925050819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6288886040516128c8929190615719565b60405180910390a46128de8288888888886136f7565b50505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612957576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294e90615471565b60405180910390fd5b61295f612e15565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806129a557506129a48361299f612e15565b61255f565b5b6129e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129db906154dd565b60405180910390fd5b60006006600084815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612a7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a7390615549565b60405180910390fd5b8181036006600085815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16612b0a612e15565b73ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628686604051612b51929190615719565b60405180910390a450505050565b606060006002836002612b729190614cc7565b612b7c9190614fac565b67ffffffffffffffff811115612b9557612b94613ebd565b5b6040519080825280601f01601f191660200182016040528015612bc75781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612bff57612bfe614eeb565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612c6357612c62614eeb565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612ca39190614cc7565b612cad9190614fac565b90505b6001811115612d4d577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612cef57612cee614eeb565b5b1a60f81b828281518110612d0657612d05614eeb565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612d4690615999565b9050612cb0565b5060008414612d91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d8890615a0f565b60405180910390fd5b8091505092915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612e0e5750612e0d826138de565b5b9050919050565b600033905090565b612e3c8473ffffffffffffffffffffffffffffffffffffffff16613958565b15612ffc578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b8152600401612e82959493929190615a84565b602060405180830381600087803b158015612e9c57600080fd5b505af1925050508015612ecd57506040513d601f19601f82011682018060405250810190612eca9190615b01565b60015b612f7357612ed9615b3b565b806308c379a01415612f365750612eee615b5d565b80612ef95750612f38565b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f2d9190613d64565b60405180910390fd5b505b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6a90615c65565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612ffa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff190615cd1565b60405180910390fd5b505b505050505050565b61300e828261181d565b61309d576130338173ffffffffffffffffffffffffffffffffffffffff166014612b5f565b6130418360001c6020612b5f565b604051602001613052929190615dba565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130949190613d64565b60405180910390fd5b5050565b6130ab828261181d565b61317d57600180600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550613122612e15565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b61318b828261181d565b1561325f5760006001600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550613204612e15565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156132d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ca9061568d565b60405180910390fd5b8151835114613317576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161330e90614e5f565b60405180910390fd5b6000613321612e15565b905060005b845181101561356657600085828151811061334457613343614eeb565b5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff16600a600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146133f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133e790615621565b60405180910390fd5b600085838151811061340557613404614eeb565b5b60200260200101511161344d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613444906156f9565b60405180910390fd5b8482815181106134605761345f614eeb565b5b60200260200101516006600083815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546134c79190614fac565b9250508190555086600a600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084828151811061353357613532614eeb565b5b6020026020010151600b60008381526020019081526020016000208190555050808061355e90615002565b915050613326565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516135de92919061504b565b60405180910390a46135f581600087878787612e1d565b5050505050565b612710811115613641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161363890615e40565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff1681526020018262ffffff1681525060008085815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548162ffffff021916908362ffffff160217905550905050505050565b6137168473ffffffffffffffffffffffffffffffffffffffff16613958565b156138d6578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b815260040161375c959493929190615e60565b602060405180830381600087803b15801561377657600080fd5b505af19250505080156137a757506040513d601f19601f820116820180604052508101906137a49190615b01565b60015b61384d576137b3615b3b565b806308c379a0141561381057506137c8615b5d565b806137d35750613812565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138079190613d64565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161384490615c65565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146138d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138cb90615cd1565b60405180910390fd5b505b505050505050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061395157506139508261396b565b5b9050919050565b600080823b905060008111915050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8280546139e190614ba3565b90600052602060002090601f016020900481019282613a035760008555613a4a565b82601f10613a1c57805160ff1916838001178555613a4a565b82800160010185558215613a4a579182015b82811115613a49578251825591602001919060010190613a2e565b5b509050613a579190613ae1565b5090565b828054613a6790614ba3565b90600052602060002090601f016020900481019282613a895760008555613ad0565b82601f10613aa257803560ff1916838001178555613ad0565b82800160010185558215613ad0579182015b82811115613acf578235825591602001919060010190613ab4565b5b509050613add9190613ae1565b5090565b5b80821115613afa576000816000905550600101613ae2565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613b3d82613b12565b9050919050565b613b4d81613b32565b8114613b5857600080fd5b50565b600081359050613b6a81613b44565b92915050565b6000819050919050565b613b8381613b70565b8114613b8e57600080fd5b50565b600081359050613ba081613b7a565b92915050565b60008060408385031215613bbd57613bbc613b08565b5b6000613bcb85828601613b5b565b9250506020613bdc85828601613b91565b9150509250929050565b613bef81613b70565b82525050565b6000602082019050613c0a6000830184613be6565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613c4581613c10565b8114613c5057600080fd5b50565b600081359050613c6281613c3c565b92915050565b600060208284031215613c7e57613c7d613b08565b5b6000613c8c84828501613c53565b91505092915050565b60008115159050919050565b613caa81613c95565b82525050565b6000602082019050613cc56000830184613ca1565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613d05578082015181840152602081019050613cea565b83811115613d14576000848401525b50505050565b6000601f19601f8301169050919050565b6000613d3682613ccb565b613d408185613cd6565b9350613d50818560208601613ce7565b613d5981613d1a565b840191505092915050565b60006020820190508181036000830152613d7e8184613d2b565b905092915050565b600060208284031215613d9c57613d9b613b08565b5b6000613daa84828501613b91565b91505092915050565b6000819050919050565b613dc681613db3565b8114613dd157600080fd5b50565b600081359050613de381613dbd565b92915050565b600060208284031215613dff57613dfe613b08565b5b6000613e0d84828501613dd4565b91505092915050565b613e1f81613db3565b82525050565b6000602082019050613e3a6000830184613e16565b92915050565b60008060408385031215613e5757613e56613b08565b5b6000613e6585828601613b91565b9250506020613e7685828601613b91565b9150509250929050565b613e8981613b32565b82525050565b6000604082019050613ea46000830185613e80565b613eb16020830184613be6565b9392505050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613ef582613d1a565b810181811067ffffffffffffffff82111715613f1457613f13613ebd565b5b80604052505050565b6000613f27613afe565b9050613f338282613eec565b919050565b600067ffffffffffffffff821115613f5357613f52613ebd565b5b602082029050602081019050919050565b600080fd5b6000613f7c613f7784613f38565b613f1d565b90508083825260208201905060208402830185811115613f9f57613f9e613f64565b5b835b81811015613fc85780613fb48882613b91565b845260208401935050602081019050613fa1565b5050509392505050565b600082601f830112613fe757613fe6613eb8565b5b8135613ff7848260208601613f69565b91505092915050565b600080fd5b600067ffffffffffffffff8211156140205761401f613ebd565b5b61402982613d1a565b9050602081019050919050565b82818337600083830152505050565b600061405861405384614005565b613f1d565b90508281526020810184848401111561407457614073614000565b5b61407f848285614036565b509392505050565b600082601f83011261409c5761409b613eb8565b5b81356140ac848260208601614045565b91505092915050565b600080600080600060a086880312156140d1576140d0613b08565b5b60006140df88828901613b5b565b95505060206140f088828901613b5b565b945050604086013567ffffffffffffffff81111561411157614110613b0d565b5b61411d88828901613fd2565b935050606086013567ffffffffffffffff81111561413e5761413d613b0d565b5b61414a88828901613fd2565b925050608086013567ffffffffffffffff81111561416b5761416a613b0d565b5b61417788828901614087565b9150509295509295909350565b6000806040838503121561419b5761419a613b08565b5b60006141a985828601613dd4565b92505060206141ba85828601613b5b565b9150509250929050565b600067ffffffffffffffff8211156141df576141de613ebd565b5b6141e882613d1a565b9050602081019050919050565b6000614208614203846141c4565b613f1d565b90508281526020810184848401111561422457614223614000565b5b61422f848285614036565b509392505050565b600082601f83011261424c5761424b613eb8565b5b813561425c8482602086016141f5565b91505092915050565b60006020828403121561427b5761427a613b08565b5b600082013567ffffffffffffffff81111561429957614298613b0d565b5b6142a584828501614237565b91505092915050565b600080fd5b600060e082840312156142c9576142c86142ae565b5b81905092915050565b6142db81613c95565b81146142e657600080fd5b50565b6000813590506142f8816142d2565b92915050565b6000806000806080858703121561431857614317613b08565b5b600085013567ffffffffffffffff81111561433657614335613b0d565b5b614342878288016142b3565b9450506020614353878288016142e9565b9350506040614364878288016142e9565b925050606085013567ffffffffffffffff81111561438557614384613b0d565b5b61439187828801614087565b91505092959194509250565b600067ffffffffffffffff8211156143b8576143b7613ebd565b5b602082029050602081019050919050565b60006143dc6143d78461439d565b613f1d565b905080838252602082019050602084028301858111156143ff576143fe613f64565b5b835b8181101561442857806144148882613b5b565b845260208401935050602081019050614401565b5050509392505050565b600082601f83011261444757614446613eb8565b5b81356144578482602086016143c9565b91505092915050565b6000806040838503121561447757614476613b08565b5b600083013567ffffffffffffffff81111561449557614494613b0d565b5b6144a185828601614432565b925050602083013567ffffffffffffffff8111156144c2576144c1613b0d565b5b6144ce85828601613fd2565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61450d81613b70565b82525050565b600061451f8383614504565b60208301905092915050565b6000602082019050919050565b6000614543826144d8565b61454d81856144e3565b9350614558836144f4565b8060005b838110156145895781516145708882614513565b975061457b8361452b565b92505060018101905061455c565b5085935050505092915050565b600060208201905081810360008301526145b08184614538565b905092915050565b60006020820190506145cd6000830184613e80565b92915050565b600080fd5b60008083601f8401126145ee576145ed613eb8565b5b8235905067ffffffffffffffff81111561460b5761460a6145d3565b5b60208301915083602082028301111561462757614626613f64565b5b9250929050565b6000806000806040858703121561464857614647613b08565b5b600085013567ffffffffffffffff81111561466657614665613b0d565b5b614672878288016145d8565b9450945050602085013567ffffffffffffffff81111561469557614694613b0d565b5b6146a1878288016145d8565b925092505092959194509250565b6000806000606084860312156146c8576146c7613b08565b5b60006146d686828701613b5b565b935050602084013567ffffffffffffffff8111156146f7576146f6613b0d565b5b61470386828701613fd2565b925050604084013567ffffffffffffffff81111561472457614723613b0d565b5b61473086828701613fd2565b9150509250925092565b6000806040838503121561475157614750613b08565b5b600061475f85828601613b5b565b9250506020614770858286016142e9565b9150509250929050565b600060e082840312156147905761478f6142ae565b5b81905092915050565b600080600080608085870312156147b3576147b2613b08565b5b600085013567ffffffffffffffff8111156147d1576147d0613b0d565b5b6147dd8782880161477a565b94505060206147ee878288016142e9565b93505060406147ff878288016142e9565b925050606085013567ffffffffffffffff8111156148205761481f613b0d565b5b61482c87828801614087565b91505092959194509250565b60008083601f84011261484e5761484d613eb8565b5b8235905067ffffffffffffffff81111561486b5761486a6145d3565b5b60208301915083600182028301111561488757614886613f64565b5b9250929050565b6000806000604084860312156148a7576148a6613b08565b5b60006148b586828701613b5b565b935050602084013567ffffffffffffffff8111156148d6576148d5613b0d565b5b6148e286828701614838565b92509250509250925092565b60008083601f84011261490457614903613eb8565b5b8235905067ffffffffffffffff811115614921576149206145d3565b5b60208301915083600182028301111561493d5761493c613f64565b5b9250929050565b6000806000806060858703121561495e5761495d613b08565b5b600061496c87828801613b91565b945050602085013567ffffffffffffffff81111561498d5761498c613b0d565b5b614999878288016148ee565b935093505060406149ac878288016142e9565b91505092959194509250565b600080604083850312156149cf576149ce613b08565b5b60006149dd85828601613b5b565b92505060206149ee85828601613b5b565b9150509250929050565b600080600080600060a08688031215614a1457614a13613b08565b5b6000614a2288828901613b5b565b9550506020614a3388828901613b5b565b9450506040614a4488828901613b91565b9350506060614a5588828901613b91565b925050608086013567ffffffffffffffff811115614a7657614a75613b0d565b5b614a8288828901614087565b9150509295509295909350565b600080600060608486031215614aa857614aa7613b08565b5b6000614ab686828701613b5b565b9350506020614ac786828701613b91565b9250506040614ad886828701613b91565b9150509250925092565b7f62616c616e636520717565727920666f7220746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000614b3e602283613cd6565b9150614b4982614ae2565b604082019050919050565b60006020820190508181036000830152614b6d81614b31565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614bbb57607f821691505b60208210811415614bcf57614bce614b74565b5b50919050565b600081905092915050565b60008190508160005260206000209050919050565b60008154614c0281614ba3565b614c0c8186614bd5565b94506001821660008114614c275760018114614c3857614c6b565b60ff19831686528186019350614c6b565b614c4185614be0565b60005b83811015614c6357815481890152600182019150602081019050614c44565b838801955050505b50505092915050565b6000614c808285614bf5565b9150614c8c8284614bf5565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614cd282613b70565b9150614cdd83613b70565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614d1657614d15614c98565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614d5b82613b70565b9150614d6683613b70565b925082614d7657614d75614d21565b5b828204905092915050565b7f7472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b6000614ddd602983613cd6565b9150614de882614d81565b604082019050919050565b60006020820190508181036000830152614e0c81614dd0565b9050919050565b7f69647320616e6420616d6f756e7473206c656e677468206d69736d6174636800600082015250565b6000614e49601f83613cd6565b9150614e5482614e13565b602082019050919050565b60006020820190508181036000830152614e7881614e3c565b9050919050565b7f7472616e7366657220746f20746865207a65726f206164647265737300000000600082015250565b6000614eb5601c83613cd6565b9150614ec082614e7f565b602082019050919050565b60006020820190508181036000830152614ee481614ea8565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f696e73756666696369656e742062616c616e636520666f72207472616e73666560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000614f76602183613cd6565b9150614f8182614f1a565b604082019050919050565b60006020820190508181036000830152614fa581614f69565b9050919050565b6000614fb782613b70565b9150614fc283613b70565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614ff757614ff6614c98565b5b828201905092915050565b600061500d82613b70565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156150405761503f614c98565b5b600182019050919050565b600060408201905081810360008301526150658185614538565b905081810360208301526150798184614538565b90509392505050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b60006150de602f83613cd6565b91506150e982615082565b604082019050919050565b6000602082019050818103600083015261510d816150d1565b9050919050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126151405761513f615114565b5b80840192508235915067ffffffffffffffff82111561516257615161615119565b5b60208301925060208202360383131561517e5761517d61511e565b5b509250929050565b600080833560016020038436030381126151a3576151a2615114565b5b80840192508235915067ffffffffffffffff8211156151c5576151c4615119565b5b6020830192506020820236038313156151e1576151e061511e565b5b509250929050565b7f69647320616e642075726973206c656e677468206d69736d6174636800000000600082015250565b600061521f601c83613cd6565b915061522a826151e9565b602082019050919050565b6000602082019050818103600083015261524e81615212565b9050919050565b60006020828403121561526b5761526a613b08565b5b600061527984828501613b5b565b91505092915050565b6000808335600160200384360303811261529f5761529e615114565b5b80840192508235915067ffffffffffffffff8211156152c1576152c0615119565b5b6020830192506001820236038313156152dd576152dc61511e565b5b509250929050565b7f696e76616c696420757269000000000000000000000000000000000000000000600082015250565b600061531b600b83613cd6565b9150615326826152e5565b602082019050919050565b6000602082019050818103600083015261534a8161530e565b9050919050565b600062ffffff82169050919050565b61536981615351565b811461537457600080fd5b50565b60008135905061538681615360565b92915050565b6000602082840312156153a2576153a1613b08565b5b60006153b084828501615377565b91505092915050565b7f6163636f756e747320616e6420696473206c656e677468206d69736d61746368600082015250565b60006153ef602083613cd6565b91506153fa826153b9565b602082019050919050565b6000602082019050818103600083015261541e816153e2565b9050919050565b7f6275726e2066726f6d20746865207a65726f2061646472657373000000000000600082015250565b600061545b601a83613cd6565b915061546682615425565b602082019050919050565b6000602082019050818103600083015261548a8161544e565b9050919050565b7f63616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564600082015250565b60006154c7602083613cd6565b91506154d282615491565b602082019050919050565b600060208201905081810360008301526154f6816154ba565b9050919050565b7f6275726e20616d6f756e7420657863656564732062616c616e63650000000000600082015250565b6000615533601b83613cd6565b915061553e826154fd565b602082019050919050565b6000602082019050818103600083015261556281615526565b9050919050565b7f73657474696e6720617070726f76616c2073746174757320666f722073656c66600082015250565b600061559f602083613cd6565b91506155aa82615569565b602082019050919050565b600060208201905081810360008301526155ce81615592565b9050919050565b7f746f6b656e20697320616c7265616479206d696e746564000000000000000000600082015250565b600061560b601783613cd6565b9150615616826155d5565b602082019050919050565b6000602082019050818103600083015261563a816155fe565b9050919050565b7f6d696e7420746f20746865207a65726f20616464726573730000000000000000600082015250565b6000615677601883613cd6565b915061568282615641565b602082019050919050565b600060208201905081810360008301526156a68161566a565b9050919050565b7f7a65726f20737570706c79000000000000000000000000000000000000000000600082015250565b60006156e3600b83613cd6565b91506156ee826156ad565b602082019050919050565b60006020820190508181036000830152615712816156d6565b9050919050565b600060408201905061572e6000830185613be6565b61573b6020830184613be6565b9392505050565b60008060006060848603121561575b5761575a613b08565b5b600084013567ffffffffffffffff81111561577957615778613b0d565b5b61578586828701613fd2565b935050602084013567ffffffffffffffff8111156157a6576157a5613b0d565b5b6157b286828701613fd2565b925050604084013567ffffffffffffffff8111156157d3576157d2613b0d565b5b6157df86828701614087565b9150509250925092565b7f696e76616c6964206465706f7369742075736572000000000000000000000000600082015250565b600061581f601483613cd6565b915061582a826157e9565b602082019050919050565b6000602082019050818103600083015261584e81615812565b9050919050565b7f6e6f7420616c6c6f776564000000000000000000000000000000000000000000600082015250565b600061588b600b83613cd6565b915061589682615855565b602082019050919050565b600060208201905081810360008301526158ba8161587e565b9050919050565b7f63726561746f72206973206e6f742066756c6c206f776e657200000000000000600082015250565b60006158f7601983613cd6565b9150615902826158c1565b602082019050919050565b60006020820190508181036000830152615926816158ea565b9050919050565b7f7572692069732066726f7a656e00000000000000000000000000000000000000600082015250565b6000615963600d83613cd6565b915061596e8261592d565b602082019050919050565b6000602082019050818103600083015261599281615956565b9050919050565b60006159a482613b70565b915060008214156159b8576159b7614c98565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006159f9602083613cd6565b9150615a04826159c3565b602082019050919050565b60006020820190508181036000830152615a28816159ec565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000615a5682615a2f565b615a608185615a3a565b9350615a70818560208601613ce7565b615a7981613d1a565b840191505092915050565b600060a082019050615a996000830188613e80565b615aa66020830187613e80565b8181036040830152615ab88186614538565b90508181036060830152615acc8185614538565b90508181036080830152615ae08184615a4b565b90509695505050505050565b600081519050615afb81613c3c565b92915050565b600060208284031215615b1757615b16613b08565b5b6000615b2584828501615aec565b91505092915050565b60008160e01c9050919050565b600060033d1115615b5a5760046000803e615b57600051615b2e565b90505b90565b600060443d1015615b6d57615bf0565b615b75613afe565b60043d036004823e80513d602482011167ffffffffffffffff82111715615b9d575050615bf0565b808201805167ffffffffffffffff811115615bbb5750505050615bf0565b80602083010160043d038501811115615bd8575050505050615bf0565b615be782602001850186613eec565b82955050505050505b90565b7f7472616e7366657220746f206e6f6e204552433131353552656365697665722060008201527f696d706c656d656e746572000000000000000000000000000000000000000000602082015250565b6000615c4f602b83613cd6565b9150615c5a82615bf3565b604082019050919050565b60006020820190508181036000830152615c7e81615c42565b9050919050565b7f4552433131353552656365697665722072656a656374656420746f6b656e7300600082015250565b6000615cbb601f83613cd6565b9150615cc682615c85565b602082019050919050565b60006020820190508181036000830152615cea81615cae565b9050919050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000615d27601783614bd5565b9150615d3282615cf1565b601782019050919050565b6000615d4882613ccb565b615d528185614bd5565b9350615d62818560208601613ce7565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000615da4601183614bd5565b9150615daf82615d6e565b601182019050919050565b6000615dc582615d1a565b9150615dd18285615d3d565b9150615ddc82615d97565b9150615de88284615d3d565b91508190509392505050565b7f45524332393831526f79616c746965733a20546f6f2068696768000000000000600082015250565b6000615e2a601a83613cd6565b9150615e3582615df4565b602082019050919050565b60006020820190508181036000830152615e5981615e1d565b9050919050565b600060a082019050615e756000830188613e80565b615e826020830187613e80565b615e8f6040830186613be6565b615e9c6060830185613be6565b8181036080830152615eae8184615a4b565b9050969550505050505056fea2646970667358221220c8a2067e670733e497ffc9d4cf02afadf9633656b4717baa00b9d88c0fa35b7364736f6c634300080900330000000000000000000000000cad382ee701bbec70f85e3b5c62a53709e85e6a000000000000000000000000a6fa4fb5f76172d178d61b04b0ecd319c5d1c0aa00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002146756e72697365204d696e7461626c65204552433131353520546f6b656e20563100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a46455243313135355631000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003368747470733a2f2f6170692e66756e726973652e696f2f636f6e74726163742f6d657461646174612f4645524331313535563100000000000000000000000000

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

0000000000000000000000000cad382ee701bbec70f85e3b5c62a53709e85e6a000000000000000000000000a6fa4fb5f76172d178d61b04b0ecd319c5d1c0aa00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002146756e72697365204d696e7461626c65204552433131353520546f6b656e20563100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a46455243313135355631000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003368747470733a2f2f6170692e66756e726973652e696f2f636f6e74726163742f6d657461646174612f4645524331313535563100000000000000000000000000

-----Decoded View---------------
Arg [0] : minter (address): 0x0cad382ee701bbec70f85e3b5c62a53709e85e6a
Arg [1] : childChainManager (address): 0xa6fa4fb5f76172d178d61b04b0ecd319c5d1c0aa
Arg [2] : name_ (string): Funrise Mintable ERC1155 Token V1
Arg [3] : symbol_ (string): FERC1155V1
Arg [4] : baseTokenURI (string): ipfs://
Arg [5] : contractURI_ (string): https://api.funrise.io/contract/metadata/FERC1155V1

-----Encoded View---------------
16 Constructor Arguments found :
Arg [0] : 0000000000000000000000000cad382ee701bbec70f85e3b5c62a53709e85e6a
Arg [1] : 000000000000000000000000a6fa4fb5f76172d178d61b04b0ecd319c5d1c0aa
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000021
Arg [7] : 46756e72697365204d696e7461626c65204552433131353520546f6b656e2056
Arg [8] : 3100000000000000000000000000000000000000000000000000000000000000
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [10] : 4645524331313535563100000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [12] : 697066733a2f2f00000000000000000000000000000000000000000000000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000033
Arg [14] : 68747470733a2f2f6170692e66756e726973652e696f2f636f6e74726163742f
Arg [15] : 6d657461646174612f4645524331313535563100000000000000000000000000


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.