// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;

import { MerkleProofLib } from "solady/utils/MerkleProofLib.sol";
import { IERC165 } from "openzeppelin/utils/introspection/IERC165.sol";
import { IRangeEditionMinterV2, EditionMintData, MintInfo } from "./interfaces/IRangeEditionMinterV2.sol";
import { BaseMinterV2 } from "./BaseMinterV2.sol";
import { IMinterModuleV2 } from "@core/interfaces/IMinterModuleV2.sol";
import { ISoundEditionV1 } from "@core/interfaces/ISoundEditionV1.sol";

/*
 * @title RangeEditionMinterV2
 * @notice Module for range edition mints of Sound editions.
 * @author Sound.xyz
 */
contract RangeEditionMinterV2 is IRangeEditionMinterV2, BaseMinterV2 {
    // =============================================================
    //                            STORAGE
    // =============================================================

    /**
     * @dev Edition mint data.
     *      `_baseDataSlot(_getBaseData(edition, mintId))` => value.
     */
    mapping(bytes32 => EditionMintData) internal _editionMintData;

    // =============================================================
    //               PUBLIC / EXTERNAL WRITE FUNCTIONS
    // =============================================================

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function createEditionMint(
        address edition,
        uint96 price,
        uint32 startTime,
        uint32 cutoffTime,
        uint32 endTime,
        uint16 affiliateFeeBPS,
        uint32 maxMintableLower,
        uint32 maxMintableUpper,
        uint32 maxMintablePerAccount
    ) public returns (uint128 mintId) {
        _requireValidCombinedTimeRange(startTime, cutoffTime, endTime);
        if (maxMintableLower > maxMintableUpper) revert InvalidMaxMintableRange();
        if (maxMintablePerAccount == 0) revert MaxMintablePerAccountIsZero();

        mintId = _createEditionMint(edition, startTime, endTime, affiliateFeeBPS);

        BaseData storage baseData = _getBaseDataUnchecked(edition, mintId);
        baseData.price = price;
        baseData.maxMintablePerAccount = maxMintablePerAccount;

        EditionMintData storage data = _editionMintData[_baseDataSlot(baseData)];
        data.cutoffTime = cutoffTime;
        data.maxMintableLower = maxMintableLower;
        data.maxMintableUpper = maxMintableUpper;

        // prettier-ignore
        emit RangeEditionMintCreated(
            edition,
            mintId,
            price,
            startTime,
            cutoffTime,
            endTime,
            affiliateFeeBPS,
            maxMintableLower,
            maxMintableUpper,
            maxMintablePerAccount
        );
    }

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function mintTo(
        address edition,
        uint128 mintId,
        address to,
        uint32 quantity,
        address affiliate,
        bytes32[] calldata affiliateProof,
        uint256 attributionId
    ) public payable {
        BaseData storage baseData = _getBaseData(edition, mintId);
        EditionMintData storage data = _editionMintData[_baseDataSlot(baseData)];

        uint32 _maxMintable = _getMaxMintable(data);

        // Increase `totalMinted` by `quantity`.
        // Require that the increased value does not exceed `maxMintable`.
        data.totalMinted = _incrementTotalMinted(data.totalMinted, quantity, _maxMintable);

        unchecked {
            // Check the additional `requestedQuantity` does not exceed the maximum mintable per account.
            uint256 numberMinted = ISoundEditionV1(edition).numberMinted(to);
            // Won't overflow. The total number of tokens minted in `edition` won't exceed `type(uint32).max`,
            // and `quantity` has 32 bits.
            if (numberMinted + quantity > baseData.maxMintablePerAccount) revert ExceedsMaxPerAccount();
        }

        _mintTo(edition, mintId, to, quantity, affiliate, affiliateProof, attributionId);
    }

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function mint(
        address edition,
        uint128 mintId,
        uint32 quantity,
        address affiliate
    ) public payable {
        mintTo(edition, mintId, msg.sender, quantity, affiliate, MerkleProofLib.emptyProof(), 0);
    }

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function setTimeRange(
        address edition,
        uint128 mintId,
        uint32 startTime,
        uint32 cutoffTime,
        uint32 endTime
    ) public onlyEditionOwnerOrAdmin(edition) {
        _requireValidCombinedTimeRange(startTime, cutoffTime, endTime);

        BaseData storage baseData = _getBaseData(edition, mintId);
        EditionMintData storage data = _editionMintData[_baseDataSlot(baseData)];

        data.cutoffTime = cutoffTime;
        baseData.startTime = startTime;
        baseData.endTime = endTime;

        emit CutoffTimeSet(edition, mintId, cutoffTime);
        emit TimeRangeSet(edition, mintId, startTime, endTime);
    }

    /**
     * @inheritdoc BaseMinterV2
     */
    function setTimeRange(
        address edition,
        uint128 mintId,
        uint32 startTime,
        uint32 endTime
    ) public override(BaseMinterV2, IMinterModuleV2) onlyEditionOwnerOrAdmin(edition) {
        BaseData storage baseData = _getBaseData(edition, mintId);
        EditionMintData storage data = _editionMintData[_baseDataSlot(baseData)];

        _requireValidCombinedTimeRange(startTime, data.cutoffTime, endTime);

        baseData.startTime = startTime;
        baseData.endTime = endTime;

        emit TimeRangeSet(edition, mintId, startTime, endTime);
    }

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function setMaxMintableRange(
        address edition,
        uint128 mintId,
        uint32 maxMintableLower,
        uint32 maxMintableUpper
    ) public onlyEditionOwnerOrAdmin(edition) {
        if (maxMintableLower > maxMintableUpper) revert InvalidMaxMintableRange();
        EditionMintData storage data = _editionMintData[_baseDataSlot(_getBaseData(edition, mintId))];
        data.maxMintableLower = maxMintableLower;
        data.maxMintableUpper = maxMintableUpper;

        emit MaxMintableRangeSet(edition, mintId, maxMintableLower, maxMintableUpper);
    }

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function setPrice(
        address edition,
        uint128 mintId,
        uint96 price
    ) public onlyEditionOwnerOrAdmin(edition) {
        _getBaseData(edition, mintId).price = price;
        emit PriceSet(edition, mintId, price);
    }

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function setMaxMintablePerAccount(
        address edition,
        uint128 mintId,
        uint32 maxMintablePerAccount
    ) public onlyEditionOwnerOrAdmin(edition) {
        if (maxMintablePerAccount == 0) revert MaxMintablePerAccountIsZero();
        _getBaseData(edition, mintId).maxMintablePerAccount = maxMintablePerAccount;
        emit MaxMintablePerAccountSet(edition, mintId, maxMintablePerAccount);
    }

    // =============================================================
    //               PUBLIC / EXTERNAL VIEW FUNCTIONS
    // =============================================================

    /**
     * @inheritdoc IRangeEditionMinterV2
     */
    function mintInfo(address edition, uint128 mintId) external view returns (MintInfo memory info) {
        BaseData storage baseData = _getBaseData(edition, mintId);
        EditionMintData storage mintData = _editionMintData[_baseDataSlot(baseData)];

        info.startTime = baseData.startTime;
        info.endTime = baseData.endTime;
        info.affiliateFeeBPS = baseData.affiliateFeeBPS;
        info.mintPaused = baseData.mintPaused;
        info.price = baseData.price;
        info.maxMintableUpper = mintData.maxMintableUpper;
        info.maxMintableLower = mintData.maxMintableLower;
        info.maxMintablePerAccount = baseData.maxMintablePerAccount;
        info.totalMinted = mintData.totalMinted;
        info.cutoffTime = mintData.cutoffTime;

        info.affiliateMerkleRoot = baseData.affiliateMerkleRoot;
    }

    /**
     * @inheritdoc IERC165
     */
    function supportsInterface(bytes4 interfaceId) public view override(IERC165, BaseMinterV2) returns (bool) {
        return BaseMinterV2.supportsInterface(interfaceId) || interfaceId == type(IRangeEditionMinterV2).interfaceId;
    }

    /**
     * @inheritdoc IMinterModuleV2
     */
    function moduleInterfaceId() public pure returns (bytes4) {
        return type(IRangeEditionMinterV2).interfaceId;
    }

    // =============================================================
    //                  INTERNAL / PRIVATE HELPERS
    // =============================================================

    /**
     * @dev Restricts the `startTime` to be less than `cutoffTime`,
     *      and `cutoffTime` to be less than `endTime`.
     * @param startTime   The start unix timestamp of the mint.
     * @param cutoffTime  The cutoff unix timestamp of the mint.
     * @param endTime     The end unix timestamp of the mint.
     */
    function _requireValidCombinedTimeRange(
        uint32 startTime,
        uint32 cutoffTime,
        uint32 endTime
    ) internal pure {
        if (!(startTime < cutoffTime && cutoffTime < endTime)) revert InvalidTimeRange();
    }

    /**
     * @dev Gets the current maximum mintable quantity.
     * @param data The edition mint data.
     * @return The computed value.
     */
    function _getMaxMintable(EditionMintData storage data) internal view returns (uint32) {
        uint32 _maxMintable;
        if (block.timestamp < data.cutoffTime) {
            _maxMintable = data.maxMintableUpper;
        } else {
            _maxMintable = data.maxMintableLower;
        }
        return _maxMintable;
    }
}
[{"inputs":[{"internalType":"uint32","name":"available","type":"uint32"}],"name":"ExceedsAvailableSupply","type":"error"},{"inputs":[],"name":"ExceedsMaxPerAccount","type":"error"},{"inputs":[],"name":"InvalidAffiliate","type":"error"},{"inputs":[],"name":"InvalidAffiliateFeeBPS","type":"error"},{"inputs":[],"name":"InvalidMaxMintableRange","type":"error"},{"inputs":[],"name":"InvalidPlatformFeeBPS","type":"error"},{"inputs":[],"name":"InvalidPlatformFlatFee","type":"error"},{"inputs":[],"name":"InvalidTimeRange","type":"error"},{"inputs":[],"name":"MaxMintablePerAccountIsZero","type":"error"},{"inputs":[],"name":"MintDoesNotExist","type":"error"},{"inputs":[{"internalType":"uint256","name":"blockTimestamp","type":"uint256"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"MintNotOpen","type":"error"},{"inputs":[],"name":"MintPaused","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"PlatformFeeAddressIsZero","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[{"internalType":"uint256","name":"paid","type":"uint256"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"Underpaid","type":"error"},{"inputs":[{"internalType":"uint256","name":"paid","type":"uint256"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"WrongPayment","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint16","name":"bps","type":"uint16"}],"name":"AffiliateFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"uint256","name":"accrued","type":"uint256"}],"name":"AffiliateFeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"AffiliateMerkleRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"cutoffTime","type":"uint32"}],"name":"CutoffTimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"}],"name":"MaxMintablePerAccountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"maxMintableLower","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"maxMintableUpper","type":"uint32"}],"name":"MaxMintableRangeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"startTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"endTime","type":"uint32"},{"indexed":false,"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"}],"name":"MintConfigCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"MintPausedSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint32","name":"fromTokenId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"quantity","type":"uint32"},{"indexed":false,"internalType":"uint128","name":"requiredEtherValue","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"platformFee","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"affiliateFee","type":"uint128"},{"indexed":false,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"bool","name":"affiliated","type":"bool"},{"indexed":true,"internalType":"uint256","name":"attributionId","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"PlatformFeeAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"bps","type":"uint16"}],"name":"PlatformFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"accrued","type":"uint128"}],"name":"PlatformFeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"flatFee","type":"uint96"}],"name":"PlatformFlatFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint96","name":"price","type":"uint96"}],"name":"PriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint96","name":"price","type":"uint96"},{"indexed":false,"internalType":"uint32","name":"startTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"cutoffTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"endTime","type":"uint32"},{"indexed":false,"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"indexed":false,"internalType":"uint32","name":"maxMintableLower","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"maxMintableUpper","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"}],"name":"RangeEditionMintCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint128","name":"mintId","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"startTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"TimeRangeSet","type":"event"},{"inputs":[],"name":"BPS_DENOMINATOR","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_AFFILIATE_FEE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_FEE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_FLAT_FEE","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"affiliateFeesAccrued","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"}],"name":"affiliateMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"cutoffTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"uint32","name":"maxMintableLower","type":"uint32"},{"internalType":"uint32","name":"maxMintableUpper","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"}],"name":"createEditionMint","outputs":[{"internalType":"uint128","name":"mintId","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"address","name":"affiliate","type":"address"}],"name":"isAffiliated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"}],"name":"isAffiliatedWithProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"affiliate","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"}],"name":"mintInfo","outputs":[{"components":[{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"bool","name":"mintPaused","type":"bool"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"maxMintableUpper","type":"uint32"},{"internalType":"uint32","name":"maxMintableLower","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"totalMinted","type":"uint32"},{"internalType":"uint32","name":"cutoffTime","type":"uint32"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"}],"internalType":"struct MintInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"},{"internalType":"uint256","name":"attributionId","type":"uint256"}],"name":"mintTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"moduleInterfaceId","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"nextMintId","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownershipHandoverValidFor","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFeeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFeeBPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFeesAccrued","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFlatFee","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"uint16","name":"bps","type":"uint16"}],"name":"setAffiliateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setAffiliateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"bool","name":"paused","type":"bool"}],"name":"setEditionMintPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"}],"name":"setMaxMintablePerAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"uint32","name":"maxMintableLower","type":"uint32"},{"internalType":"uint32","name":"maxMintableUpper","type":"uint32"}],"name":"setMaxMintableRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"bps","type":"uint16"}],"name":"setPlatformFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setPlatformFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"flatFee","type":"uint96"}],"name":"setPlatformFlatFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"uint96","name":"price","type":"uint96"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"setTimeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"cutoffTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"setTimeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint128","name":"mintId","type":"uint128"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint32","name":"quantity","type":"uint32"}],"name":"totalPrice","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"affiliate","type":"address"}],"name":"withdrawForAffiliate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawForPlatform","outputs":[],"stateMutability":"nonpayable","type":"function"}]