// SPDX-License-Identifier: MIT
// Author: Philipp Adrian (ph101pp.eth)

pragma solidity ^0.8.0;

import "./ERC1155MintRangePausable.sol";
import "./Ph101ppDailyPhotoUtils.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";

import "hardhat/console.sol";

// Extension of ERC1155MintRange enables updating initial holders addresses
// of existing tokens.
abstract contract ERC1155MintRangeUpdateable is ERC1155MintRangePausable {
    struct UpdateInitialHoldersInput {
        address[] fromAddresses;
        address[] toAddresses;
        uint[][] ids;
        uint[][] amounts;
        address[][] newInitialHolders;
        uint[] newInitialHolderRanges;
    }

    struct VerifyUpdateInitialHoldersInput {
        address[] fromAddresses;
        address[] toAddresses;
        uint[][] ids;
        uint[][] amounts;
        address[][] newInitialHolders;
        uint[] newInitialHolderRanges;
        // privates
        ERC1155MintRangeUpdateable caller;
    }

    uint256 public lastRangeTokenIdWithLockedInitialHolders;
    bool public isZeroLocked;

    /**
     * @dev Lock initial holders up to tokenid
     */
    function _setLockInitialHoldersUpTo(
        uint256 tokenId
    ) internal virtual whenNotPaused {
        // Token must not be smaller than last locked token
        require(tokenId > lastRangeTokenIdWithLockedInitialHolders, "H:01");
        // token must be minted
        require(isZeroMinted && tokenId <= lastRangeTokenIdMinted, "H:02");
        lastRangeTokenIdWithLockedInitialHolders = tokenId;
        if (!isZeroLocked) {
            isZeroLocked = true;
        }
    }

    // Update initial holders for a range of ids.
    function _updateInitialHolders(
        UpdateInitialHoldersInput memory input
    ) internal virtual whenPaused {
        // Update initialHoldersAddress Map
        // && check no locked initial holders were updated

        require(
            // range must to start at 0
            input.newInitialHolderRanges[0] == 0 &&
                // and end before last minted id
                input.newInitialHolderRanges[
                    input.newInitialHolderRanges.length - 1
                ] <=
                lastRangeTokenIdMinted &&
                // amount of ranges & initialHolders must match
                input.newInitialHolderRanges.length ==
                input.newInitialHolders.length,
            "H:03"
        );

        uint a = 0;
        uint b = 0;

        // cycle through all overlapping range group segments
        // A: |--|–----|
        // B: |-----|--|
        // => |--|--|--|
        while (
            a <= input.newInitialHolderRanges.length &&
            b <= _initialHolderRanges.length
        ) {
            // add last minted token Id to end of range
            uint tokenA = a < input.newInitialHolderRanges.length
                ? input.newInitialHolderRanges[a]
                : lastRangeTokenIdMinted + 1;
            uint tokenB = b < _initialHolderRanges.length
                ? _initialHolderRanges[b]
                : lastRangeTokenIdMinted + 1;

            if (tokenA != tokenB) {
                // Calculate group details:
                uint fromId;
                uint toId;
                address[] memory newInitialHolders;
                address[] memory currentInitialHolders;

                if (tokenA > tokenB) {
                    // token before larger
                    uint tokenA0 = a - 1 >= 0
                        ? input.newInitialHolderRanges[a - 1]
                        : 0;
                    // token after smaller
                    uint tokenB1 = b + 1 < _initialHolderRanges.length
                        ? _initialHolderRanges[b + 1]
                        : lastRangeTokenIdMinted + 1;

                    fromId = tokenA0 > tokenB ? tokenA0 : tokenB;
                    toId = (tokenB1 < tokenA ? tokenB1 : tokenA) - 1;

                    newInitialHolders = input.newInitialHolders[a - 1];
                    currentInitialHolders = _initialHolders[b];
                } else {
                    // token before large
                    uint tokenB0 = b - 1 >= 0 ? _initialHolderRanges[b - 1] : 0;
                    // token after smaller
                    uint tokenA1 = a + 1 < input.newInitialHolderRanges.length
                        ? input.newInitialHolderRanges[a + 1]
                        : lastRangeTokenIdMinted + 1;

                    fromId = tokenB0 > tokenA ? tokenB0 : tokenA;
                    toId = (tokenA1 < tokenB ? tokenA1 : tokenB) - 1;

                    newInitialHolders = input.newInitialHolders[a];
                    currentInitialHolders = _initialHolders[b - 1];
                }
                require(
                    currentInitialHolders.length == newInitialHolders.length,
                    "H:04"
                );

                // for each initial holder address in group
                for (uint i = 0; i < newInitialHolders.length; i++) {
                    address fromAddress = currentInitialHolders[i];
                    address toAddress = newInitialHolders[i];

                    // if address was updated
                    if (fromAddress != toAddress) {
                        // initialHolders cant be zero-address
                        require(toAddress != address(0), "H:05");
                        require(
                            !isHolderAddress[toAddress] ||
                                isInitialHolderAddress[toAddress],
                            "H:06"
                        );
                        // initialHolders must be unique per tokenId
                        for (
                            uint j = i + 1;
                            j < newInitialHolders.length;
                            j++
                        ) {
                            require(toAddress != newInitialHolders[j], "H:07");
                        }

                        // add address to initial holders map
                        isInitialHolderAddress[toAddress] = true;

                        // for each token in range group
                        for (uint id = fromId; id <= toId; id++) {
                            // must not be locked
                            require(
                                !isZeroLocked ||
                                    id >
                                    lastRangeTokenIdWithLockedInitialHolders,
                                "H:08"
                            );
                            // initialize from-address
                            // if there are already funds in to-address
                            // or if to-address was initialized.
                            if (
                                isBalanceInitialized[toAddress][id] ||
                                isBalanceInitialized[fromAddress][id]
                            ) {
                                _maybeInitializeBalance(fromAddress, id);
                                _maybeInitializeBalance(toAddress, id);
                            }
                        }
                    }
                }
            }
            // increase range with lower tokenId
            if (
                tokenA > tokenB || a + 1 > input.newInitialHolderRanges.length
            ) {
                b++;
            } else {
                require(
                    a <= 0 ||
                        input.newInitialHolderRanges[a] >
                        input.newInitialHolderRanges[a - 1],
                    "H:09"
                );
                a++;
            }
        }

        // Set new initial holders (ranges cannot be changed)
        _initialHolders = input.newInitialHolders;
        _initialHolderRanges = input.newInitialHolderRanges;

        _unpause();
        // emit "transfer" events
        for (uint i = 0; i < input.toAddresses.length; i++) {
            emit TransferBatch(
                msg.sender,
                input.fromAddresses[i],
                input.toAddresses[i],
                input.ids[i],
                input.amounts[i]
            );
        }
        _pause();
    }

    // Verifies the checksum generated by verifyUpdateInitialHoldersInput
    function _updateInitialHoldersSafe(
        UpdateInitialHoldersInput memory input,
        bytes32 inputChecksum
    ) internal virtual {
        bytes32 checksum = keccak256(
            abi.encode(input, _initialHolders, _initialHolderRanges, paused())
        );
        require(inputChecksum == checksum, "H:10");
        _updateInitialHolders(input);
    }

    // Verify and hash input updateInitialHolderRange method.
    function verifyUpdateInitialHoldersInput(
        UpdateInitialHoldersInput memory input
    ) public view virtual whenPaused returns (bytes32) {
        return
            Ph101ppDailyPhotoUtils.verifyUpdateInitialHoldersInput(
                VerifyUpdateInitialHoldersInput(
                    input.fromAddresses,
                    input.toAddresses,
                    input.ids,
                    input.amounts,
                    input.newInitialHolders,
                    input.newInitialHolderRanges,
                    this
                )
            );
    }
}
[{"inputs":[{"internalType":"string","name":"newProxyUri","type":"string"},{"internalType":"address[]","name":"initialHolders","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"CLAIM_TOKEN_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"START_DATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"getMintRangeInput","outputs":[{"components":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[][]","name":"amounts","type":"uint256[][]"}],"internalType":"struct ERC1155MintRange.MintRangeInput","name":"","type":"tuple"},{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialHolderRanges","outputs":[{"internalType":"address[][]","name":"holders","type":"address[][]"},{"internalType":"uint256[]","name":"ranges","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"initialHolders","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"initialSupply","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialSupplyRanges","outputs":[{"internalType":"uint256[][]","name":"supplies","type":"uint256[][]"},{"internalType":"uint256[]","name":"ranges","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"isBalanceInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isHolderAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isInitialHolderAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialHoldersRangeUpdatePermanentlyDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isManualMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOperatorFilterRegistryAddressPermanentlyFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTransferEventListenerAddressPermanentlyFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isZeroLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isZeroMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRangeTokenIdMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRangeTokenIdWithLockedInitialHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRangeTokenIdWithPermanentUri","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintClaims","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[][]","name":"amounts","type":"uint256[][]"}],"internalType":"struct ERC1155MintRange.MintRangeInput","name":"input","type":"tuple"},{"internalType":"bytes32","name":"checksum","type":"bytes32"}],"name":"mintPhotos","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operatorFilterRegistryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"period","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodRanges","outputs":[{"internalType":"string[]","name":"periods","type":"string[]"},{"internalType":"uint256[]","name":"ranges","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permanentBaseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permanentBaseUriRanges","outputs":[{"internalType":"string[]","name":"permanentBaseUris","type":"string[]"},{"internalType":"uint256[]","name":"ranges","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permanentlyDisableInitialHoldersRangeUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permanentlyFreezeOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permanentlyFreezeTransferEventListenerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxyBaseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"redeemClaims","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"resetTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"vault","type":"address"}],"name":"setInitialHolders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"newInitialSupply","type":"uint256[]"}],"name":"setInitialSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"setLockInitialHoldersUpTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operatorFilterRegistryAddress","type":"address"}],"name":"setOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"periodName","type":"string"}],"name":"setPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newUri","type":"string"},{"internalType":"uint256","name":"validUpToTokenId","type":"uint256"}],"name":"setPermanentBaseUriUpTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newProxyUri","type":"string"}],"name":"setProxyBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"listener","type":"address"}],"name":"setTransferEventListenerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"}],"name":"tokenSlugFromDate","outputs":[{"internalType":"string","name":"tokenSlug","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenSlugFromTokenId","outputs":[{"internalType":"string","name":"tokenSlug","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transferEventListenerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"fromAddresses","type":"address[]"},{"internalType":"address[]","name":"toAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"ids","type":"uint256[][]"},{"internalType":"uint256[][]","name":"amounts","type":"uint256[][]"},{"internalType":"address[][]","name":"newInitialHolders","type":"address[][]"},{"internalType":"uint256[]","name":"newInitialHolderRanges","type":"uint256[]"}],"internalType":"struct ERC1155MintRangeUpdateable.UpdateInitialHoldersInput","name":"input","type":"tuple"},{"internalType":"bytes32","name":"checksum","type":"bytes32"}],"name":"updateInitialHolders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uriHistory","outputs":[{"internalType":"string[][]","name":"","type":"string[][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"fromAddresses","type":"address[]"},{"internalType":"address[]","name":"toAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"ids","type":"uint256[][]"},{"internalType":"uint256[][]","name":"amounts","type":"uint256[][]"},{"internalType":"address[][]","name":"newInitialHolders","type":"address[][]"},{"internalType":"uint256[]","name":"newInitialHolderRanges","type":"uint256[]"}],"internalType":"struct ERC1155MintRangeUpdateable.UpdateInitialHoldersInput","name":"input","type":"tuple"}],"name":"verifyUpdateInitialHoldersInput","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]