APE Price: $1.13 (-1.14%)

Contract Diff Checker

Contract Name:
PermissionlessPaymentProcessorConfiguration

Contract Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @dev Storage data struct for stored approvals and order approvals
struct PackedApproval {
    // Only used for partial fill position 1155 transfers
    uint8 state;
    // Amount allowed
    uint200 amount;
    // Permission expiry
    uint48 expiration;
}

/// @dev Calldata data struct for order fill amounts
struct OrderFillAmounts {
    uint256 orderStartAmount;
    uint256 requestedFillAmount;
    uint256 minimumFillAmount;
}

//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity ^0.8.0;

/*
# PolyForm Strict License 1.0.0

<https://polyformproject.org/licenses/strict/1.0.0>

## Acceptance

In order to get any license under these terms, you must agree
to them as both strict obligations and conditions to all
your licenses.

## Copyright License

The licensor grants you a copyright license for the software
to do everything you might do with the software that would
otherwise infringe the licensor's copyright in it for any
permitted purpose, other than distributing the software or
making changes or new works based on the software.

## Patent License

The licensor grants you a patent license for the software that
covers patent claims the licensor can license, or becomes able
to license, that you would infringe by using the software.

## Noncommercial Purposes

Any noncommercial purpose is a permitted purpose.

## Personal Uses

Personal use for research, experiment, and testing for
the benefit of public knowledge, personal study, private
entertainment, hobby projects, amateur pursuits, or religious
observance, without any anticipated commercial application,
is use for a permitted purpose.

## Noncommercial Organizations

Use by any charitable organization, educational institution,
public research organization, public safety or health
organization, environmental protection organization,
or government institution is use for a permitted purpose
regardless of the source of funding or obligations resulting
from the funding.

## Fair Use

You may have "fair use" rights for the software under the
law. These terms do not limit them.

## No Other Rights

These terms do not allow you to sublicense or transfer any of
your licenses to anyone else, or prevent the licensor from
granting licenses to anyone else.  These terms do not imply
any other licenses.

## Patent Defense

If you make any written claim that the software infringes or
contributes to infringement of any patent, your patent license
for the software granted under these terms ends immediately. If
your company makes such a claim, your patent license ends
immediately for work on behalf of your company.

## Violations

The first time you are notified in writing that you have
violated any of these terms, or done anything with the software
not covered by your licenses, your licenses can nonetheless
continue if you come into full compliance with these terms,
and take practical steps to correct past violations, within
32 days of receiving notice.  Otherwise, all your licenses
end immediately.

## No Liability

***As far as the law allows, the software comes as is, without
any warranty or condition, and the licensor will not be liable
to you for any damages arising out of these terms or the use
or nature of the software, under any kind of legal claim.***

## Definitions

The **licensor** is the individual or entity offering these
terms, and the **software** is the software the licensor makes
available under these terms.

**You** refers to the individual or entity agreeing to these
terms.

**Your company** is any legal entity, sole proprietorship,
or other kind of organization that you work for, plus all
organizations that have control over, are under the control of,
or are under common control with that organization.  **Control**
means ownership of substantially all the assets of an entity,
or the power to direct its management and policies by vote,
contract, or otherwise.  Control can be direct or indirect.

**Your licenses** are all the licenses granted to you for the
software under these terms.

**Use** means anything you do with the software requiring one
of your licenses.
*/

pragma solidity ^0.8.4;

// General Purpose Custom Errors
error Error__BadConstructorArgument();

// Authorization Errors
error RoleClient__Unauthorized();

// Extensible Custom Errors
error Extensible__ConflictingFunctionSelectorAlreadyInstalled();
error Extensible__ExtensionAlreadyInstalled();
error Extensible__ExtensionNotInstalled();
error Extensible__InvalidExtension();

pragma solidity ^0.8.4;

interface IRoleClient {
    function onRoleHolderChanged(bytes32 /*role*/, address /*roleHolder*/) external;
}

pragma solidity ^0.8.4;

interface IRoleServer {
    function getRoleHolder(bytes32 /*role*/) external view returns (address);
    function setRoleHolder(bytes32 /*role*/, address /*authority*/, address[] calldata /*clients*/) external;
}

pragma solidity ^0.8.4;

import "./IRoleClient.sol";
import "./IRoleServer.sol";
import "../Errors.sol";

abstract contract RoleClient is IRoleClient {
    event RoleUpdatesRequested(address indexed roleServer, bytes32 indexed role);

    struct RoleRecord {
        address roleHolder;
        uint64 expiration;
        uint32 ttl;
    }

    IRoleServer private immutable _roleServer;

    struct RoleClientStorage {
        mapping (bytes32 role => RoleRecord record) roleRecords;
    }

    bytes32 private constant ROLE_CLIENT_STORAGE_SLOT = keccak256("storage.RoleClient");
    
    function roleClientStorage() internal pure returns (RoleClientStorage storage ptr) {
        bytes32 slot = ROLE_CLIENT_STORAGE_SLOT;
        assembly {
            ptr.slot := slot
        }
    }

    constructor(address roleServer) {
        if (roleServer == address(0)) {
            revert Error__BadConstructorArgument();
        }

        _roleServer = IRoleServer(roleServer);
        _setupRoles();
    }

    modifier callerHasRole(bytes32 role) {
        _requireCallerHasRole(role);
        _;
    }

    function onRoleHolderChanged(bytes32 role, address roleHolder) external {
        if (msg.sender != address(_roleServer)) {
            revert RoleClient__Unauthorized();
        }

        unchecked {
            RoleRecord storage record = roleClientStorage().roleRecords[role];
            record.roleHolder = roleHolder;
            record.expiration = uint64(block.timestamp + record.ttl);
        }
    }

    function _getRoleHolder(bytes32 role) internal returns (address roleHolder) {
        RoleRecord storage record = roleClientStorage().roleRecords[role];
        roleHolder = record.roleHolder;

        unchecked {
            if (record.expiration < block.timestamp) {
                roleHolder = _roleServer.getRoleHolder(role);
                record.roleHolder = roleHolder;
                record.expiration = uint64(block.timestamp + record.ttl);
            }
        }
    }

    function _getRoleHolderView(bytes32 role) internal view returns (address roleHolder) {
        RoleRecord storage record = roleClientStorage().roleRecords[role];
        roleHolder = record.roleHolder;

        unchecked {
            if (record.expiration < block.timestamp) {
                roleHolder = _roleServer.getRoleHolder(role);
            }
        }
    }

    function _requireCallerHasRole(bytes32 role) internal {
        if (msg.sender != _getRoleHolder(role)) {
            revert RoleClient__Unauthorized();
        }
    }

    function _setupRole(bytes32 role, uint32 ttl) internal {
        unchecked {
            RoleRecord storage record = roleClientStorage().roleRecords[role];
            record.roleHolder = _roleServer.getRoleHolder(role);
            record.ttl = ttl;
            record.expiration = uint64(block.timestamp) + ttl;
        }
    }

    function _setupRoles() internal virtual;
}

pragma solidity ^0.8.4;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```solidity
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position is the index of the value in the `values` array plus 1.
        // Position 0 is used to mean a value is not in the set.
        mapping(bytes32 value => uint256) _positions;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._positions[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We cache the value's position to prevent multiple reads from the same storage slot
        uint256 position = set._positions[value];

        if (position != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 valueIndex = position - 1;
            uint256 lastIndex = set._values.length - 1;

            if (valueIndex != lastIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the lastValue to the index where the value to delete is
                set._values[valueIndex] = lastValue;
                // Update the tracked position of the lastValue (that was just moved)
                set._positions[lastValue] = position;
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the tracked position for the deleted slot
            delete set._positions[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._positions[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

import "@limitbreak/tm-core-lib/src/utils/structs/EnumerableSet.sol";

import { 
    OrderFillAmounts
} from "@limitbreak/permit-c/DataTypes.sol";

/**
 * @dev Used internally to indicate which side of the order the taker is on.
 */
enum Sides { 
    // 0: Taker is on buy side of order.
    Buy, 

    // 1: Taker is on sell side of order.
    Sell 
}

/**
 * @dev Defines the rules applied to a collection for payments.
 */
enum PaymentSettings { 
    // 0: Utilize Payment Processor default whitelist.
    DefaultPaymentMethodWhitelist,

    // 1: Allow any payment method.
    AllowAnyPaymentMethod,

    // 2: Use a custom payment method whitelist.
    CustomPaymentMethodWhitelist,

    // 3: Single payment method with floor and ceiling limits on collections only.
    PricingConstraintsCollectionOnly,

    // 4: Single payment method with floor and ceiling limits, allows both token and collection level constraints.
    PricingConstraints,

    // 5: Pauses trading for the collection.
    Paused
}

/**
 * @dev This struct is used internally for the deployment of the Payment Processor contract and 
 * @dev module deployments to define the default payment method whitelist.
 */
struct DefaultPaymentMethods {
    address defaultPaymentMethod1;
    address defaultPaymentMethod2;
    address defaultPaymentMethod3;
    address defaultPaymentMethod4;
}

/**
 * @dev This struct is used internally for the deployment of the Payment Processor contract and 
 * @dev module deployments to define the default trusted permit processors.
 */
struct TrustedPermitProcessors {
    address permitProcessor1;
    address permitProcessor2;
}

/**
 * @dev This struct is used internally for the deployment of the Payment Processor contract to define the
 * @dev module addresses to be used for the contract.
 */
struct PaymentProcessorModules {
    address moduleOnChainCancellation;
    address moduleBuyListings;
    address moduleAcceptOffers;
    address moduleSweeps;
}

/**
 * @dev This struct defines the payment settings parameters for a collection.
 *
 * @dev **paymentSettings**: The general rule definition for payment methods allowed.
 * @dev **paymentMethodWhitelistId**: The list id to be used when paymentSettings is set to CustomPaymentMethodWhitelist.
 * @dev **royaltyBackfillReceiver**: The backfilled royalty receiver for a collection.
 * @dev **royaltyBackfillNumerator**: The royalty fee to apply to the collection when ERC2981 is not supported.
 * @dev **royaltyBountyNumerator**: The percentage of royalties the creator will grant to a marketplace for order fulfillment.
 * @dev **isRoyaltyBountyExclusive**: If true, royalty bounties will only be paid if the order marketplace is the set exclusive marketplace.
 * @dev **blockTradesFromUntrustedChannels**: If true, trades that originate from untrusted channels will not be executed.
 */
struct CollectionPaymentSettings {
    bool initialized;
    PaymentSettings paymentSettings;
    uint32 paymentMethodWhitelistId;
    address royaltyBackfillReceiver;
    uint16 royaltyBackfillNumerator;
    uint16 royaltyBountyNumerator;
    uint8 flags;
}

/**
 * @dev The `v`, `r`, and `s` components of an ECDSA signature.  For more information
 *      [refer to this article](https://medium.com/mycrypto/the-magic-of-digital-signatures-on-ethereum-98fe184dc9c7).
 */
struct SignatureECDSA {
    uint256 v;
    bytes32 r;
    bytes32 s;
}

/**
 * @dev This struct defines order execution parameters.
 * 
 * @dev **protocol**: The order protocol to apply to the order.
 * @dev **maker**: The user that created and signed the order to be executed by a taker.
 * @dev **beneficiary**: The account that will receive the tokens.
 * @dev **marketplace**: The fee receiver of the marketplace that the order was created on.
 * @dev **fallbackRoyaltyRecipient**: The address that will receive royalties if ERC2981 
 * @dev is not supported by the collection and the creator has not defined backfilled royalties with Payment Processor.
 * @dev **paymentMethod**: The payment method for the order.
 * @dev **tokenAddress**: The address of the token collection the order is for.
 * @dev **tokenId**: The token id that the order is for.
 * @dev **amount**: The quantity of token the order is for.
 * @dev **itemPrice**: The price for the order in base units for the payment method.
 * @dev **nonce**: The maker's nonce for the order.
 * @dev **expiration**: The time, in seconds since the Unix epoch, that the order will expire.
 * @dev **marketplaceFeeNumerator**: The percentage fee that will be sent to the marketplace.
 * @dev **maxRoyaltyFeeNumerator**: The maximum royalty the maker is willing to accept. This will be used
 * @dev as the royalty amount when ERC2981 is not supported by the collection.
 * @dev **requestedFillAmount**: The amount of tokens for an ERC1155 partial fill order that the taker wants to fill.
 * @dev **minimumFillAmount**: The minimum amount of tokens for an ERC1155 partial fill order that the taker will accept.
 * @dev **protocolFeeVersion**: The protocol fee version to use when applying protocol fees.
 */
struct Order {
    uint256 protocol;
    address maker;
    address beneficiary;
    address marketplace;
    address fallbackRoyaltyRecipient;
    address paymentMethod;
    address tokenAddress;
    uint256 tokenId;
    uint256 amount;
    uint256 itemPrice;
    uint256 nonce;
    uint256 expiration;
    uint256 marketplaceFeeNumerator;
    uint256 maxRoyaltyFeeNumerator;
    uint256 requestedFillAmount;
    uint256 minimumFillAmount;
    uint256 protocolFeeVersion;
}

/**
 * @dev This struct defines the items required to execute an advanced order.
 *
 * @dev **saleDetails**: The order execution parameters.
 * @dev **signature**: The signature of the maker authorizing the order execution.
 * @dev **cosignature**: The cosignature of the maker authorizing the order execution.
 * @dev **permitContext**: Contains the address of the permit processor and the permit nonce to be used.
 */
struct AdvancedOrder {
    Order saleDetails;
    SignatureECDSA signature;
    Cosignature cosignature;
    PermitContext permitContext;
}

/**
 * @dev This struct defines the items required to execute an advanced bid order.
 * 
 * @dev **offerType**: The type of offer to execute.
 * @dev **advancedOrder**: The order execution parameters.
 * @dev **sellerPermitSignature**: The signature of the seller to be used for the permit.
 */
struct AdvancedBidOrder {
    uint256 offerType;
    AdvancedOrder advancedOrder;
    SignatureECDSA sellerPermitSignature;
}

/**
 * @dev This struct defines the items required to execute an advanced sweep order.
 *
 * @dev **feeOnTop**: The additional fee to be paid by the taker.
 * @dev **sweepOrder**: The order execution parameters.
 * @dev **items**: An array of items to be executed as part of the sweep order.
 */
struct AdvancedSweep {
    FeeOnTop feeOnTop;
    SweepOrder sweepOrder;
    AdvancedSweepItem[] items;
}

/**
 * @dev This struct is a wrapper for a sweep order item that includes the permit context, bulk order information, signature and cosignature.
 *
 * @dev **sweepItem**: The sweep order item to be executed.
 * @dev **signature**: The signature of the maker authorizing the order execution.
 * @dev **cosignature**: The cosignature of the maker authorizing the order execution.
 * @dev **permitContext**: Contains the address of the permit processor and the permit nonce to be used.
 * @dev **bulkOrderProof**: The proof data for the bulk order.
 */
struct AdvancedSweepItem {
    SweepItem sweepItem;
    SignatureECDSA signature;
    Cosignature cosignature;
    PermitContext permitContext;
    BulkOrderProof bulkOrderProof;
}

/**
 * @dev This struct defines the cosignature for verifying an order that is a cosigned order.
 *
 * @dev **signer**: The address that signed the cosigned order. This must match the cosigner that is part of the order signature.
 * @dev **taker**: The address of the order taker.
 * @dev **expiration**: The time, in seconds since the Unix epoch, that the cosignature will expire.
 * @dev The `v`, `r`, and `s` components of an ECDSA signature.  For more information
 *      [refer to this article](https://medium.com/mycrypto/the-magic-of-digital-signatures-on-ethereum-98fe184dc9c7).
 */
struct Cosignature {
    address signer;
    address taker;
    uint256 expiration;
    uint256 v;
    bytes32 r;
    bytes32 s;
}

/**
 * @dev This struct defines an additional fee on top of an order, paid by taker.
 *
 * @dev **recipient**: The recipient of the additional fee.
 * @dev **amount**: The amount of the additional fee, in base units of the payment token.
 */
struct FeeOnTop {
    address recipient;
    uint256 amount;
}

/**
 * @dev This struct defines the proof data for accepting an offer that is for a subset
 * @dev of items in a collection. The computed root hash from the proof must match the root
 * @dev hash that was signed by the order maker to recover the maker address.
 * 
 * @dev **proof**: The merkle proofs for the item being supplied to fulfill the offer order.
 */
struct TokenSetProof {
    bytes32[] proof;
}

/**
 * @dev This struct defines the proof data for a bulk order.
 * 
 * @dev **orderIndex**: The index of the order in the bulk order.
 * @dev **proof**: The merkle proofs for the order being supplied to fulfill the bulk order.
 */
struct BulkOrderProof {
    uint256 orderIndex;
    bytes32[] proof;
}

/**
 * @dev Current state of a partially fillable order.
 */
enum PartiallyFillableOrderState { 
    // 0: Order is open and may continue to be filled.
    Open, 

    // 1: Order has been completely filled.
    Filled, 

    // 2: Order has been cancelled.
    Cancelled
}

/**
 * @dev This struct defines the current status of a partially fillable order.
 * 
 * @dev **state**: The current state of the order as defined by the PartiallyFillableOrderState enum.
 * @dev **remainingFillableQuantity**: The remaining quantity that may be filled for the order.
 */
struct PartiallyFillableOrderStatus {
    PartiallyFillableOrderState state;
    uint248 remainingFillableQuantity;
}

/**
 * @dev This struct defines order information that is common to all items in a sweep order.
 * 
 * @dev **protocol**: The order protocol to apply to the order.
 * @dev **tokenAddress**: The address of the token collection the order is for.
 * @dev **paymentMethod**: The payment method for the order.
 * @dev **beneficiary**: The account that will receive the tokens.
 */
struct SweepOrder {
    uint256 protocol;
    address tokenAddress;
    address paymentMethod;
    address beneficiary;
}

/**
 * @dev This struct defines order information that is unique to each item of a sweep order.
 * @dev Combined with the SweepOrder header information to make an Order to execute.
 * 
 * @dev **maker**: The user that created and signed the order to be executed by a taker.
 * @dev **marketplace**: The marketplace that the order was created on.
 * @dev **fallbackRoyaltyRecipient**: The address that will receive royalties if ERC2981 
 * @dev is not supported by the collection and the creator has not defined royalties with Payment Processor.
 * @dev **tokenId**: The token id that the order is for.
 * @dev **amount**: The quantity of token the order is for.
 * @dev **itemPrice**: The price for the order in base units for the payment method.
 * @dev **nonce**: The maker's nonce for the order.
 * @dev **expiration**: The time, in seconds since the Unix epoch, that the order will expire.
 * @dev **marketplaceFeeNumerator**: The percentage fee that will be sent to the marketplace.
 * @dev **maxRoyaltyFeeNumerator**: The maximum royalty the maker is willing to accept. This will be used
 * @dev as the royalty amount when ERC2981 is not supported by the collection.
 * @dev **protocolFeeVersion**: The protocol fee version to use when applying protocol fees.
 */
struct SweepItem {
    address maker;
    address marketplace;
    address fallbackRoyaltyRecipient;
    uint256 tokenId;
    uint256 amount;
    uint256 itemPrice;
    uint256 nonce;
    uint256 expiration;
    uint256 marketplaceFeeNumerator;
    uint256 maxRoyaltyFeeNumerator;
    uint256 protocolFeeVersion;
}

/**
 * @dev This struct is used to define pricing constraints for a collection or individual token.
 *
 * @dev **isSet**: When true, this indicates that pricing constraints are set for the collection or token.
 * @dev **floorPrice**: The minimum price for a token or collection.  This is only enforced when 
 * @dev `enforcePricingConstraints` is `true`.
 * @dev **ceilingPrice**: The maximum price for a token or collection.  This is only enforced when
 * @dev `enforcePricingConstraints` is `true`.
 */
struct PricingBounds {
    bool initialized;
    bool isSet;
    uint120 floorPrice;
    uint120 ceilingPrice;
}

/**
 * @dev This struct defines the parameters for a bulk offer acceptance transaction.
 * 
 * 
 * @dev **offerType**: Offer type to execute.
 * @dev **saleDetails**: Order execution details.
 * @dev **signature**: Maker signature authorizing the order executions.
 * @dev **cosignature**: Additional cosignature for cosigned orders, as applicable.
 */
struct BulkAcceptOffersParams {
    uint256 offerType;
    Order saleDetails;
    SignatureECDSA signature;
    Cosignature cosignature;
}

/**
 * @dev This struct defines the parameters for a sweep execution transaction.
 *
 * @dev **fnPointers**: The function pointers to use for the sweep execution.
 * @dev **accumulator**: The accumulator to use for the sweep execution.
 * @dev **paymentCoin**: The payment token to use for the sweep execution.
 * @dev **paymentSettings**: The payment settings to use for the sweep execution.
 */
struct SweepExecutionParams {
    FulfillOrderFunctionPointers fnPointers;
    PayoutsAccumulator accumulator;
    address paymentCoin;
    PaymentSettings paymentSettings;
}

/** 
 * @dev This struct defines the parameters for the proceeds to be split between the seller, marketplace, and royalty recipient.
 *
 * @dev **royaltyRecipient**: The address of the royalty recipient.
 * @dev **royaltyProceeds**: The amount of proceeds to be sent to the royalty recipient.
 * @dev **marketplaceProceeds**: The amount of proceeds to be sent to the marketplace.
 * @dev **sellerProceeds**: The amount of proceeds to be sent to the seller.
 * @dev **infrastructureProceeds**: The amount of proceeds to be sent to the infrastructure recipient.
 */
struct SplitProceeds {
    address royaltyRecipient;
    uint256 royaltyProceeds;
    uint256 marketplaceProceeds;
    uint256 sellerProceeds;
    uint256 infrastructureProceeds;
}

/** 
 * @dev This struct defines the parameters to be used to accumulate payouts for an order.
 *
 * @dev **lastSeller**: The address of the last seller to receive proceeds.
 * @dev **lastMarketplace**: The address of the last marketplace to receive proceeds.
 * @dev **lastRoyaltyRecipient**: The address of the last royalty recipient to receive proceeds.
 * @dev **lastProtocolFeeRecipient**: The address of the last protocol fee recipient to receive proceeds.
 * @dev **accumulatedSellerProceeds**: The total amount of proceeds accumulated for the seller.
 * @dev **accumulatedMarketplaceProceeds**: The total amount of proceeds accumulated for the marketplace.
 * @dev **accumulatedRoyaltyProceeds**: The total amount of proceeds accumulated for the royalty recipient.
 * @dev **accumulatedInfrastructureProceeds**: The total amount of proceeds accumulated for the infrastructure recipient.
 */
struct PayoutsAccumulator {
    address lastSeller;
    address lastMarketplace;
    address lastRoyaltyRecipient;
    address lastProtocolFeeRecipient;
    uint256 accumulatedSellerProceeds;
    uint256 accumulatedMarketplaceProceeds;
    uint256 accumulatedRoyaltyProceeds;
    uint256 accumulatedInfrastructureProceeds;
}

/** 
 * @dev This struct defines the function pointers to be used for the fulfillment of an order.
 *
 * @dev **funcPayout**: The function pointer to use for the payout.
 * @dev **funcDispenseToken**: The function pointer to use for the token dispensation.
 * @dev **funcEmitOrderExecutionEvent**: The function pointer to use for emitting the order execution event.
 */
 struct FulfillOrderFunctionPointers {
    function(address,address,address,uint256) funcPayout;
    function(address,address,address,uint256,uint256) returns (bool) funcDispenseToken;
    function(TradeContext memory, Order memory) funcEmitOrderExecutionEvent;
 }

 /** 
 * @dev This struct defines the context to be used for a trade execution.
 *
 * @dev **channel**: The address of the channel to use for the trade.
 * @dev **taker**: The address of the taker for the trade.
 * @dev **disablePartialFill**: A flag to indicate if partial fills are disabled.
 * @dev **orderDigest**: The digest of the order to be executed.
 * @dev **backfillNumerator**: The numerator to use for the backfill.
 * @dev **backfillReceiver**: The address of the backfill receiver.
 * @dev **bountyNumerator**: The numerator to use for the bounty.
 * @dev **exclusiveMarketplace**: The address of the exclusive marketplace.
 * @dev **useRoyaltyBackfillAsRoyaltySource**: A flag to indicate if the royalty backfill should be used as the royalty source.
 * @dev **protocolFeeVersion**: The protocol fee version to use when applying protocol fees.
 * @dev **protocolFees**: Struct containing the loaded protocol fees for the current context.
 */
 struct TradeContext {
    address channel;
    address taker;
    bool disablePartialFill;
    bytes32 orderDigest;
    uint16 backfillNumerator;
    address backfillReceiver;
    uint16 bountyNumerator;
    address exclusiveMarketplace;
    bool useRoyaltyBackfillAsRoyaltySource;
    uint256 protocolFeeVersion;
    ProtocolFees protocolFees;
 }

/** 
 * @dev This struct defines the items required to handle a permitted order.
 *
 * @dev **permitProcessor**: The address of the permit processor to use for the order.
 * @dev **permitNonce**: The nonce to use for the permit.
 */
 struct PermitContext {
    address permitProcessor;
    uint256 permitNonce;
 }

/** 
 * @dev This struct defines the protocol fees to be applied to a trade based on the protocol fee version.
 *
 * @dev **protocolFeeReceiver**: The address to receive protocol fees.
 * @dev **minimumProtocolFeeBps**: The minimum fee in BPS that is applied to a trade.
 * @dev **marketplaceFeeProtocolTaxBps**: The fee in BPS that is applied to marketplace fees.
 * @dev **feeOnTopProtocolTaxBps**: The fee in BPS that is applied to a fee on top.
 * @dev **versionExpiration**: The timestamp when the protocol fee version expires.
 */
 struct ProtocolFees {
    address protocolFeeReceiver;
    uint16 minimumProtocolFeeBps;
    uint16 marketplaceFeeProtocolTaxBps;
    uint16 feeOnTopProtocolTaxBps;
    uint48 versionExpiration;
 }

/**
 * @dev This struct defines contract-level storage to be used across all Payment Processor modules.
 * @dev Follows the Diamond storage pattern.
 */
struct PaymentProcessorStorage {
    /**
     * @notice User-specific master nonce that allows buyers and sellers to efficiently cancel all listings or offers
     *         they made previously. The master nonce for a user only changes when they explicitly request to revoke all
     *         existing listings and offers.
     *
     * @dev    When prompting sellers to sign a listing or offer, marketplaces must query the current master nonce of
     *         the user and include it in the listing/offer signature data.
     */
    mapping(address => uint256) masterNonces;

    /**
     * @dev The mapping key is the user address.
     *
     * @dev The mapping value is another nested mapping of "slot" (key) to a bitmap (value) containing boolean flags
     *      indicating whether or not a nonce has been used or invalidated.
     *
     * @dev Marketplaces MUST track their own nonce by user, incrementing it for every signed listing or offer the user
     *      creates.  Listings and purchases may be executed out of order, and they may never be executed if orders
     *      are not matched prior to expriation.
     *
     * @dev The slot and the bit offset within the mapped value are computed as:
     *
     * @dev ```slot = nonce / 256;```
     * @dev ```offset = nonce % 256;```
     */
    mapping(address => mapping(uint256 => uint256)) invalidatedSignatures;
    
    /// @dev Mapping of token contract addresses to the collection payment settings.
    mapping (address => CollectionPaymentSettings) collectionPaymentSettings;

    /// @dev Mapping of payment method whitelist id to a defined list of allowed payment methods.
    mapping (uint32 => EnumerableSet.AddressSet) collectionPaymentMethodWhitelists;

    /// @dev Mapping of token contract addresses to the collection-level pricing boundaries (floor and ceiling price).
    mapping (address => PricingBounds) collectionPricingBounds;

    /// @dev Mapping of token contract addresses to the token-level pricing boundaries (floor and ceiling price).
    mapping (address => mapping (uint256 => PricingBounds)) tokenPricingBounds;

    /// @dev Mapping of token contract addresses to the defined pricing constaint payment method.
    mapping (address => address) collectionConstrainedPricingPaymentMethods;

    /// @dev Mapping of token contract addresses to the defined exclusive bounty receivers.
    mapping (address => address) collectionExclusiveBountyReceivers;

    /// @dev Mapping of maker addresses to a mapping of order digests to the status of the partially fillable order for that digest.
    mapping (address => mapping(bytes32 => PartiallyFillableOrderStatus)) partiallyFillableOrderStatuses;

    /// @dev Mapping of token contract addresses to the defined list of trusted channels for the token contract.
    mapping (address => EnumerableSet.AddressSet) collectionTrustedChannels;

    /// @dev A mapping of all co-signers that have self-destructed and can never be used as cosigners again.
    mapping (address => bool) destroyedCosigners;

    /// @dev An enumerable set of trusted permit processors that may be used.
    EnumerableSet.AddressSet trustedPermitProcessors;

    /// @dev Protocol Fee Current Version.
    uint256 currentProtocolFeeVersion;

    /// @dev Protocol Fee Version History.
    mapping (uint256 => ProtocolFees) protocolFeeVersions;
}

//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

/// @dev Thrown when an order is an ERC721 order and the amount is not one.
error PaymentProcessor__AmountForERC721SalesMustEqualOne();

/// @dev Thrown when an order is an ERC1155 order and the amount is zero.
error PaymentProcessor__AmountForERC1155SalesGreaterThanZero();

/// @dev Thrown when processing a permitted order and the order amount exceeds type(uint248).max
error PaymentProcessor__AmountExceedsMaximum();

/// @dev Thrown when appended data length is not zero or twenty bytes.
error PaymentProcessor__BadCalldataLength();

/// @dev Thrown when an offer is being accepted and the payment method is the chain native token.
error PaymentProcessor__BadPaymentMethod();

/**
 * @dev Thrown when a call is made to a function that must be called by the Collection Settings Registry 
 * @dev or by a self call from Payment Processor and the caller is not either of those addresses.
 */
error PaymentProcessor__CallerIsNotSettingsRegistryOrSelf();

/**
 * @dev Thrown when modifying collection payment settings, pricing bounds, or trusted channels on a collection
 * @dev that the caller is not the owner of or a member of the default admin role for.
 */
error PaymentProcessor__CallerMustHaveElevatedPermissionsForSpecifiedNFT();

/// @dev Thrown when the current block time is greater than the expiration time for the cosignature.
error PaymentProcessor__CosignatureHasExpired();

/// @dev Thrown when the cosigner has self destructed.
error PaymentProcessor__CosignerHasSelfDestructed();

/// @dev Thrown when a token failed to transfer to the beneficiary and partial fills are disabled.
error PaymentProcessor__DispensingTokenWasUnsuccessful();

/// @dev Thrown when a maker is a contract and the contract does not return the correct EIP1271 response to validate the signature.
error PaymentProcessor__EIP1271SignatureInvalid();

/// @dev Thrown when a native token transfer call fails to transfer the tokens.
error PaymentProcessor__FailedToTransferProceeds();

/// @dev Thrown when the additional fee on top exceeds the item price.
error PaymentProcessor__FeeOnTopCannotBeGreaterThanItemPrice();

/// @dev Thrown when the supplied root hash, token and proof do not match.
error PaymentProcessor__IncorrectTokenSetMerkleProof();

/// @dev Thrown when an input array has zero items in a location where it must have items.
error PaymentProcessor__InputArrayLengthCannotBeZero();

/// @dev Thrown when multiple input arrays have different lengths but are required to be the same length.
error PaymentProcessor__InputArrayLengthMismatch();

/// @dev Thrown when the height of the bulk order tree is either 0 or greater than 12.
error PaymentProcessor__InvalidBulkOrderHeight();

/// @dev Thrown when Payment Processor or a module is being deployed with invalid constructor arguments.
error PaymentProcessor__InvalidConstructorArguments();

/// @dev Thrown when an offer type parameter is not a valid offer type.
error PaymentProcessor__InvalidOfferType();

/// @dev Thrown when an order protocol parameter is not a valid order protocol type.
error PaymentProcessor__InvalidOrderProtocol();

/// @dev Thrown when a signature `v` value is greater than 255.
error PaymentProcessor__InvalidSignatureV();

/// @dev Thrown when the combined marketplace and royalty fees will exceed the item price.
error PaymentProcessor__MarketplaceAndRoyaltyFeesWillExceedSalePrice();

/// @dev Thrown when the version expiration grace period is exceeded.
error PaymentProcessor__MaxGracePeriodExceeded();

/// @dev Thrown when the recovered address from a cosignature does not match the order cosigner.
error PaymentProcessor__NotAuthorizedByCosigner();

/// @dev Thrown when the ERC2981 or backfilled royalties exceed the maximum fee specified by the order maker.
error PaymentProcessor__OnchainRoyaltiesExceedMaximumApprovedRoyaltyFee();

/// @dev Thrown when the current block timestamp is greater than the order expiration time.
error PaymentProcessor__OrderHasExpired();

/// @dev Thrown when attempting to fill a partially fillable order that has already been filled or cancelled.
error PaymentProcessor__OrderIsEitherCancelledOrFilled();

/// @dev Thrown when attempting to execute a sweep order for partially fillable orders.
error PaymentProcessor__OrderProtocolERC1155FillPartialUnsupportedInSweeps();

/// @dev Thrown when attempting to partially fill an order where the item price is not equally divisible by the amount of tokens.
error PaymentProcessor__PartialFillsNotSupportedForNonDivisibleItems();

/// @dev Thrown when attempting to execute an order with a payment method that is not allowed by the collection payment settings.
error PaymentProcessor__PaymentCoinIsNotAnApprovedPaymentMethod();

/// @dev Thrown when both a permit and a bulk order proof are submitted for an order, as these features are incompatible.
error PaymentProcessor__PermitsAreNotCompatibleWithBulkOrders();

/// @dev Thrown when attempting to use an untrusted permit processing system.
error PaymentProcessor__PermitProcessorNotTrusted();

/// @dev Thrown when the protocol fee is set to a value exceeding the maximum fee cap.
error PaymentProcessor__ProtocolFeeOrTaxExceedsCap();

/// @dev Thrown when the protocol fee version is expired.
error PaymentProcessor__ProtocolFeeVersionExpired();

/// @dev Thrown when distributing payments and fees in native token and the amount remaining is less than the amount to distribute.
error PaymentProcessor__RanOutOfNativeFunds();

/// @dev Thrown when a collection is set to pricing constraints and the item price exceeds the defined maximum price.
error PaymentProcessor__SalePriceAboveMaximumCeiling();

/// @dev Thrown when a collection is set to pricing constraints and the item price is below the defined minimum price.
error PaymentProcessor__SalePriceBelowMinimumFloor();

/// @dev Thrown when a maker's nonce has already been used for an executed order or cancelled by the maker.
error PaymentProcessor__SignatureAlreadyUsedOrRevoked();

/// @dev Thrown when a maker's nonce has not already been used for an executed order but an item with that nonce fails to fill.
error PaymentProcessor__SignatureNotUsedOrRevoked();

/**
 * @dev Thrown when a collection is set to block untrusted channels and the order execution originates from a channel 
 * @dev that is not in the collection's trusted channel list.
 */ 
error PaymentProcessor__TradeOriginatedFromUntrustedChannel();

/// @dev Thrown when a trading of a specific collection has been paused by the collection owner or admin.
error PaymentProcessor__TradingIsPausedForCollection();

/**
 * @dev Thrown when attempting to fill a partially fillable order and the amount available to fill 
 * @dev is less than the specified minimum to fill.
 */
error PaymentProcessor__UnableToFillMinimumRequestedQuantity();

/// @dev Thrown when the recovered signer for an order does not match the order maker.
error PaymentProcessor__UnauthorizedOrder();

/// @dev Thrown when the taker on a cosigned order does not match the taker on the cosignature.
error PaymentProcessor__UnauthorizedTaker();

/// @dev Thrown when the Payment Processor or a module is being deployed with uninitialized configuration values.
error PaymentProcessor__UninitializedConfiguration();

//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

import "./DataTypes.sol";
import "./Errors.sol";
import "./interfaces/IPaymentProcessorConfiguration.sol";

import "@limitbreak/tm-core-lib/src/licenses/LicenseRef-PolyForm-Strict-1.0.0.sol";
import "@limitbreak/tm-core-lib/src/utils/security/RoleClient.sol";

/*
                                                     @@@@@@@@@@@@@@             
                                                    @@@@@@@@@@@@@@@@@@(         
                                                   @@@@@@@@@@@@@@@@@@@@@        
                                                  @@@@@@@@@@@@@@@@@@@@@@@@      
                                                           #@@@@@@@@@@@@@@      
                                                               @@@@@@@@@@@@     
                            @@@@@@@@@@@@@@*                    @@@@@@@@@@@@     
                           @@@@@@@@@@@@@@@     @               @@@@@@@@@@@@     
                          @@@@@@@@@@@@@@@     @                @@@@@@@@@@@      
                         @@@@@@@@@@@@@@@     @@               @@@@@@@@@@@@      
                        @@@@@@@@@@@@@@@     #@@             @@@@@@@@@@@@/       
                        @@@@@@@@@@@@@@.     @@@@@@@@@@@@@@@@@@@@@@@@@@@         
                       @@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@            
                      @@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@             
                     @@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@           
                    @@@@@@@@@@@@@@@     @@@@@&%%%%%%%%&&@@@@@@@@@@@@@@          
                    @@@@@@@@@@@@@@      @@@@@               @@@@@@@@@@@         
                   @@@@@@@@@@@@@@@     @@@@@                 @@@@@@@@@@@        
                  @@@@@@@@@@@@@@@     @@@@@@                 @@@@@@@@@@@        
                 @@@@@@@@@@@@@@@     @@@@@@@                 @@@@@@@@@@@        
                @@@@@@@@@@@@@@@     @@@@@@@                 @@@@@@@@@@@&        
                @@@@@@@@@@@@@@     *@@@@@@@               (@@@@@@@@@@@@         
               @@@@@@@@@@@@@@@     @@@@@@@@             @@@@@@@@@@@@@@          
              @@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           
             @@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            
            @@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              
           .@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                 
           @@@@@@@@@@@@@@%     @@@@@@@@@@@@@@@@@@@@@@@@(                        
          @@@@@@@@@@@@@@@                                                       
         @@@@@@@@@@@@@@@                                                        
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                         
       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                          
       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&                                          
      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                           
 
* @title PermissionlessPaymentProcessorConfiguration
* @custom:version 3.0.0
* @author Limit Break, Inc.
*/ 

contract PermissionlessPaymentProcessorConfiguration is RoleClient, IPaymentProcessorConfiguration {

    bytes32 private constant PP_V3_MODULE_ON_CHAIN_CANCELLATION = keccak256("PP_V3_MODULE_ON_CHAIN_CANCELLATION");
    bytes32 private constant PP_V3_MODULE_BUY_LISTINGS = keccak256("PP_V3_MODULE_BUY_LISTINGS");
    bytes32 private constant PP_V3_MODULE_ACCEPT_OFFERS = keccak256("PP_V3_MODULE_ACCEPT_OFFERS");
    bytes32 private constant PP_V3_MODULE_SWEEPS = keccak256("PP_V3_MODULE_SWEEPS");
    bytes32 private constant PP_V3_MAIN_DETERMINISTIC_ADDRESS = keccak256("PP_V3_MAIN_DETERMINISTIC_ADDRESS");

    ///@dev Configuration Values For Payment Processor Modules
    address private immutable _trustedForwarderFactory;
    address private immutable _wrappedNativeCoin;
    address private immutable defaultPaymentMethod1;
    address private immutable defaultPaymentMethod2;
    address private immutable defaultPaymentMethod3;
    address private immutable defaultPaymentMethod4;
    address private immutable permitProcessor1;
    address private immutable permitProcessor2;
    address private immutable _collectionSettingsRegistry;
    address private immutable _infrastructureFeeReceiver;

    /// @dev Configuration Values For Payment Processor Main Contract
    address private _infrastructureAdmin;

    constructor(
        address roleServer,
        address infrastructureAdmin,
        address infrastructureFeeReceiver,
        address wrappedNative, 
        address trustedForwarderFactory,
        address collectionSettingsRegistry,
        address permitProcessor1_,
        address permitProcessor2_) 
    RoleClient(roleServer) {
        if (roleServer == address(0) ||
            infrastructureAdmin == address(0) ||
            infrastructureFeeReceiver == address(0) ||
            wrappedNative == address(0) ||
            trustedForwarderFactory == address(0) || 
            collectionSettingsRegistry == address(0) ||
            permitProcessor1_ == address(0) ||
            permitProcessor2_ == address(0)) {
            revert PaymentProcessor__InvalidConstructorArguments();
        }

        _infrastructureAdmin = infrastructureAdmin;
        _infrastructureFeeReceiver = infrastructureFeeReceiver;
        _wrappedNativeCoin = wrappedNative;
        _trustedForwarderFactory = trustedForwarderFactory;
        _collectionSettingsRegistry = collectionSettingsRegistry;
        permitProcessor1 = permitProcessor1_;
        permitProcessor2 = permitProcessor2_;

        if (block.chainid == 1) { // ETH MAINNET
            defaultPaymentMethod1 = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
            defaultPaymentMethod2 = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
            defaultPaymentMethod3 = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 10) { // OPTIMISM MAINNET
            defaultPaymentMethod1 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod2 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod3 = address(0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85);
            defaultPaymentMethod4 = address(0x7F5c764cBc14f9669B88837ca1490cCa17c31607);
        } else if (block.chainid == 56) { // BSC MAINNET
            defaultPaymentMethod1 = address(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c);
            defaultPaymentMethod2 = address(0x2170Ed0880ac9A755fd29B2688956BD959F933F8);
            defaultPaymentMethod3 = address(0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 137) { // POLYGON MAINNET
            defaultPaymentMethod1 = address(0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270);
            defaultPaymentMethod2 = address(0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619);
            defaultPaymentMethod3 = address(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359);
            defaultPaymentMethod4 = address(0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174);
        } else if (block.chainid == 324) { // ZKSYNC MAINNET
            defaultPaymentMethod1 = address(0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91);
            defaultPaymentMethod2 = address(0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4);
        } else if (block.chainid == 1101) { // POLYGON ZKEVM MAINNET
            defaultPaymentMethod1 = address(0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9);
            defaultPaymentMethod2 = address(0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9);
            defaultPaymentMethod3 = address(0xA8CE8aee21bC2A48a5EF670afCc9274C7bbbC035);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 8453) { // BASE MAINNET
            defaultPaymentMethod1 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod2 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod3 = address(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);
            defaultPaymentMethod4 = address(0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA);
        } else if (block.chainid == 42161) { // ARBITRUM MAINNET
            defaultPaymentMethod1 = address(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1);
            defaultPaymentMethod2 = address(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1);
            defaultPaymentMethod3 = address(0xaf88d065e77c8cC2239327C5EDb3A432268e5831);
            defaultPaymentMethod4 = address(0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8);
        } else if (block.chainid == 42170) { // ARBITRUM NOVA MAINNET
            defaultPaymentMethod1 = address(0x722E8BdD2ce80A4422E880164f2079488e115365);
            defaultPaymentMethod2 = address(0x722E8BdD2ce80A4422E880164f2079488e115365);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 43114) { // AVALANCHE MAINNET
            defaultPaymentMethod1 = address(0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7);
            defaultPaymentMethod2 = address(0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB);
            defaultPaymentMethod3 = address(0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 59144) { // LINEA MAINNET
            defaultPaymentMethod1 = address(0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f);
            defaultPaymentMethod2 = address(0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 7777777) { // ZORA MAINNET
            defaultPaymentMethod1 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod2 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 534352) { // SCROLL MAINNET
            defaultPaymentMethod1 = address(0x5300000000000000000000000000000000000004);
            defaultPaymentMethod2 = address(0x5300000000000000000000000000000000000004);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 5) { // GOERLI TESTNET
            defaultPaymentMethod1 = address(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6);
            defaultPaymentMethod2 = address(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6);
            defaultPaymentMethod3 = address(0x07865c6E87B9F70255377e024ace6630C1Eaa37F);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 999) { // ZORA TESTNET
            defaultPaymentMethod1 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod2 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 5001) { // MANTLE TESTNET
            defaultPaymentMethod1 = address(0xbAAFeC4B6eF4F5E0bAFA850CBC48364B953EFCf9);
            defaultPaymentMethod2 = address(0xbAAFeC4B6eF4F5E0bAFA850CBC48364B953EFCf9);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 59140) { // LINEA TESTNET
            defaultPaymentMethod1 = address(0x2C1b868d6596a18e32E61B901E4060C872647b6C);
            defaultPaymentMethod2 = address(0x2C1b868d6596a18e32E61B901E4060C872647b6C);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 80001) { // MUMBAI TESTNET
            defaultPaymentMethod1 = address(0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889);
            defaultPaymentMethod2 = address(0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa);
            defaultPaymentMethod3 = address(0x9999f7Fea5938fD3b1E26A12c3f2fb024e194f97);
            defaultPaymentMethod4 = address(0x0FA8781a83E46826621b3BC094Ea2A0212e71B23);
        } else if (block.chainid == 84531) { // BASE GOERLI TESTNET
            defaultPaymentMethod1 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod2 = address(0x4200000000000000000000000000000000000006);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 534353) { // SCROLL ALPHA TESTNET
            defaultPaymentMethod1 = address(0x7160570BB153Edd0Ea1775EC2b2Ac9b65F1aB61B);
            defaultPaymentMethod2 = address(0x7160570BB153Edd0Ea1775EC2b2Ac9b65F1aB61B);
            defaultPaymentMethod3 = address(0x0000000000000000000000000000000000000000);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        } else if (block.chainid == 11155111) { // SEPOLIA TESTNET
            defaultPaymentMethod1 = address(0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9);
            defaultPaymentMethod2 = address(0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9);
            defaultPaymentMethod3 = address(0x8267cF9254734C6Eb452a7bb9AAF97B392258b21);
            defaultPaymentMethod4 = address(0x0000000000000000000000000000000000000000);
        }
    }

    /**
     * @notice Returns the ERC2771 context setup params for payment processor modules.
     */
    function getPaymentProcessorModuleERC2771ContextParams() external view returns (address trustedForwarderFactory) {
        trustedForwarderFactory = _trustedForwarderFactory;
    }

    /**
     * @notice Returns the setup params for payment processor modules.
     */
    function getPaymentProcessorModuleDeploymentParams() 
        external 
        view 
        returns (
            address deterministicPaymentProcessorAddress,
            address wrappedNativeCoin,
            DefaultPaymentMethods memory defaultPaymentMethods,
            TrustedPermitProcessors memory trustedPermitProcessors,
            address collectionSettingsRegistry,
            address infrastructureFeeReceiver
        ) 
    {
        deterministicPaymentProcessorAddress = _getRoleHolderView(PP_V3_MAIN_DETERMINISTIC_ADDRESS);

        if (deterministicPaymentProcessorAddress == address(0)) {
            revert PaymentProcessor__UninitializedConfiguration();
        }

        wrappedNativeCoin = _wrappedNativeCoin;
        defaultPaymentMethods = DefaultPaymentMethods({
            defaultPaymentMethod1: defaultPaymentMethod1,
            defaultPaymentMethod2: defaultPaymentMethod2,
            defaultPaymentMethod3: defaultPaymentMethod3,
            defaultPaymentMethod4: defaultPaymentMethod4
        });
        trustedPermitProcessors = TrustedPermitProcessors({
            permitProcessor1: permitProcessor1,
            permitProcessor2: permitProcessor2
        });
        collectionSettingsRegistry = _collectionSettingsRegistry;
        infrastructureFeeReceiver = _infrastructureFeeReceiver;
    }

    /**
     * @notice Returns the setup params for payment processor.
     */
    function getPaymentProcessorDeploymentParams()
        external
        view
        returns (
            address defaultContractOwner,
            PaymentProcessorModules memory paymentProcessorModules
        )
    {
        defaultContractOwner = _infrastructureAdmin;

        paymentProcessorModules = PaymentProcessorModules({
            moduleOnChainCancellation: _getRoleHolderView(PP_V3_MODULE_ON_CHAIN_CANCELLATION),
            moduleBuyListings: _getRoleHolderView(PP_V3_MODULE_BUY_LISTINGS),
            moduleAcceptOffers: _getRoleHolderView(PP_V3_MODULE_ACCEPT_OFFERS),
            moduleSweeps: _getRoleHolderView(PP_V3_MODULE_SWEEPS)
        });

        if (paymentProcessorModules.moduleOnChainCancellation == address(0) ||
            paymentProcessorModules.moduleBuyListings == address(0) ||
            paymentProcessorModules.moduleAcceptOffers == address(0) ||
            paymentProcessorModules.moduleSweeps == address(0)) {
            revert PaymentProcessor__UninitializedConfiguration();
        }
    }

    function _setupRoles() internal virtual override {
        _setupRole(PP_V3_MODULE_ON_CHAIN_CANCELLATION, 0);
        _setupRole(PP_V3_MODULE_BUY_LISTINGS, 0);
        _setupRole(PP_V3_MODULE_ACCEPT_OFFERS, 0);
        _setupRole(PP_V3_MODULE_SWEEPS, 0);
        _setupRole(PP_V3_MAIN_DETERMINISTIC_ADDRESS, 0);
    }
}

//SPDX-License-Identifier: LicenseRef-PolyForm-Strict-1.0.0
pragma solidity 0.8.24;

import "../DataTypes.sol";

/** 
* @title IPaymentProcessorConfiguration
* @custom:version 3.0.0
* @author Limit Break, Inc.
*/ 
interface IPaymentProcessorConfiguration {

    /**
     * @notice Returns the ERC2771 context setup params for payment processor modules.
     */
    function getPaymentProcessorModuleERC2771ContextParams() 
        external 
        view 
        returns (
            address /*trustedForwarderFactory*/
        );

    /**
     * @notice Returns the setup params for payment processor modules.
     */
    function getPaymentProcessorModuleDeploymentParams() 
        external 
        view 
        returns (
            address, /*deterministicPaymentProcessorAddress*/
            address, /*wrappedNativeCoin*/
            DefaultPaymentMethods memory /*defaultPaymentMethods*/,
            TrustedPermitProcessors memory /*trustedPermitProcessors*/,
            address /*collectionPaymentSettings*/,
            address /*infrastructureFeeReceiver*/
        );

    /**
     * @notice Returns the setup params for payment processor.
     */
    function getPaymentProcessorDeploymentParams()
        external
        view
        returns (
            address, /*defaultContractOwner*/
            PaymentProcessorModules memory /*paymentProcessorModules*/
        );
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):